jenkins-bot has submitted this change and it was merged.

Change subject: Make controlbar layout depend on the player width
......................................................................


Make controlbar layout depend on the player width

Uses a new videojs plugin to apply layout classes depending on the
width of the player. As fewer width is available, controls like
time remaining, fullscreen or progress are dropped from the layout.

Bug: T119049
Change-Id: I60307f1ccd5300359920c4ce6e63144eece2e75d
---
M .jshintignore
M Gruntfile.js
M TimedMediaHandler.hooks.php
M package.json
M resources/ext.tmh.player.js
A resources/videojs-responsive-layout/videojs-responsive-layout.js
A resources/videojs-responsive-layout/videojs-responsive-layout.min.js
7 files changed, 468 insertions(+), 3 deletions(-)

Approvals:
  Brion VIBBER: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/.jshintignore b/.jshintignore
index 2ffb9b1..caf89b4 100644
--- a/.jshintignore
+++ b/.jshintignore
@@ -1,6 +1,7 @@
 MwEmbedModules
 resources/videojs
 resources/videojs-resolution-switcher
+resources/videojs-responsive-layout
 
 node_modules
 vendor
diff --git a/Gruntfile.js b/Gruntfile.js
index e978e49..acadfd5 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -35,7 +35,7 @@
                },
                exec: {
                        'npm-update-videojs': {
-                               cmd: 'npm update video.js 
videojs-resolution-switcher videojs-ogvjs',
+                               cmd: 'npm update video.js 
videojs-resolution-switcher videojs-ogvjs videojs-responsive-layout',
                                callback: function ( error, stdout, stderr ) {
                                        grunt.log.write( stdout );
                                        if ( stderr ) {
@@ -74,6 +74,12 @@
                                cwd: 
'node_modules/videojs-resolution-switcher/lib/',
                                src: [ '**' ],
                                dest: 'resources/videojs-resolution-switcher/'
+                       },
+                       'videojs-responsive-layout': {
+                               expand: true,
+                               cwd: 
'node_modules/videojs-responsive-layout/dist/',
+                               src: [ '**' ],
+                               dest: 'resources/videojs-responsive-layout/'
                        }
                },
                patch: {
@@ -89,7 +95,7 @@
                }
        } );
 
-       grunt.registerTask( 'update-videojs', [ 'exec:npm-update-videojs', 
'copy:video.js', 'copy:videojs-resolution-switcher', 'copy:videojs-ogvjs', 
'patch:video.js' ] );
+       grunt.registerTask( 'update-videojs', [ 'exec:npm-update-videojs', 
'copy:video.js', 'copy:videojs-resolution-switcher', 'copy:videojs-ogvjs', 
'copy:videojs-responsive-layout', 'patch:video.js' ] );
        grunt.registerTask( 'test', [ 'jshint', 'jscs', 'jsonlint', 'banana' ] 
);
        grunt.registerTask( 'default', 'test' );
 };
diff --git a/TimedMediaHandler.hooks.php b/TimedMediaHandler.hooks.php
index 3cf00f7..406f55c 100644
--- a/TimedMediaHandler.hooks.php
+++ b/TimedMediaHandler.hooks.php
@@ -148,6 +148,13 @@
                                                        'ext.tmh.video-js',
                                                ),
                                        ),
+                               'ext.tmh.videojs-responsive-layout' => 
$baseExtensionResource + array(
+                                               'scripts' => 
'resources/videojs-responsive-layout/videojs-responsive-layout.js',
+                                               'targets' => array( 'mobile', 
'desktop' ),
+                                               'dependencies' => array(
+                                                       'ext.tmh.video-js',
+                                               ),
+                                       ),
                                'ext.tmh.player' => $baseExtensionResource + 
array(
                                                'scripts' => 
'resources/ext.tmh.player.js',
                                                'targets' => array( 'mobile', 
'desktop' ),
@@ -155,6 +162,7 @@
                                                        'ext.tmh.video-js',
                                                        
'ext.tmh.videojs-resolution-switcher',
                                                        'ext.tmh.videojs-ogvjs',
+                                                       
'ext.tmh.videojs-responsive-layout',
                                                        // 
'ext.tmh.videojs-offset',
                                                ),
                                        ),
