videojs-mobile-ui 0.8.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +4 -2
  2. package/dist/lang/de.js +3 -0
  3. package/dist/lang/en.js +1 -1
  4. package/dist/lang/it.js +3 -0
  5. package/dist/videojs-mobile-ui.cjs.js +118 -193
  6. package/dist/videojs-mobile-ui.css +2 -2
  7. package/dist/videojs-mobile-ui.es.js +111 -185
  8. package/dist/videojs-mobile-ui.js +122 -236
  9. package/dist/videojs-mobile-ui.min.js +2 -2
  10. package/index.html +1 -7
  11. package/package.json +10 -10
  12. package/src/plugin.css +13 -1
  13. package/src/plugin.js +5 -33
  14. package/src/touchOverlay.js +46 -56
  15. package/CHANGELOG.md +0 -95
  16. package/docs/api/TouchOverlay.html +0 -964
  17. package/docs/api/fonts/OpenSans-Bold-webfont.eot +0 -0
  18. package/docs/api/fonts/OpenSans-Bold-webfont.svg +0 -1830
  19. package/docs/api/fonts/OpenSans-Bold-webfont.woff +0 -0
  20. package/docs/api/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
  21. package/docs/api/fonts/OpenSans-BoldItalic-webfont.svg +0 -1830
  22. package/docs/api/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
  23. package/docs/api/fonts/OpenSans-Italic-webfont.eot +0 -0
  24. package/docs/api/fonts/OpenSans-Italic-webfont.svg +0 -1830
  25. package/docs/api/fonts/OpenSans-Italic-webfont.woff +0 -0
  26. package/docs/api/fonts/OpenSans-Light-webfont.eot +0 -0
  27. package/docs/api/fonts/OpenSans-Light-webfont.svg +0 -1831
  28. package/docs/api/fonts/OpenSans-Light-webfont.woff +0 -0
  29. package/docs/api/fonts/OpenSans-LightItalic-webfont.eot +0 -0
  30. package/docs/api/fonts/OpenSans-LightItalic-webfont.svg +0 -1835
  31. package/docs/api/fonts/OpenSans-LightItalic-webfont.woff +0 -0
  32. package/docs/api/fonts/OpenSans-Regular-webfont.eot +0 -0
  33. package/docs/api/fonts/OpenSans-Regular-webfont.svg +0 -1831
  34. package/docs/api/fonts/OpenSans-Regular-webfont.woff +0 -0
  35. package/docs/api/global.html +0 -957
  36. package/docs/api/index.html +0 -159
  37. package/docs/api/plugin.js.html +0 -221
  38. package/docs/api/scripts/linenumber.js +0 -25
  39. package/docs/api/scripts/prettify/Apache-License-2.0.txt +0 -202
  40. package/docs/api/scripts/prettify/lang-css.js +0 -2
  41. package/docs/api/scripts/prettify/prettify.js +0 -28
  42. package/docs/api/styles/jsdoc-default.css +0 -358
  43. package/docs/api/styles/prettify-jsdoc.css +0 -111
  44. package/docs/api/styles/prettify-tomorrow.css +0 -132
  45. package/docs/api/touchOverlay.js.html +0 -211
@@ -1,21 +1,22 @@
1
- /*! @name videojs-mobile-ui @version 0.8.0 @license MIT */
1
+ /*! @name videojs-mobile-ui @version 1.0.1 @license MIT */
2
2
  import videojs from 'video.js';
3
- import _inheritsLoose from '@babel/runtime/helpers/inheritsLoose';
4
3
  import window from 'global/window';
5
4
 
6
- var version = "0.8.0";
5
+ var version = "1.0.1";
6
+
7
+ /**
8
+ * @file touchOverlay.js
9
+ * Touch UI component
10
+ */
11
+ const Component = videojs.getComponent('Component');
12
+ const dom = videojs.dom || videojs;
7
13
 
8
- var Component = videojs.getComponent('Component');
9
- var dom = videojs.dom || videojs;
10
14
  /**
11
15
  * The `TouchOverlay` is an overlay to capture tap events.
12
16
  *
13
17
  * @extends Component
14
18
  */
