videojs-mobile-ui 0.7.0 → 0.8.0

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 (40) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +10 -2
  3. package/dist/videojs-mobile-ui.cjs.js +19 -10
  4. package/dist/videojs-mobile-ui.css +1 -1
  5. package/dist/videojs-mobile-ui.es.js +19 -10
  6. package/dist/videojs-mobile-ui.js +19 -10
  7. package/dist/videojs-mobile-ui.min.js +2 -2
  8. package/docs/api/TouchOverlay.html +964 -0
  9. package/docs/api/fonts/OpenSans-Bold-webfont.eot +0 -0
  10. package/docs/api/fonts/OpenSans-Bold-webfont.svg +1830 -0
  11. package/docs/api/fonts/OpenSans-Bold-webfont.woff +0 -0
  12. package/docs/api/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
  13. package/docs/api/fonts/OpenSans-BoldItalic-webfont.svg +1830 -0
  14. package/docs/api/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
  15. package/docs/api/fonts/OpenSans-Italic-webfont.eot +0 -0
  16. package/docs/api/fonts/OpenSans-Italic-webfont.svg +1830 -0
  17. package/docs/api/fonts/OpenSans-Italic-webfont.woff +0 -0
  18. package/docs/api/fonts/OpenSans-Light-webfont.eot +0 -0
  19. package/docs/api/fonts/OpenSans-Light-webfont.svg +1831 -0
  20. package/docs/api/fonts/OpenSans-Light-webfont.woff +0 -0
  21. package/docs/api/fonts/OpenSans-LightItalic-webfont.eot +0 -0
  22. package/docs/api/fonts/OpenSans-LightItalic-webfont.svg +1835 -0
  23. package/docs/api/fonts/OpenSans-LightItalic-webfont.woff +0 -0
  24. package/docs/api/fonts/OpenSans-Regular-webfont.eot +0 -0
  25. package/docs/api/fonts/OpenSans-Regular-webfont.svg +1831 -0
  26. package/docs/api/fonts/OpenSans-Regular-webfont.woff +0 -0
  27. package/docs/api/global.html +957 -0
  28. package/docs/api/index.html +159 -0
  29. package/docs/api/plugin.js.html +221 -0
  30. package/docs/api/scripts/linenumber.js +25 -0
  31. package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -0
  32. package/docs/api/scripts/prettify/lang-css.js +2 -0
  33. package/docs/api/scripts/prettify/prettify.js +28 -0
  34. package/docs/api/styles/jsdoc-default.css +358 -0
  35. package/docs/api/styles/prettify-jsdoc.css +111 -0
  36. package/docs/api/styles/prettify-tomorrow.css +132 -0
  37. package/docs/api/touchOverlay.js.html +211 -0
  38. package/index.html +181 -102
  39. package/package.json +9 -6
  40. package/src/plugin.js +18 -8