diff --git a/package.json b/package.json
index d4d3b50..9b5eaed 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
     "jscs-preset-wikimedia": "~1.0.0",
     "video.js": "^5.8.6",
     "videojs-ogvjs": "^1.0.6",
-    "videojs-resolution-switcher": "^0.4.1"
+    "videojs-resolution-switcher": "^0.4.1",
+    "videojs-responsive-layout": "^1.1.0"
   }
 }
diff --git a/resources/ext.tmh.player.js b/resources/ext.tmh.player.js
index 7af02b7..5e303f5 100755
--- a/resources/ext.tmh.player.js
+++ b/resources/ext.tmh.player.js
@@ -16,6 +16,14 @@
                plugins: {
                        videoJsResolutionSwitcher: {
                                sourceOrder: true
+                       },
+                       responsiveLayout: {
+                               layoutMap: [
+                                       { layoutClassName: 'vjs-layout-tiny', 
width: 3 },
+                                       { layoutClassName: 
'vjs-layout-x-small', width: 4 },
+                                       { layoutClassName: 'vjs-layout-small', 
width: 5 },
+                                       { layoutClassName: 'defaults', width: 6 
}
+                               ]
                        }
                },
                ogvjs: {
diff --git a/resources/videojs-responsive-layout/videojs-responsive-layout.js 
b/resources/videojs-responsive-layout/videojs-responsive-layout.js
new file mode 100644
index 0000000..e9233d9
--- /dev/null
+++ b/resources/videojs-responsive-layout/videojs-responsive-layout.js
@@ -0,0 +1,434 @@
+/**
+ * videojs-responsive-layout
+ * @version 1.1.1
+ * @copyright 2016 Derk-Jan Hartman
+ * @license (MIT OR Apache-2.0)
+ */
+(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.videojsResponsiveLayout = 
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(require,module,exports){
+
+},{}],2:[function(require,module,exports){
+var throttle = require('./throttle');
+
+/**
+ * Debounce execution of a function. Debouncing, unlike throttling,
+ * guarantees that a function is only executed a single time, either at the
+ * very beginning of a series of calls, or at the very end.
+ *
+ * @param  {Number}   delay         A zero-or-greater delay in milliseconds. 
For event callbacks, values around 100 or 250 (or even higher) are most useful.
+ * @param  {Boolean}  atBegin       Optional, defaults to false. If atBegin is 
false or unspecified, callback will only be executed `delay` milliseconds
+ *                                  after the last debounced-function call. If 
atBegin is true, callback will be executed only at the first debounced-function 
call.
+ *                                  (After the throttled-function has not been 
called for `delay` milliseconds, the internal counter is reset).
+ * @param  {Function} callback      A function to be executed after delay 
milliseconds. The `this` context and all arguments are passed through, as-is,
+ *                                  to `callback` when the debounced-function 
is executed.
+ *
+ * @return {Function} A new, debounced function.
+ */
+module.exports = function ( delay, atBegin, callback ) {
+       return callback === undefined ? throttle(delay, atBegin, false) : 
throttle(delay, callback, atBegin !== false);
+};
+
+},{"./throttle":4}],3:[function(require,module,exports){
+module.exports = {
+       throttle: require('./throttle'),
+       debounce: require('./debounce')
+};
+
+},{"./debounce":2,"./throttle":4}],4:[function(require,module,exports){
+var $ = require('jquery');
+
+/**
+ * Throttle execution of a function. Especially useful for rate limiting
+ * execution of handlers on events like resize and scroll.
+ *
+ * @param  {Number}    delay          A zero-or-greater delay in milliseconds. 
For event callbacks, values around 100 or 250 (or even higher) are most useful.
+ * @param  {Boolean}   noTrailing     Optional, defaults to false. If 
noTrailing is true, callback will only execute every `delay` milliseconds while 
the
+ *                                    throttled-function is being called. If 
noTrailing is false or unspecified, callback will be executed one final time
+ *                                    after the last throttled-function call. 
(After the throttled-function has not been called for `delay` milliseconds,
+ *                                    the internal counter is reset)
+ * @param  {Function}  callback       A function to be executed after delay 
milliseconds. The `this` context and all arguments are passed through, as-is,
+ *                                    to `callback` when the 
throttled-function is executed.
+ * @param  {Boolean}   debounceMode   If `debounceMode` is true (at begin), 
schedule `clear` to execute after `delay` ms. If `debounceMode` is false (at 
end),
+ *                                    schedule `callback` to execute after 
`delay` ms.
+ *
+ * @return {Function}  A new, throttled, function.
+ */
+module.exports = function ( delay, noTrailing, callback, debounceMode ) {
+
+       // After wrapper has stopped being called, this timeout ensures that
+       // `callback` is executed at the proper times in `throttle` and `end`
+       // debounce modes.
+       var timeoutID;
+
+       // Keep track of the last time `callback` was executed.
+       var lastExec = 0;
+
+       // `noTrailing` defaults to falsy.
+       if ( typeof(noTrailing) !== 'boolean' ) {
+               debounceMode = callback;
+               callback = noTrailing;
+               noTrailing = undefined;
+       }
+
+       // The `wrapper` function encapsulates all of the throttling / 
debouncing
+       // functionality and when executed will limit the rate at which 
`callback`
+       // is executed.
+       function wrapper () {
+
+               var self = this;
+               var elapsed = Number(new Date()) - lastExec;
+               var args = arguments;
+
+               // Execute `callback` and update the `lastExec` timestamp.
+               function exec () {
+                       lastExec = Number(new Date());
+                       callback.apply(self, args);
+               }
+
+               // If `debounceMode` is true (at begin) this is used to clear 
the flag
+               // to allow future `callback` executions.
+               function clear () {
+                       timeoutID = undefined;
+               }
+
+               if ( debounceMode && !timeoutID ) {
+                       // Since `wrapper` is being called for the first time 
and
+                       // `debounceMode` is true (at begin), execute 
`callback`.
+                       exec();
+               }
+
+               // Clear any existing timeout.
+               if ( timeoutID ) {
+                       clearTimeout(timeoutID);
+               }
+
+               if ( debounceMode === undefined && elapsed > delay ) {
+                       // In throttle mode, if `delay` time has been exceeded, 
execute
+                       // `callback`.
+                       exec();
+
+               } else if ( noTrailing !== true ) {
+                       // In trailing throttle mode, since `delay` time has 
not been
+                       // exceeded, schedule `callback` to execute `delay` ms 
after most
+                       // recent execution.
+                       //
+                       // If `debounceMode` is true (at begin), schedule 
`clear` to execute
+                       // after `delay` ms.
+                       //
+                       // If `debounceMode` is false (at end), schedule 
`callback` to
+                       // execute after `delay` ms.
+                       timeoutID = setTimeout(debounceMode ? clear : exec, 
debounceMode === undefined ? delay - elapsed : delay);
+               }
+
+       }
+
+       // Set the guid of `wrapper` function to the same of original callback, 
so
+       // it can be removed in jQuery 1.4+ .unbind or .die by using the 
original
+       // callback as a reference.
+       if ( $ && $.guid ) {
+               wrapper.guid = callback.guid = callback.guid || $.guid++;
+       }
+
+       // Return the wrapper function.
+       return wrapper;
+
+};
+
+},{"jquery":1}],5:[function(require,module,exports){
+(function (global){
+/* jshint esnext:true */
+'use strict';
+
+Object.defineProperty(exports, '__esModule', {
+  value: true
+});
+
+var _createClass = (function () { function defineProperties(target, props) { 
for (var i = 0; i < props.length; i++) { var descriptor = props[i]; 
descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable 
= true; if ('value' in descriptor) descriptor.writable = true; 
Object.defineProperty(target, descriptor.key, descriptor); } } return function 
(Constructor, protoProps, staticProps) { if (protoProps) 
defineProperties(Constructor.prototype, protoProps); if (staticProps) 
defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 
'default': obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof 
Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+var _videoJs = (typeof window !== "undefined" ? window['videojs'] : typeof 
global !== "undefined" ? global['videojs'] : null);
+
+var _videoJs2 = _interopRequireDefault(_videoJs);
+
+var debounce = require('throttle-debounce').debounce;
+
+// Default options for the plugin.
+var defaults = {
+  debounceDelay: 200,
+  layoutMap: [{ layoutClassName: 'vjs-layout-tiny', width: 2 }, { 
layoutClassName: 'vjs-layout-x-small', width: 3 }, { layoutClassName: 
'vjs-layout-small', width: 4 }, { layoutClassName: 'defaults', width: 5 }]
+};
+
+/**
+ * Retrieve the outerWidth of an element, including margins
+ *
+ * @function getElementOuterWidth
+ * @param    {Element} el to measure
+ * @return   {number} the width of the element in pixels
+ */
+var _getElementOuterWidth = function _getElementOuterWidth(el) {
+  var width = el.offsetWidth;
+  var style = getComputedStyle(el);
+
+  width += parseInt(style.marginLeft, 10) + parseInt(style.marginRight, 10);
+  return width;
+};
+
+/**
+ * Retrieve the width an element
+ *
+ * @function getElementWidth
+ * @param    {Element} el to measure
+ * @return   {number} the width of the element in pixels
+ */
+var _getElementWidth = function _getElementWidth(el) {
+  return parseInt(getComputedStyle(el).width, 10);
+};
+
+/**
+ * Check if an element is currently visible.
+ *
+ * Use this to filter on elements that should be taken into account during 
calculations.
+ *
+ * @function isElementVisible
+ * @param    {Element} el to test
+ * @return   {boolean} true if el is visible
+ */
+var _isElementVisible = function _isElementVisible(el) {
+  return el.offsetWidth > 0 || el.offsetHeight > 0;
+};
+
+var dimensionsCheck = function dimensionsCheck() {
+  /**
+   * Set a layout class on a video-js element
+   *
+   * @function setLayout
+   * @param    {Player} player to apply the layout to
+   */
+  var setLayout = function setLayout(layouter) {
+    var el = layouter.player.el();
+    var layoutDefinition = layouter.options.layoutMap[layouter.currentLayout_];
+
+    if (layoutDefinition.layoutClassName !== 'defaults') {
+      _videoJs2['default'].addClass(el, layoutDefinition.layoutClassName);
+    }
+    layouter.options.layoutMap.forEach(function (element, index) {
+      if (index !== layouter.currentLayout_ && element.layoutClassName !== 
'defaults') {
+        _videoJs2['default'].removeClass(el, element.layoutClassName);
+      }
+    });
+  };
+
+  /**
+   * Calculate for the giving dimensions which layout class of the layoutMap 
should be
+   * used
+   *
+   * @function setLayout
+   * @param    {Player} player to apply the layout to
+   */
+  var calculateLayout = function calculateLayout(layouter, playerWidth, 
controlBarWidth, controlWidth) {
+    var layoutMap = layouter.options.layoutMap;
+
+    if (controlBarWidth > playerWidth && layouter.currentLayout_ > 0) {
+      // smaller
+      layouter.currentLayout_--;
+      setLayout(layouter);
+      window.setTimeout(dimensionsCheck.bind(layouter), 1);
+    } else if (layouter.currentLayout_ < layoutMap.length - 1 && playerWidth 
>= layoutMap[layouter.currentLayout_ + 1].width * controlWidth) {
+      // bigger
+      layouter.currentLayout_++;
+      setLayout(layouter);
+      window.setTimeout(dimensionsCheck.bind(layouter), 1);
+    }
+  };
+
+  if (!this.el || this.player.usingNativeControls() || 
!_isElementVisible(this.el.querySelectorAll('.vjs-control-bar')[0])) {
+    return;
+  }
+  var playerWidth = this.getPlayerWidth();
+  var controlWidth = this.getControlWidth();
+  var controlBarWidth = this.getControlBarWidth();
+
+  if (this.options.calculateLayout) {
+    this.options.calculateLayout(this, playerWidth, controlBarWidth, 
controlWidth);
+  } else {
+    calculateLayout(this, playerWidth, controlBarWidth, controlWidth);
+  }
+};
+
+var Layouter = (function () {
+  function Layouter(player, options) {
+    _classCallCheck(this, Layouter);
+
+    this.player_ = player;
+    this.options_ = options;
+    this.currentLayout_ = options.layoutMap.length - 1;
+    this.debouncedCheckSize_ = debounce(options.debounceDelay, 
dimensionsCheck);
+  }
+
+  /**
+   * A video.js plugin.
+   *
+   * In the plugin function, the value of `this` is a video.js `Player`
+   * instance. You cannot rely on the player being in a "ready" state here,
+   * depending on how the plugin is invoked. This may or may not be important
+   * to you; if not, remove the wait for "ready"!
+   *
+   * @function responsiveLayout
+   * @param    {Object} [options={}]
+   *           An object of options left to the plugin author to define.
+   */
+
+  _createClass(Layouter, [{
+    key: 'ready',
+    value: function ready() {
+      var _this = this;
+
+      this.player.addClass('vjs-responsive-layout');
+
+      this.windowResizeListener_ = window.addEventListener('resize', function 
() {
+        return _this.debouncedCheckSize_();
+      });
+
+      this.player.on(['play', 'resize'], function () {
+        return _this.debouncedCheckSize_();
+      });
+      this.player.on('dispose', function () {
+        window.removeEventListener('resize', this.windowResizeListener_);
+      });
+
+      // Let's do the first measure
+      this.player.trigger('resize');
+    }
+
+    /**
+     * Retrieve player to which this Layouter object belongs
+     *
+     * @property player
+     * @return   {number} the width of the controlbar in pixels
+     */
+  }, {
+    key: 'getControlWidth',
+
+    /**
+     * Retrieve current width of a control in the video.js controlbar
+     *
+     * This function relies on the presence of the play control. If you
+     * mess with it's visibility, things likely will break :)
+     *
+     * @function getControlWidth
+     * @return   {number} the width of the controlbar in pixels
+     */
+    value: function getControlWidth() {
+      return 
_getElementOuterWidth(this.el.querySelectorAll('.vjs-play-control')[0]);
+    }
+
+    /**
+     * Retrieve current width of the video.js controlbar
+     *
+     * @function getControlBarWidth
+     * @return   {number} the width of the controlbar in pixels
+     */
+  }, {
+    key: 'getControlBarWidth',
+    value: function getControlBarWidth() {
+      var controlBarWidth = 0;
+      var cbElements = this.el.querySelectorAll('.vjs-control-bar > *');
+
+      Array.from(cbElements).forEach(function (el) {
+        if (_isElementVisible(el)) {
+          controlBarWidth += _getElementOuterWidth(el);
+        }
+      });
+      return controlBarWidth;
+    }
+
+    /**
+     * Retrieve current width of the video.js player element
+     *
+     * @function getPlayerWidth
+     * @return   {number} the width of the player in pixels
+     */
+  }, {
+    key: 'getPlayerWidth',
+    value: function getPlayerWidth() {
+      return _getElementWidth(this.el);
+    }
+
+    /**
+     * Retrieve the outerWidth of an element, including margins
+     *
+     * @function outerWidth
+     * @param    {Element} el to measure
+     * @return   {number} the width of the element in pixels
+     */
+  }, {
+    key: 'player',
+    get: function get() {
+      return this.player_;
+    }
+  }, {
+    key: 'el',
+    get: function get() {
+      return this.player_.el();
+    }
+  }, {
+    key: 'options',
+    get: function get() {
+      return this.options_;
+    }
+  }], [{
+    key: 'getElementOuterWidth',
+    value: function getElementOuterWidth(el) {
+      return _getElementOuterWidth(el);
+    }
+
+    /**
+     * Retrieve the width an element
+     *
+     * @function getElementWidth
+     * @param    {Element} el to measure
+     * @return   {number} the width of the element in pixels
+     */
+  }, {
+    key: 'getElementWidth',
+    value: function getElementWidth(el) {
+      return _getElementWidth(el);
+    }
+
+    /**
+     * Check if an element is currently visible.
+     *
+     * Use this to filter on elements that should be taken into account during 
calculations.
+     *
+     * @function isElementVisible
+     * @param    {Element} el to test
+     * @return   {boolean} true if el is visible
+     */
+  }, {
+    key: 'isElementVisible',
+    value: function isElementVisible(el) {
+      return _isElementVisible(el);
+    }
+  }]);
+
+  return Layouter;
+})();
+
+var responsiveLayout = function responsiveLayout(options) {
+  var layout = new Layouter(this, _videoJs2['default'].mergeOptions(defaults, 
options));
+
+  this.ready(function () {
+    layout.ready();
+  });
+};
+
+// Register the plugin with video.js.
+_videoJs2['default'].plugin('responsiveLayout', responsiveLayout);
+
+exports['default'] = responsiveLayout;
+module.exports = exports['default'];
+}).call(this,typeof global !== "undefined" ? global : typeof self !== 
"undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"throttle-debounce":3}]},{},[5])(5)
+});
\ No newline at end of file
diff --git 
a/resources/videojs-responsive-layout/videojs-responsive-layout.min.js 
b/resources/videojs-responsive-layout/videojs-responsive-layout.min.js
new file mode 100644
index 0000000..5715da4
--- /dev/null
+++ b/resources/videojs-responsive-layout/videojs-responsive-layout.min.js
@@ -0,0 +1,7 @@
+/**
+ * videojs-responsive-layout
+ * @version 1.1.1
+ * @copyright 2016 Derk-Jan Hartman
+ * @license (MIT OR Apache-2.0)
+ */
+!function(e){if("object"==typeof exports&&"undefined"!=typeof 
module)module.exports=e();else if("function"==typeof 
define&&define.amd)define([],e);else{var t;t="undefined"!=typeof 
window?window:"undefined"!=typeof global?global:"undefined"!=typeof 
self?self:this,t.videojsResponsiveLayout=e()}}(function(){return function 
e(t,n,o){function i(u,a){if(!n[u]){if(!t[u]){var l="function"==typeof 
require&&require;if(!a&&l)return l(u,!0);if(r)return r(u,!0);var s=new 
Error("Cannot find module '"+u+"'");throw s.code="MODULE_NOT_FOUND",s}var 
f=n[u]={exports:{}};t[u][0].call(f.exports,function(e){var n=t[u][1][e];return 
i(n?n:e)},f,f.exports,e,t,n,o)}return n[u].exports}for(var r="function"==typeof 
require&&require,u=0;u<o.length;u++)i(o[u]);return 
i}({1:[function(e,t,n){},{}],2:[function(e,t,n){var 
o=e("./throttle");t.exports=function(e,t,n){return void 
0===n?o(e,t,!1):o(e,n,t!==!1)}},{"./throttle":4}],3:[function(e,t,n){t.exports={throttle:e("./throttle"),debounce:e("./debounce")}},{"./debounce":2,"./throttle":4}],4:[function(e,t,n){var
 o=e("jquery");t.exports=function(e,t,n,i){function r(){function 
o(){a=Number(new Date),n.apply(l,f)}function r(){u=void 0}var 
l=this,s=Number(new Date)-a,f=arguments;i&&!u&&o(),u&&clearTimeout(u),void 
0===i&&s>e?o():t!==!0&&(u=setTimeout(i?r:o,void 0===i?e-s:e))}var 
u,a=0;return"boolean"!=typeof t&&(i=n,n=t,t=void 
0),o&&o.guid&&(r.guid=n.guid=n.guid||o.guid++),r}},{jquery:1}],5:[function(e,t,n){(function(o){"use
 strict";function i(e){return e&&e.__esModule?e:{"default":e}}function 
r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a 
function")}Object.defineProperty(n,"__esModule",{value:!0});var 
u=function(){function e(e,t){for(var n=0;n<t.length;n++){var 
o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in 
o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return 
function(t,n,o){return 
n&&e(t.prototype,n),o&&e(t,o),t}}(),a="undefined"!=typeof 
window?window.videojs:"undefined"!=typeof 
o?o.videojs:null,l=i(a),s=e("throttle-debounce").debounce,f={debounceDelay:200,layoutMap:[{layoutClassName:"vjs-layout-tiny",width:2},{layoutClassName:"vjs-layout-x-small",width:3},{layoutClassName:"vjs-layout-small",width:4},{layoutClassName:"defaults",width:5}]},d=function(e){var
 t=e.offsetWidth,n=getComputedStyle(e);return 
t+=parseInt(n.marginLeft,10)+parseInt(n.marginRight,10)},c=function(e){return 
parseInt(getComputedStyle(e).width,10)},y=function(e){return 
e.offsetWidth>0||e.offsetHeight>0},h=function w(){var e=function(e){var 
t=e.player.el(),n=e.options.layoutMap[e.currentLayout_];"defaults"!==n.layoutClassName&&l["default"].addClass(t,n.layoutClassName),e.options.layoutMap.forEach(function(n,o){o!==e.currentLayout_&&"defaults"!==n.layoutClassName&&l["default"].removeClass(t,n.layoutClassName)})},t=function(t,n,o,i){var
 
r=t.options.layoutMap;o>n&&t.currentLayout_>0?(t.currentLayout_--,e(t),window.setTimeout(w.bind(t),1)):t.currentLayout_<r.length-1&&n>=r[t.currentLayout_+1].width*i&&(t.currentLayout_++,e(t),window.setTimeout(w.bind(t),1))};if(this.el&&!this.player.usingNativeControls()&&y(this.el.querySelectorAll(".vjs-control-bar")[0])){var
 
n=this.getPlayerWidth(),o=this.getControlWidth(),i=this.getControlBarWidth();this.options.calculateLayout?this.options.calculateLayout(this,n,i,o):t(this,n,i,o)}},p=function(){function
 
e(t,n){r(this,e),this.player_=t,this.options_=n,this.currentLayout_=n.layoutMap.length-1,this.debouncedCheckSize_=s(n.debounceDelay,h)}return
 u(e,[{key:"ready",value:function(){var 
e=this;this.player.addClass("vjs-responsive-layout"),this.windowResizeListener_=window.addEventListener("resize",function(){return
 e.debouncedCheckSize_()}),this.player.on(["play","resize"],function(){return 
e.debouncedCheckSize_()}),this.player.on("dispose",function(){window.removeEventListener("resize",this.windowResizeListener_)}),this.player.trigger("resize")}},{key:"getControlWidth",value:function(){return
 
d(this.el.querySelectorAll(".vjs-play-control")[0])}},{key:"getControlBarWidth",value:function(){var
 e=0,t=this.el.querySelectorAll(".vjs-control-bar > *");return 
Array.from(t).forEach(function(t){y(t)&&(e+=d(t))}),e}},{key:"getPlayerWidth",value:function(){return
 c(this.el)}},{key:"player",get:function(){return 
this.player_}},{key:"el",get:function(){return 
this.player_.el()}},{key:"options",get:function(){return 
this.options_}}],[{key:"getElementOuterWidth",value:function(e){return 
d(e)}},{key:"getElementWidth",value:function(e){return 
c(e)}},{key:"isElementVisible",value:function(e){return 
y(e)}}]),e}(),v=function(e){var t=new 
p(this,l["default"].mergeOptions(f,e));this.ready(function(){t.ready()})};l["default"].plugin("responsiveLayout",v),n["default"]=v,t.exports=n["default"]}).call(this,"undefined"!=typeof
 global?global:"undefined"!=typeof self?self:"undefined"!=typeof 
window?window:{})},{"throttle-debounce":3}]},{},[5])(5)});
\ No newline at end of file

-- 
To view, visit https://gerrit.wikimedia.org/r/258359
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I60307f1ccd5300359920c4ce6e63144eece2e75d
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/extensions/TimedMediaHandler
Gerrit-Branch: master
Gerrit-Owner: TheDJ <[email protected]>
Gerrit-Reviewer: Brion VIBBER <[email protected]>
Gerrit-Reviewer: Paladox <[email protected]>
Gerrit-Reviewer: TheDJ <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to