15
-
16
- var TouchOverlay = /*#__PURE__*/function (_Component) {
17
- _inheritsLoose(TouchOverlay, _Component);
18
-
19
+ class TouchOverlay extends Component {
19
20
  /**
20
21
  * Creates an instance of the this class.
21
22
  *
@@ -25,46 +26,80 @@ var TouchOverlay = /*#__PURE__*/function (_Component) {
25
26
  * @param {Object} [options]
26
27
  * The key/value store of player options.
27
28
  */
28
- function TouchOverlay(player, options) {
29
- var _this;
30
-
31
- _this = _Component.call(this, player, options) || this;
32
- _this.seekSeconds = options.seekSeconds;
33
- _this.tapTimeout = options.tapTimeout; // Add play toggle overlay
34
-
35
- _this.addChild('playToggle', {}); // Clear overlay when playback starts or with control fade
36
-
37
-
38
- player.on(['playing', 'userinactive'], function (e) {
39
- _this.removeClass('show-play-toggle');
40
- }); // A 0 inactivity timeout won't work here
29
+ constructor(player, options) {
30
+ super(player, options);
31
+ this.seekSeconds = options.seekSeconds;
32
+ this.tapTimeout = options.tapTimeout;
33
+ this.taps = 0;
34
+
35
+ // Add play toggle overlay
36
+ this.addChild('playToggle', {});
37
+
38
+ // Clear overlay when playback starts or with control fade
39
+ player.on(['playing', 'userinactive'], e => {
40
+ this.removeClass('show-play-toggle');
41
+ });
41
42
 
42
- if (_this.player_.options_.inactivityTimeout === 0) {
43
- _this.player_.options_.inactivityTimeout = 5000;
43
+ // A 0 inactivity timeout won't work here
44
+ if (this.player_.options_.inactivityTimeout === 0) {
45
+ this.player_.options_.inactivityTimeout = 5000;
44
46
  }
45
47
 
46
- _this.enable();
48
+ /**
49
+ * Debounced tap handler.
50
+ * Seeks number of (taps - 1) * configured seconds to skip.
51
+ * One tap is a non-op
52
+ *
53
+ * @param {Event} event
54
+ */
55
+ this.handleTaps_ = videojs.fn.debounce(event => {
56
+ const increment = (this.taps - 1) * this.seekSeconds;
57
+ this.taps = 0;
58
+ if (increment < 1) {
59
+ return;
60
+ }
61
+ const rect = this.el_.getBoundingClientRect();
62
+ const x = event.changedTouches[0].clientX - rect.left;
63
+
64
+ // Check if double tap is in left or right area
65
+ if (x < rect.width * 0.4) {
66
+ this.player_.currentTime(Math.max(0, this.player_.currentTime() - increment));
67
+ this.addClass('reverse');
68
+ } else if (x > rect.width - rect.width * 0.4) {
69
+ this.player_.currentTime(Math.min(this.player_.duration(), this.player_.currentTime() + increment));
70
+ this.removeClass('reverse');
71
+ } else {
72
+ return;
73
+ }
47
74
 
48
- return _this;
75
+ // Remove play toggle if showing
76
+ this.removeClass('show-play-toggle');
77
+
78
+ // Remove and readd class to trigger animation
79
+ this.setAttribute('data-skip-text', `${increment} ${this.localize('seconds')}`);
80
+ this.removeClass('skip');
81
+ window.requestAnimationFrame(() => {
82
+ this.addClass('skip');
83
+ });
84
+ }, this.tapTimeout);
85
+ this.enable();
49
86
  }
87
+
50
88
  /**
51
89
  * Builds the DOM element.
52
90
  *
53
91
  * @return {Element}
54
92
  * The DOM element.
55
93
  */
56
-
57
-
58
- var _proto = TouchOverlay.prototype;
59
-
60
- _proto.createEl = function createEl() {
61
- var el = dom.createEl('div', {
94
+ createEl() {
95
+ const el = dom.createEl('div', {
62
96
  className: 'vjs-touch-overlay',
63
97
  // Touch overlay is not tabbable.
64
98
  tabIndex: -1
65
99
  });
66
100
  return el;
67
101
  }
102
+
68
103
  /**
69
104
  * Debounces to either handle a delayed single tap, or a double tap
70
105
  *
@@ -72,111 +107,44 @@ var TouchOverlay = /*#__PURE__*/function (_Component) {
72
107
  * The touch event
73
108
  *
74
109
  */
75
- ;
76
-
77
- _proto.handleTap = function handleTap(event) {
78
- var _this2 = this;
79
-
110
+ handleTap(event) {
80
111
  // Don't handle taps on the play button
81
112
  if (event.target !== this.el_) {
82
113
  return;
83
114
  }
84
-
85
115
  event.preventDefault();
86
-
87
- if (this.firstTapCaptured) {
88
- this.firstTapCaptured = false;
89
-
90
- if (this.timeout) {
91
- window.clearTimeout(this.timeout);
92
- }
93
-
94
- this.handleDoubleTap(event);
95
- } else {
96
- this.firstTapCaptured = true;
97
- this.timeout = window.setTimeout(function () {
98
- _this2.firstTapCaptured = false;
99
-
100
- _this2.handleSingleTap(event);
101
- }, this.tapTimeout);
116
+ this.taps += 1;
117
+ if (this.taps === 1) {
118
+ this.removeClass('skip');
119
+ this.toggleClass('show-play-toggle');
102
120
  }
121
+ this.handleTaps_(event);
103
122
  }
104
- /**
105
- * Toggles display of play toggle
106
- *
107
- * @param {Event} event
108
- * The touch event
109
- *
110
- */
111
- ;
112
-
113
- _proto.handleSingleTap = function handleSingleTap(event) {
114
- this.removeClass('skip');
115
- this.toggleClass('show-play-toggle');
116
- }
117
- /**
118
- * Seeks by configured number of seconds if left or right part of video double tapped
119
- *
120
- * @param {Event} event
121
- * The touch event
122
- *
123
- */
124
- ;
125
-
126
- _proto.handleDoubleTap = function handleDoubleTap(event) {
127
- var _this3 = this;
128
-
129
- var rect = this.el_.getBoundingClientRect();
130
- var x = event.changedTouches[0].clientX - rect.left; // Check if double tap is in left or right area
131
-
132
- if (x < rect.width * 0.4) {
133
- this.player_.currentTime(Math.max(0, this.player_.currentTime() - this.seekSeconds));
134
- this.addClass('reverse');
135
- } else if (x > rect.width - rect.width * 0.4) {
136
- this.player_.currentTime(Math.min(this.player_.duration(), this.player_.currentTime() + this.seekSeconds));
137
- this.removeClass('reverse');
138
- } else {
139
- return;
140
- } // Remove play toggle if showing
141
123
 
142
-
143
- this.removeClass('show-play-toggle'); // Remove and readd class to trigger animation
144
-
145
- this.removeClass('skip');
146
- window.requestAnimationFrame(function () {
147
- _this3.addClass('skip');
148
- });
149
- }
150
124
  /**
151
125
  * Enables touch handler
152
126
  */
153
- ;
154
-
155
- _proto.enable = function enable() {
127
+ enable() {
156
128
  this.firstTapCaptured = false;
157
129
  this.on('touchend', this.handleTap);
158
130
  }
131
+
159
132
  /**
160
133
  * Disables touch handler
161
134
  */
162
- ;
163
-
164
- _proto.disable = function disable() {
135
+ disable() {
165
136
  this.off('touchend', this.handleTap);
166
- };
167
-
168
- return TouchOverlay;
169
- }(Component);
170
-
137
+ }
138
+ }
171
139
  Component.registerComponent('TouchOverlay', TouchOverlay);
172
140
 
173
- var defaults = {
141
+ // Default options for the plugin.
142
+ const defaults = {
174
143
  fullscreen: {
175
144
  enterOnRotate: true,
176
145
  exitOnRotate: true,
177
146
  lockOnRotate: true,
178
147
  lockToLandscapeOnEnter: false,
179
- iOS: false,
180
148
  disabled: false
181
149
  },
182
150
  touchControls: {
@@ -186,37 +154,32 @@ var defaults = {
186
154
  disabled: false
187
155
  }
188
156
  };
189
- var screen = window.screen;
157
+ const screen = window.screen;
158
+
190
159
  /**
191
160
  * Gets 'portrait' or 'lanscape' from the two orientation APIs
192
161
  *
193
162
  * @return {string} orientation
194
163
  */
195
-
196
- var getOrientation = function getOrientation() {
197
- if (screen) {
164
+ const getOrientation = () => {
165
+ if (window.screen) {
198
166
  // Prefer the string over angle, as 0° can be landscape on some tablets
199
- var orientationString = ((screen.orientation || {}).type || screen.mozOrientation || screen.msOrientation || '').split('-')[0];
200
-
167
+ const orientationString = ((window.screen.orientation || {}).type || window.screen.mozOrientation || window.screen.msOrientation || '').split('-')[0];
201
168
  if (orientationString === 'landscape' || orientationString === 'portrait') {
202
169
  return orientationString;
203
170
  }
204
- } // iOS only supports window.orientation
205
-
171
+ }
206
172
 
173
+ // iOS only supports window.orientation
207
174
  if (typeof window.orientation === 'number') {
208
175
  if (window.orientation === 0 || window.orientation === 180) {
209
176
  return 'portrait';
210
177
  }
211
-
212
178
  return 'landscape';
213
179
  }
214
-
215
180
  return 'portrait';
216
- }; // Cross-compatibility for Video.js 5 and 6.
217
-
181
+ };
218
182
 
219
- var registerPlugin = videojs.registerPlugin || videojs.plugin;
220
183
  /**
221
184
  * Add UI and event listeners
222
185
  *
@@ -227,59 +190,30 @@ var registerPlugin = videojs.registerPlugin || videojs.plugin;
227
190
  * @param {Object} [options={}]
228
191
  * A plain object containing options for the plugin.
229
192
  */
230
-
231
- var onPlayerReady = function onPlayerReady(player, options) {
193
+ const onPlayerReady = (player, options) => {
232
194
  player.addClass('vjs-mobile-ui');
233
-
234
- if (options.fullscreen.iOS) {
235
- videojs.log.warn('videojs-mobile-ui: `fullscreen.iOS` is deprecated. Use Video.js option `preferFullWindow` instead.');
236
-
237
- if (videojs.browser.IS_IOS && videojs.browser.IOS_VERSION > 9 && !player.el_.ownerDocument.querySelector('.bc-iframe')) {
238
- player.tech_.el_.setAttribute('playsinline', 'playsinline');
239
-
240
- player.tech_.supportsFullScreen = function () {
241
- return false;
242
- };
243
- }
244
- }
245
-
246
195
  if (!options.touchControls.disabled) {
247
196
  if (options.touchControls.disableOnEnd || typeof player.endscreen === 'function') {
248
197
  player.addClass('vjs-mobile-ui-disable-end');
249
- } // Insert before the control bar
250
-
251
-
252
- var controlBarIdx;
253
- var versionParts = videojs.VERSION.split('.');
254
- var major = parseInt(versionParts[0], 10);
255
- var minor = parseInt(versionParts[1], 10); // Video.js < 7.7.0 doesn't account for precedding components that don't have elements
256
-
257
- if (major < 7 || major === 7 && minor < 7) {
258
- controlBarIdx = Array.prototype.indexOf.call(player.el_.children, player.getChild('ControlBar').el_);
259
- } else {
260
- controlBarIdx = player.children_.indexOf(player.getChild('ControlBar'));
261
198
  }
262
199
 
200
+ // Insert before the control bar
201
+ const controlBarIdx = player.children_.indexOf(player.getChild('ControlBar'));
263
202
  player.touchOverlay = player.addChild('TouchOverlay', options.touchControls, controlBarIdx);
264
203
  }
265
-
266
204
  if (options.fullscreen.disabled) {
267
205
  return;
268
206
  }
269
-
270
- var locked = false;
271
-
272
- var rotationHandler = function rotationHandler() {
273
- var currentOrientation = getOrientation();
274
-
207
+ let locked = false;
208
+ const rotationHandler = () => {
209
+ const currentOrientation = getOrientation();
275
210
  if (currentOrientation === 'landscape' && options.fullscreen.enterOnRotate) {
276
211
  if (player.paused() === false) {
277
212
  player.requestFullscreen();
278
-
279
213
  if ((options.fullscreen.lockOnRotate || options.fullscreen.lockToLandscapeOnEnter) && screen.orientation && screen.orientation.lock) {
280
- screen.orientation.lock('landscape').then(function () {
214
+ screen.orientation.lock('landscape').then(() => {
281
215
  locked = true;
282
- }).catch(function (e) {
216
+ }).catch(e => {
283
217
  videojs.log('Browser refused orientation lock:', e);
284
218
  });
285
219
  }
@@ -290,27 +224,25 @@ var onPlayerReady = function onPlayerReady(player, options) {
290
224
  }
291
225
  }
292
226
  };
293
-
294
227
  if (options.fullscreen.enterOnRotate || options.fullscreen.exitOnRotate) {
295
228
  if (videojs.browser.IS_IOS) {
296
229
  window.addEventListener('orientationchange', rotationHandler);
297
- player.on('dispose', function () {
230
+ player.on('dispose', () => {
298
231
  window.removeEventListener('orientationchange', rotationHandler);
299
232
  });
300
233
  } else if (screen.orientation) {
301
234
  // addEventListener('orientationchange') is not a user interaction on Android
302
235
  screen.orientation.onchange = rotationHandler;
303
- player.on('dispose', function () {
236
+ player.on('dispose', () => {
304
237
  screen.orientation.onchange = null;
305
238
  });
306
239
  }
307
240
  }
308
-
309
- player.on('fullscreenchange', function (_) {
241
+ player.on('fullscreenchange', _ => {
310
242
  if (player.isFullscreen() && options.fullscreen.lockToLandscapeOnEnter && getOrientation() === 'portrait') {
311
- screen.orientation.lock('landscape').then(function () {
243
+ screen.orientation.lock('landscape').then(() => {
312
244
  locked = true;
313
- }).catch(function (e) {
245
+ }).catch(e => {
314
246
  videojs.log('Browser refused orientation lock:', e);
315
247
  });
316
248
  } else if (!player.isFullscreen() && locked) {
@@ -318,13 +250,14 @@ var onPlayerReady = function onPlayerReady(player, options) {
318
250
  locked = false;
319
251
  }
320
252
  });
321
- player.on('ended', function (_) {
253
+ player.on('ended', _ => {
322
254
  if (locked === true) {
323
255
  screen.orientation.unlock();
324
256
  locked = false;
325
257
  }
326
258
  });
327
259
  };
260
+
328
261
  /**
329
262
  * A video.js plugin.
330
263
  *
@@ -363,25 +296,18 @@ var onPlayerReady = function onPlayerReady(player, options) {
363
296
  * Whether to disable when the video ends (e.g., if there is an endscreen)
364
297
  * Never shows if the endscreen plugin is present
365
298
  */
366
-
367
-
368
- var mobileUi = function mobileUi(options) {
369
- var _this = this;
370
-
371
- if (options === void 0) {
372
- options = {};
373
- }
374
-
299
+ const mobileUi = function (options = {}) {
375
300
  if (options.forceForTesting || videojs.browser.IS_ANDROID || videojs.browser.IS_IOS) {
376
- this.ready(function () {
377
- onPlayerReady(_this, videojs.mergeOptions(defaults, options));
301
+ this.ready(() => {
302
+ onPlayerReady(this, videojs.obj.merge(defaults, options));
378
303
  });
379
304
  }
380
- }; // Register the plugin with video.js.
381
-
305
+ };
382
306
 
383
- registerPlugin('mobileUi', mobileUi); // Include the version number.
307
+ // Register the plugin with video.js.
308
+ videojs.registerPlugin('mobileUi', mobileUi);
384
309
 
310
+ // Include the version number.
385
311
  mobileUi.VERSION = version;
386
312
 
387
- export default mobileUi;
313
+ export { mobileUi as default };