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.
- package/README.md +4 -2
- package/dist/lang/de.js +3 -0
- package/dist/lang/en.js +1 -1
- package/dist/lang/it.js +3 -0
- package/dist/videojs-mobile-ui.cjs.js +118 -193
- package/dist/videojs-mobile-ui.css +2 -2
- package/dist/videojs-mobile-ui.es.js +111 -185
- package/dist/videojs-mobile-ui.js +122 -236
- package/dist/videojs-mobile-ui.min.js +2 -2
- package/index.html +1 -7
- package/package.json +10 -10
- package/src/plugin.css +13 -1
- package/src/plugin.js +5 -33
- package/src/touchOverlay.js +46 -56
- package/CHANGELOG.md +0 -95
- package/docs/api/TouchOverlay.html +0 -964
- package/docs/api/fonts/OpenSans-Bold-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.svg +0 -1830
- package/docs/api/fonts/OpenSans-Bold-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.svg +0 -1830
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.svg +0 -1830
- package/docs/api/fonts/OpenSans-Italic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Light-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Light-webfont.svg +0 -1831
- package/docs/api/fonts/OpenSans-Light-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.svg +0 -1835
- package/docs/api/fonts/OpenSans-LightItalic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.svg +0 -1831
- package/docs/api/fonts/OpenSans-Regular-webfont.woff +0 -0
- package/docs/api/global.html +0 -957
- package/docs/api/index.html +0 -159
- package/docs/api/plugin.js.html +0 -221
- package/docs/api/scripts/linenumber.js +0 -25
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +0 -202
- package/docs/api/scripts/prettify/lang-css.js +0 -2
- package/docs/api/scripts/prettify/prettify.js +0 -28
- package/docs/api/styles/jsdoc-default.css +0 -358
- package/docs/api/styles/prettify-jsdoc.css +0 -111
- package/docs/api/styles/prettify-tomorrow.css +0 -132
- package/docs/api/touchOverlay.js.html +0 -211
|
@@ -1,68 +1,29 @@
|
|
|
1
|
-
/*! @name videojs-mobile-ui @version 0.
|
|
1
|
+
/*! @name videojs-mobile-ui @version 1.0.1 @license MIT */
|
|
2
2
|
(function (global, factory) {
|
|
3
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('video.js')
|
|
4
|
-
typeof define === 'function' && define.amd ? define(['video.js'
|
|
5
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.videojsMobileUi = factory(global.videojs
|
|
6
|
-
}(this, (function (videojs
|
|
3
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('video.js')) :
|
|
4
|
+
typeof define === 'function' && define.amd ? define(['video.js'], factory) :
|
|
5
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.videojsMobileUi = factory(global.videojs));
|
|
6
|
+
})(this, (function (videojs) { 'use strict';
|
|
7
7
|
|
|
8
8
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
9
9
|
|
|
10
10
|
var videojs__default = /*#__PURE__*/_interopDefaultLegacy(videojs);
|
|
11
|
-
var window__default = /*#__PURE__*/_interopDefaultLegacy(window);
|
|
12
11
|
|
|
13
|
-
var version = "0.
|
|
12
|
+
var version = "1.0.1";
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
}, fn(module, module.exports), module.exports;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function commonjsRequire () {
|
|
26
|
-
throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
var setPrototypeOf = createCommonjsModule(function (module) {
|
|
30
|
-
function _setPrototypeOf(o, p) {
|
|
31
|
-
module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
|
|
32
|
-
o.__proto__ = p;
|
|
33
|
-
return o;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|
37
|
-
return _setPrototypeOf(o, p);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
module.exports = _setPrototypeOf;
|
|
41
|
-
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
var inheritsLoose = createCommonjsModule(function (module) {
|
|
45
|
-
function _inheritsLoose(subClass, superClass) {
|
|
46
|
-
subClass.prototype = Object.create(superClass.prototype);
|
|
47
|
-
subClass.prototype.constructor = subClass;
|
|
48
|
-
setPrototypeOf(subClass, superClass);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
module.exports = _inheritsLoose;
|
|
52
|
-
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|
53
|
-
});
|
|
14
|
+
/**
|
|
15
|
+
* @file touchOverlay.js
|
|
16
|
+
* Touch UI component
|
|
17
|
+
*/
|
|
18
|
+
const Component = videojs__default["default"].getComponent('Component');
|
|
19
|
+
const dom = videojs__default["default"].dom || videojs__default["default"];
|
|
54
20
|
|
|
55
|
-
var Component = videojs__default['default'].getComponent('Component');
|
|
56
|
-
var dom = videojs__default['default'].dom || videojs__default['default'];
|
|
57
21
|
/**
|
|
58
22
|
* The `TouchOverlay` is an overlay to capture tap events.
|
|
59
23
|
*
|
|
60
24
|
* @extends Component
|
|
61
25
|
*/
|
|
62
|
-
|
|
63
|
-
var TouchOverlay = /*#__PURE__*/function (_Component) {
|
|
64
|
-
inheritsLoose(TouchOverlay, _Component);
|
|
65
|
-
|
|
26
|
+
class TouchOverlay extends Component {
|
|
66
27
|
/**
|
|
67
28
|
* Creates an instance of the this class.
|
|
68
29
|
*
|
|
@@ -72,46 +33,80 @@
|
|
|
72
33
|
* @param {Object} [options]
|
|
73
34
|
* The key/value store of player options.
|
|
74
35
|
*/
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
player.on(['playing', 'userinactive'],
|
|
86
|
-
|
|
87
|
-
});
|
|
36
|
+
constructor(player, options) {
|
|
37
|
+
super(player, options);
|
|
38
|
+
this.seekSeconds = options.seekSeconds;
|
|
39
|
+
this.tapTimeout = options.tapTimeout;
|
|
40
|
+
this.taps = 0;
|
|
41
|
+
|
|
42
|
+
// Add play toggle overlay
|
|
43
|
+
this.addChild('playToggle', {});
|
|
44
|
+
|
|
45
|
+
// Clear overlay when playback starts or with control fade
|
|
46
|
+
player.on(['playing', 'userinactive'], e => {
|
|
47
|
+
this.removeClass('show-play-toggle');
|
|
48
|
+
});
|
|
88
49
|
|
|
89
|
-
|
|
90
|
-
|
|
50
|
+
// A 0 inactivity timeout won't work here
|
|
51
|
+
if (this.player_.options_.inactivityTimeout === 0) {
|
|
52
|
+
this.player_.options_.inactivityTimeout = 5000;
|
|
91
53
|
}
|
|
92
54
|
|
|
93
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Debounced tap handler.
|
|
57
|
+
* Seeks number of (taps - 1) * configured seconds to skip.
|
|
58
|
+
* One tap is a non-op
|
|
59
|
+
*
|
|
60
|
+
* @param {Event} event
|
|
61
|
+
*/
|
|
62
|
+
this.handleTaps_ = videojs__default["default"].fn.debounce(event => {
|
|
63
|
+
const increment = (this.taps - 1) * this.seekSeconds;
|
|
64
|
+
this.taps = 0;
|
|
65
|
+
if (increment < 1) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const rect = this.el_.getBoundingClientRect();
|
|
69
|
+
const x = event.changedTouches[0].clientX - rect.left;
|
|
70
|
+
|
|
71
|
+
// Check if double tap is in left or right area
|
|
72
|
+
if (x < rect.width * 0.4) {
|
|
73
|
+
this.player_.currentTime(Math.max(0, this.player_.currentTime() - increment));
|
|
74
|
+
this.addClass('reverse');
|
|
75
|
+
} else if (x > rect.width - rect.width * 0.4) {
|
|
76
|
+
this.player_.currentTime(Math.min(this.player_.duration(), this.player_.currentTime() + increment));
|
|
77
|
+
this.removeClass('reverse');
|
|
78
|
+
} else {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Remove play toggle if showing
|
|
83
|
+
this.removeClass('show-play-toggle');
|
|
94
84
|
|
|
95
|
-
|
|
85
|
+
// Remove and readd class to trigger animation
|
|
86
|
+
this.setAttribute('data-skip-text', `${increment} ${this.localize('seconds')}`);
|
|
87
|
+
this.removeClass('skip');
|
|
88
|
+
window.requestAnimationFrame(() => {
|
|
89
|
+
this.addClass('skip');
|
|
90
|
+
});
|
|
91
|
+
}, this.tapTimeout);
|
|
92
|
+
this.enable();
|
|
96
93
|
}
|
|
94
|
+
|
|
97
95
|
/**
|
|
98
96
|
* Builds the DOM element.
|
|
99
97
|
*
|
|
100
98
|
* @return {Element}
|
|
101
99
|
* The DOM element.
|
|
102
100
|
*/
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
var _proto = TouchOverlay.prototype;
|
|
106
|
-
|
|
107
|
-
_proto.createEl = function createEl() {
|
|
108
|
-
var el = dom.createEl('div', {
|
|
101
|
+
createEl() {
|
|
102
|
+
const el = dom.createEl('div', {
|
|
109
103
|
className: 'vjs-touch-overlay',
|
|
110
104
|
// Touch overlay is not tabbable.
|
|
111
105
|
tabIndex: -1
|
|
112
106
|
});
|
|
113
107
|
return el;
|
|
114
108
|
}
|
|
109
|
+
|
|
115
110
|
/**
|
|
116
111
|
* Debounces to either handle a delayed single tap, or a double tap
|
|
117
112
|
*
|
|
@@ -119,111 +114,44 @@
|
|
|
119
114
|
* The touch event
|
|
120
115
|
*
|
|
121
116
|
*/
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
_proto.handleTap = function handleTap(event) {
|
|
125
|
-
var _this2 = this;
|
|
126
|
-
|
|
117
|
+
handleTap(event) {
|
|
127
118
|
// Don't handle taps on the play button
|
|
128
119
|
if (event.target !== this.el_) {
|
|
129
120
|
return;
|
|
130
121
|
}
|
|
131
|
-
|
|
132
122
|
event.preventDefault();
|
|
133
|
-
|
|
134
|
-
if (this.
|
|
135
|
-
this.
|
|
136
|
-
|
|
137
|
-
if (this.timeout) {
|
|
138
|
-
window__default['default'].clearTimeout(this.timeout);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
this.handleDoubleTap(event);
|
|
142
|
-
} else {
|
|
143
|
-
this.firstTapCaptured = true;
|
|
144
|
-
this.timeout = window__default['default'].setTimeout(function () {
|
|
145
|
-
_this2.firstTapCaptured = false;
|
|
146
|
-
|
|
147
|
-
_this2.handleSingleTap(event);
|
|
148
|
-
}, this.tapTimeout);
|
|
123
|
+
this.taps += 1;
|
|
124
|
+
if (this.taps === 1) {
|
|
125
|
+
this.removeClass('skip');
|
|
126
|
+
this.toggleClass('show-play-toggle');
|
|
149
127
|
}
|
|
128
|
+
this.handleTaps_(event);
|
|
150
129
|
}
|
|
151
|
-
/**
|
|
152
|
-
* Toggles display of play toggle
|
|
153
|
-
*
|
|
154
|
-
* @param {Event} event
|
|
155
|
-
* The touch event
|
|
156
|
-
*
|
|
157
|
-
*/
|
|
158
|
-
;
|
|
159
130
|
|
|
160
|
-
_proto.handleSingleTap = function handleSingleTap(event) {
|
|
161
|
-
this.removeClass('skip');
|
|
162
|
-
this.toggleClass('show-play-toggle');
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Seeks by configured number of seconds if left or right part of video double tapped
|
|
166
|
-
*
|
|
167
|
-
* @param {Event} event
|
|
168
|
-
* The touch event
|
|
169
|
-
*
|
|
170
|
-
*/
|
|
171
|
-
;
|
|
172
|
-
|
|
173
|
-
_proto.handleDoubleTap = function handleDoubleTap(event) {
|
|
174
|
-
var _this3 = this;
|
|
175
|
-
|
|
176
|
-
var rect = this.el_.getBoundingClientRect();
|
|
177
|
-
var x = event.changedTouches[0].clientX - rect.left; // Check if double tap is in left or right area
|
|
178
|
-
|
|
179
|
-
if (x < rect.width * 0.4) {
|
|
180
|
-
this.player_.currentTime(Math.max(0, this.player_.currentTime() - this.seekSeconds));
|
|
181
|
-
this.addClass('reverse');
|
|
182
|
-
} else if (x > rect.width - rect.width * 0.4) {
|
|
183
|
-
this.player_.currentTime(Math.min(this.player_.duration(), this.player_.currentTime() + this.seekSeconds));
|
|
184
|
-
this.removeClass('reverse');
|
|
185
|
-
} else {
|
|
186
|
-
return;
|
|
187
|
-
} // Remove play toggle if showing
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
this.removeClass('show-play-toggle'); // Remove and readd class to trigger animation
|
|
191
|
-
|
|
192
|
-
this.removeClass('skip');
|
|
193
|
-
window__default['default'].requestAnimationFrame(function () {
|
|
194
|
-
_this3.addClass('skip');
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
131
|
/**
|
|
198
132
|
* Enables touch handler
|
|
199
133
|
*/
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
_proto.enable = function enable() {
|
|
134
|
+
enable() {
|
|
203
135
|
this.firstTapCaptured = false;
|
|
204
136
|
this.on('touchend', this.handleTap);
|
|
205
137
|
}
|
|
138
|
+
|
|
206
139
|
/**
|
|
207
140
|
* Disables touch handler
|
|
208
141
|
*/
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
_proto.disable = function disable() {
|
|
142
|
+
disable() {
|
|
212
143
|
this.off('touchend', this.handleTap);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
return TouchOverlay;
|
|
216
|
-
}(Component);
|
|
217
|
-
|
|
144
|
+
}
|
|
145
|
+
}
|
|
218
146
|
Component.registerComponent('TouchOverlay', TouchOverlay);
|
|
219
147
|
|
|
220
|
-
|
|
148
|
+
// Default options for the plugin.
|
|
149
|
+
const defaults = {
|
|
221
150
|
fullscreen: {
|
|
222
151
|
enterOnRotate: true,
|
|
223
152
|
exitOnRotate: true,
|
|
224
153
|
lockOnRotate: true,
|
|
225
154
|
lockToLandscapeOnEnter: false,
|
|
226
|
-
iOS: false,
|
|
227
155
|
disabled: false
|
|
228
156
|
},
|
|
229
157
|
touchControls: {
|
|
@@ -233,37 +161,32 @@
|
|
|
233
161
|
disabled: false
|
|
234
162
|
}
|
|
235
163
|
};
|
|
236
|
-
|
|
164
|
+
const screen = window.screen;
|
|
165
|
+
|
|
237
166
|
/**
|
|
238
167
|
* Gets 'portrait' or 'lanscape' from the two orientation APIs
|
|
239
168
|
*
|
|
240
169
|
* @return {string} orientation
|
|
241
170
|
*/
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
if (screen) {
|
|
171
|
+
const getOrientation = () => {
|
|
172
|
+
if (window.screen) {
|
|
245
173
|
// Prefer the string over angle, as 0° can be landscape on some tablets
|
|
246
|
-
|
|
247
|
-
|
|
174
|
+
const orientationString = ((window.screen.orientation || {}).type || window.screen.mozOrientation || window.screen.msOrientation || '').split('-')[0];
|
|
248
175
|
if (orientationString === 'landscape' || orientationString === 'portrait') {
|
|
249
176
|
return orientationString;
|
|
250
177
|
}
|
|
251
|
-
}
|
|
252
|
-
|
|
178
|
+
}
|
|
253
179
|
|
|
254
|
-
|
|
255
|
-
|
|
180
|
+
// iOS only supports window.orientation
|
|
181
|
+
if (typeof window.orientation === 'number') {
|
|
182
|
+
if (window.orientation === 0 || window.orientation === 180) {
|
|
256
183
|
return 'portrait';
|
|
257
184
|
}
|
|
258
|
-
|
|
259
185
|
return 'landscape';
|
|
260
186
|
}
|
|
261
|
-
|
|
262
187
|
return 'portrait';
|
|
263
|
-
};
|
|
264
|
-
|
|
188
|
+
};
|
|
265
189
|
|
|
266
|
-
var registerPlugin = videojs__default['default'].registerPlugin || videojs__default['default'].plugin;
|
|
267
190
|
/**
|
|
268
191
|
* Add UI and event listeners
|
|
269
192
|
*
|
|
@@ -274,60 +197,31 @@
|
|
|
274
197
|
* @param {Object} [options={}]
|
|
275
198
|
* A plain object containing options for the plugin.
|
|
276
199
|
*/
|
|
277
|
-
|
|
278
|
-
var onPlayerReady = function onPlayerReady(player, options) {
|
|
200
|
+
const onPlayerReady = (player, options) => {
|
|
279
201
|
player.addClass('vjs-mobile-ui');
|
|
280
|
-
|
|
281
|
-
if (options.fullscreen.iOS) {
|
|
282
|
-
videojs__default['default'].log.warn('videojs-mobile-ui: `fullscreen.iOS` is deprecated. Use Video.js option `preferFullWindow` instead.');
|
|
283
|
-
|
|
284
|
-
if (videojs__default['default'].browser.IS_IOS && videojs__default['default'].browser.IOS_VERSION > 9 && !player.el_.ownerDocument.querySelector('.bc-iframe')) {
|
|
285
|
-
player.tech_.el_.setAttribute('playsinline', 'playsinline');
|
|
286
|
-
|
|
287
|
-
player.tech_.supportsFullScreen = function () {
|
|
288
|
-
return false;
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
202
|
if (!options.touchControls.disabled) {
|
|
294
203
|
if (options.touchControls.disableOnEnd || typeof player.endscreen === 'function') {
|
|
295
204
|
player.addClass('vjs-mobile-ui-disable-end');
|
|
296
|
-
} // Insert before the control bar
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
var controlBarIdx;
|
|
300
|
-
var versionParts = videojs__default['default'].VERSION.split('.');
|
|
301
|
-
var major = parseInt(versionParts[0], 10);
|
|
302
|
-
var minor = parseInt(versionParts[1], 10); // Video.js < 7.7.0 doesn't account for precedding components that don't have elements
|
|
303
|
-
|
|
304
|
-
if (major < 7 || major === 7 && minor < 7) {
|
|
305
|
-
controlBarIdx = Array.prototype.indexOf.call(player.el_.children, player.getChild('ControlBar').el_);
|
|
306
|
-
} else {
|
|
307
|
-
controlBarIdx = player.children_.indexOf(player.getChild('ControlBar'));
|
|
308
205
|
}
|
|
309
206
|
|
|
207
|
+
// Insert before the control bar
|
|
208
|
+
const controlBarIdx = player.children_.indexOf(player.getChild('ControlBar'));
|
|
310
209
|
player.touchOverlay = player.addChild('TouchOverlay', options.touchControls, controlBarIdx);
|
|
311
210
|
}
|
|
312
|
-
|
|
313
211
|
if (options.fullscreen.disabled) {
|
|
314
212
|
return;
|
|
315
213
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
var rotationHandler = function rotationHandler() {
|
|
320
|
-
var currentOrientation = getOrientation();
|
|
321
|
-
|
|
214
|
+
let locked = false;
|
|
215
|
+
const rotationHandler = () => {
|
|
216
|
+
const currentOrientation = getOrientation();
|
|
322
217
|
if (currentOrientation === 'landscape' && options.fullscreen.enterOnRotate) {
|
|
323
218
|
if (player.paused() === false) {
|
|
324
219
|
player.requestFullscreen();
|
|
325
|
-
|
|
326
220
|
if ((options.fullscreen.lockOnRotate || options.fullscreen.lockToLandscapeOnEnter) && screen.orientation && screen.orientation.lock) {
|
|
327
|
-
screen.orientation.lock('landscape').then(
|
|
221
|
+
screen.orientation.lock('landscape').then(() => {
|
|
328
222
|
locked = true;
|
|
329
|
-
}).catch(
|
|
330
|
-
videojs__default[
|
|
223
|
+
}).catch(e => {
|
|
224
|
+
videojs__default["default"].log('Browser refused orientation lock:', e);
|
|
331
225
|
});
|
|
332
226
|
}
|
|
333
227
|
}
|
|
@@ -337,41 +231,40 @@
|
|
|
337
231
|
}
|
|
338
232
|
}
|
|
339
233
|
};
|
|
340
|
-
|
|
341
234
|
if (options.fullscreen.enterOnRotate || options.fullscreen.exitOnRotate) {
|
|
342
|
-
if (videojs__default[
|
|
343
|
-
|
|
344
|
-
player.on('dispose',
|
|
345
|
-
|
|
235
|
+
if (videojs__default["default"].browser.IS_IOS) {
|
|
236
|
+
window.addEventListener('orientationchange', rotationHandler);
|
|
237
|
+
player.on('dispose', () => {
|
|
238
|
+
window.removeEventListener('orientationchange', rotationHandler);
|
|
346
239
|
});
|
|
347
240
|
} else if (screen.orientation) {
|
|
348
241
|
// addEventListener('orientationchange') is not a user interaction on Android
|
|
349
242
|
screen.orientation.onchange = rotationHandler;
|
|
350
|
-
player.on('dispose',
|
|
243
|
+
player.on('dispose', () => {
|
|
351
244
|
screen.orientation.onchange = null;
|
|
352
245
|
});
|
|
353
246
|
}
|
|
354
247
|
}
|
|
355
|
-
|
|
356
|
-
player.on('fullscreenchange', function (_) {
|
|
248
|
+
player.on('fullscreenchange', _ => {
|
|
357
249
|
if (player.isFullscreen() && options.fullscreen.lockToLandscapeOnEnter && getOrientation() === 'portrait') {
|
|
358
|
-
screen.orientation.lock('landscape').then(
|
|
250
|
+
screen.orientation.lock('landscape').then(() => {
|
|
359
251
|
locked = true;
|
|
360
|
-
}).catch(
|
|
361
|
-
videojs__default[
|
|
252
|
+
}).catch(e => {
|
|
253
|
+
videojs__default["default"].log('Browser refused orientation lock:', e);
|
|
362
254
|
});
|
|
363
255
|
} else if (!player.isFullscreen() && locked) {
|
|
364
256
|
screen.orientation.unlock();
|
|
365
257
|
locked = false;
|
|
366
258
|
}
|
|
367
259
|
});
|
|
368
|
-
player.on('ended',
|
|
260
|
+
player.on('ended', _ => {
|
|
369
261
|
if (locked === true) {
|
|
370
262
|
screen.orientation.unlock();
|
|
371
263
|
locked = false;
|
|
372
264
|
}
|
|
373
265
|
});
|
|
374
266
|
};
|
|
267
|
+
|
|
375
268
|
/**
|
|
376
269
|
* A video.js plugin.
|
|
377
270
|
*
|
|
@@ -410,27 +303,20 @@
|
|
|
410
303
|
* Whether to disable when the video ends (e.g., if there is an endscreen)
|
|
411
304
|
* Never shows if the endscreen plugin is present
|
|
412
305
|
*/
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
if (options === void 0) {
|
|
419
|
-
options = {};
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
if (options.forceForTesting || videojs__default['default'].browser.IS_ANDROID || videojs__default['default'].browser.IS_IOS) {
|
|
423
|
-
this.ready(function () {
|
|
424
|
-
onPlayerReady(_this, videojs__default['default'].mergeOptions(defaults, options));
|
|
306
|
+
const mobileUi = function (options = {}) {
|
|
307
|
+
if (options.forceForTesting || videojs__default["default"].browser.IS_ANDROID || videojs__default["default"].browser.IS_IOS) {
|
|
308
|
+
this.ready(() => {
|
|
309
|
+
onPlayerReady(this, videojs__default["default"].obj.merge(defaults, options));
|
|
425
310
|
});
|
|
426
311
|
}
|
|
427
|
-
};
|
|
428
|
-
|
|
312
|
+
};
|
|
429
313
|
|
|
430
|
-
|
|
314
|
+
// Register the plugin with video.js.
|
|
315
|
+
videojs__default["default"].registerPlugin('mobileUi', mobileUi);
|
|
431
316
|
|
|
317
|
+
// Include the version number.
|
|
432
318
|
mobileUi.VERSION = version;
|
|
433
319
|
|
|
434
320
|
return mobileUi;
|
|
435
321
|
|
|
436
|
-
}))
|
|
322
|
+
}));
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! @name videojs-mobile-ui @version 0.
|
|
2
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("video.js")
|
|
1
|
+
/*! @name videojs-mobile-ui @version 1.0.1 @license MIT */
|
|
2
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("video.js")):"function"==typeof define&&define.amd?define(["video.js"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).videojsMobileUi=t(e.videojs)}(this,(function(e){"use strict";function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=t(e);const o=n.default.getComponent("Component"),i=n.default.dom||n.default;o.registerComponent("TouchOverlay",class extends o{constructor(e,t){super(e,t),this.seekSeconds=t.seekSeconds,this.tapTimeout=t.tapTimeout,this.taps=0,this.addChild("playToggle",{}),e.on(["playing","userinactive"],(e=>{this.removeClass("show-play-toggle")})),0===this.player_.options_.inactivityTimeout&&(this.player_.options_.inactivityTimeout=5e3),this.handleTaps_=n.default.fn.debounce((e=>{const t=(this.taps-1)*this.seekSeconds;if(this.taps=0,t<1)return;const n=this.el_.getBoundingClientRect(),o=e.changedTouches[0].clientX-n.left;if(o<.4*n.width)this.player_.currentTime(Math.max(0,this.player_.currentTime()-t)),this.addClass("reverse");else{if(!(o>n.width-.4*n.width))return;this.player_.currentTime(Math.min(this.player_.duration(),this.player_.currentTime()+t)),this.removeClass("reverse")}this.removeClass("show-play-toggle"),this.setAttribute("data-skip-text",`${t} ${this.localize("seconds")}`),this.removeClass("skip"),window.requestAnimationFrame((()=>{this.addClass("skip")}))}),this.tapTimeout),this.enable()}createEl(){return i.createEl("div",{className:"vjs-touch-overlay",tabIndex:-1})}handleTap(e){e.target===this.el_&&(e.preventDefault(),this.taps+=1,1===this.taps&&(this.removeClass("skip"),this.toggleClass("show-play-toggle")),this.handleTaps_(e))}enable(){this.firstTapCaptured=!1,this.on("touchend",this.handleTap)}disable(){this.off("touchend",this.handleTap)}});const s={fullscreen:{enterOnRotate:!0,exitOnRotate:!0,lockOnRotate:!0,lockToLandscapeOnEnter:!1,disabled:!1},touchControls:{seekSeconds:10,tapTimeout:300,disableOnEnd:!1,disabled:!1}},a=window.screen,r=()=>{if(window.screen){const e=((window.screen.orientation||{}).type||window.screen.mozOrientation||window.screen.msOrientation||"").split("-")[0];if("landscape"===e||"portrait"===e)return e}return"number"==typeof window.orientation?0===window.orientation||180===window.orientation?"portrait":"landscape":"portrait"},l=function(e={}){(e.forceForTesting||n.default.browser.IS_ANDROID||n.default.browser.IS_IOS)&&this.ready((()=>{((e,t)=>{if(e.addClass("vjs-mobile-ui"),!t.touchControls.disabled){(t.touchControls.disableOnEnd||"function"==typeof e.endscreen)&&e.addClass("vjs-mobile-ui-disable-end");const n=e.children_.indexOf(e.getChild("ControlBar"));e.touchOverlay=e.addChild("TouchOverlay",t.touchControls,n)}if(t.fullscreen.disabled)return;let o=!1;const i=()=>{const i=r();"landscape"===i&&t.fullscreen.enterOnRotate?!1===e.paused()&&(e.requestFullscreen(),(t.fullscreen.lockOnRotate||t.fullscreen.lockToLandscapeOnEnter)&&a.orientation&&a.orientation.lock&&a.orientation.lock("landscape").then((()=>{o=!0})).catch((e=>{n.default.log("Browser refused orientation lock:",e)}))):"portrait"===i&&t.fullscreen.exitOnRotate&&!o&&e.isFullscreen()&&e.exitFullscreen()};(t.fullscreen.enterOnRotate||t.fullscreen.exitOnRotate)&&(n.default.browser.IS_IOS?(window.addEventListener("orientationchange",i),e.on("dispose",(()=>{window.removeEventListener("orientationchange",i)}))):a.orientation&&(a.orientation.onchange=i,e.on("dispose",(()=>{a.orientation.onchange=null})))),e.on("fullscreenchange",(i=>{e.isFullscreen()&&t.fullscreen.lockToLandscapeOnEnter&&"portrait"===r()?a.orientation.lock("landscape").then((()=>{o=!0})).catch((e=>{n.default.log("Browser refused orientation lock:",e)})):!e.isFullscreen()&&o&&(a.orientation.unlock(),o=!1)})),e.on("ended",(e=>{!0===o&&(a.orientation.unlock(),o=!1)}))})(this,n.default.obj.merge(s,e))}))};return n.default.registerPlugin("mobileUi",l),l.VERSION="1.0.1",l}));
|
package/index.html
CHANGED
|
@@ -24,8 +24,7 @@
|
|
|
24
24
|
controls
|
|
25
25
|
playsinline
|
|
26
26
|
>
|
|
27
|
-
<source src="
|
|
28
|
-
<source src="//vjs.zencdn.net/v/oceans.webm" type="video/webm" />
|
|
27
|
+
<source src="https://d2zihajmogu5jn.cloudfront.net/bipbop-advanced/bipbop_16x9_variant.m3u8" type="application/x-mpegurl" />
|
|
29
28
|
</video-js>
|
|
30
29
|
<ul>
|
|
31
30
|
<li><a href="test/">Run unit tests in browser.</a></li>
|
|
@@ -63,10 +62,6 @@
|
|
|
63
62
|
id="alwaysLockToLandscape"
|
|
64
63
|
/>alwaysLockToLandscape
|
|
65
64
|
</li>
|
|
66
|
-
<li>
|
|
67
|
-
<input type="checkbox" data-section="fullscreen" id="iOS" />iOS
|
|
68
|
-
<b>Deprecated</b>
|
|
69
|
-
</li>
|
|
70
65
|
<li>
|
|
71
66
|
<input
|
|
72
67
|
type="checkbox"
|
|
@@ -119,7 +114,6 @@
|
|
|
119
114
|
exitOnRotate: true,
|
|
120
115
|
lockOnRotate: true,
|
|
121
116
|
alwaysLockToLandscape: false,
|
|
122
|
-
iOS: false,
|
|
123
117
|
disabled: false,
|
|
124
118
|
},
|
|
125
119
|
touchControls: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "videojs-mobile-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Mobile tap controls and fullscreen on rotate for Video.js",
|
|
5
5
|
"main": "dist/videojs-mobile-ui.cjs.js",
|
|
6
6
|
"module": "dist/videojs-mobile-ui.es.js",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"watch": "npm-run-all -p watch:*",
|
|
32
32
|
"watch:css": "npm run build:css -- -w",
|
|
33
33
|
"watch:js": "npm run build:js -- -w",
|
|
34
|
-
"prepublishOnly": "npm-run-all build-prod && vjsverify --verbose"
|
|
34
|
+
"prepublishOnly": "npm-run-all build-prod && vjsverify --verbose --skip-es-check"
|
|
35
35
|
},
|
|
36
36
|
"engines": {
|
|
37
37
|
"node": ">=14",
|
|
@@ -71,24 +71,24 @@
|
|
|
71
71
|
"global": "^4.4.0"
|
|
72
72
|
},
|
|
73
73
|
"peerDependencies": {
|
|
74
|
-
"video.js": "^
|
|
74
|
+
"video.js": "^8"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
77
|
"@babel/runtime": "^7.14.0",
|
|
78
|
-
"@videojs/generator-helpers": "~2.0
|
|
79
|
-
"husky": "^
|
|
80
|
-
"jsdoc": "^
|
|
78
|
+
"@videojs/generator-helpers": "~3.2.0",
|
|
79
|
+
"husky": "^8.0.1",
|
|
80
|
+
"jsdoc": "^4.0.0",
|
|
81
81
|
"karma": "^6.3.2",
|
|
82
82
|
"postcss": "^8.2.13",
|
|
83
83
|
"postcss-cli": "^8.3.1",
|
|
84
84
|
"rollup": "^2.46.0",
|
|
85
|
-
"sinon": "^
|
|
86
|
-
"video.js": "^
|
|
85
|
+
"sinon": "^15.0.0",
|
|
86
|
+
"video.js": "^8.0.0",
|
|
87
87
|
"videojs-generate-karma-config": "~8.0.0",
|
|
88
88
|
"videojs-generate-postcss-config": "~3.0.0",
|
|
89
|
-
"videojs-generate-rollup-config": "
|
|
89
|
+
"videojs-generate-rollup-config": "^7.0.0",
|
|
90
90
|
"videojs-generator-verify": "^4.1.0",
|
|
91
91
|
"videojs-languages": "^2.0.0",
|
|
92
|
-
"videojs-standard": "^
|
|
92
|
+
"videojs-standard": "^9.0.1"
|
|
93
93
|
}
|
|
94
94
|
}
|
package/src/plugin.css
CHANGED
|
@@ -30,16 +30,28 @@
|
|
|
30
30
|
|
|
31
31
|
&.skip {
|
|
32
32
|
opacity: 0;
|
|
33
|
-
animation: fadeAndScale 0.
|
|
33
|
+
animation: fadeAndScale 0.8s linear;
|
|
34
34
|
background-repeat: no-repeat;
|
|
35
35
|
background-position: 80% center;
|
|
36
36
|
background-size: 10%;
|
|
37
37
|
background-image: url('data:image/svg+xml;utf8,<svg fill="%23FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
|
|
38
|
+
|
|
39
|
+
&:after {
|
|
40
|
+
content: attr(data-skip-text);
|
|
41
|
+
position: absolute;
|
|
42
|
+
top: 60%;
|
|
43
|
+
left: 70%;
|
|
44
|
+
}
|
|
38
45
|
}
|
|
39
46
|
|
|
40
47
|
&.skip.reverse {
|
|
41
48
|
background-position: 20% center;
|
|
42
49
|
background-image: url('data:image/svg+xml;utf8,<svg fill="%23FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
|
|
50
|
+
|
|
51
|
+
&:after {
|
|
52
|
+
right: 70%;
|
|
53
|
+
left: unset;
|
|
54
|
+
}
|
|
43
55
|
}
|
|
44
56
|
|
|
45
57
|
.vjs-play-control {
|