videojs-mobile-ui 0.8.0 → 0.9.0-beta.3

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.
@@ -1,2 +1,2 @@
1
- /*! @name videojs-mobile-ui @version 0.8.0 @license MIT */
2
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("video.js"),require("global/window")):"function"==typeof define&&define.amd?define(["video.js","global/window"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).videojsMobileUi=t(e.videojs,e.window)}(this,(function(e,t){"use strict";function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=n(e),i=n(t);function r(e,t,n){return e(n={path:t,exports:{},require:function(e,t){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==t&&n.path)}},n.exports),n.exports}var a=r((function(e){function t(n,o){return e.exports=t=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},e.exports.default=e.exports,e.exports.__esModule=!0,t(n,o)}e.exports=t,e.exports.default=e.exports,e.exports.__esModule=!0})),l=r((function(e){e.exports=function(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,a(e,t)},e.exports.default=e.exports,e.exports.__esModule=!0})),s=o.default.getComponent("Component"),u=o.default.dom||o.default,c=function(e){function t(t,n){var o;return(o=e.call(this,t,n)||this).seekSeconds=n.seekSeconds,o.tapTimeout=n.tapTimeout,o.addChild("playToggle",{}),t.on(["playing","userinactive"],(function(e){o.removeClass("show-play-toggle")})),0===o.player_.options_.inactivityTimeout&&(o.player_.options_.inactivityTimeout=5e3),o.enable(),o}l(t,e);var n=t.prototype;return n.createEl=function(){return u.createEl("div",{className:"vjs-touch-overlay",tabIndex:-1})},n.handleTap=function(e){var t=this;e.target===this.el_&&(e.preventDefault(),this.firstTapCaptured?(this.firstTapCaptured=!1,this.timeout&&i.default.clearTimeout(this.timeout),this.handleDoubleTap(e)):(this.firstTapCaptured=!0,this.timeout=i.default.setTimeout((function(){t.firstTapCaptured=!1,t.handleSingleTap(e)}),this.tapTimeout)))},n.handleSingleTap=function(e){this.removeClass("skip"),this.toggleClass("show-play-toggle")},n.handleDoubleTap=function(e){var t=this,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()-this.seekSeconds)),this.addClass("reverse");else{if(!(o>n.width-.4*n.width))return;this.player_.currentTime(Math.min(this.player_.duration(),this.player_.currentTime()+this.seekSeconds)),this.removeClass("reverse")}this.removeClass("show-play-toggle"),this.removeClass("skip"),i.default.requestAnimationFrame((function(){t.addClass("skip")}))},n.enable=function(){this.firstTapCaptured=!1,this.on("touchend",this.handleTap)},n.disable=function(){this.off("touchend",this.handleTap)},t}(s);s.registerComponent("TouchOverlay",c);var d={fullscreen:{enterOnRotate:!0,exitOnRotate:!0,lockOnRotate:!0,lockToLandscapeOnEnter:!1,iOS:!1,disabled:!1},touchControls:{seekSeconds:10,tapTimeout:300,disableOnEnd:!1,disabled:!1}},f=i.default.screen,p=function(){if(f){var e=((f.orientation||{}).type||f.mozOrientation||f.msOrientation||"").split("-")[0];if("landscape"===e||"portrait"===e)return e}return"number"==typeof i.default.orientation?0===i.default.orientation||180===i.default.orientation?"portrait":"landscape":"portrait"},h=o.default.registerPlugin||o.default.plugin,m=function(e){var t=this;void 0===e&&(e={}),(e.forceForTesting||o.default.browser.IS_ANDROID||o.default.browser.IS_IOS)&&this.ready((function(){!function(e,t){if(e.addClass("vjs-mobile-ui"),t.fullscreen.iOS&&(o.default.log.warn("videojs-mobile-ui: `fullscreen.iOS` is deprecated. Use Video.js option `preferFullWindow` instead."),o.default.browser.IS_IOS&&o.default.browser.IOS_VERSION>9&&!e.el_.ownerDocument.querySelector(".bc-iframe")&&(e.tech_.el_.setAttribute("playsinline","playsinline"),e.tech_.supportsFullScreen=function(){return!1})),!t.touchControls.disabled){var n;(t.touchControls.disableOnEnd||"function"==typeof e.endscreen)&&e.addClass("vjs-mobile-ui-disable-end");var r=o.default.VERSION.split("."),a=parseInt(r[0],10),l=parseInt(r[1],10);n=a<7||7===a&&l<7?Array.prototype.indexOf.call(e.el_.children,e.getChild("ControlBar").el_):e.children_.indexOf(e.getChild("ControlBar")),e.touchOverlay=e.addChild("TouchOverlay",t.touchControls,n)}if(!t.fullscreen.disabled){var s=!1,u=function(){var n=p();"landscape"===n&&t.fullscreen.enterOnRotate?!1===e.paused()&&(e.requestFullscreen(),(t.fullscreen.lockOnRotate||t.fullscreen.lockToLandscapeOnEnter)&&f.orientation&&f.orientation.lock&&f.orientation.lock("landscape").then((function(){s=!0})).catch((function(e){o.default.log("Browser refused orientation lock:",e)}))):"portrait"===n&&t.fullscreen.exitOnRotate&&!s&&e.isFullscreen()&&e.exitFullscreen()};(t.fullscreen.enterOnRotate||t.fullscreen.exitOnRotate)&&(o.default.browser.IS_IOS?(i.default.addEventListener("orientationchange",u),e.on("dispose",(function(){i.default.removeEventListener("orientationchange",u)}))):f.orientation&&(f.orientation.onchange=u,e.on("dispose",(function(){f.orientation.onchange=null})))),e.on("fullscreenchange",(function(n){e.isFullscreen()&&t.fullscreen.lockToLandscapeOnEnter&&"portrait"===p()?f.orientation.lock("landscape").then((function(){s=!0})).catch((function(e){o.default.log("Browser refused orientation lock:",e)})):!e.isFullscreen()&&s&&(f.orientation.unlock(),s=!1)})),e.on("ended",(function(e){!0===s&&(f.orientation.unlock(),s=!1)}))}}(t,o.default.mergeOptions(d,e))}))};return h("mobileUi",m),m.VERSION="0.8.0",m}));
1
+ /*! @name videojs-mobile-ui @version 0.9.0-beta.3 @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 s=n.default.getComponent("Component"),i=n.default.dom||n.default;s.registerComponent("TouchOverlay",class extends s{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_=((e,t)=>{let n=null;return(...s)=>{window.clearTimeout(n),n=window.setTimeout(()=>{e.apply(null,s)},t)}})(e=>{const t=(this.taps-1)*this.seekSeconds;if(this.taps=0,t<1)return;const n=this.el_.getBoundingClientRect(),s=e.changedTouches[0].clientX-n.left;if(s<.4*n.width)this.player_.currentTime(Math.max(0,this.player_.currentTime()-t)),this.addClass("reverse");else{if(!(s>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.cancelable&&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 o={fullscreen:{enterOnRotate:!0,exitOnRotate:!0,lockOnRotate:!0,lockToLandscapeOnEnter:!1,swipeToFullscreen:!1,swipeFromFullscreen:!1,disabled:!1},touchControls:{seekSeconds:10,tapTimeout:300,disableOnEnd:!1,disabled:!1}},l=window.screen,r=n.default.registerPlugin||n.default.plugin,a=()=>{if(l){const e=((l.orientation||{}).type||l.mozOrientation||l.msOrientation||"").split("-")[0];if("landscape"===e||"portrait"===e)return e}return"number"==typeof window.orientation?0===window.orientation||180===window.orientation?"portrait":"landscape":"portrait"},c=(e,t)=>{if(e.addClass("vjs-mobile-ui"),!t.touchControls.disabled){let s;(t.touchControls.disableOnEnd||"function"==typeof e.endscreen)&&e.addClass("vjs-mobile-ui-disable-end");const i=n.default.VERSION.split("."),o=parseInt(i[0],10),l=parseInt(i[1],10);s=o<7||7===o&&l<7?Array.prototype.indexOf.call(e.el_.children,e.getChild("ControlBar").el_):e.children_.indexOf(e.getChild("ControlBar")),e.touchOverlay=e.addChild("TouchOverlay",t.touchControls,s)}if(t.fullscreen.disabled)return;(t.fullscreen.swipeToFullscreen||t.fullscreen.swipeFromFullscreen)&&((e,t)=>{const{swipeToFullscreen:n,swipeFromFullscreen:s}=t.fullscreen;n&&e.addClass("using-fs-swipe-up"),s&&e.addClass("using-fs-swipe-down");let i=0,o=!1;const l=t=>{const l=e.isFullscreen();!l&&!n||l&&!s?o=!1:(i=t.changedTouches[0].clientY,o=!0,e.tech_.el().style.transition="")},r=t=>{if(!o)return;const n=t.touches[0].clientY,s=i-n,l=e.isFullscreen();let r=1;!l&&s>0?(r=1+Math.min(.1,s/500),e.tech_.el().style.transform=`scale(${r})`):l&&s<0&&(r=1-Math.min(.1,Math.abs(s)/500),e.tech_.el().style.transform=`scale(${r})`)},a=t=>{if(!o)return;if(o=!1,e.tech_.el().style.transition="transform 0.3s ease-out",e.tech_.el().style.transform="scale(1)","touchcancel"===t.type)return;const n=t.changedTouches[0].clientY,s=i-n;s>30&&!e.isFullscreen()?e.requestFullscreen().catch(t=>{e.log.warn("Browser refused fullscreen",t)}):s<-30&&e.isFullscreen()&&e.exitFullscreen()};e.el().addEventListener("touchstart",l,{passive:!0}),e.el().addEventListener("touchmove",r,{passive:!0}),e.el().addEventListener("touchend",a,{passive:!0}),e.el().addEventListener("touchcancel",a,{passive:!0}),e.on("dispose",()=>{e.el().removeEventListener("touchstart",l,{passive:!0}),e.el().removeEventListener("touchmove",r,{passive:!0}),e.el().removeEventListener("touchend",a,{passive:!0}),e.el().removeEventListener("touchcancel",a,{passive:!0}),e.tech_.el().style.transform="",e.tech_.el().style.transition=""})})(e,t);let s=!1;const i=()=>{const i=a();"landscape"===i&&t.fullscreen.enterOnRotate?e.paused()||e.isFullscreen()||(e.requestFullscreen().catch(t=>{e.log.warn("Browser refused fullscreen request:",t)}),(t.fullscreen.lockOnRotate||t.fullscreen.lockToLandscapeOnEnter)&&l.orientation&&l.orientation.lock&&l.orientation.lock("landscape").then(()=>{s=!0}).catch(e=>{n.default.log.warn("Browser refused orientation lock:",e)})):"portrait"===i&&t.fullscreen.exitOnRotate&&!s&&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)})):l.orientation&&(l.orientation.onchange=i,e.on("dispose",()=>{l.orientation.onchange=null}))),e.on("fullscreenchange",i=>{e.isFullscreen()&&t.fullscreen.lockToLandscapeOnEnter&&"portrait"===a()?l.orientation.lock("landscape").then(()=>{s=!0}).catch(e=>{n.default.log("Browser refused orientation lock:",e)}):!e.isFullscreen()&&s&&(l.orientation.unlock(),s=!1)}),e.on("ended",e=>{!0===s&&(l.orientation.unlock(),s=!1)})},u=function(e={}){(e.forceForTesting||n.default.browser.IS_ANDROID||n.default.browser.IS_IOS)&&this.ready(()=>{c(this,n.default.mergeOptions(o,e))})};return r("mobileUi",u),u.VERSION="0.9.0-beta.3",u});
@@ -0,0 +1,173 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>JSDoc: Source: swipeFullscreen.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: swipeFullscreen.js</h1>
21
+
22
+
23
+
24
+
25
+
26
+
27
+ <section>
28
+ <article>
29
+ <pre class="prettyprint source linenums"><code>/** @import Player from 'video.js/dist/types/player' */
30
+ /** @import Plugin from 'video.js/dist/types/plugin' */
31
+ /** @import {MobileUiOptions} from './plugin' */
32
+
33
+ /**
34
+ * Sets up swiping to enter and exit fullscreen.
35
+ *
36
+ * @this {Plugin}
37
+ * @param {Player} player
38
+ * The player to initialise on.
39
+ * @param {MobileUiOptions} pluginOptions
40
+ * The options used by the mobile ui plugin.
41
+ */
42
+ const initSwipe = (player, pluginOptions) => {
43
+ const {swipeToFullscreen, swipeFromFullscreen} = pluginOptions.fullscreen;
44
+
45
+ if (swipeToFullscreen) {
46
+ player.addClass('using-fs-swipe-up');
47
+ }
48
+ if (swipeFromFullscreen) {
49
+ player.addClass('using-fs-swipe-down');
50
+ }
51
+
52
+ let touchStartY = 0;
53
+ let couldBeSwiping = false;
54
+ const swipeThreshold = 30;
55
+
56
+ /**
57
+ * Monitor the possible start of a swipe
58
+ *
59
+ * @param {TouchEvent} e Triggering touch event
60
+ */
61
+ const onStart = (e) => {
62
+ const isFullscreen = player.isFullscreen();
63
+
64
+ if (
65
+ (!isFullscreen &amp;&amp; !swipeToFullscreen) ||
66
+ (isFullscreen &amp;&amp; !swipeFromFullscreen)
67
+ ) {
68
+ couldBeSwiping = false;
69
+ return;
70
+ }
71
+
72
+ touchStartY = e.changedTouches[0].clientY;
73
+ couldBeSwiping = true;
74
+ player.tech_.el().style.transition = '';
75
+ };
76
+
77
+ /**
78
+ * Monitor the movement of a swipe
79
+ *
80
+ * @param {TouchEvent} e Triggering touch event
81
+ */
82
+ const onMove = (e) => {
83
+ if (!couldBeSwiping) {
84
+ return;
85
+ }
86
+
87
+ const currentY = e.touches[0].clientY;
88
+ const deltaY = touchStartY - currentY;
89
+ const isFullscreen = player.isFullscreen();
90
+
91
+ let scale = 1;
92
+
93
+ if (!isFullscreen &amp;&amp; deltaY > 0) {
94
+ // Swiping up to enter fullscreen: Zoom in (Max 1.1)
95
+ scale = 1 + Math.min(0.1, deltaY / 500);
96
+ player.tech_.el().style.transform = `scale(${scale})`;
97
+ } else if (isFullscreen &amp;&amp; deltaY &lt; 0) {
98
+ // Swiping down to exit fullscreen: Zoom out (Min 0.9)
99
+ scale = 1 - Math.min(0.1, Math.abs(deltaY) / 500);
100
+ player.tech_.el().style.transform = `scale(${scale})`;
101
+ }
102
+ };
103
+
104
+ /**
105
+ * Monitor the touch end to determine a valid swipe
106
+ *
107
+ * @param {TouchEvent} e Triggering touch event
108
+ */
109
+ const onEnd = (e) => {
110
+ if (!couldBeSwiping) {
111
+ return;
112
+ }
113
+ couldBeSwiping = false;
114
+
115
+ player.tech_.el().style.transition = 'transform 0.3s ease-out';
116
+ player.tech_.el().style.transform = 'scale(1)';
117
+
118
+ if (e.type === 'touchcancel') {
119
+ return;
120
+ }
121
+
122
+ const touchEndY = e.changedTouches[0].clientY;
123
+ const deltaY = touchStartY - touchEndY;
124
+
125
+ if (deltaY > swipeThreshold &amp;&amp; !player.isFullscreen()) {
126
+ player.requestFullscreen().catch((err) => {
127
+ player.log.warn('Browser refused fullscreen', err);
128
+ });
129
+ } else if (deltaY &lt; -swipeThreshold &amp;&amp; player.isFullscreen()) {
130
+ player.exitFullscreen();
131
+ }
132
+ };
133
+
134
+ player.el().addEventListener('touchstart', onStart, { passive: true });
135
+ player.el().addEventListener('touchmove', onMove, { passive: true });
136
+ player.el().addEventListener('touchend', onEnd, { passive: true });
137
+ player.el().addEventListener('touchcancel', onEnd, { passive: true });
138
+
139
+ player.on('dispose', () => {
140
+ player.el().removeEventListener('touchstart', onStart, { passive: true });
141
+ player.el().removeEventListener('touchmove', onMove, { passive: true });
142
+ player.el().removeEventListener('touchend', onEnd, { passive: true });
143
+ player.el().removeEventListener('touchcancel', onEnd, { passive: true });
144
+ player.tech_.el().style.transform = '';
145
+ player.tech_.el().style.transition = '';
146
+ });
147
+
148
+ };
149
+
150
+ export default initSwipe;
151
+ </code></pre>
152
+ </article>
153
+ </section>
154
+
155
+
156
+
157
+
158
+ </div>
159
+
160
+ <nav>
161
+ <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#Component">Component</a></li><li><a href="global.html#defaults">defaults</a></li><li><a href="global.html#getOrientation">getOrientation</a></li><li><a href="global.html#initSwipe">initSwipe</a></li><li><a href="global.html#mobileUi">mobileUi</a></li><li><a href="global.html#onPlayerReady">onPlayerReady</a></li></ul>
162
+ </nav>
163
+
164
+ <br class="clear">
165
+
166
+ <footer>
167
+ Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.5</a> on Fri Jan 23 2026 14:03:20 GMT+0100 (Mitteleuropäische Normalzeit)
168
+ </footer>
169
+
170
+ <script> prettyPrint(); </script>
171
+ <script src="scripts/linenumber.js"> </script>
172
+ </body>
173
+ </html>
package/index.html CHANGED
@@ -1,9 +1,11 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
+
3
4
  <head>
