vidply 1.0.33 → 1.0.35

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 (64) hide show
  1. package/dist/dev/{vidply.HLSRenderer-LIFBU6UD.js → vidply.HLSRenderer-YGWCAICA.js} +3 -3
  2. package/dist/dev/{vidply.HTML5Renderer-YWMVYWFS.js → vidply.HTML5Renderer-PMNFHAKW.js} +3 -3
  3. package/dist/dev/{vidply.SoundCloudRenderer-CD7VJKNS.js → vidply.SoundCloudRenderer-HCMKXHSX.js} +2 -4
  4. package/dist/dev/vidply.SoundCloudRenderer-HCMKXHSX.js.map +7 -0
  5. package/dist/dev/{vidply.TranscriptManager-R7NJRU7E.js → vidply.TranscriptManager-EIIN5YOF.js} +3 -3
  6. package/dist/dev/{vidply.VimeoRenderer-VPH4RNES.js → vidply.VimeoRenderer-SLEBCZTT.js} +2 -3
  7. package/dist/dev/vidply.VimeoRenderer-SLEBCZTT.js.map +7 -0
  8. package/dist/dev/{vidply.YouTubeRenderer-6MGKEFTZ.js → vidply.YouTubeRenderer-E6F4UGVF.js} +2 -3
  9. package/dist/dev/vidply.YouTubeRenderer-E6F4UGVF.js.map +7 -0
  10. package/dist/dev/{vidply.chunk-PMRKJBGH.js → vidply.chunk-AXXU22HR.js} +92 -15
  11. package/dist/dev/{vidply.chunk-PMRKJBGH.js.map → vidply.chunk-AXXU22HR.js.map} +2 -2
  12. package/dist/dev/{vidply.chunk-UVO24MXU.js → vidply.chunk-IIN4G4UQ.js} +2 -2
  13. package/dist/dev/{vidply.de-CEGBLV67.js → vidply.de-YBEYEXBL.js} +2 -2
  14. package/dist/dev/{vidply.es-2QCQKZ4U.js → vidply.es-QA4YSA5S.js} +2 -2
  15. package/dist/dev/vidply.esm.js +56 -68
  16. package/dist/dev/vidply.esm.js.map +2 -2
  17. package/dist/dev/{vidply.fr-FJAZRL4L.js → vidply.fr-LAM3XJZI.js} +2 -2
  18. package/dist/dev/{vidply.ja-2XQOW53T.js → vidply.ja-FTBFZD66.js} +2 -2
  19. package/dist/legacy/vidply.js +142 -74
  20. package/dist/legacy/vidply.js.map +3 -3
  21. package/dist/legacy/vidply.min.js +2 -2
  22. package/dist/legacy/vidply.min.meta.json +20 -20
  23. package/dist/prod/{vidply.HLSRenderer-ESR6NAMI.min.js → vidply.HLSRenderer-D2KTBEEI.min.js} +2 -2
  24. package/dist/prod/{vidply.HTML5Renderer-6ROXQSQY.min.js → vidply.HTML5Renderer-ZSV6PDOH.min.js} +2 -2
  25. package/dist/prod/vidply.SoundCloudRenderer-D2FNOEG6.min.js +6 -0
  26. package/dist/prod/{vidply.TranscriptManager-B65LKXGG.min.js → vidply.TranscriptManager-VXCTCJ7X.min.js} +2 -2
  27. package/dist/prod/vidply.VimeoRenderer-QELFZVDU.min.js +6 -0
  28. package/dist/prod/vidply.YouTubeRenderer-ZL6YUHTF.min.js +6 -0
  29. package/dist/prod/{vidply.chunk-7HVHEUHH.min.js → vidply.chunk-SQVOYVKH.min.js} +1 -1
  30. package/dist/prod/{vidply.chunk-IQKD4GUB.min.js → vidply.chunk-Z6BHMOGK.min.js} +2 -2
  31. package/dist/prod/{vidply.de-IHKC573T.min.js → vidply.de-WCUZUF3T.min.js} +1 -1
  32. package/dist/prod/{vidply.es-3IJCQLJ7.min.js → vidply.es-54CIIDMO.min.js} +1 -1
  33. package/dist/prod/vidply.esm.min.js +4 -4
  34. package/dist/prod/{vidply.fr-NC4VEAPH.min.js → vidply.fr-7FYGFFK2.min.js} +1 -1
  35. package/dist/prod/{vidply.ja-4ZC6ZQLV.min.js → vidply.ja-E4UTAURP.min.js} +1 -1
  36. package/dist/vidply.css +219 -109
  37. package/dist/vidply.esm.min.meta.json +50 -50
  38. package/dist/vidply.min.css +2 -2
  39. package/package.json +3 -3
  40. package/src/controls/ControlBar.js +3 -0
  41. package/src/controls/KeyboardManager.js +19 -0
  42. package/src/core/Player.js +1 -64
  43. package/src/core/SignLanguageManager.js +18 -4
  44. package/src/features/PlaylistManager.js +31 -19
  45. package/src/index.js +3 -1
  46. package/src/renderers/SoundCloudRenderer.js +0 -2
  47. package/src/renderers/VimeoRenderer.js +0 -1
  48. package/src/renderers/YouTubeRenderer.js +0 -1
  49. package/src/styles/vidply.css +218 -108
  50. package/src/utils/DraggableResizable.js +123 -12
  51. package/dist/dev/vidply.SoundCloudRenderer-CD7VJKNS.js.map +0 -7
  52. package/dist/dev/vidply.VimeoRenderer-VPH4RNES.js.map +0 -7
  53. package/dist/dev/vidply.YouTubeRenderer-6MGKEFTZ.js.map +0 -7
  54. package/dist/prod/vidply.SoundCloudRenderer-MOR2CUFH.min.js +0 -6
  55. package/dist/prod/vidply.VimeoRenderer-3HBMM2WR.min.js +0 -6
  56. package/dist/prod/vidply.YouTubeRenderer-MFC2GMAC.min.js +0 -6
  57. /package/dist/dev/{vidply.HLSRenderer-LIFBU6UD.js.map → vidply.HLSRenderer-YGWCAICA.js.map} +0 -0
  58. /package/dist/dev/{vidply.HTML5Renderer-YWMVYWFS.js.map → vidply.HTML5Renderer-PMNFHAKW.js.map} +0 -0
  59. /package/dist/dev/{vidply.TranscriptManager-R7NJRU7E.js.map → vidply.TranscriptManager-EIIN5YOF.js.map} +0 -0
  60. /package/dist/dev/{vidply.chunk-UVO24MXU.js.map → vidply.chunk-IIN4G4UQ.js.map} +0 -0
  61. /package/dist/dev/{vidply.de-CEGBLV67.js.map → vidply.de-YBEYEXBL.js.map} +0 -0
  62. /package/dist/dev/{vidply.es-2QCQKZ4U.js.map → vidply.es-QA4YSA5S.js.map} +0 -0
  63. /package/dist/dev/{vidply.fr-FJAZRL4L.js.map → vidply.fr-LAM3XJZI.js.map} +0 -0
  64. /package/dist/dev/{vidply.ja-2XQOW53T.js.map → vidply.ja-FTBFZD66.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Universal, Accessible Video Player
3
- * (c) 2025 Matthias Peltzer
3
+ * (c) 2026 Matthias Peltzer
4
4
  * Released under GPL-2.0-or-later License
5
5
  */
6
6
 
@@ -32,7 +32,7 @@ var HLSRenderer = class {
32
32
  return video.canPlayType("application/vnd.apple.mpegurl") !== "";
33
33
  }
34
34
  async initNative() {
35
- const HTML5Renderer = (await import("./vidply.HTML5Renderer-YWMVYWFS.js")).HTML5Renderer;
35
+ const HTML5Renderer = (await import("./vidply.HTML5Renderer-PMNFHAKW.js")).HTML5Renderer;
36
36
  const renderer = new HTML5Renderer(this.player);
37
37
  await renderer.init();
38
38
  Object.getOwnPropertyNames(Object.getPrototypeOf(renderer)).forEach((method) => {
@@ -314,4 +314,4 @@ var HLSRenderer = class {
314
314
  export {
315
315
  HLSRenderer
316
316
  };
317
- //# sourceMappingURL=vidply.HLSRenderer-LIFBU6UD.js.map
317
+ //# sourceMappingURL=vidply.HLSRenderer-YGWCAICA.js.map
@@ -1,12 +1,12 @@
1
1
  /*!
2
2
  * Universal, Accessible Video Player
3
- * (c) 2025 Matthias Peltzer
3
+ * (c) 2026 Matthias Peltzer
4
4
  * Released under GPL-2.0-or-later License
5
5
  */
6
6
  import {
7
7
  HTML5Renderer
8
- } from "./vidply.chunk-UVO24MXU.js";
8
+ } from "./vidply.chunk-IIN4G4UQ.js";
9
9
  export {
10
10
  HTML5Renderer
11
11
  };
12
- //# sourceMappingURL=vidply.HTML5Renderer-YWMVYWFS.js.map
12
+ //# sourceMappingURL=vidply.HTML5Renderer-PMNFHAKW.js.map
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Universal, Accessible Video Player
3
- * (c) 2025 Matthias Peltzer
3
+ * (c) 2026 Matthias Peltzer
4
4
  * Released under GPL-2.0-or-later License
5
5
  */
6
6
 
@@ -97,10 +97,8 @@ var SoundCloudRenderer = class {
97
97
  this.iframe.style.width = "100%";
98
98
  this.iframe.style.display = "block";
99
99
  if (this.isPlaylist()) {
100
- this.iframe.style.aspectRatio = "16 / 9";
101
100
  this.iframe.classList.add("vidply-soundcloud-iframe", "vidply-soundcloud-playlist");
102
101
  } else {
103
- this.iframe.style.aspectRatio = "16 / 3";
104
102
  this.iframe.classList.add("vidply-soundcloud-iframe");
105
103
  }
106
104
  this.iframe.style.maxHeight = "100%";
@@ -277,4 +275,4 @@ export {
277
275
  SoundCloudRenderer,
278
276
  SoundCloudRenderer_default as default
279
277
  };
280
- //# sourceMappingURL=vidply.SoundCloudRenderer-CD7VJKNS.js.map
278
+ //# sourceMappingURL=vidply.SoundCloudRenderer-HCMKXHSX.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/renderers/SoundCloudRenderer.js"],
4
+ "sourcesContent": ["/**\r\n * SoundCloud Renderer\r\n * Uses SoundCloud Widget API for embedded track playback\r\n */\r\n\r\nexport class SoundCloudRenderer {\r\n constructor(player) {\r\n this.player = player;\r\n this.widget = null;\r\n this.trackUrl = null;\r\n this.isReady = false;\r\n this.iframe = null;\r\n this.iframeId = null;\r\n }\r\n\r\n async init() {\r\n // Extract track URL - use currentSource which works for external renderers\r\n this.trackUrl = this.player.currentSource || this.player.element.src || this.player.element.querySelector('source')?.src;\r\n \r\n if (!this.trackUrl || !this.isValidSoundCloudUrl(this.trackUrl)) {\r\n throw new Error('Invalid SoundCloud URL');\r\n }\r\n\r\n // Load SoundCloud Widget API\r\n await this.loadSoundCloudAPI();\r\n\r\n // Create iframe\r\n this.createIframe();\r\n\r\n // Initialize widget\r\n await this.initializeWidget();\r\n }\r\n\r\n /**\r\n * Validate SoundCloud URL\r\n * @param {string} url \r\n * @returns {boolean}\r\n */\r\n isValidSoundCloudUrl(url) {\r\n return url.includes('soundcloud.com') || url.includes('api.soundcloud.com');\r\n }\r\n\r\n /**\r\n * Check if URL is a playlist/set\r\n */\r\n isPlaylist() {\r\n return this.trackUrl && this.trackUrl.includes('/sets/');\r\n }\r\n\r\n /**\r\n * Extract track/playlist info from URL for embed\r\n * SoundCloud URLs can be:\r\n * - https://soundcloud.com/artist/track\r\n * - https://soundcloud.com/artist/sets/playlist\r\n * - https://api.soundcloud.com/tracks/123456\r\n */\r\n getEmbedUrl() {\r\n // SoundCloud widget needs the track URL encoded\r\n const encodedUrl = encodeURIComponent(this.trackUrl);\r\n \r\n // Build widget URL with parameters\r\n const params = new URLSearchParams({\r\n url: this.trackUrl,\r\n auto_play: this.player.options.autoplay ? 'true' : 'false',\r\n hide_related: 'true',\r\n show_comments: 'false',\r\n show_user: 'true',\r\n show_reposts: 'false',\r\n show_teaser: 'false',\r\n visual: 'false', // Use classic player for better control\r\n color: '%23007bff'\r\n });\r\n \r\n return `https://w.soundcloud.com/player/?${params.toString()}`;\r\n }\r\n\r\n async loadSoundCloudAPI() {\r\n // Check if API is already loaded\r\n if (window.SC && window.SC.Widget) {\r\n return Promise.resolve();\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n const script = document.createElement('script');\r\n script.src = 'https://w.soundcloud.com/player/api.js';\r\n script.onload = () => {\r\n // Wait a bit for SC.Widget to be fully available\r\n setTimeout(() => {\r\n if (window.SC && window.SC.Widget) {\r\n resolve();\r\n } else {\r\n reject(new Error('SoundCloud Widget API not available'));\r\n }\r\n }, 100);\r\n };\r\n script.onerror = () => reject(new Error('Failed to load SoundCloud Widget API'));\r\n document.head.appendChild(script);\r\n });\r\n }\r\n\r\n createIframe() {\r\n // Hide original element and remove poster (SoundCloud has its own visual widget)\r\n this.player.element.style.display = 'none';\r\n this.player.element.removeAttribute('poster');\r\n \r\n // Remove poster overlay from video wrapper if present\r\n if (this.player.videoWrapper) {\r\n this.player.videoWrapper.classList.remove('vidply-forced-poster');\r\n this.player.videoWrapper.style.removeProperty('--vidply-poster-image');\r\n }\r\n\r\n // Generate unique ID for iframe\r\n this.iframeId = `soundcloud-player-${Math.random().toString(36).substr(2, 9)}`;\r\n\r\n // Create iframe for SoundCloud widget\r\n this.iframe = document.createElement('iframe');\r\n this.iframe.id = this.iframeId;\r\n this.iframe.scrolling = 'no';\r\n this.iframe.frameBorder = 'no';\r\n this.iframe.allow = 'autoplay';\r\n this.iframe.src = this.getEmbedUrl();\r\n this.iframe.style.width = '100%';\r\n this.iframe.style.display = 'block';\r\n \r\n // Use different aspect ratio for playlists vs single tracks\r\n // Playlists need more height to show the track list\r\n if (this.isPlaylist()) {\r\n this.iframe.classList.add('vidply-soundcloud-iframe', 'vidply-soundcloud-playlist');\r\n } else {\r\n this.iframe.classList.add('vidply-soundcloud-iframe');\r\n }\r\n this.iframe.style.maxHeight = '100%';\r\n \r\n this.player.element.parentNode.insertBefore(this.iframe, this.player.element);\r\n }\r\n\r\n async initializeWidget() {\r\n return new Promise((resolve, reject) => {\r\n // Wait for iframe to load\r\n this.iframe.addEventListener('load', () => {\r\n try {\r\n this.widget = window.SC.Widget(this.iframe);\r\n \r\n this.widget.bind(window.SC.Widget.Events.READY, () => {\r\n this.isReady = true;\r\n this.attachEvents();\r\n \r\n // Hide VidPly controls - SoundCloud has its own\r\n if (this.player.container) {\r\n this.player.container.classList.add('vidply-external-controls');\r\n }\r\n \r\n // Get initial sound info\r\n this.widget.getCurrentSound((sound) => {\r\n if (sound) {\r\n this.player.state.duration = sound.duration / 1000; // Convert ms to seconds\r\n this.player.emit('loadedmetadata');\r\n }\r\n });\r\n \r\n resolve();\r\n });\r\n \r\n this.widget.bind(window.SC.Widget.Events.ERROR, (error) => {\r\n this.player.handleError(new Error(`SoundCloud error: ${error.message || 'Unknown error'}`));\r\n });\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n \r\n // Timeout after 10 seconds\r\n setTimeout(() => {\r\n if (!this.isReady) {\r\n reject(new Error('SoundCloud widget initialization timeout'));\r\n }\r\n }, 10000);\r\n });\r\n }\r\n\r\n attachEvents() {\r\n if (!this.widget) return;\r\n \r\n const Events = window.SC.Widget.Events;\r\n\r\n this.widget.bind(Events.PLAY, () => {\r\n this.player.state.playing = true;\r\n this.player.state.paused = false;\r\n this.player.state.ended = false;\r\n this.player.emit('play');\r\n \r\n if (this.player.options.onPlay) {\r\n this.player.options.onPlay.call(this.player);\r\n }\r\n });\r\n\r\n this.widget.bind(Events.PAUSE, () => {\r\n this.player.state.playing = false;\r\n this.player.state.paused = true;\r\n this.player.emit('pause');\r\n \r\n if (this.player.options.onPause) {\r\n this.player.options.onPause.call(this.player);\r\n }\r\n });\r\n\r\n this.widget.bind(Events.FINISH, () => {\r\n this.player.state.playing = false;\r\n this.player.state.paused = true;\r\n this.player.state.ended = true;\r\n this.player.emit('ended');\r\n \r\n if (this.player.options.onEnded) {\r\n this.player.options.onEnded.call(this.player);\r\n }\r\n \r\n if (this.player.options.loop) {\r\n this.seek(0);\r\n this.play();\r\n }\r\n });\r\n\r\n this.widget.bind(Events.PLAY_PROGRESS, (data) => {\r\n // data.currentPosition is in milliseconds\r\n const currentTime = data.currentPosition / 1000;\r\n this.player.state.currentTime = currentTime;\r\n this.player.emit('timeupdate', currentTime);\r\n \r\n if (this.player.options.onTimeUpdate) {\r\n this.player.options.onTimeUpdate.call(this.player, currentTime);\r\n }\r\n });\r\n\r\n this.widget.bind(Events.SEEK, (data) => {\r\n this.player.state.currentTime = data.currentPosition / 1000;\r\n this.player.emit('seeked');\r\n });\r\n\r\n this.widget.bind(Events.LOAD_PROGRESS, (data) => {\r\n // data.loadedProgress is 0-1\r\n if (this.player.state.duration) {\r\n const buffered = data.loadedProgress * this.player.state.duration;\r\n this.player.emit('progress', buffered);\r\n }\r\n });\r\n }\r\n\r\n play() {\r\n if (this.isReady && this.widget) {\r\n // Save scroll position to prevent browser from scrolling\r\n const scrollX = window.scrollX;\r\n const scrollY = window.scrollY;\r\n \r\n this.widget.play();\r\n \r\n // Restore scroll position\r\n window.scrollTo(scrollX, scrollY);\r\n }\r\n }\r\n\r\n pause() {\r\n if (this.isReady && this.widget) {\r\n this.widget.pause();\r\n }\r\n }\r\n\r\n seek(time) {\r\n if (this.isReady && this.widget) {\r\n // SoundCloud seekTo uses milliseconds\r\n this.widget.seekTo(time * 1000);\r\n this.player.state.currentTime = time;\r\n }\r\n }\r\n\r\n setVolume(volume) {\r\n if (this.isReady && this.widget) {\r\n // SoundCloud setVolume expects 0-100\r\n this.widget.setVolume(volume * 100);\r\n this.player.state.volume = volume;\r\n }\r\n }\r\n\r\n setMuted(muted) {\r\n if (this.isReady && this.widget) {\r\n // SoundCloud doesn't have a native mute, use volume instead\r\n if (muted) {\r\n // Store current volume before muting\r\n this.widget.getVolume((vol) => {\r\n this._previousVolume = vol;\r\n this.widget.setVolume(0);\r\n });\r\n } else {\r\n this.widget.setVolume(this._previousVolume || 100);\r\n }\r\n this.player.state.muted = muted;\r\n }\r\n }\r\n\r\n setPlaybackSpeed(speed) {\r\n // SoundCloud Widget API doesn't support playback speed\r\n this.player.log('SoundCloud does not support playback speed control', 'warn');\r\n }\r\n\r\n /**\r\n * Get current track info\r\n * @returns {Promise<Object>}\r\n */\r\n getCurrentSound() {\r\n return new Promise((resolve) => {\r\n if (this.isReady && this.widget) {\r\n this.widget.getCurrentSound((sound) => {\r\n resolve(sound);\r\n });\r\n } else {\r\n resolve(null);\r\n }\r\n });\r\n }\r\n\r\n destroy() {\r\n // Unbind all events\r\n if (this.widget) {\r\n const Events = window.SC.Widget.Events;\r\n try {\r\n this.widget.unbind(Events.READY);\r\n this.widget.unbind(Events.PLAY);\r\n this.widget.unbind(Events.PAUSE);\r\n this.widget.unbind(Events.FINISH);\r\n this.widget.unbind(Events.PLAY_PROGRESS);\r\n this.widget.unbind(Events.SEEK);\r\n this.widget.unbind(Events.LOAD_PROGRESS);\r\n this.widget.unbind(Events.ERROR);\r\n } catch (e) {\r\n // Ignore unbind errors\r\n }\r\n }\r\n\r\n if (this.iframe && this.iframe.parentNode) {\r\n this.iframe.parentNode.removeChild(this.iframe);\r\n }\r\n\r\n // Show original element\r\n if (this.player.element) {\r\n this.player.element.style.display = '';\r\n }\r\n\r\n this.widget = null;\r\n this.isReady = false;\r\n }\r\n}\r\n\r\nexport default SoundCloudRenderer;\r\n\r\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Universal, Accessible Video Player
3
- * (c) 2025 Matthias Peltzer
3
+ * (c) 2026 Matthias Peltzer
4
4
  * Released under GPL-2.0-or-later License
5
5
  */
6
6
  import {
@@ -15,7 +15,7 @@ import {
15
15
  focusElement,
16
16
  i18n,
17
17
  preventDragOnElement
18
- } from "./vidply.chunk-PMRKJBGH.js";
18
+ } from "./vidply.chunk-AXXU22HR.js";
19
19
 
20
20
  // src/controls/TranscriptManager.js
21
21
  var TranscriptManager = class {
@@ -1740,4 +1740,4 @@ var TranscriptManager = class {
1740
1740
  export {
1741
1741
  TranscriptManager
1742
1742
  };
1743
- //# sourceMappingURL=vidply.TranscriptManager-R7NJRU7E.js.map
1743
+ //# sourceMappingURL=vidply.TranscriptManager-EIIN5YOF.js.map
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Universal, Accessible Video Player
3
- * (c) 2025 Matthias Peltzer
3
+ * (c) 2026 Matthias Peltzer
4
4
  * Released under GPL-2.0-or-later License
5
5
  */
6
6
 
@@ -54,7 +54,6 @@ var VimeoRenderer = class {
54
54
  this.iframe = document.createElement("div");
55
55
  this.iframe.id = `vimeo-player-${Math.random().toString(36).substr(2, 9)}`;
56
56
  this.iframe.style.width = "100%";
57
- this.iframe.style.aspectRatio = "16 / 9";
58
57
  this.iframe.style.maxHeight = "100%";
59
58
  this.player.element.parentNode.insertBefore(this.iframe, this.player.element);
60
59
  }
@@ -223,4 +222,4 @@ var VimeoRenderer = class {
223
222
  export {
224
223
  VimeoRenderer
225
224
  };
226
- //# sourceMappingURL=vidply.VimeoRenderer-VPH4RNES.js.map
225
+ //# sourceMappingURL=vidply.VimeoRenderer-SLEBCZTT.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/renderers/VimeoRenderer.js"],
4
+ "sourcesContent": ["/**\r\n * Vimeo Renderer\r\n */\r\n\r\nexport class VimeoRenderer {\r\n constructor(player) {\r\n this.player = player;\r\n this.vimeo = null;\r\n this.videoId = null;\r\n this.isReady = false;\r\n this.iframe = null;\r\n }\r\n\r\n async init() {\r\n // Extract video ID from URL - use currentSource which works for external renderers\r\n const src = this.player.currentSource || this.player.element.src;\r\n this.videoId = this.extractVideoId(src);\r\n \r\n if (!this.videoId) {\r\n throw new Error('Invalid Vimeo URL');\r\n }\r\n\r\n // Load Vimeo Player API\r\n await this.loadVimeoAPI();\r\n\r\n // Create iframe\r\n this.createIframe();\r\n\r\n // Initialize player\r\n await this.initializePlayer();\r\n }\r\n\r\n extractVideoId(url) {\r\n const patterns = [\r\n /vimeo\\.com\\/(\\d+)/,\r\n /vimeo\\.com\\/video\\/(\\d+)/,\r\n /player\\.vimeo\\.com\\/video\\/(\\d+)/\r\n ];\r\n\r\n for (const pattern of patterns) {\r\n const match = url.match(pattern);\r\n if (match && match[1]) {\r\n return match[1];\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n async loadVimeoAPI() {\r\n // Check if API is already loaded\r\n if (window.Vimeo && window.Vimeo.Player) {\r\n return Promise.resolve();\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n const script = document.createElement('script');\r\n script.src = 'https://player.vimeo.com/api/player.js';\r\n script.onload = () => resolve();\r\n script.onerror = () => reject(new Error('Failed to load Vimeo API'));\r\n document.head.appendChild(script);\r\n });\r\n }\r\n\r\n createIframe() {\r\n // Hide original element\r\n this.player.element.style.display = 'none';\r\n\r\n // Create container for iframe\r\n this.iframe = document.createElement('div');\r\n this.iframe.id = `vimeo-player-${Math.random().toString(36).substr(2, 9)}`;\r\n this.iframe.style.width = '100%';\r\n this.iframe.style.maxHeight = '100%';\r\n \r\n this.player.element.parentNode.insertBefore(this.iframe, this.player.element);\r\n }\r\n\r\n async initializePlayer() {\r\n const options = {\r\n id: this.videoId,\r\n width: '100%',\r\n height: '100%',\r\n controls: true, // Use Vimeo native controls\r\n autoplay: this.player.options.autoplay,\r\n muted: this.player.options.muted,\r\n loop: this.player.options.loop,\r\n keyboard: false\r\n };\r\n\r\n if (this.player.options.startTime > 0) {\r\n options.startTime = this.player.options.startTime;\r\n }\r\n\r\n this.vimeo = new window.Vimeo.Player(this.iframe.id, options);\r\n\r\n // Wait for player to be ready\r\n await this.vimeo.ready();\r\n this.isReady = true;\r\n \r\n // Ensure the iframe has 100% width and height\r\n const vimeoIframe = this.iframe.querySelector('iframe');\r\n if (vimeoIframe) {\r\n vimeoIframe.style.width = '100%';\r\n vimeoIframe.style.height = '100%';\r\n vimeoIframe.setAttribute('width', '100%');\r\n vimeoIframe.setAttribute('height', '100%');\r\n }\r\n \r\n // Hide VidPly controls - Vimeo has its own\r\n if (this.player.container) {\r\n this.player.container.classList.add('vidply-external-controls');\r\n }\r\n\r\n this.attachEvents();\r\n\r\n // Get initial duration\r\n try {\r\n const duration = await this.vimeo.getDuration();\r\n this.player.state.duration = duration;\r\n this.player.emit('loadedmetadata');\r\n } catch (error) {\r\n this.player.log('Error getting duration:', error, 'warn');\r\n }\r\n }\r\n\r\n attachEvents() {\r\n this.vimeo.on('play', () => {\r\n this.player.state.playing = true;\r\n this.player.state.paused = false;\r\n this.player.state.ended = false;\r\n this.player.emit('play');\r\n \r\n if (this.player.options.onPlay) {\r\n this.player.options.onPlay.call(this.player);\r\n }\r\n });\r\n\r\n this.vimeo.on('pause', () => {\r\n this.player.state.playing = false;\r\n this.player.state.paused = true;\r\n this.player.emit('pause');\r\n \r\n if (this.player.options.onPause) {\r\n this.player.options.onPause.call(this.player);\r\n }\r\n });\r\n\r\n this.vimeo.on('ended', () => {\r\n this.player.state.playing = false;\r\n this.player.state.paused = true;\r\n this.player.state.ended = true;\r\n this.player.emit('ended');\r\n \r\n if (this.player.options.onEnded) {\r\n this.player.options.onEnded.call(this.player);\r\n }\r\n });\r\n\r\n this.vimeo.on('timeupdate', (data) => {\r\n this.player.state.currentTime = data.seconds;\r\n this.player.state.duration = data.duration;\r\n this.player.emit('timeupdate', data.seconds);\r\n \r\n if (this.player.options.onTimeUpdate) {\r\n this.player.options.onTimeUpdate.call(this.player, data.seconds);\r\n }\r\n });\r\n\r\n this.vimeo.on('volumechange', (data) => {\r\n this.player.state.volume = data.volume;\r\n this.player.emit('volumechange', data.volume);\r\n });\r\n\r\n this.vimeo.on('bufferstart', () => {\r\n this.player.state.buffering = true;\r\n this.player.emit('waiting');\r\n });\r\n\r\n this.vimeo.on('bufferend', () => {\r\n this.player.state.buffering = false;\r\n this.player.emit('canplay');\r\n });\r\n\r\n this.vimeo.on('seeking', () => {\r\n this.player.state.seeking = true;\r\n this.player.emit('seeking');\r\n });\r\n\r\n this.vimeo.on('seeked', () => {\r\n this.player.state.seeking = false;\r\n this.player.emit('seeked');\r\n });\r\n\r\n this.vimeo.on('playbackratechange', (data) => {\r\n this.player.state.playbackSpeed = data.playbackRate;\r\n this.player.emit('ratechange', data.playbackRate);\r\n });\r\n\r\n this.vimeo.on('error', (error) => {\r\n this.player.handleError(new Error(`Vimeo error: ${error.message}`));\r\n });\r\n }\r\n\r\n play() {\r\n if (this.isReady && this.vimeo) {\r\n // Save scroll position to prevent browser from scrolling to video\r\n const scrollX = window.scrollX;\r\n const scrollY = window.scrollY;\r\n \r\n this.vimeo.play().catch(error => {\r\n this.player.log('Play error:', error, 'warn');\r\n });\r\n \r\n // Restore scroll position immediately to prevent auto-scroll\r\n window.scrollTo(scrollX, scrollY);\r\n }\r\n }\r\n\r\n pause() {\r\n if (this.isReady && this.vimeo) {\r\n this.vimeo.pause().catch(error => {\r\n this.player.log('Pause error:', error, 'warn');\r\n });\r\n }\r\n }\r\n\r\n seek(time) {\r\n if (this.isReady && this.vimeo) {\r\n this.vimeo.setCurrentTime(time).catch(error => {\r\n this.player.log('Seek error:', error, 'warn');\r\n });\r\n }\r\n }\r\n\r\n setVolume(volume) {\r\n if (this.isReady && this.vimeo) {\r\n this.vimeo.setVolume(volume).catch(error => {\r\n this.player.log('Volume error:', error, 'warn');\r\n });\r\n this.player.state.volume = volume;\r\n }\r\n }\r\n\r\n setMuted(muted) {\r\n if (this.isReady && this.vimeo) {\r\n if (muted) {\r\n this.vimeo.setVolume(0);\r\n } else {\r\n this.vimeo.setVolume(this.player.state.volume);\r\n }\r\n this.player.state.muted = muted;\r\n }\r\n }\r\n\r\n setPlaybackSpeed(speed) {\r\n if (this.isReady && this.vimeo) {\r\n this.vimeo.setPlaybackRate(speed).catch(error => {\r\n this.player.log('Playback rate error:', error, 'warn');\r\n });\r\n this.player.state.playbackSpeed = speed;\r\n }\r\n }\r\n\r\n destroy() {\r\n if (this.vimeo && this.vimeo.destroy) {\r\n this.vimeo.destroy();\r\n }\r\n\r\n if (this.iframe && this.iframe.parentNode) {\r\n this.iframe.parentNode.removeChild(this.iframe);\r\n }\r\n\r\n // Show original element\r\n if (this.player.element) {\r\n this.player.element.style.display = '';\r\n }\r\n }\r\n}\r\n\r\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Universal, Accessible Video Player
3
- * (c) 2025 Matthias Peltzer
3
+ * (c) 2026 Matthias Peltzer
4
4
  * Released under GPL-2.0-or-later License
5
5
  */
6
6
 
@@ -64,7 +64,6 @@ var YouTubeRenderer = class {
64
64
  this.iframe = document.createElement("div");
65
65
  this.iframe.id = `youtube-player-${Math.random().toString(36).substr(2, 9)}`;
66
66
  this.iframe.style.width = "100%";
67
- this.iframe.style.aspectRatio = "16 / 9";
68
67
  this.iframe.style.maxHeight = "100%";
69
68
  this.player.element.parentNode.insertBefore(this.iframe, this.player.element);
70
69
  }
@@ -232,4 +231,4 @@ var YouTubeRenderer = class {
232
231
  export {
233
232
  YouTubeRenderer
234
233
  };
235
- //# sourceMappingURL=vidply.YouTubeRenderer-6MGKEFTZ.js.map
234
+ //# sourceMappingURL=vidply.YouTubeRenderer-E6F4UGVF.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/renderers/YouTubeRenderer.js"],
4
+ "sourcesContent": ["/**\r\n * YouTube Renderer\r\n */\r\n\r\nexport class YouTubeRenderer {\r\n constructor(player) {\r\n this.player = player;\r\n this.youtube = null;\r\n this.videoId = null;\r\n this.isReady = false;\r\n this.iframe = null;\r\n }\r\n\r\n async init() {\r\n // Extract video ID from URL - use currentSource which works for external renderers\r\n const src = this.player.currentSource || this.player.element.src;\r\n this.videoId = this.extractVideoId(src);\r\n \r\n if (!this.videoId) {\r\n throw new Error('Invalid YouTube URL');\r\n }\r\n\r\n // Load YouTube IFrame API\r\n await this.loadYouTubeAPI();\r\n\r\n // Create iframe\r\n this.createIframe();\r\n\r\n // Initialize player\r\n await this.initializePlayer();\r\n }\r\n\r\n extractVideoId(url) {\r\n const patterns = [\r\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/)([^&\\s]+)/,\r\n /youtube\\.com\\/embed\\/([^&\\s]+)/\r\n ];\r\n\r\n for (const pattern of patterns) {\r\n const match = url.match(pattern);\r\n if (match && match[1]) {\r\n return match[1];\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n async loadYouTubeAPI() {\r\n // Check if API is already loaded\r\n if (window.YT && window.YT.Player) {\r\n return Promise.resolve();\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n // Check if script is already being loaded\r\n if (window.onYouTubeIframeAPIReady) {\r\n const originalCallback = window.onYouTubeIframeAPIReady;\r\n window.onYouTubeIframeAPIReady = () => {\r\n originalCallback();\r\n resolve();\r\n };\r\n return;\r\n }\r\n\r\n // Load the API script\r\n const tag = document.createElement('script');\r\n tag.src = 'https://www.youtube.com/iframe_api';\r\n \r\n window.onYouTubeIframeAPIReady = () => {\r\n resolve();\r\n };\r\n\r\n tag.onerror = () => reject(new Error('Failed to load YouTube API'));\r\n \r\n const firstScriptTag = document.getElementsByTagName('script')[0];\r\n firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\r\n });\r\n }\r\n\r\n createIframe() {\r\n // Hide original element\r\n this.player.element.style.display = 'none';\r\n\r\n // Create container for iframe\r\n this.iframe = document.createElement('div');\r\n this.iframe.id = `youtube-player-${Math.random().toString(36).substr(2, 9)}`;\r\n this.iframe.style.width = '100%';\r\n this.iframe.style.maxHeight = '100%';\r\n \r\n this.player.element.parentNode.insertBefore(this.iframe, this.player.element);\r\n }\r\n\r\n async initializePlayer() {\r\n return new Promise((resolve) => {\r\n this.youtube = new window.YT.Player(this.iframe.id, {\r\n videoId: this.videoId,\r\n width: '100%',\r\n height: '100%',\r\n playerVars: {\r\n controls: 1, // Use YouTube native controls\r\n disablekb: 0, // Allow keyboard controls\r\n fs: 1, // Allow fullscreen\r\n modestbranding: 1,\r\n rel: 0,\r\n showinfo: 0,\r\n iv_load_policy: 3,\r\n autoplay: this.player.options.autoplay ? 1 : 0,\r\n mute: this.player.options.muted ? 1 : 0,\r\n start: this.player.options.startTime || 0\r\n },\r\n events: {\r\n onReady: (event) => {\r\n this.isReady = true;\r\n this.attachEvents();\r\n // Hide VidPly controls - YouTube has its own\r\n if (this.player.container) {\r\n this.player.container.classList.add('vidply-external-controls');\r\n }\r\n resolve();\r\n },\r\n onStateChange: (event) => this.handleStateChange(event),\r\n onError: (event) => this.handleError(event)\r\n }\r\n });\r\n });\r\n }\r\n\r\n attachEvents() {\r\n // Set up polling for time updates (YouTube doesn't provide timeupdate events)\r\n this.timeUpdateInterval = setInterval(() => {\r\n if (this.isReady && this.youtube) {\r\n const currentTime = this.youtube.getCurrentTime();\r\n const duration = this.youtube.getDuration();\r\n \r\n this.player.state.currentTime = currentTime;\r\n this.player.state.duration = duration;\r\n \r\n this.player.emit('timeupdate', currentTime);\r\n }\r\n }, 250);\r\n\r\n // Initial metadata\r\n if (this.youtube.getDuration) {\r\n this.player.state.duration = this.youtube.getDuration();\r\n this.player.emit('loadedmetadata');\r\n }\r\n }\r\n\r\n handleStateChange(event) {\r\n const states = window.YT.PlayerState;\r\n\r\n switch (event.data) {\r\n case states.PLAYING:\r\n this.player.state.playing = true;\r\n this.player.state.paused = false;\r\n this.player.state.ended = false;\r\n this.player.state.buffering = false;\r\n this.player.emit('play');\r\n this.player.emit('playing');\r\n \r\n if (this.player.options.onPlay) {\r\n this.player.options.onPlay.call(this.player);\r\n }\r\n break;\r\n\r\n case states.PAUSED:\r\n this.player.state.playing = false;\r\n this.player.state.paused = true;\r\n this.player.emit('pause');\r\n \r\n if (this.player.options.onPause) {\r\n this.player.options.onPause.call(this.player);\r\n }\r\n break;\r\n\r\n case states.ENDED:\r\n this.player.state.playing = false;\r\n this.player.state.paused = true;\r\n this.player.state.ended = true;\r\n this.player.emit('ended');\r\n \r\n if (this.player.options.onEnded) {\r\n this.player.options.onEnded.call(this.player);\r\n }\r\n \r\n if (this.player.options.loop) {\r\n this.youtube.seekTo(0);\r\n this.youtube.playVideo();\r\n }\r\n break;\r\n\r\n case states.BUFFERING:\r\n this.player.state.buffering = true;\r\n this.player.emit('waiting');\r\n break;\r\n\r\n case states.CUED:\r\n this.player.emit('loadedmetadata');\r\n break;\r\n }\r\n }\r\n\r\n handleError(event) {\r\n const errors = {\r\n 2: 'Invalid video ID',\r\n 5: 'HTML5 player error',\r\n 100: 'Video not found',\r\n 101: 'Video not allowed to be played in embedded players',\r\n 150: 'Video not allowed to be played in embedded players'\r\n };\r\n\r\n const error = new Error(errors[event.data] || 'YouTube player error');\r\n this.player.handleError(error);\r\n }\r\n\r\n play() {\r\n if (this.isReady && this.youtube) {\r\n // Save scroll position to prevent browser from scrolling to video\r\n const scrollX = window.scrollX;\r\n const scrollY = window.scrollY;\r\n \r\n this.youtube.playVideo();\r\n \r\n // Restore scroll position immediately to prevent auto-scroll\r\n window.scrollTo(scrollX, scrollY);\r\n }\r\n }\r\n\r\n pause() {\r\n if (this.isReady && this.youtube) {\r\n this.youtube.pauseVideo();\r\n }\r\n }\r\n\r\n seek(time) {\r\n if (this.isReady && this.youtube) {\r\n this.youtube.seekTo(time, true);\r\n }\r\n }\r\n\r\n setVolume(volume) {\r\n if (this.isReady && this.youtube) {\r\n this.youtube.setVolume(volume * 100);\r\n this.player.state.volume = volume;\r\n }\r\n }\r\n\r\n setMuted(muted) {\r\n if (this.isReady && this.youtube) {\r\n if (muted) {\r\n this.youtube.mute();\r\n } else {\r\n this.youtube.unMute();\r\n }\r\n this.player.state.muted = muted;\r\n }\r\n }\r\n\r\n setPlaybackSpeed(speed) {\r\n if (this.isReady && this.youtube) {\r\n this.youtube.setPlaybackRate(speed);\r\n this.player.state.playbackSpeed = speed;\r\n }\r\n }\r\n\r\n destroy() {\r\n if (this.timeUpdateInterval) {\r\n clearInterval(this.timeUpdateInterval);\r\n }\r\n\r\n if (this.youtube && this.youtube.destroy) {\r\n this.youtube.destroy();\r\n }\r\n\r\n if (this.iframe && this.iframe.parentNode) {\r\n this.iframe.parentNode.removeChild(this.iframe);\r\n }\r\n\r\n // Show original element\r\n if (this.player.element) {\r\n this.player.element.style.display = '';\r\n }\r\n }\r\n}\r\n\r\n"],
5
+ "mappings": ";;;;;;;AAIO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAAY,QAAQ;AAClB,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,OAAO;AAEX,UAAM,MAAM,KAAK,OAAO,iBAAiB,KAAK,OAAO,QAAQ;AAC7D,SAAK,UAAU,KAAK,eAAe,GAAG;AAEtC,QAAI,CAAC,KAAK,SAAS;AACjB,YAAM,IAAI,MAAM,qBAAqB;AAAA,IACvC;AAGA,UAAM,KAAK,eAAe;AAG1B,SAAK,aAAa;AAGlB,UAAM,KAAK,iBAAiB;AAAA,EAC9B;AAAA,EAEA,eAAe,KAAK;AAClB,UAAM,WAAW;AAAA,MACf;AAAA,MACA;AAAA,IACF;AAEA,eAAW,WAAW,UAAU;AAC9B,YAAM,QAAQ,IAAI,MAAM,OAAO;AAC/B,UAAI,SAAS,MAAM,CAAC,GAAG;AACrB,eAAO,MAAM,CAAC;AAAA,MAChB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB;AAErB,QAAI,OAAO,MAAM,OAAO,GAAG,QAAQ;AACjC,aAAO,QAAQ,QAAQ;AAAA,IACzB;AAEA,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AAEtC,UAAI,OAAO,yBAAyB;AAClC,cAAM,mBAAmB,OAAO;AAChC,eAAO,0BAA0B,MAAM;AACrC,2BAAiB;AACjB,kBAAQ;AAAA,QACV;AACA;AAAA,MACF;AAGA,YAAM,MAAM,SAAS,cAAc,QAAQ;AAC3C,UAAI,MAAM;AAEV,aAAO,0BAA0B,MAAM;AACrC,gBAAQ;AAAA,MACV;AAEA,UAAI,UAAU,MAAM,OAAO,IAAI,MAAM,4BAA4B,CAAC;AAElE,YAAM,iBAAiB,SAAS,qBAAqB,QAAQ,EAAE,CAAC;AAChE,qBAAe,WAAW,aAAa,KAAK,cAAc;AAAA,IAC5D,CAAC;AAAA,EACH;AAAA,EAEA,eAAe;AAEb,SAAK,OAAO,QAAQ,MAAM,UAAU;AAGpC,SAAK,SAAS,SAAS,cAAc,KAAK;AAC1C,SAAK,OAAO,KAAK,kBAAkB,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC,CAAC;AAC1E,SAAK,OAAO,MAAM,QAAQ;AAC1B,SAAK,OAAO,MAAM,YAAY;AAE9B,SAAK,OAAO,QAAQ,WAAW,aAAa,KAAK,QAAQ,KAAK,OAAO,OAAO;AAAA,EAC9E;AAAA,EAEA,MAAM,mBAAmB;AACvB,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,WAAK,UAAU,IAAI,OAAO,GAAG,OAAO,KAAK,OAAO,IAAI;AAAA,QAClD,SAAS,KAAK;AAAA,QACd,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,YAAY;AAAA,UACV,UAAU;AAAA;AAAA,UACV,WAAW;AAAA;AAAA,UACX,IAAI;AAAA;AAAA,UACJ,gBAAgB;AAAA,UAChB,KAAK;AAAA,UACL,UAAU;AAAA,UACV,gBAAgB;AAAA,UAChB,UAAU,KAAK,OAAO,QAAQ,WAAW,IAAI;AAAA,UAC7C,MAAM,KAAK,OAAO,QAAQ,QAAQ,IAAI;AAAA,UACtC,OAAO,KAAK,OAAO,QAAQ,aAAa;AAAA,QAC1C;AAAA,QACA,QAAQ;AAAA,UACN,SAAS,CAAC,UAAU;AAClB,iBAAK,UAAU;AACf,iBAAK,aAAa;AAElB,gBAAI,KAAK,OAAO,WAAW;AACzB,mBAAK,OAAO,UAAU,UAAU,IAAI,0BAA0B;AAAA,YAChE;AACA,oBAAQ;AAAA,UACV;AAAA,UACA,eAAe,CAAC,UAAU,KAAK,kBAAkB,KAAK;AAAA,UACtD,SAAS,CAAC,UAAU,KAAK,YAAY,KAAK;AAAA,QAC5C;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,eAAe;AAEb,SAAK,qBAAqB,YAAY,MAAM;AAC1C,UAAI,KAAK,WAAW,KAAK,SAAS;AAChC,cAAM,cAAc,KAAK,QAAQ,eAAe;AAChD,cAAM,WAAW,KAAK,QAAQ,YAAY;AAE1C,aAAK,OAAO,MAAM,cAAc;AAChC,aAAK,OAAO,MAAM,WAAW;AAE7B,aAAK,OAAO,KAAK,cAAc,WAAW;AAAA,MAC5C;AAAA,IACF,GAAG,GAAG;AAGN,QAAI,KAAK,QAAQ,aAAa;AAC5B,WAAK,OAAO,MAAM,WAAW,KAAK,QAAQ,YAAY;AACtD,WAAK,OAAO,KAAK,gBAAgB;AAAA,IACnC;AAAA,EACF;AAAA,EAEA,kBAAkB,OAAO;AACvB,UAAM,SAAS,OAAO,GAAG;AAEzB,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK,OAAO;AACV,aAAK,OAAO,MAAM,UAAU;AAC5B,aAAK,OAAO,MAAM,SAAS;AAC3B,aAAK,OAAO,MAAM,QAAQ;AAC1B,aAAK,OAAO,MAAM,YAAY;AAC9B,aAAK,OAAO,KAAK,MAAM;AACvB,aAAK,OAAO,KAAK,SAAS;AAE1B,YAAI,KAAK,OAAO,QAAQ,QAAQ;AAC9B,eAAK,OAAO,QAAQ,OAAO,KAAK,KAAK,MAAM;AAAA,QAC7C;AACA;AAAA,MAEF,KAAK,OAAO;AACV,aAAK,OAAO,MAAM,UAAU;AAC5B,aAAK,OAAO,MAAM,SAAS;AAC3B,aAAK,OAAO,KAAK,OAAO;AAExB,YAAI,KAAK,OAAO,QAAQ,SAAS;AAC/B,eAAK,OAAO,QAAQ,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC9C;AACA;AAAA,MAEF,KAAK,OAAO;AACV,aAAK,OAAO,MAAM,UAAU;AAC5B,aAAK,OAAO,MAAM,SAAS;AAC3B,aAAK,OAAO,MAAM,QAAQ;AAC1B,aAAK,OAAO,KAAK,OAAO;AAExB,YAAI,KAAK,OAAO,QAAQ,SAAS;AAC/B,eAAK,OAAO,QAAQ,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC9C;AAEA,YAAI,KAAK,OAAO,QAAQ,MAAM;AAC5B,eAAK,QAAQ,OAAO,CAAC;AACrB,eAAK,QAAQ,UAAU;AAAA,QACzB;AACA;AAAA,MAEF,KAAK,OAAO;AACV,aAAK,OAAO,MAAM,YAAY;AAC9B,aAAK,OAAO,KAAK,SAAS;AAC1B;AAAA,MAEF,KAAK,OAAO;AACV,aAAK,OAAO,KAAK,gBAAgB;AACjC;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,YAAY,OAAO;AACjB,UAAM,SAAS;AAAA,MACb,GAAG;AAAA,MACH,GAAG;AAAA,MACH,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAEA,UAAM,QAAQ,IAAI,MAAM,OAAO,MAAM,IAAI,KAAK,sBAAsB;AACpE,SAAK,OAAO,YAAY,KAAK;AAAA,EAC/B;AAAA,EAEA,OAAO;AACL,QAAI,KAAK,WAAW,KAAK,SAAS;AAEhC,YAAM,UAAU,OAAO;AACvB,YAAM,UAAU,OAAO;AAEvB,WAAK,QAAQ,UAAU;AAGvB,aAAO,SAAS,SAAS,OAAO;AAAA,IAClC;AAAA,EACF;AAAA,EAEA,QAAQ;AACN,QAAI,KAAK,WAAW,KAAK,SAAS;AAChC,WAAK,QAAQ,WAAW;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,KAAK,MAAM;AACT,QAAI,KAAK,WAAW,KAAK,SAAS;AAChC,WAAK,QAAQ,OAAO,MAAM,IAAI;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,UAAU,QAAQ;AAChB,QAAI,KAAK,WAAW,KAAK,SAAS;AAChC,WAAK,QAAQ,UAAU,SAAS,GAAG;AACnC,WAAK,OAAO,MAAM,SAAS;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,SAAS,OAAO;AACd,QAAI,KAAK,WAAW,KAAK,SAAS;AAChC,UAAI,OAAO;AACT,aAAK,QAAQ,KAAK;AAAA,MACpB,OAAO;AACL,aAAK,QAAQ,OAAO;AAAA,MACtB;AACA,WAAK,OAAO,MAAM,QAAQ;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,iBAAiB,OAAO;AACtB,QAAI,KAAK,WAAW,KAAK,SAAS;AAChC,WAAK,QAAQ,gBAAgB,KAAK;AAClC,WAAK,OAAO,MAAM,gBAAgB;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,UAAU;AACR,QAAI,KAAK,oBAAoB;AAC3B,oBAAc,KAAK,kBAAkB;AAAA,IACvC;AAEA,QAAI,KAAK,WAAW,KAAK,QAAQ,SAAS;AACxC,WAAK,QAAQ,QAAQ;AAAA,IACvB;AAEA,QAAI,KAAK,UAAU,KAAK,OAAO,YAAY;AACzC,WAAK,OAAO,WAAW,YAAY,KAAK,MAAM;AAAA,IAChD;AAGA,QAAI,KAAK,OAAO,SAAS;AACvB,WAAK,OAAO,QAAQ,MAAM,UAAU;AAAA,IACtC;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Universal, Accessible Video Player
3
- * (c) 2025 Matthias Peltzer
3
+ * (c) 2026 Matthias Peltzer
4
4
  * Released under GPL-2.0-or-later License
5
5
  */
6
6
 
@@ -398,10 +398,10 @@ var en = {
398
398
 
399
399
  // src/i18n/translations.js
400
400
  var builtInLanguageLoaders = {
401
- de: () => import("./vidply.de-CEGBLV67.js"),
402
- es: () => import("./vidply.es-2QCQKZ4U.js"),
403
- fr: () => import("./vidply.fr-FJAZRL4L.js"),
404
- ja: () => import("./vidply.ja-2XQOW53T.js")
401
+ de: () => import("./vidply.de-YBEYEXBL.js"),
402
+ es: () => import("./vidply.es-QA4YSA5S.js"),
403
+ fr: () => import("./vidply.fr-LAM3XJZI.js"),
404
+ ja: () => import("./vidply.ja-FTBFZD66.js")
405
405
  };
406
406
  function getBaseTranslations() {
407
407
  return { en };
@@ -957,9 +957,16 @@ var DraggableResizable = class {
957
957
  touchstart: this.onTouchStart.bind(this),
958
958
  touchmove: this.onTouchMove.bind(this),
959
959
  touchend: this.onTouchEnd.bind(this),
960
+ pointerdown: this.onPointerDown.bind(this),
961
+ pointermove: this.onPointerMove.bind(this),
962
+ pointerup: this.onPointerUp.bind(this),
963
+ pointercancel: this.onPointerUp.bind(this),
960
964
  keydown: this.onKeyDown.bind(this),
961
- resizeHandleMousedown: this.onResizeHandleMouseDown.bind(this)
965
+ resizeHandleMousedown: this.onResizeHandleMouseDown.bind(this),
966
+ resizeHandlePointerDown: this.onResizeHandlePointerDown.bind(this)
962
967
  };
968
+ this.activePointerId = null;
969
+ this.activePointerType = null;
963
970
  this.init();
964
971
  }
965
972
  hasManagedResizeHandles() {
@@ -996,17 +1003,28 @@ var DraggableResizable = class {
996
1003
  }
997
1004
  init() {
998
1005
  const dragHandle = this.options.dragHandle || this.element;
999
- dragHandle.addEventListener("mousedown", this.handlers.mousedown);
1000
- dragHandle.addEventListener("touchstart", this.handlers.touchstart);
1001
- document.addEventListener("mousemove", this.handlers.mousemove);
1002
- document.addEventListener("mouseup", this.handlers.mouseup);
1003
- document.addEventListener("touchmove", this.handlers.touchmove, { passive: false });
1004
- document.addEventListener("touchend", this.handlers.touchend);
1006
+ if (typeof window !== "undefined" && "PointerEvent" in window) {
1007
+ dragHandle.addEventListener("pointerdown", this.handlers.pointerdown);
1008
+ document.addEventListener("pointermove", this.handlers.pointermove, { passive: false });
1009
+ document.addEventListener("pointerup", this.handlers.pointerup);
1010
+ document.addEventListener("pointercancel", this.handlers.pointercancel);
1011
+ } else {
1012
+ dragHandle.addEventListener("mousedown", this.handlers.mousedown);
1013
+ dragHandle.addEventListener("touchstart", this.handlers.touchstart, { passive: false });
1014
+ document.addEventListener("mousemove", this.handlers.mousemove);
1015
+ document.addEventListener("mouseup", this.handlers.mouseup);
1016
+ document.addEventListener("touchmove", this.handlers.touchmove, { passive: false });
1017
+ document.addEventListener("touchend", this.handlers.touchend);
1018
+ }
1005
1019
  this.element.addEventListener("keydown", this.handlers.keydown);
1006
1020
  if (this.options.resizeHandles && this.options.resizeHandles.length > 0) {
1007
1021
  this.options.resizeHandles.forEach((handle) => {
1008
- handle.addEventListener("mousedown", this.handlers.resizeHandleMousedown);
1009
- handle.addEventListener("touchstart", this.handlers.resizeHandleMousedown);
1022
+ if (typeof window !== "undefined" && "PointerEvent" in window) {
1023
+ handle.addEventListener("pointerdown", this.handlers.resizeHandlePointerDown);
1024
+ } else {
1025
+ handle.addEventListener("mousedown", this.handlers.resizeHandleMousedown);
1026
+ handle.addEventListener("touchstart", this.handlers.resizeHandleMousedown, { passive: false });
1027
+ }
1010
1028
  const managed = handle.dataset.vidplyManagedResize === "true";
1011
1029
  this.resizeHandlesManaged.set(handle, managed);
1012
1030
  if (managed) {
@@ -1016,6 +1034,44 @@ var DraggableResizable = class {
1016
1034
  });
1017
1035
  }
1018
1036
  }
1037
+ onPointerDown(e) {
1038
+ if (e.isPrimary === false) return;
1039
+ if (e.pointerType === "mouse" && e.button !== 0) return;
1040
+ if (e.target.classList.contains(`${this.options.classPrefix}-resize-handle`)) {
1041
+ return;
1042
+ }
1043
+ if (this.options.onDragStart && !this.options.onDragStart(e)) {
1044
+ return;
1045
+ }
1046
+ this.activePointerId = e.pointerId;
1047
+ this.activePointerType = e.pointerType;
1048
+ try {
1049
+ e.currentTarget?.setPointerCapture?.(e.pointerId);
1050
+ } catch {
1051
+ }
1052
+ this.startDragging(e.clientX, e.clientY);
1053
+ e.preventDefault();
1054
+ }
1055
+ onPointerMove(e) {
1056
+ if (this.activePointerId !== null && e.pointerId !== this.activePointerId) return;
1057
+ if (this.isDragging) {
1058
+ this.drag(e.clientX, e.clientY);
1059
+ e.preventDefault();
1060
+ } else if (this.isResizing) {
1061
+ this.resize(e.clientX, e.clientY);
1062
+ e.preventDefault();
1063
+ }
1064
+ }
1065
+ onPointerUp(e) {
1066
+ if (this.activePointerId !== null && e.pointerId !== this.activePointerId) return;
1067
+ if (this.isDragging) {
1068
+ this.stopDragging();
1069
+ } else if (this.isResizing) {
1070
+ this.stopResizing();
1071
+ }
1072
+ this.activePointerId = null;
1073
+ this.activePointerType = null;
1074
+ }
1019
1075
  onMouseDown(e) {
1020
1076
  if (e.target.classList.contains(`${this.options.classPrefix}-resize-handle`)) {
1021
1077
  return;
@@ -1035,6 +1091,22 @@ var DraggableResizable = class {
1035
1091
  }
1036
1092
  const touch = e.touches[0];
1037
1093
  this.startDragging(touch.clientX, touch.clientY);
1094
+ e.preventDefault();
1095
+ }
1096
+ onResizeHandlePointerDown(e) {
1097
+ if (e.isPrimary === false) return;
1098
+ if (e.pointerType === "mouse" && e.button !== 0) return;
1099
+ e.preventDefault();
1100
+ e.stopPropagation();
1101
+ const handle = e.target;
1102
+ this.resizeDirection = handle.getAttribute("data-direction");
1103
+ this.activePointerId = e.pointerId;
1104
+ this.activePointerType = e.pointerType;
1105
+ try {
1106
+ e.currentTarget?.setPointerCapture?.(e.pointerId);
1107
+ } catch {
1108
+ }
1109
+ this.startResizing(e.clientX, e.clientY);
1038
1110
  }
1039
1111
  onResizeHandleMouseDown(e) {
1040
1112
  e.preventDefault();
@@ -1474,15 +1546,20 @@ var DraggableResizable = class {
1474
1546
  this.disablePointerResizeMode();
1475
1547
  dragHandle.removeEventListener("mousedown", this.handlers.mousedown);
1476
1548
  dragHandle.removeEventListener("touchstart", this.handlers.touchstart);
1549
+ dragHandle.removeEventListener("pointerdown", this.handlers.pointerdown);
1477
1550
  document.removeEventListener("mousemove", this.handlers.mousemove);
1478
1551
  document.removeEventListener("mouseup", this.handlers.mouseup);
1479
1552
  document.removeEventListener("touchmove", this.handlers.touchmove);
1480
1553
  document.removeEventListener("touchend", this.handlers.touchend);
1554
+ document.removeEventListener("pointermove", this.handlers.pointermove);
1555
+ document.removeEventListener("pointerup", this.handlers.pointerup);
1556
+ document.removeEventListener("pointercancel", this.handlers.pointercancel);
1481
1557
  this.element.removeEventListener("keydown", this.handlers.keydown);
1482
1558
  if (this.options.resizeHandles && this.options.resizeHandles.length > 0) {
1483
1559
  this.options.resizeHandles.forEach((handle) => {
1484
1560
  handle.removeEventListener("mousedown", this.handlers.resizeHandleMousedown);
1485
1561
  handle.removeEventListener("touchstart", this.handlers.resizeHandleMousedown);
1562
+ handle.removeEventListener("pointerdown", this.handlers.resizeHandlePointerDown);
1486
1563
  });
1487
1564
  }
1488
1565
  this.element.classList.remove(
@@ -1679,4 +1756,4 @@ export {
1679
1756
  createLabeledSelect,
1680
1757
  preventDragOnElement
1681
1758
  };
1682
- //# sourceMappingURL=vidply.chunk-PMRKJBGH.js.map
1759
+ //# sourceMappingURL=vidply.chunk-AXXU22HR.js.map