vidply 1.0.34 → 1.0.36

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 (42) hide show
  1. package/dist/dev/{vidply.SoundCloudRenderer-RIA3QKP3.js → vidply.SoundCloudRenderer-HCMKXHSX.js} +1 -3
  2. package/dist/dev/vidply.SoundCloudRenderer-HCMKXHSX.js.map +7 -0
  3. package/dist/dev/{vidply.TranscriptManager-T3BVTZHZ.js → vidply.TranscriptManager-EIIN5YOF.js} +2 -2
  4. package/dist/dev/{vidply.VimeoRenderer-DY2FG7LZ.js → vidply.VimeoRenderer-SLEBCZTT.js} +1 -2
  5. package/dist/dev/vidply.VimeoRenderer-SLEBCZTT.js.map +7 -0
  6. package/dist/dev/{vidply.YouTubeRenderer-EVXXE34A.js → vidply.YouTubeRenderer-E6F4UGVF.js} +1 -2
  7. package/dist/dev/vidply.YouTubeRenderer-E6F4UGVF.js.map +7 -0
  8. package/dist/dev/{vidply.chunk-74NJTDQI.js → vidply.chunk-AXXU22HR.js} +87 -10
  9. package/dist/dev/{vidply.chunk-74NJTDQI.js.map → vidply.chunk-AXXU22HR.js.map} +2 -2
  10. package/dist/dev/vidply.esm.js +83 -50
  11. package/dist/dev/vidply.esm.js.map +2 -2
  12. package/dist/legacy/vidply.js +170 -58
  13. package/dist/legacy/vidply.js.map +3 -3
  14. package/dist/legacy/vidply.min.js +1 -1
  15. package/dist/legacy/vidply.min.meta.json +18 -18
  16. package/dist/prod/vidply.SoundCloudRenderer-D2FNOEG6.min.js +6 -0
  17. package/dist/prod/{vidply.TranscriptManager-GPAOXEK4.min.js → vidply.TranscriptManager-VXCTCJ7X.min.js} +1 -1
  18. package/dist/prod/vidply.VimeoRenderer-QELFZVDU.min.js +6 -0
  19. package/dist/prod/vidply.YouTubeRenderer-ZL6YUHTF.min.js +6 -0
  20. package/dist/prod/{vidply.chunk-OM7DNW5P.min.js → vidply.chunk-Z6BHMOGK.min.js} +1 -1
  21. package/dist/prod/vidply.esm.min.js +3 -3
  22. package/dist/vidply.css +293 -108
  23. package/dist/vidply.esm.min.meta.json +33 -33
  24. package/dist/vidply.min.css +1 -1
  25. package/package.json +3 -3
  26. package/src/controls/ControlBar.js +3 -0
  27. package/src/controls/KeyboardManager.js +19 -0
  28. package/src/core/Player.js +75 -64
  29. package/src/core/SignLanguageManager.js +18 -4
  30. package/src/index.js +3 -1
  31. package/src/renderers/SoundCloudRenderer.js +0 -2
  32. package/src/renderers/VimeoRenderer.js +0 -1
  33. package/src/renderers/YouTubeRenderer.js +0 -1
  34. package/src/styles/vidply.css +293 -108
  35. package/src/utils/DraggableResizable.js +123 -12
  36. package/dist/dev/vidply.SoundCloudRenderer-RIA3QKP3.js.map +0 -7
  37. package/dist/dev/vidply.VimeoRenderer-DY2FG7LZ.js.map +0 -7
  38. package/dist/dev/vidply.YouTubeRenderer-EVXXE34A.js.map +0 -7
  39. package/dist/prod/vidply.SoundCloudRenderer-BFV5SSIU.min.js +0 -6
  40. package/dist/prod/vidply.VimeoRenderer-UQWHQ4LC.min.js +0 -6
  41. package/dist/prod/vidply.YouTubeRenderer-K7A57ICA.min.js +0 -6
  42. /package/dist/dev/{vidply.TranscriptManager-T3BVTZHZ.js.map → vidply.TranscriptManager-EIIN5YOF.js.map} +0 -0
@@ -21,7 +21,7 @@ import {
21
21
  focusFirstMenuItem,
22
22
  i18n,
23
23
  preventDragOnElement
24
- } from "./vidply.chunk-74NJTDQI.js";
24
+ } from "./vidply.chunk-AXXU22HR.js";
25
25
 
26
26
  // src/utils/EventEmitter.js