4
5
  <meta charset="utf-8" />
5
6
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
7
  <title>videojs-mobile-ui Demo</title>
8
+ <link href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20height%3D%2224px%22%20viewBox%3D%220%20-960%20960%20960%22%20width%3D%2224px%22%20fill%3D%22%231f1f1f%22%3E%3Cpath%20d%3D%22M419-80q-28%200-52.5-12T325-126L124-381q-8-9-7-21.5t9-20.5q20-21%2048-25t52%2011l74%2045v-328q0-17%2011.5-28.5T340-760q17%200%2029%2011.5t12%2028.5v200h299q50%200%2085%2035t35%2085v160q0%2066-47%20113T640-80H419Zm60-520q-17%200-28.5-11.5T439-640q0-2%205-20%208-14%2012-28.5t4-31.5q0-50-35-85t-85-35q-50%200-85%2035t-35%2085q0%2017%204%2031.5t12%2028.5q3%205%204%2010t1%2010q0%2017-11%2028.5T202-600q-11%200-20.5-6T167-621q-13-22-20-47t-7-52q0-83%2058.5-141.5T340-920q83%200%20141.5%2058.5T540-720q0%2027-7%2052t-20%2047q-5%209-14%2015t-20%206Z%22%2F%3E%3C%2Fsvg%3E" rel="icon" type="image/x-icon" />
7
9
  <link href="node_modules/video.js/dist/video-js.css" rel="stylesheet" />