@@ -0,0 +1,211 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>JSDoc: Source: touchOverlay.js</title>
6
+
7
+ <script src="scripts/prettify/prettify.js"> </script>
8
+ <script src="scripts/prettify/lang-css.js"> </script>
9
+ <!--[if lt IE 9]>
10
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
11
+ <![endif]-->
12
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
13
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
14
+ </head>
15
+
16
+ <body>
17
+
18
+ <div id="main">
19
+
20
+ <h1 class="page-title">Source: touchOverlay.js</h1>
21
+
22
+
23
+
24
+
25
+
26
+
27
+ <section>
28
+ <article>
29
+ <pre class="prettyprint source linenums"><code>/**
30
+ * @file touchOverlay.js
31
+ * Touch UI component
32
+ */
33
+
34
+ import videojs from 'video.js';
35
+ import window from 'global/window';
36
+
37
+ const Component = videojs.getComponent('Component');
38
+ const dom = videojs.dom || videojs;
39
+
40
+ /**
41
+ * The `TouchOverlay` is an overlay to capture tap events.
42
+ *
43
+ * @extends Component
44
+ */
45
+ class TouchOverlay extends Component {
46
+
47
+ /**
48
+ * Creates an instance of the this class.
49
+ *
50
+ * @param {Player} player
51
+ * The `Player` that this class should be attached to.
52
+ *
53
+ * @param {Object} [options]
54
+ * The key/value store of player options.
55
+ */
56
+ constructor(player, options) {
57
+ super(player, options);
58
+
59
+ this.seekSeconds = options.seekSeconds;
60
+ this.tapTimeout = options.tapTimeout;
61
+
62
+ // Add play toggle overlay
63
+ this.addChild('playToggle', {});
64
+
65
+ // Clear overlay when playback starts or with control fade
66
+ player.on(['playing', 'userinactive'], e => {
67
+ this.removeClass('show-play-toggle');
68
+ });
69
+
70
+ // A 0 inactivity timeout won't work here
71
+ if (this.player_.options_.inactivityTimeout === 0) {
72
+ this.player_.options_.inactivityTimeout = 5000;
73
+ }
74
+
75
+ this.enable();
76
+ }
77
+
78
+ /**
79
+ * Builds the DOM element.
80
+ *
81
+ * @return {Element}
82
+ * The DOM element.
83
+ */
84
+ createEl() {
85
+ const el = dom.createEl('div', {
86
+ className: 'vjs-touch-overlay',
87
+ // Touch overlay is not tabbable.
88
+ tabIndex: -1
89
+ });
90
+
91
+ return el;
92
+ }
93
+
94
+ /**
95
+ * Debounces to either handle a delayed single tap, or a double tap
96
+ *
97
+ * @param {Event} event
98
+ * The touch event
99
+ *
100
+ */
101
+ handleTap(event) {
102
+ // Don't handle taps on the play button
103
+ if (event.target !== this.el_) {
104
+ return;
105
+ }
106
+
107
+ event.preventDefault();
108
+
109
+ if (this.firstTapCaptured) {
110
+ this.firstTapCaptured = false;
111
+ if (this.timeout) {
112
+ window.clearTimeout(this.timeout);
113
+ }
114
+ this.handleDoubleTap(event);
115
+ } else {
116
+ this.firstTapCaptured = true;
117
+ this.timeout = window.setTimeout(() => {
118
+ this.firstTapCaptured = false;
119
+ this.handleSingleTap(event);
120
+ }, this.tapTimeout);
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Toggles display of play toggle
126
+ *
127
+ * @param {Event} event
128
+ * The touch event
129
+ *
130
+ */
131
+ handleSingleTap(event) {
132
+ this.removeClass('skip');
133
+ this.toggleClass('show-play-toggle');
134
+ }
135
+
136
+ /**
137
+ * Seeks by configured number of seconds if left or right part of video double tapped
138
+ *
139
+ * @param {Event} event
140
+ * The touch event
141
+ *
142
+ */
143
+ handleDoubleTap(event) {
144
+ const rect = this.el_.getBoundingClientRect();
145
+ const x = event.changedTouches[0].clientX - rect.left;
146
+
147
+ // Check if double tap is in left or right area
148
+ if (x &lt; rect.width * 0.4) {
149
+ this.player_.currentTime(Math.max(
150
+ 0, this.player_.currentTime() - this.seekSeconds));
151
+ this.addClass('reverse');
152
+ } else if (x > rect.width - (rect.width * 0.4)) {
153
+ this.player_.currentTime(Math.min(
154
+ this.player_.duration(), this.player_.currentTime() + this.seekSeconds));
155
+ this.removeClass('reverse');
156
+ } else {
157
+ return;
158
+ }
159
+
160
+ // Remove play toggle if showing
161
+ this.removeClass('show-play-toggle');
162
+
163
+ // Remove and readd class to trigger animation
164
+ this.removeClass('skip');
165
+ window.requestAnimationFrame(() => {
166
+ this.addClass('skip');
167
+ });
168
+ }
169
+
170
+ /**
171
+ * Enables touch handler
172
+ */
173
+ enable() {
174
+ this.firstTapCaptured = false;
175
+ this.on('touchend', this.handleTap);
176
+ }
177
+
178
+ /**
179
+ * Disables touch handler
180
+ */
181
+ disable() {
182
+ this.off('touchend', this.handleTap);
183
+ }
184
+
185
+ }
186
+
187
+ Component.registerComponent('TouchOverlay', TouchOverlay);
188
+ export default TouchOverlay;
189
+ </code></pre>
190
+ </article>
191
+ </section>
192
+
193
+
194
+
195
+
196
+ </div>
197
+
198
+ <nav>
199
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="TouchOverlay.html">TouchOverlay</a></li></ul><h3>Global</h3><ul><li><a href="global.html#mobileUi">mobileUi</a></li><li><a href="global.html#onPlayerReady">onPlayerReady</a></li></ul>
200
+ </nav>
201
+
202
+ <br class="clear">
203
+
204
+ <footer>
205
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Tue Feb 02 2021 09:43:56 GMT+0100 (CET)
206
+ </footer>
207
+
208
+ <script> prettyPrint(); </script>
209
+ <script src="scripts/linenumber.js"> </script>
210
+ </body>
211
+ </html>
package/index.html CHANGED
@@ -1,127 +1,206 @@
1
- <!doctype html>
1
+ <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <title>videojs-mobile-ui Demo</title>
7
- <link href="node_modules/video.js/dist/video-js.css" rel="stylesheet">
8
- <link href="dist/videojs-mobile-ui.css" rel="stylesheet">
7
+ <link href="node_modules/video.js/dist/video-js.css" rel="stylesheet" />
8
+ <link href="dist/videojs-mobile-ui.css" rel="stylesheet" />
9
9
  <style>
10
- .testEl {
11
- width: 10%;
12
- height: 10%;
13
- position: absolute;
14
- top: 0;
15
- pointer-events: none;
16
- display: none;
17
- }
10
+ .testEl {
11
+ width: 10%;
12
+ height: 10%;
13
+ position: absolute;
14
+ top: 0;
15
+ pointer-events: none;
16
+ display: none;
17
+ }
18
18
  </style>
19
19
  </head>
20
20
  <body>
21
- <video-js id="videojs-mobile-ui-player" class="video-js vjs-default-skin vjs-fluid" controls playsinline>
22
- <source src="//vjs.zencdn.net/v/oceans.mp4" type='video/mp4'>
23
- <source src="//vjs.zencdn.net/v/oceans.webm" type='video/webm'>
24
- </video-js>
21
+ <video-js
22
+ id="videojs-mobile-ui-player"
23
+ class="video-js vjs-default-skin vjs-fluid"
24
+ controls
25
+ playsinline
26
+ >
27
+ <source src="//vjs.zencdn.net/v/oceans.mp4" type="video/mp4" />
28
+ <source src="//vjs.zencdn.net/v/oceans.webm" type="video/webm" />
29
+ </video-js>
30
+ <ul>
31
+ <li><a href="test/">Run unit tests in browser.</a></li>
32
+ <li><a href="docs/api/">Read generated docs.</a></li>
33
+ </ul>
34
+ <h2>Options</h2>
35
+ <ul id="options">
36
+ <li>fullscreen:</li>
25
37
  <ul>
26
- <li><a href="test/">Run unit tests in browser.</a></li>
27
- <li><a href="docs/api/">Read generated docs.</a></li>
38
+ <li>
39
+ <input
40
+ type="checkbox"
41
+ data-section="fullscreen"
42
+ id="enterOnRotate"
43
+ />enterOnRotate
44
+ </li>
45
+ <li>
46
+ <input
47
+ type="checkbox"
48
+ data-section="fullscreen"
49
+ id="exitOnRotate"
50
+ />exitOnRotate
51
+ </li>
52
+ <li>
53
+ <input
54
+ type="checkbox"
55
+ data-section="fullscreen"
56
+ id="lockOnRotate"
57
+ />lockOnRotate
58
+ </li>
59
+ <li>
60
+ <input
61
+ type="checkbox"
62
+ data-section="fullscreen"
63
+ id="alwaysLockToLandscape"
64
+ />alwaysLockToLandscape
65
+ </li>
66
+ <li>
67
+ <input type="checkbox" data-section="fullscreen" id="iOS" />iOS
68
+ <b>Deprecated</b>
69
+ </li>
70
+ <li>
71
+ <input
72
+ type="checkbox"
73
+ data-section="fullscreen"
74
+ id="fullscreenDisabled"
75
+ />disabled
76
+ </li>
28
77
  </ul>
29
- <h2>Options</h2>
30
- <ul id="options">
31
- <li>fullscreen:</li>
32
- <ul>
33
- <li><input type="checkbox" data-section="fullscreen" id="enterOnRotate">enterOnRotate</li>
34
- <li><input type="checkbox" data-section="fullscreen" id="exitOnRotate">exitOnRotate</li>
35
- <li><input type="checkbox" data-section="fullscreen" id="lockOnRotate">lockOnRotate</li>
36
- <li><input type="checkbox" data-section="fullscreen" id="iOS">iOS <b>Deprecated</b></li>
37
- <li><input type="checkbox" data-section="fullscreen" id="fullscreenDisabled">disabled</li>
38
- </ul>
39
- <li>touchControls:</li>
40
- <ul>
41
- <li><input type="number" data-section="touchControls" id="seekSeconds">seekSeconds</li>
42
- <li><input type="number" data-section="touchControls" id="tapTimeout">tapTimeout</li>
43
- <li><input type="checkbox" data-section="touchControls" id="disableOnEnd">disableOnEnd</li>
44
- <li><input type="checkbox" data-section="touchControls" id="touchControlsDisabled">disabled</li>
45
- </ul>
78
+ <li>touchControls:</li>
79
+ <ul>
80
+ <li>
81
+ <input
82
+ type="number"
83
+ data-section="touchControls"
84
+ id="seekSeconds"
85
+ />seekSeconds
86
+ </li>
87
+ <li>
88
+ <input
89
+ type="number"
90
+ data-section="touchControls"
91
+ id="tapTimeout"
92
+ />tapTimeout
93
+ </li>
94
+ <li>
95
+ <input
96
+ type="checkbox"
97
+ data-section="touchControls"
98
+ id="disableOnEnd"
99
+ />disableOnEnd
100
+ </li>
101
+ <li>
102
+ <input
103
+ type="checkbox"
104
+ data-section="touchControls"
105
+ id="touchControlsDisabled"
106
+ />disabled
107
+ </li>
46
108
  </ul>
47
- <button id="reload">Reload with options</button>
48
- <ul id="log"></ul>
49
- <script src="node_modules/video.js/dist/video.js"></script>
50
- <script src="dist/videojs-mobile-ui.js"></script>
51
- <script>
52
- (function(window, videojs) {
53
- var options = {
54
- fullscreen: {
55
- enterOnRotate: true,
56
- exitOnRotate: true,
57
- lockOnRotate: true,
58
- iOS: false,
59
- disabled: false
60
- },
61
- touchControls: {
62
- seekSeconds: 10,
63
- tapTimeout: 300,
64
- disableOnEnd: false,
65
- disabled: false
66
- }
67
- };
109
+ </ul>
110
+ <button id="reload">Reload with options</button>
111
+ <ul id="log"></ul>
112
+ <script src="node_modules/video.js/dist/video.js"></script>
113
+ <script src="dist/videojs-mobile-ui.js"></script>
114
+ <script>
115
+ (function (window, videojs) {
116
+ var options = {
117
+ fullscreen: {
118
+ enterOnRotate: true,
119
+ exitOnRotate: true,
120
+ lockOnRotate: true,
121
+ alwaysLockToLandscape: false,
122
+ iOS: false,
123
+ disabled: false,
124
+ },
125
+ touchControls: {
126
+ seekSeconds: 10,
127
+ tapTimeout: 300,
128
+ disableOnEnd: false,
129
+ disabled: false,
130
+ },
131
+ };
68
132
 
69
- var url = new URL(window.location);
70
- if (url.searchParams.has('options')) {
71
- options = JSON.parse(url.searchParams.get('options'));
72
- }
133
+ var url = new URL(window.location);
134
+ if (url.searchParams.has('options')) {
135
+ options = JSON.parse(url.searchParams.get('options'));
136
+ }
73
137
 
74
- console.log(JSON.stringify(options, null, 2));
138
+ console.log(JSON.stringify(options, null, 2));
75
139
 
76
- Object.keys(options).forEach(function(section) {
77
- Object.keys(options[section]).forEach(function(prop) {
78
- const val = options[section][prop];
140
+ Object.keys(options).forEach(function (section) {
141
+ Object.keys(options[section]).forEach(function (prop) {
142
+ const val = options[section][prop];
79
143
 
80
- if (prop === 'disabled') {
81
- prop = `${section}Disabled`;
82
- }
144
+ if (prop === 'disabled') {
145
+ prop = `${section}Disabled`;
146
+ }
83
147
 
84
- if (typeof val === 'boolean') {
85
- document.getElementById(prop).checked = val;
86
- }
87
- if (typeof val === 'number') {
88
- document.getElementById(prop).value = val;
89
- }
90
- });
148
+ if (typeof val === 'boolean') {
149
+ document.getElementById(prop).checked = val;
150
+ }
151
+ if (typeof val === 'number') {
152
+ document.getElementById(prop).value = val;
153
+ }
91
154
  });
155
+ });
92
156
 
93
- document.getElementById('options').querySelectorAll('input').forEach(function(opt) {
94
- opt.addEventListener('change', function() {
95
- if (this.type === 'checkbox') {
96
- const param = this.id.endsWith('Disabled') ? 'disabled' : this.id;
157
+ document
158
+ .getElementById('options')
159
+ .querySelectorAll('input')
160
+ .forEach(function (opt) {
161
+ opt.addEventListener('change', function () {
162
+ if (this.type === 'checkbox') {
163
+ const param = this.id.endsWith('Disabled')
164
+ ? 'disabled'
165
+ : this.id;
97
166
 
98
- options[this.getAttribute('data-section')][param] = this.checked;
99
- } else {
100
- options[this.getAttribute('data-section')][this.id] = parseFloat(this.value);
101
- }
102
- console.log(options);
103
- });
167
+ options[this.getAttribute('data-section')][param] =
168
+ this.checked;
169
+ } else {
170
+ options[this.getAttribute('data-section')][this.id] =
171
+ parseFloat(this.value);
172
+ }
173
+ console.log(options);
104
174
  });
175
+ });
105
176
 
106
- document.getElementById('reload').addEventListener('click', function() {
107
- url.searchParams.set('options', JSON.stringify(options));
177
+ document
178
+ .getElementById('reload')
179
+ .addEventListener('click', function () {
180
+ url.searchParams.set('options', JSON.stringify(options));
108
181
 
109
- window.location = url.href;
110
- })
182
+ window.location = url.href;
183
+ });
111
184
 
112
- window.addEventListener('orientationchange', function() {
113
- var el = document.createElement('li');
114
- var message = (new Date).toTimeString().split(' ')[0] + ' ' + window.orientation;
115
- message += (screen && screen.orientation ? ' ' + screen.orientation.type + ' ' + screen.orientation.angle : '');
116
- el.textContent = message;
117
- console.log(message);
118
- document.getElementById('log').appendChild(el);
119
- });
185
+ window.addEventListener('orientationchange', function () {
186
+ var el = document.createElement('li');
187
+ var message =
188
+ new Date().toTimeString().split(' ')[0] + ' ' + window.orientation;
189
+ message +=
190
+ screen && screen.orientation
191
+ ? ' ' + screen.orientation.type + ' ' + screen.orientation.angle
192
+ : '';
193
+ el.textContent = message;
194
+ console.log(message);
195
+ document.getElementById('log').appendChild(el);
196
+ });
120
197
 
121
- var testPlayer = window.testPlayer = videojs('videojs-mobile-ui-player');
122
- testPlayer.endscreen = function() {};
123
- testPlayer.mobileUi(options);
124
- }(window, window.videojs));
125
- </script>
198
+ var testPlayer = (window.testPlayer = videojs(
199
+ 'videojs-mobile-ui-player'
200
+ ));
201
+ testPlayer.endscreen = function () {};
202
+ testPlayer.mobileUi(options);
203
+ })(window, window.videojs);
204
+ </script>
126
205
  </body>
127
206
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "videojs-mobile-ui",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
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",
@@ -68,24 +68,27 @@
68
68
  "README.md": "doctoc --notitle"
69
69
  },
70
70
  "dependencies": {
71
- "global": "^4.4.0",
72
- "video.js": "^7"
71
+ "global": "^4.4.0"
72
+ },
73
+ "peerDependencies": {
74
+ "video.js": "^6 || ^7"
73
75
  },
74
76
  "devDependencies": {
75
77
  "@babel/runtime": "^7.14.0",
76
78
  "@videojs/generator-helpers": "~2.0.2",
79
+ "husky": "^6.0.0",
77
80
  "jsdoc": "^3.6.7",
78
81
  "karma": "^6.3.2",
79
82
  "postcss": "^8.2.13",
80
83
  "postcss-cli": "^8.3.1",
81
84
  "rollup": "^2.46.0",
82
85
  "sinon": "^9.1.0",
86
+ "video.js": "^6 || ^7",
83
87
  "videojs-generate-karma-config": "~8.0.0",
84
88
  "videojs-generate-postcss-config": "~3.0.0",
85
89
  "videojs-generate-rollup-config": "~6.2.0",
86
- "videojs-generator-verify": "~3.0.3",
90
+ "videojs-generator-verify": "^4.1.0",
87
91
  "videojs-languages": "^2.0.0",
88
- "videojs-standard": "^8.0.4",
89
- "husky": "^6.0.0"
92
+ "videojs-standard": "^8.0.4"
90
93
  }
91
94
  }
package/src/plugin.js CHANGED
@@ -9,6 +9,7 @@ const defaults = {
9
9
  enterOnRotate: true,
10
10
  exitOnRotate: true,
11
11
  lockOnRotate: true,
12
+ lockToLandscapeOnEnter: false,
12
13
  iOS: false,
13
14
  disabled: false
14
15
  },
@@ -112,7 +113,7 @@ const onPlayerReady = (player, options) => {
112
113
  if (currentOrientation === 'landscape' && options.fullscreen.enterOnRotate) {
113
114
  if (player.paused() === false) {
114
115
  player.requestFullscreen();
115
- if (options.fullscreen.lockOnRotate &&
116
+ if ((options.fullscreen.lockOnRotate || options.fullscreen.lockToLandscapeOnEnter) &&
116
117
  screen.orientation && screen.orientation.lock) {
117
118
  screen.orientation.lock('landscape').then(() => {
118
119
  locked = true;
@@ -143,15 +144,21 @@ const onPlayerReady = (player, options) => {
143
144
  screen.orientation.onchange = null;
144
145
  });
145
146
  }
146
-
147
- player.on('fullscreenchange', _ => {
148
- if (!player.isFullscreen() && locked) {
149
- screen.orientation.unlock();
150
- locked = false;
151
- }
152
- });
153
147
  }
154
148
 
149
+ player.on('fullscreenchange', _ => {
150
+ if (player.isFullscreen() && options.fullscreen.lockToLandscapeOnEnter && getOrientation() === 'portrait') {
151
+ screen.orientation.lock('landscape').then(()=>{
152
+ locked = true;
153
+ }).catch((e) => {
154
+ videojs.log('Browser refused orientation lock:', e);
155
+ });
156
+ } else if (!player.isFullscreen() && locked) {
157
+ screen.orientation.unlock();
158
+ locked = false;
159
+ }
160
+ });
161
+
155
162
  player.on('ended', _ => {
156
163
  if (locked === true) {
157
164
  screen.orientation.unlock();
@@ -180,6 +187,9 @@ const onPlayerReady = (player, options) => {
180
187
  * Whether to leave fullscreen when rotating to portrait (if not locked)
181
188
  * @param {boolean} [options.fullscreen.lockOnRotate=true]
182
189
  * Whether to lock orientation when rotating to landscape
190
+ * Unlocked when exiting fullscreen or on 'ended
191
+ * @param {boolean} [options.fullscreen.lockToLandscapeOnEnter=false]
192
+ * Whether to always lock orientation to landscape on fullscreen mode
183
193
  * Unlocked when exiting fullscreen or on 'ended'
184
194
  * @param {boolean} [options.fullscreen.iOS=false]
185
195
  * Deprecated: Whether to disable iOS's native fullscreen so controls can work