27
27
  var EventEmitter = class {
@@ -271,6 +271,7 @@ var ControlBar = class {
271
271
  }
272
272
  if (menuRect.top < 10) {
273
273
  menu.style.top = "10px";
274
+ menu.style.bottom = "auto";
274
275
  }
275
276
  if (menuRect.bottom > viewportHeight - 10) {
276
277
  menu.style.bottom = "10px";
@@ -3235,6 +3236,20 @@ var KeyboardManager = class {
3235
3236
  if (playlistButton) {
3236
3237
  return;
3237
3238
  }
3239
+ const signWrapper = activeElement.closest(".vidply-sign-language-wrapper");
3240
+ if (signWrapper) {
3241
+ const draggable = this.player.signLanguageManager?.draggable;
3242
+ if (draggable?.keyboardDragMode || draggable?.keyboardResizeMode) {
3243
+ return;
3244
+ }
3245
+ }
3246
+ const transcriptWindow = activeElement.closest(".vidply-transcript-window");
3247
+ if (transcriptWindow) {
3248
+ const draggable = this.player.transcriptManager?.draggableResizable;
3249
+ if (draggable?.keyboardDragMode || draggable?.keyboardResizeMode) {
3250
+ return;
3251
+ }
3252
+ }
3238
3253
  }
3239
3254
  const key = e.key;
3240
3255
  let handled = false;
@@ -4298,7 +4313,7 @@ var SignLanguageManager = class {
4298
4313
  _setupInteraction() {
4299
4314
  const isMobile2 = window.innerWidth < 768;
4300
4315
  const isFullscreen = this.player.state.fullscreen;
4301
- if (isMobile2 && !isFullscreen) {
4316
+ if (isMobile2 && !isFullscreen && this.player?.options?.signLanguageDragOnMobile === false) {
4302
4317
  if (this.draggable) {
4303
4318
  this.draggable.destroy();
4304
4319
  this.draggable = null;
@@ -4308,7 +4323,9 @@ var SignLanguageManager = class {
4308
4323
  if (this.draggable) return;
4309
4324
  const classPrefix = this.player.options.classPrefix;
4310
4325
  this.draggable = new DraggableResizable(this.wrapper, {
4311
- dragHandle: this.header,
4326
+ // Allow dragging from anywhere on the sign-language window (better for touch).
4327
+ // We still block dragging when interacting with controls via `onDragStart` below.
4328
+ dragHandle: this.wrapper,
4312
4329
  resizeHandles: this.resizeHandles,
4313
4330
  constrainToViewport: true,
4314
4331
  maintainAspectRatio: true,
@@ -4557,9 +4574,15 @@ var SignLanguageManager = class {
4557
4574
  hasTextClass: true,
4558
4575
  onClick: () => {
4559
4576
  this.toggleKeyboardDragMode();
4560
- this.hideSettingsMenu();
4577
+ this.hideSettingsMenu({ focusButton: false });
4578
+ if (this.draggable?.keyboardDragMode) {
4579
+ setTimeout(() => {
4580
+ this.wrapper?.focus?.({ preventScroll: true });
4581
+ }, 20);
4582
+ }
4561
4583
  }
4562
4584
  });
4585
+ dragOption.setAttribute("data-setting", "keyboard-drag");
4563
4586
  dragOption.setAttribute("role", "switch");
4564
4587
  dragOption.setAttribute("aria-checked", "false");
4565
4588
  this._removeTooltipFromMenuItem(dragOption);
@@ -5251,7 +5274,7 @@ var Player = class _Player extends EventEmitter {
5251
5274
  if (!this.options.transcript && !this.options.transcriptButton) {
5252
5275
  return null;
5253
5276
  }
5254
- const module = await import("./vidply.TranscriptManager-T3BVTZHZ.js");
5277
+ const module = await import("./vidply.TranscriptManager-EIIN5YOF.js");
5255
5278
  const Manager = module.TranscriptManager || module.default;
5256
5279
  if (!Manager) {
5257
5280
  return null;
@@ -5335,23 +5358,9 @@ var Player = class _Player extends EventEmitter {
5335
5358
  if (this.options.height) {
5336
5359
  this.container.style.height = typeof this.options.height === "number" ? `${this.options.height}px` : this.options.height;
5337
5360
  }
5338
- if (this.element.tagName === "VIDEO" && !this.options.height) {
5339
- const wAttr = parseInt(this.element.getAttribute("width") || "", 10);
5340
- const hAttr = parseInt(this.element.getAttribute("height") || "", 10);
5341
- if (Number.isFinite(wAttr) && Number.isFinite(hAttr) && wAttr > 0 && hAttr > 0) {
5342
- if (!this.container.style.aspectRatio) {
5343
- this.container.style.aspectRatio = `${wAttr} / ${hAttr}`;
5344
- }
5345
- if (this.videoWrapper && !this.videoWrapper.style.aspectRatio) {
5346
- this.videoWrapper.style.aspectRatio = `${wAttr} / ${hAttr}`;
5347
- this.videoWrapper.style.height = "auto";
5348
- }
5349
- }
5350
- }
5351
5361
  if (this.options.poster && this.element.tagName === "VIDEO") {
5352
5362
  const resolvedPoster = this.resolvePosterPath(this.options.poster);
5353
5363
  this.element.poster = resolvedPoster;
5354
- this.applyPosterAspectRatio(resolvedPoster);
5355
5364
  }
5356
5365
  if (this.element.tagName === "VIDEO") {
5357
5366
  this.createPlayButtonOverlay();
@@ -5379,34 +5388,6 @@ var Player = class _Player extends EventEmitter {
5379
5388
  }
5380
5389
  }, { once: true });
5381
5390
  }
5382
- /**
5383
- * Apply aspect ratio to the video wrapper based on the poster's intrinsic size.
5384
- * This helps render correct poster sizing before media metadata is available.
5385
- */
5386
- applyPosterAspectRatio(posterUrl) {
5387
- try {
5388
- if (!posterUrl) return;
5389
- if (this.element.tagName !== "VIDEO") return;
5390
- if (!this.videoWrapper) return;
5391
- if (this.options.width || this.options.height) return;
5392
- if (this._posterAspectAppliedFor === posterUrl) return;
5393
- this._posterAspectAppliedFor = posterUrl;
5394
- const img = new Image();
5395
- img.decoding = "async";
5396
- img.onload = () => {
5397
- const w = img.naturalWidth;
5398
- const h = img.naturalHeight;
5399
- if (!w || !h) return;
5400
- this.videoWrapper.style.aspectRatio = `${w} / ${h}`;
5401
- this.videoWrapper.style.height = "auto";
5402
- if (this.container && !this.container.style.aspectRatio) {
5403
- this.container.style.aspectRatio = `${w} / ${h}`;
5404
- }
5405
- };
5406
- img.src = posterUrl;
5407
- } catch (e) {
5408
- }
5409
- }
5410
5391
  createPlayButtonOverlay() {
5411
5392
  this.playButtonOverlay = createPlayOverlay();
5412
5393
  this.playButtonOverlay.addEventListener("click", () => {
@@ -5468,16 +5449,16 @@ var Player = class _Player extends EventEmitter {
5468
5449
  }
5469
5450
  let rendererClass = HTML5Renderer;
5470
5451
  if (src.includes("youtube.com") || src.includes("youtu.be")) {
5471
- const module = await import("./vidply.YouTubeRenderer-EVXXE34A.js");
5452
+ const module = await import("./vidply.YouTubeRenderer-E6F4UGVF.js");
5472
5453
  rendererClass = module.YouTubeRenderer || module.default;
5473
5454
  } else if (src.includes("vimeo.com")) {
5474
- const module = await import("./vidply.VimeoRenderer-DY2FG7LZ.js");
5455
+ const module = await import("./vidply.VimeoRenderer-SLEBCZTT.js");
5475
5456
  rendererClass = module.VimeoRenderer || module.default;
5476
5457
  } else if (src.includes(".m3u8")) {
5477
5458
  const module = await import("./vidply.HLSRenderer-YGWCAICA.js");
5478
5459
  rendererClass = module.HLSRenderer || module.default;
5479
5460
  } else if (src.includes("soundcloud.com") || src.includes("api.soundcloud.com")) {
5480
- const module = await import("./vidply.SoundCloudRenderer-RIA3QKP3.js");
5461
+ const module = await import("./vidply.SoundCloudRenderer-HCMKXHSX.js");
5481
5462
  rendererClass = module.SoundCloudRenderer || module.default;
5482
5463
  }
5483
5464
  this.log(`Using ${rendererClass?.name || "HTML5Renderer"} renderer`);
@@ -6074,6 +6055,7 @@ var Player = class _Player extends EventEmitter {
6074
6055
  _enablePseudoFullscreen() {
6075
6056
  this.state.fullscreen = true;
6076
6057
  this.container.classList.add(`${this.options.classPrefix}-fullscreen`);
6058
+ document.body.classList.add("vidply-fullscreen-active");
6077
6059
  this._originalScrollX = window.scrollX || window.pageXOffset;
6078
6060
  this._originalScrollY = window.scrollY || window.pageYOffset;
6079
6061
  this._originalBodyOverflow = document.body.style.overflow;
@@ -6081,20 +6063,58 @@ var Player = class _Player extends EventEmitter {
6081
6063
  this._originalBodyWidth = document.body.style.width;
6082
6064
  this._originalBodyHeight = document.body.style.height;
6083
6065
  this._originalHtmlOverflow = document.documentElement.style.overflow;
6066
+ this._originalBodyBackground = document.body.style.background;
6067
+ this._originalHtmlBackground = document.documentElement.style.background;
6084
6068
  document.body.style.overflow = "hidden";
6085
6069
  document.body.style.width = "100%";
6086
6070
  document.body.style.height = "100%";
6071
+ document.body.style.background = "#000";
6087
6072
  document.documentElement.style.overflow = "hidden";
6073
+ document.documentElement.style.background = "#000";
6088
6074
  this._originalViewport = document.querySelector('meta[name="viewport"]')?.getAttribute("content");
6089
6075
  const viewport = document.querySelector('meta[name="viewport"]');
6090
6076
  if (viewport) {
6091
6077
  viewport.setAttribute("content", "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no");
6092
6078
  }
6093
6079
  window.scrollTo(0, 0);
6080
+ this._makeBackgroundInert();
6094
6081
  this.emit("fullscreenchange", true);
6095
6082
  this.emit("enterfullscreen");
6096
6083
  }
6084
+ /**
6085
+ * Makes all page content except the fullscreen player inert (non-focusable)
6086
+ * This prevents keyboard navigation from focusing on hidden background elements
6087
+ */
6088
+ _makeBackgroundInert() {
6089
+ this._inertElements = [];
6090
+ let current = this.container;
6091
+ while (current && current !== document.body && current !== document.documentElement) {
6092
+ const parent = current.parentElement;
6093
+ if (parent) {
6094
+ Array.from(parent.children).forEach((sibling) => {
6095
+ if (sibling !== current && sibling.nodeType === Node.ELEMENT_NODE && !sibling.hasAttribute("inert") && sibling.tagName !== "SCRIPT" && sibling.tagName !== "STYLE" && sibling.tagName !== "LINK" && sibling.tagName !== "META") {
6096
+ sibling.setAttribute("inert", "");
6097
+ this._inertElements.push(sibling);
6098
+ }
6099
+ });
6100
+ }
6101
+ current = parent;
6102
+ }
6103
+ }
6104
+ /**
6105
+ * Restores interactivity to elements that were made inert during fullscreen
6106
+ */
6107
+ _restoreBackgroundInteractivity() {
6108
+ if (this._inertElements) {
6109
+ this._inertElements.forEach((el) => {
6110
+ el.removeAttribute("inert");
6111
+ });
6112
+ this._inertElements = [];
6113
+ }
6114
+ }
6097
6115
  _disablePseudoFullscreen() {
6116
+ document.body.classList.remove("vidply-fullscreen-active");
6117
+ this._restoreBackgroundInteractivity();
6098
6118
  if (this._originalBodyOverflow !== void 0) {
6099
6119
  document.body.style.overflow = this._originalBodyOverflow;
6100
6120
  delete this._originalBodyOverflow;
@@ -6115,6 +6135,14 @@ var Player = class _Player extends EventEmitter {
6115
6135
  document.documentElement.style.overflow = this._originalHtmlOverflow;
6116
6136
  delete this._originalHtmlOverflow;
6117
6137
  }
6138
+ if (this._originalBodyBackground !== void 0) {
6139
+ document.body.style.background = this._originalBodyBackground;
6140
+ delete this._originalBodyBackground;
6141
+ }
6142
+ if (this._originalHtmlBackground !== void 0) {
6143
+ document.documentElement.style.background = this._originalHtmlBackground;
6144
+ delete this._originalHtmlBackground;
6145
+ }
6118
6146
  if (this._originalViewport !== void 0) {
6119
6147
  const viewport = document.querySelector('meta[name="viewport"]');
6120
6148
  if (viewport) {
@@ -8130,8 +8158,12 @@ var Player = class _Player extends EventEmitter {
8130
8158
  this.state.fullscreen = isFullscreen;
8131
8159
  if (isFullscreen) {
8132
8160
  this.container.classList.add(`${this.options.classPrefix}-fullscreen`);
8161
+ document.body.classList.add("vidply-fullscreen-active");
8162
+ this._makeBackgroundInert();
8133
8163
  } else {
8134
8164
  this.container.classList.remove(`${this.options.classPrefix}-fullscreen`);
8165
+ document.body.classList.remove("vidply-fullscreen-active");
8166
+ this._restoreBackgroundInteractivity();
8135
8167
  this._disablePseudoFullscreen();
8136
8168
  }
8137
8169
  this.emit("fullscreenchange", isFullscreen);
@@ -9809,6 +9841,7 @@ function parseDataAttributes(dataset) {
9809
9841
  "responsive": "responsive",
9810
9842
  "pipButton": "pipButton",
9811
9843
  "fullscreenButton": "fullscreenButton"
9844
+ // Layout
9812
9845
  };
9813
9846
  Object.keys(attributeMap).forEach((dataKey) => {
9814
9847
  const optionKey = attributeMap[dataKey];