8
10
  <link href="dist/videojs-mobile-ui.css" rel="stylesheet" />
9
11
  <style>
@@ -15,192 +17,252 @@
15
17
  pointer-events: none;
16
18
  display: none;
17
19
  }
20
+
21
+ body {
22
+ font-size: 16px;
23
+ line-height: 1.4;
24
+ margin-bottom: 60px;
25
+ }
26
+
27
+ .video-container {
28
+ width: 100vw;
29
+ margin-left: calc(50% - 50vw);
30
+ }
31
+
32
+ video-js:fullscreen .vjs-control-bar {
33
+ font-size: 1.1em;
34
+ padding-bottom: 20px;
35
+ height: calc(3em + 20px);
36
+ }
37
+
38
+ #demoOptions {
39
+
40
+ ul {
41
+ list-style: none;
42
+ padding: 0;
43
+ margin: 0;
44
+ }
45
+
46
+ li {
47
+ margin-bottom: 10px;
48
+ }
49
+
50
+ label {
51
+ min-height: 44px;
52
+ /* Apple/Google tap target guidance */
53
+ cursor: pointer;
54
+ font-family: ui-monospace, 'Courier New', Courier, monospace;
55
+ }
56
+
57
+ /* Text inputs */
58
+ input[type="text"],
59
+ input[type="email"],
60
+ input[type="number"],
61
+ input[type="password"],
62
+ textarea {
63
+ width: 90%;
64
+ padding: 10px 12px;
65
+ font-size: 16px;
66
+ /* Prevents iOS zoom */
67
+ border: 1px solid #ccc;
68
+ border-radius: 6px;
69
+ }
70
+
71
+ /* Checkboxes (simple but usable) */
72
+ input[type="checkbox"] {
73
+ width: 20px;
74
+ height: 20px;
75
+ flex-shrink: 0;
76
+ }
77
+
78
+ /* Optional: subtle focus style */
79
+ input:focus,
80
+ textarea:focus {
81
+ outline: none;
82
+ border-color: #007aff;
83
+ /* iOS blue */
84
+ }
85
+
86
+ /* Optional: slightly separate groups */
87
+ li+li {
88
+ border-top: 1px solid #eee;
89
+ padding-top: 8px;
90
+ }
91
+
92
+ button {
93
+ font-size: 16px;
94
+ margin-bottom: 10px;
95
+ }
96
+ }
18
97
  </style>
19
98
  </head>
99
+
20
100
  <body>
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>
101
+ <h1>videojs-mobile-ui test page.</h1>
102
+ <div class="video-container">
103
+ <video-js id="videojs-mobile-ui-player" class="video-js vjs-default-skin vjs-fluid" controls playsinline>
104
+ <source src="https://d2zihajmogu5jn.cloudfront.net/bipbop-advanced/bipbop_16x9_variant.m3u8"
105
+ type="application/x-mpegurl" />
106
+ </video-js>
107
+ </div>
37
108
  <ul>
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>
109
+ <li><a href="test/">Run unit tests in browser.</a></li>
77
110
  </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>
108
- </ul>
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
- };
132
-
133
- var url = new URL(window.location);
134
- if (url.searchParams.has('options')) {
135
- options = JSON.parse(url.searchParams.get('options'));
136
- }
111
+ <h2>Options</h2>
112
+ <div id="demoOptions">
113
+ <p>Reload to apply changed options.</p>
114
+ <button id="reload">Reload with options</button>
115
+ <ul id="options">
116
+ <li>
117
+ <h3>fullscreen:</h3>
118
+ </li>
119
+ <ul>
120
+ <li>
121
+ <input type="checkbox" data-section="fullscreen" id="enterOnRotate" /> <label for="enterOnRotate">enterOnRotate</label>
122
+ </li>
123
+ <li>
124
+ <input type="checkbox" data-section="fullscreen" id="exitOnRotate" />
125
+ <label for="exitOnRotate">exitOnRotate</label>
126
+ </li>
127
+ <li>
128
+ <input type="checkbox" data-section="fullscreen" id="lockOnRotate" />
129
+ <label for="lockOnRotate">lockOnRotate</label>
130
+ </li>
131
+ <li>
132
+ <input type="checkbox" data-section="fullscreen" id="alwaysLockToLandscape" />
133
+ <label for="alwaysLockToLandscape">alwaysLockToLandscape</label>
134
+ </li>
135
+ <li>
136
+ <input type="checkbox" data-section="fullscreen" id="swipeToFullscreen" />
137
+ <label for="swipeToFullscreen">swipeToFullscreen</label>
138
+ </li>
139
+ <li>
140
+ <input type="checkbox" data-section="fullscreen" id="swipeFromFullscreen" />
141
+ <label for="swipeFromFullscreen">swipeFromFullscreen</label>
142
+ </li>
143
+ <li>
144
+ <input type="checkbox" data-section="fullscreen" id="fullscreenDisabled" />
145
+ <label for="disabled">disabled</label>
146
+ </li>
147
+ </ul>
148
+ <li>
149
+ <h3>touchControls:</h3>
150
+ </li>
151
+ <ul>
152
+ <li>
153
+ <input type="number" data-section="touchControls" id="seekSeconds" />
154
+ <label for="seekSeconds">seekSeconds</label>
155
+ </li>
156
+ <li>
157
+ <input type="number" data-section="touchControls" id="tapTimeout" />
158
+ <label for="tapTimeout">tapTimeout</label>
159
+ </li>
160
+ <li>
161
+ <input type="checkbox" data-section="touchControls" id="disableOnEnd" />
162
+ <label for="disableOnEnd">disableOnEnd</label>
163
+ </li>
164
+ <li>
165
+ <input type="checkbox" data-section="touchControls" id="touchControlsDisabled" />
166
+ <label for="disabled">disabled</label>
167
+ </li>
168
+ </ul>
169
+ </ul>
170
+ </div>
171
+ <ul id="log"></ul>
172
+ <script src="node_modules/video.js/dist/video.js"></script>
173
+ <script src="dist/videojs-mobile-ui.js"></script>
174
+ <script>
175
+ (function (window, videojs) {
176
+ var options = {
177
+ fullscreen: {
178
+ enterOnRotate: true,
179
+ exitOnRotate: true,
180
+ lockOnRotate: true,
181
+ alwaysLockToLandscape: false,
182
+ swipeToFullscreen: false,
183
+ swipeFromFullscreen: false,
184
+ disabled: false,
185
+ },
186
+ touchControls: {
187
+ seekSeconds: 10,
188
+ tapTimeout: 300,
189
+ disableOnEnd: false,
190
+ disabled: false,
191
+ },
192
+ };
193
+
194
+ var url = new URL(window.location);
195
+ if (url.searchParams.has('options')) {
196
+ options = JSON.parse(url.searchParams.get('options'));
197
+ }
137
198
 
138
- console.log(JSON.stringify(options, null, 2));
199
+ console.log(JSON.stringify(options, null, 2));
139
200
 
140
- Object.keys(options).forEach(function (section) {
141
- Object.keys(options[section]).forEach(function (prop) {
142
- const val = options[section][prop];
201
+ Object.keys(options).forEach(function (section) {
202
+ Object.keys(options[section]).forEach(function (prop) {
203
+ const val = options[section][prop];
143
204
 
144
- if (prop === 'disabled') {
145
- prop = `${section}Disabled`;
146
- }
205
+ if (prop === 'disabled') {
206
+ prop = `${section}Disabled`;
207
+ }
147
208
 
148
- if (typeof val === 'boolean') {
149
- document.getElementById(prop).checked = val;
150
- }
151
- if (typeof val === 'number') {
152
- document.getElementById(prop).value = val;
153
- }
209
+ if (typeof val === 'boolean') {
210
+ document.getElementById(prop).checked = val;
211
+ }
212
+ if (typeof val === 'number') {
213
+ document.getElementById(prop).value = val;
214
+ }
215
+ });
154
216
  });
155
- });
156
-
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;
166
-
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);
217
+
218
+ document
219
+ .getElementById('options')
220
+ .querySelectorAll('input')
221
+ .forEach(function (opt) {
222
+ opt.addEventListener('change', function () {
223
+ if (this.type === 'checkbox') {
224
+ const param = this.id.endsWith('Disabled')
225
+ ? 'disabled'
226
+ : this.id;
227
+
228
+ options[this.getAttribute('data-section')][param] =
229
+ this.checked;
230
+ } else {
231
+ options[this.getAttribute('data-section')][this.id] =
232
+ parseFloat(this.value);
233
+ }
234
+ console.log(options);
235
+ });
236
+ });
237
+
238
+ document
239
+ .getElementById('reload')
240
+ .addEventListener('click', function () {
241
+ url.searchParams.set('options', JSON.stringify(options));
242
+
243
+ window.location = url.href;
244
+ });
245
+
246
+ window.addEventListener('orientationchange', function () {
247
+ var el = document.createElement('li');
248
+ var message =
249
+ new Date().toTimeString().split(' ')[0] + ' ' + window.orientation;
250
+ message +=
251
+ screen && screen.orientation
252
+ ? ' ' + screen.orientation.type + ' ' + screen.orientation.angle
253
+ : '';
254
+ el.textContent = message;
255
+ console.log(message);
256
+ document.getElementById('log').appendChild(el);
174
257
  });
175
- });
176
-
177
- document
178
- .getElementById('reload')
179
- .addEventListener('click', function () {
180
- url.searchParams.set('options', JSON.stringify(options));
181
-
182
- window.location = url.href;
183
- });
184
-
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
- });
197
-
198
- var testPlayer = (window.testPlayer = videojs(
199
- 'videojs-mobile-ui-player'
258
+
259
+ var testPlayer = (window.testPlayer = videojs(
260
+ 'videojs-mobile-ui-player'
200
261
  ));
201
- testPlayer.endscreen = function () {};
202
- testPlayer.mobileUi(options);
203
- })(window, window.videojs);
204
- </script>
262
+ testPlayer.endscreen = function () { };
263
+ testPlayer.mobileUi(options);
264
+ })(window, window.videojs);
265
+ </script>
205
266
  </body>
206
- </html>
267
+
268
+ </html>