vidply 1.0.21 → 1.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/vidply.css +720 -547
- package/dist/vidply.esm.js +411 -104
- package/dist/vidply.esm.js.map +2 -2
- package/dist/vidply.esm.min.js +11 -7
- package/dist/vidply.esm.min.meta.json +30 -25
- package/dist/vidply.js +411 -104
- package/dist/vidply.js.map +2 -2
- package/dist/vidply.min.css +1 -1
- package/dist/vidply.min.js +11 -7
- package/dist/vidply.min.meta.json +30 -25
- package/package.json +2 -2
- package/src/controls/ControlBar.js +3343 -3246
- package/src/controls/TranscriptManager.js +2296 -2271
- package/src/core/Player.js +4768 -4730
- package/src/features/PlaylistManager.js +1202 -1039
- package/src/i18n/languages/de.js +5 -1
- package/src/i18n/languages/en.js +5 -1
- package/src/i18n/languages/es.js +5 -1
- package/src/i18n/languages/fr.js +5 -1
- package/src/i18n/languages/ja.js +5 -1
- package/src/styles/vidply.css +720 -547
- package/src/utils/DOMUtils.js +67 -0
- package/src/utils/MenuUtils.js +10 -4
- package/src/utils/SettingsMenuFactory.js +8 -4
- package/src/utils/WindowComponents.js +6 -4
package/dist/vidply.js
CHANGED
|
@@ -426,6 +426,63 @@ var VidPly = (() => {
|
|
|
426
426
|
const safeHtml = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "").replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, "").replace(/on\w+\s*=/gi, "").replace(/javascript:/gi, "");
|
|
427
427
|
temp.innerHTML = safeHtml;
|
|
428
428
|
return temp.innerHTML;
|
|
429
|
+
},
|
|
430
|
+
/**
|
|
431
|
+
* Create a tooltip element that is aria-hidden (not read by screen readers)
|
|
432
|
+
* @param {string} text - Tooltip text
|
|
433
|
+
* @param {string} classPrefix - Class prefix for styling
|
|
434
|
+
* @returns {HTMLElement} Tooltip element
|
|
435
|
+
*/
|
|
436
|
+
createTooltip(text, classPrefix = "vidply") {
|
|
437
|
+
const tooltip = this.createElement("span", {
|
|
438
|
+
className: `${classPrefix}-tooltip`,
|
|
439
|
+
textContent: text,
|
|
440
|
+
attributes: {
|
|
441
|
+
"aria-hidden": "true"
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
return tooltip;
|
|
445
|
+
},
|
|
446
|
+
/**
|
|
447
|
+
* Attach a tooltip to an element
|
|
448
|
+
* @param {HTMLElement} element - Element to attach tooltip to
|
|
449
|
+
* @param {string} text - Tooltip text
|
|
450
|
+
* @param {string} classPrefix - Class prefix for styling
|
|
451
|
+
*/
|
|
452
|
+
attachTooltip(element, text, classPrefix = "vidply") {
|
|
453
|
+
if (!element || !text) return;
|
|
454
|
+
const existingTooltip = element.querySelector(`.${classPrefix}-tooltip`);
|
|
455
|
+
if (existingTooltip) {
|
|
456
|
+
existingTooltip.remove();
|
|
457
|
+
}
|
|
458
|
+
const tooltip = this.createTooltip(text, classPrefix);
|
|
459
|
+
element.appendChild(tooltip);
|
|
460
|
+
const showTooltip = () => {
|
|
461
|
+
tooltip.classList.add(`${classPrefix}-tooltip-visible`);
|
|
462
|
+
};
|
|
463
|
+
const hideTooltip = () => {
|
|
464
|
+
tooltip.classList.remove(`${classPrefix}-tooltip-visible`);
|
|
465
|
+
};
|
|
466
|
+
element.addEventListener("mouseenter", showTooltip);
|
|
467
|
+
element.addEventListener("mouseleave", hideTooltip);
|
|
468
|
+
element.addEventListener("focus", showTooltip);
|
|
469
|
+
element.addEventListener("blur", hideTooltip);
|
|
470
|
+
},
|
|
471
|
+
/**
|
|
472
|
+
* Create visible button text that is hidden by CSS but visible when CSS is disabled
|
|
473
|
+
* @param {string} text - Button text
|
|
474
|
+
* @param {string} classPrefix - Class prefix for styling
|
|
475
|
+
* @returns {HTMLElement} Button text element
|
|
476
|
+
*/
|
|
477
|
+
createButtonText(text, classPrefix = "vidply") {
|
|
478
|
+
const buttonText = this.createElement("span", {
|
|
479
|
+
className: `${classPrefix}-button-text`,
|
|
480
|
+
textContent: text,
|
|
481
|
+
attributes: {
|
|
482
|
+
"aria-hidden": "true"
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
return buttonText;
|
|
429
486
|
}
|
|
430
487
|
};
|
|
431
488
|
|
|
@@ -592,7 +649,11 @@ var VidPly = (() => {
|
|
|
592
649
|
nowPlaying: "Now playing: Track {current} of {total}. {title}{artist}",
|
|
593
650
|
by: " by ",
|
|
594
651
|
untitled: "Untitled",
|
|
595
|
-
trackUntitled: "Track {number}"
|
|
652
|
+
trackUntitled: "Track {number}",
|
|
653
|
+
currentlyPlaying: "Currently playing",
|
|
654
|
+
notPlaying: "Not playing",
|
|
655
|
+
pressEnterPlay: "Press Enter to play",
|
|
656
|
+
pressEnterRestart: "Press Enter to restart"
|
|
596
657
|
}
|
|
597
658
|
};
|
|
598
659
|
|
|
@@ -759,7 +820,11 @@ var VidPly = (() => {
|
|
|
759
820
|
nowPlaying: "L\xE4uft gerade: Titel {current} von {total}. {title}{artist}",
|
|
760
821
|
by: " von ",
|
|
761
822
|
untitled: "Ohne Titel",
|
|
762
|
-
trackUntitled: "Titel {number}"
|
|
823
|
+
trackUntitled: "Titel {number}",
|
|
824
|
+
currentlyPlaying: "Wird gerade abgespielt",
|
|
825
|
+
notPlaying: "Nicht aktiv",
|
|
826
|
+
pressEnterPlay: "Eingabetaste zum Abspielen",
|
|
827
|
+
pressEnterRestart: "Eingabetaste zum Neustart"
|
|
763
828
|
}
|
|
764
829
|
};
|
|
765
830
|
|
|
@@ -926,7 +991,11 @@ var VidPly = (() => {
|
|
|
926
991
|
nowPlaying: "Reproduciendo ahora: Pista {current} de {total}. {title}{artist}",
|
|
927
992
|
by: " por ",
|
|
928
993
|
untitled: "Sin t\xEDtulo",
|
|
929
|
-
trackUntitled: "Pista {number}"
|
|
994
|
+
trackUntitled: "Pista {number}",
|
|
995
|
+
currentlyPlaying: "Reproduciendo actualmente",
|
|
996
|
+
notPlaying: "Sin reproducir",
|
|
997
|
+
pressEnterPlay: "Pulsa Enter para reproducir",
|
|
998
|
+
pressEnterRestart: "Pulsa Enter para reiniciar"
|
|
930
999
|
}
|
|
931
1000
|
};
|
|
932
1001
|
|
|
@@ -1093,7 +1162,11 @@ var VidPly = (() => {
|
|
|
1093
1162
|
nowPlaying: "Lecture en cours : Piste {current} sur {total}. {title}{artist}",
|
|
1094
1163
|
by: " par ",
|
|
1095
1164
|
untitled: "Sans titre",
|
|
1096
|
-
trackUntitled: "Piste {number}"
|
|
1165
|
+
trackUntitled: "Piste {number}",
|
|
1166
|
+
currentlyPlaying: "En cours de lecture",
|
|
1167
|
+
notPlaying: "Non en lecture",
|
|
1168
|
+
pressEnterPlay: "Appuyez sur Entr\xE9e pour lire",
|
|
1169
|
+
pressEnterRestart: "Appuyez sur Entr\xE9e pour recommencer"
|
|
1097
1170
|
}
|
|
1098
1171
|
};
|
|
1099
1172
|
|
|
@@ -1260,7 +1333,11 @@ var VidPly = (() => {
|
|
|
1260
1333
|
nowPlaying: "\u518D\u751F\u4E2D: \u30C8\u30E9\u30C3\u30AF {current}/{total}. {title}{artist}",
|
|
1261
1334
|
by: " - ",
|
|
1262
1335
|
untitled: "\u30BF\u30A4\u30C8\u30EB\u306A\u3057",
|
|
1263
|
-
trackUntitled: "\u30C8\u30E9\u30C3\u30AF {number}"
|
|
1336
|
+
trackUntitled: "\u30C8\u30E9\u30C3\u30AF {number}",
|
|
1337
|
+
currentlyPlaying: "\u518D\u751F\u4E2D",
|
|
1338
|
+
notPlaying: "\u505C\u6B62\u4E2D",
|
|
1339
|
+
pressEnterPlay: "Enter\u30AD\u30FC\u3067\u518D\u751F",
|
|
1340
|
+
pressEnterRestart: "Enter\u30AD\u30FC\u3067\u6700\u521D\u304B\u3089\u518D\u751F"
|
|
1264
1341
|
}
|
|
1265
1342
|
};
|
|
1266
1343
|
|
|
@@ -1969,13 +2046,15 @@ var VidPly = (() => {
|
|
|
1969
2046
|
e.preventDefault();
|
|
1970
2047
|
e.stopPropagation();
|
|
1971
2048
|
const nextIndex = (currentIndex + 1) % menuItems.length;
|
|
1972
|
-
menuItems[nextIndex].focus();
|
|
2049
|
+
menuItems[nextIndex].focus({ preventScroll: false });
|
|
2050
|
+
menuItems[nextIndex].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
1973
2051
|
break;
|
|
1974
2052
|
case "ArrowUp":
|
|
1975
2053
|
e.preventDefault();
|
|
1976
2054
|
e.stopPropagation();
|
|
1977
2055
|
const prevIndex = (currentIndex - 1 + menuItems.length) % menuItems.length;
|
|
1978
|
-
menuItems[prevIndex].focus();
|
|
2056
|
+
menuItems[prevIndex].focus({ preventScroll: false });
|
|
2057
|
+
menuItems[prevIndex].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
1979
2058
|
break;
|
|
1980
2059
|
case "ArrowLeft":
|
|
1981
2060
|
case "ArrowRight":
|
|
@@ -1985,12 +2064,14 @@ var VidPly = (() => {
|
|
|
1985
2064
|
case "Home":
|
|
1986
2065
|
e.preventDefault();
|
|
1987
2066
|
e.stopPropagation();
|
|
1988
|
-
menuItems[0].focus();
|
|
2067
|
+
menuItems[0].focus({ preventScroll: false });
|
|
2068
|
+
menuItems[0].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
1989
2069
|
break;
|
|
1990
2070
|
case "End":
|
|
1991
2071
|
e.preventDefault();
|
|
1992
2072
|
e.stopPropagation();
|
|
1993
|
-
menuItems[menuItems.length - 1].focus();
|
|
2073
|
+
menuItems[menuItems.length - 1].focus({ preventScroll: false });
|
|
2074
|
+
menuItems[menuItems.length - 1].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
1994
2075
|
break;
|
|
1995
2076
|
case "Enter":
|
|
1996
2077
|
case " ":
|
|
@@ -2141,20 +2222,27 @@ var VidPly = (() => {
|
|
|
2141
2222
|
buttonContainer.appendChild(leftButtons);
|
|
2142
2223
|
buttonContainer.appendChild(this.rightButtons);
|
|
2143
2224
|
this.element.appendChild(buttonContainer);
|
|
2144
|
-
this.
|
|
2225
|
+
this.ensureButtonTooltips(buttonContainer);
|
|
2145
2226
|
}
|
|
2146
2227
|
/**
|
|
2147
2228
|
* Ensure all buttons in the controls have title attributes
|
|
2148
2229
|
* Uses aria-label as title if title is not present
|
|
2149
2230
|
*/
|
|
2150
|
-
|
|
2231
|
+
ensureButtonTooltips(container) {
|
|
2151
2232
|
const buttons = container.querySelectorAll("button");
|
|
2152
2233
|
buttons.forEach((button) => {
|
|
2153
|
-
if (
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2234
|
+
if (button.querySelector(`.${this.player.options.classPrefix}-tooltip`)) {
|
|
2235
|
+
return;
|
|
2236
|
+
}
|
|
2237
|
+
if (button.querySelector(`.${this.player.options.classPrefix}-button-text`)) {
|
|
2238
|
+
return;
|
|
2239
|
+
}
|
|
2240
|
+
if (button.getAttribute("role") === "menuitem" || button.classList.contains(`${this.player.options.classPrefix}-settings-item`) || button.classList.contains(`${this.player.options.classPrefix}-menu-item`) || button.classList.contains(`${this.player.options.classPrefix}-transcript-settings-item`) || button.classList.contains(`${this.player.options.classPrefix}-sign-language-settings-item`) || button.classList.contains(`${this.player.options.classPrefix}-popup-settings-item`)) {
|
|
2241
|
+
return;
|
|
2242
|
+
}
|
|
2243
|
+
const ariaLabel = button.getAttribute("aria-label");
|
|
2244
|
+
if (ariaLabel) {
|
|
2245
|
+
DOMUtils.attachTooltip(button, ariaLabel, this.player.options.classPrefix);
|
|
2158
2246
|
}
|
|
2159
2247
|
});
|
|
2160
2248
|
}
|
|
@@ -2254,7 +2342,6 @@ var VidPly = (() => {
|
|
|
2254
2342
|
if (!this.isDraggingProgress) {
|
|
2255
2343
|
const { time } = updateProgress(e.clientX);
|
|
2256
2344
|
this.controls.progressTooltip.textContent = TimeUtils.formatTime(time);
|
|
2257
|
-
this.controls.progressTooltip.setAttribute("aria-label", TimeUtils.formatDuration(time));
|
|
2258
2345
|
this.controls.progressTooltip.style.left = `${e.clientX - progress.getBoundingClientRect().left}px`;
|
|
2259
2346
|
this.controls.progressTooltip.style.display = "block";
|
|
2260
2347
|
}
|
|
@@ -2727,7 +2814,7 @@ var VidPly = (() => {
|
|
|
2727
2814
|
setTimeout(() => {
|
|
2728
2815
|
const firstItem = menu.querySelector(`.${this.player.options.classPrefix}-menu-item`);
|
|
2729
2816
|
if (firstItem) {
|
|
2730
|
-
firstItem.focus();
|
|
2817
|
+
firstItem.focus({ preventScroll: true });
|
|
2731
2818
|
}
|
|
2732
2819
|
}, 0);
|
|
2733
2820
|
}
|
|
@@ -2742,16 +2829,17 @@ var VidPly = (() => {
|
|
|
2742
2829
|
this.attachMenuCloseHandler(menu, button);
|
|
2743
2830
|
}
|
|
2744
2831
|
createQualityButton() {
|
|
2832
|
+
const ariaLabel = i18n.t("player.quality");
|
|
2745
2833
|
const button = DOMUtils.createElement("button", {
|
|
2746
2834
|
className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-quality`,
|
|
2747
2835
|
attributes: {
|
|
2748
2836
|
"type": "button",
|
|
2749
|
-
"aria-label":
|
|
2750
|
-
"aria-expanded": "false"
|
|
2751
|
-
"title": i18n.t("player.quality")
|
|
2837
|
+
"aria-label": ariaLabel,
|
|
2838
|
+
"aria-expanded": "false"
|
|
2752
2839
|
}
|
|
2753
2840
|
});
|
|
2754
2841
|
button.appendChild(createIconElement("hd"));
|
|
2842
|
+
DOMUtils.attachTooltip(button, ariaLabel, this.player.options.classPrefix);
|
|
2755
2843
|
const qualityText = DOMUtils.createElement("span", {
|
|
2756
2844
|
className: `${this.player.options.classPrefix}-quality-text`,
|
|
2757
2845
|
textContent: ""
|
|
@@ -2850,7 +2938,7 @@ var VidPly = (() => {
|
|
|
2850
2938
|
setTimeout(() => {
|
|
2851
2939
|
const focusTarget = activeItem || menu.querySelector(`.${this.player.options.classPrefix}-menu-item`);
|
|
2852
2940
|
if (focusTarget) {
|
|
2853
|
-
focusTarget.focus();
|
|
2941
|
+
focusTarget.focus({ preventScroll: true });
|
|
2854
2942
|
}
|
|
2855
2943
|
}, 0);
|
|
2856
2944
|
}
|
|
@@ -2872,13 +2960,13 @@ var VidPly = (() => {
|
|
|
2872
2960
|
this.attachMenuCloseHandler(menu, button);
|
|
2873
2961
|
}
|
|
2874
2962
|
createCaptionStyleButton() {
|
|
2963
|
+
const ariaLabel = i18n.t("player.captionStyling");
|
|
2875
2964
|
const button = DOMUtils.createElement("button", {
|
|
2876
2965
|
className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-caption-style`,
|
|
2877
2966
|
attributes: {
|
|
2878
2967
|
"type": "button",
|
|
2879
|
-
"aria-label":
|
|
2880
|
-
"aria-expanded": "false"
|
|
2881
|
-
"title": i18n.t("player.captionStyling")
|
|
2968
|
+
"aria-label": ariaLabel,
|
|
2969
|
+
"aria-expanded": "false"
|
|
2882
2970
|
}
|
|
2883
2971
|
});
|
|
2884
2972
|
const textIcon = DOMUtils.createElement("span", {
|
|
@@ -2889,6 +2977,7 @@ var VidPly = (() => {
|
|
|
2889
2977
|
}
|
|
2890
2978
|
});
|
|
2891
2979
|
button.appendChild(textIcon);
|
|
2980
|
+
DOMUtils.attachTooltip(button, ariaLabel, this.player.options.classPrefix);
|
|
2892
2981
|
button.addEventListener("click", () => {
|
|
2893
2982
|
this.showCaptionStyleMenu(button);
|
|
2894
2983
|
});
|
|
@@ -3241,7 +3330,7 @@ var VidPly = (() => {
|
|
|
3241
3330
|
setTimeout(() => {
|
|
3242
3331
|
const focusTarget = activeItem || menu.querySelector(`.${this.player.options.classPrefix}-menu-item`);
|
|
3243
3332
|
if (focusTarget) {
|
|
3244
|
-
focusTarget.focus();
|
|
3333
|
+
focusTarget.focus({ preventScroll: true });
|
|
3245
3334
|
}
|
|
3246
3335
|
}, 0);
|
|
3247
3336
|
}
|
|
@@ -3344,7 +3433,7 @@ var VidPly = (() => {
|
|
|
3344
3433
|
setTimeout(() => {
|
|
3345
3434
|
const focusTarget = activeItem || menu.querySelector(`.${this.player.options.classPrefix}-menu-item`);
|
|
3346
3435
|
if (focusTarget) {
|
|
3347
|
-
focusTarget.focus();
|
|
3436
|
+
focusTarget.focus({ preventScroll: true });
|
|
3348
3437
|
}
|
|
3349
3438
|
}, 0);
|
|
3350
3439
|
}
|
|
@@ -3379,17 +3468,18 @@ var VidPly = (() => {
|
|
|
3379
3468
|
this.controls.transcript.setAttribute("aria-expanded", isVisible ? "true" : "false");
|
|
3380
3469
|
}
|
|
3381
3470
|
createAudioDescriptionButton() {
|
|
3471
|
+
const ariaLabel = i18n.t("player.audioDescription");
|
|
3382
3472
|
const button = DOMUtils.createElement("button", {
|
|
3383
3473
|
className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-audio-description`,
|
|
3384
3474
|
attributes: {
|
|
3385
3475
|
"type": "button",
|
|
3386
|
-
"aria-label":
|
|
3476
|
+
"aria-label": ariaLabel,
|
|
3387
3477
|
"role": "switch",
|
|
3388
|
-
"aria-checked": "false"
|
|
3389
|
-
"title": i18n.t("player.audioDescription")
|
|
3478
|
+
"aria-checked": "false"
|
|
3390
3479
|
}
|
|
3391
3480
|
});
|
|
3392
3481
|
button.appendChild(createIconElement("audioDescription"));
|
|
3482
|
+
DOMUtils.attachTooltip(button, ariaLabel, this.player.options.classPrefix);
|
|
3393
3483
|
button.addEventListener("click", async () => {
|
|
3394
3484
|
await this.player.toggleAudioDescription();
|
|
3395
3485
|
this.updateAudioDescriptionButton();
|
|
@@ -3405,16 +3495,17 @@ var VidPly = (() => {
|
|
|
3405
3495
|
this.controls.audioDescription.setAttribute("aria-checked", isEnabled ? "true" : "false");
|
|
3406
3496
|
}
|
|
3407
3497
|
createSignLanguageButton() {
|
|
3498
|
+
const ariaLabel = i18n.t("player.signLanguage");
|
|
3408
3499
|
const button = DOMUtils.createElement("button", {
|
|
3409
3500
|
className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-sign-language`,
|
|
3410
3501
|
attributes: {
|
|
3411
3502
|
"type": "button",
|
|
3412
|
-
"aria-label":
|
|
3413
|
-
"aria-expanded": "false"
|
|
3414
|
-
"title": i18n.t("player.signLanguage")
|
|
3503
|
+
"aria-label": ariaLabel,
|
|
3504
|
+
"aria-expanded": "false"
|
|
3415
3505
|
}
|
|
3416
3506
|
});
|
|
3417
3507
|
button.appendChild(createIconElement("signLanguage"));
|
|
3508
|
+
DOMUtils.attachTooltip(button, ariaLabel, this.player.options.classPrefix);
|
|
3418
3509
|
button.addEventListener("click", () => {
|
|
3419
3510
|
this.player.toggleSignLanguage();
|
|
3420
3511
|
this.updateSignLanguageButton();
|
|
@@ -3433,6 +3524,60 @@ var VidPly = (() => {
|
|
|
3433
3524
|
isEnabled ? i18n.t("signLanguage.hide") : i18n.t("signLanguage.show")
|
|
3434
3525
|
);
|
|
3435
3526
|
}
|
|
3527
|
+
/**
|
|
3528
|
+
* Update accessibility buttons visibility based on current track data.
|
|
3529
|
+
* Called when loading a new playlist track to show/hide buttons accordingly.
|
|
3530
|
+
*/
|
|
3531
|
+
updateAccessibilityButtons() {
|
|
3532
|
+
const hasAudioDescription = this.hasAudioDescription();
|
|
3533
|
+
const hasSignLanguage = this.hasSignLanguage();
|
|
3534
|
+
if (hasAudioDescription) {
|
|
3535
|
+
if (!this.controls.audioDescription && this.player.options.audioDescriptionButton !== false) {
|
|
3536
|
+
const btn = this.createAudioDescriptionButton();
|
|
3537
|
+
btn.dataset.overflowPriority = "2";
|
|
3538
|
+
btn.dataset.overflowPriorityMobile = "3";
|
|
3539
|
+
const transcriptBtn = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-transcript`);
|
|
3540
|
+
const playlistBtn = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-playlist-toggle`);
|
|
3541
|
+
const insertBefore = transcriptBtn || playlistBtn || null;
|
|
3542
|
+
if (insertBefore) {
|
|
3543
|
+
this.rightButtons.insertBefore(btn, insertBefore);
|
|
3544
|
+
} else {
|
|
3545
|
+
this.rightButtons.appendChild(btn);
|
|
3546
|
+
}
|
|
3547
|
+
this.setupOverflowMenu();
|
|
3548
|
+
}
|
|
3549
|
+
if (this.controls.audioDescription) {
|
|
3550
|
+
this.controls.audioDescription.style.display = "";
|
|
3551
|
+
}
|
|
3552
|
+
} else {
|
|
3553
|
+
if (this.controls.audioDescription) {
|
|
3554
|
+
this.controls.audioDescription.style.display = "none";
|
|
3555
|
+
}
|
|
3556
|
+
}
|
|
3557
|
+
if (hasSignLanguage) {
|
|
3558
|
+
if (!this.controls.signLanguage && this.player.options.signLanguageButton !== false) {
|
|
3559
|
+
const btn = this.createSignLanguageButton();
|
|
3560
|
+
btn.dataset.overflowPriority = "3";
|
|
3561
|
+
btn.dataset.overflowPriorityMobile = "3";
|
|
3562
|
+
const qualityBtn = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-quality`);
|
|
3563
|
+
const fullscreenBtn = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-fullscreen`);
|
|
3564
|
+
const insertBefore = qualityBtn || fullscreenBtn || null;
|
|
3565
|
+
if (insertBefore) {
|
|
3566
|
+
this.rightButtons.insertBefore(btn, insertBefore);
|
|
3567
|
+
} else {
|
|
3568
|
+
this.rightButtons.appendChild(btn);
|
|
3569
|
+
}
|
|
3570
|
+
this.setupOverflowMenu();
|
|
3571
|
+
}
|
|
3572
|
+
if (this.controls.signLanguage) {
|
|
3573
|
+
this.controls.signLanguage.style.display = "";
|
|
3574
|
+
}
|
|
3575
|
+
} else {
|
|
3576
|
+
if (this.controls.signLanguage) {
|
|
3577
|
+
this.controls.signLanguage.style.display = "none";
|
|
3578
|
+
}
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3436
3581
|
createSettingsButton() {
|
|
3437
3582
|
const button = DOMUtils.createElement("button", {
|
|
3438
3583
|
className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-settings`,
|
|
@@ -3509,7 +3654,7 @@ var VidPly = (() => {
|
|
|
3509
3654
|
icon.innerHTML = isPlaying ? createIconElement("pause").innerHTML : createIconElement("play").innerHTML;
|
|
3510
3655
|
const newAriaLabel = isPlaying ? i18n.t("player.pause") : i18n.t("player.play");
|
|
3511
3656
|
this.controls.playPause.setAttribute("aria-label", newAriaLabel);
|
|
3512
|
-
this.controls.playPause
|
|
3657
|
+
DOMUtils.attachTooltip(this.controls.playPause, newAriaLabel, this.player.options.classPrefix);
|
|
3513
3658
|
}
|
|
3514
3659
|
updateProgress() {
|
|
3515
3660
|
if (!this.controls.played) return;
|
|
@@ -3565,7 +3710,7 @@ var VidPly = (() => {
|
|
|
3565
3710
|
icon.innerHTML = createIconElement(iconName).innerHTML;
|
|
3566
3711
|
const newMuteAriaLabel = this.player.state.muted ? i18n.t("player.unmute") : i18n.t("player.mute");
|
|
3567
3712
|
this.controls.mute.setAttribute("aria-label", newMuteAriaLabel);
|
|
3568
|
-
this.controls.mute
|
|
3713
|
+
DOMUtils.attachTooltip(this.controls.mute, newMuteAriaLabel, this.player.options.classPrefix);
|
|
3569
3714
|
}
|
|
3570
3715
|
}
|
|
3571
3716
|
if (this.controls.volumeSlider) {
|
|
@@ -3677,16 +3822,17 @@ var VidPly = (() => {
|
|
|
3677
3822
|
showControls();
|
|
3678
3823
|
}
|
|
3679
3824
|
createOverflowMenuButton() {
|
|
3825
|
+
const ariaLabel = i18n.t("player.moreOptions");
|
|
3680
3826
|
const button = DOMUtils.createElement("button", {
|
|
3681
3827
|
className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-overflow-menu`,
|
|
3682
3828
|
attributes: {
|
|
3683
3829
|
"type": "button",
|
|
3684
|
-
"aria-label":
|
|
3685
|
-
"aria-expanded": "false"
|
|
3686
|
-
"title": i18n.t("player.moreOptions")
|
|
3830
|
+
"aria-label": ariaLabel,
|
|
3831
|
+
"aria-expanded": "false"
|
|
3687
3832
|
}
|
|
3688
3833
|
});
|
|
3689
3834
|
button.appendChild(createIconElement("moreVertical"));
|
|
3835
|
+
DOMUtils.attachTooltip(button, ariaLabel, this.player.options.classPrefix);
|
|
3690
3836
|
button.addEventListener("click", () => {
|
|
3691
3837
|
this.showOverflowMenu(button);
|
|
3692
3838
|
});
|
|
@@ -3768,7 +3914,7 @@ var VidPly = (() => {
|
|
|
3768
3914
|
setTimeout(() => {
|
|
3769
3915
|
const firstItem = menu.querySelector(`.${this.player.options.classPrefix}-menu-item`);
|
|
3770
3916
|
if (firstItem && firstItem.tagName === "BUTTON") {
|
|
3771
|
-
firstItem.focus();
|
|
3917
|
+
firstItem.focus({ preventScroll: true });
|
|
3772
3918
|
}
|
|
3773
3919
|
}, 0);
|
|
3774
3920
|
}
|
|
@@ -4699,7 +4845,8 @@ var VidPly = (() => {
|
|
|
4699
4845
|
menuItems.forEach((item, idx) => {
|
|
4700
4846
|
item.setAttribute("tabindex", idx === nextIndex ? "0" : "-1");
|
|
4701
4847
|
});
|
|
4702
|
-
menuItems[nextIndex].focus();
|
|
4848
|
+
menuItems[nextIndex].focus({ preventScroll: false });
|
|
4849
|
+
menuItems[nextIndex].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
4703
4850
|
break;
|
|
4704
4851
|
case "ArrowUp":
|
|
4705
4852
|
e.preventDefault();
|
|
@@ -4708,7 +4855,8 @@ var VidPly = (() => {
|
|
|
4708
4855
|
menuItems.forEach((item, idx) => {
|
|
4709
4856
|
item.setAttribute("tabindex", idx === prevIndex ? "0" : "-1");
|
|
4710
4857
|
});
|
|
4711
|
-
menuItems[prevIndex].focus();
|
|
4858
|
+
menuItems[prevIndex].focus({ preventScroll: false });
|
|
4859
|
+
menuItems[prevIndex].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
4712
4860
|
break;
|
|
4713
4861
|
case "Home":
|
|
4714
4862
|
e.preventDefault();
|
|
@@ -4716,7 +4864,8 @@ var VidPly = (() => {
|
|
|
4716
4864
|
menuItems.forEach((item, idx) => {
|
|
4717
4865
|
item.setAttribute("tabindex", idx === 0 ? "0" : "-1");
|
|
4718
4866
|
});
|
|
4719
|
-
menuItems[0].focus();
|
|
4867
|
+
menuItems[0].focus({ preventScroll: false });
|
|
4868
|
+
menuItems[0].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
4720
4869
|
break;
|
|
4721
4870
|
case "End":
|
|
4722
4871
|
e.preventDefault();
|
|
@@ -4725,7 +4874,8 @@ var VidPly = (() => {
|
|
|
4725
4874
|
menuItems.forEach((item, idx) => {
|
|
4726
4875
|
item.setAttribute("tabindex", idx === lastIndex ? "0" : "-1");
|
|
4727
4876
|
});
|
|
4728
|
-
menuItems[lastIndex].focus();
|
|
4877
|
+
menuItems[lastIndex].focus({ preventScroll: false });
|
|
4878
|
+
menuItems[lastIndex].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
4729
4879
|
break;
|
|
4730
4880
|
case "Enter":
|
|
4731
4881
|
case " ":
|
|
@@ -4763,6 +4913,7 @@ var VidPly = (() => {
|
|
|
4763
4913
|
item.setAttribute("tabindex", index === 0 ? "0" : "-1");
|
|
4764
4914
|
});
|
|
4765
4915
|
focusElement(menuItems[0], { delay: 0 });
|
|
4916
|
+
menuItems[0].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
4766
4917
|
}
|
|
4767
4918
|
}, delay);
|
|
4768
4919
|
}
|
|
@@ -5555,7 +5706,7 @@ var VidPly = (() => {
|
|
|
5555
5706
|
if (focusButton) {
|
|
5556
5707
|
const transcriptButton = (_b = (_a = this.player.controlBar) == null ? void 0 : _a.controls) == null ? void 0 : _b.transcript;
|
|
5557
5708
|
if (transcriptButton && typeof transcriptButton.focus === "function") {
|
|
5558
|
-
transcriptButton.focus();
|
|
5709
|
+
transcriptButton.focus({ preventScroll: true });
|
|
5559
5710
|
}
|
|
5560
5711
|
}
|
|
5561
5712
|
}
|
|
@@ -5580,15 +5731,17 @@ var VidPly = (() => {
|
|
|
5580
5731
|
this.headerLeft = DOMUtils.createElement("div", {
|
|
5581
5732
|
className: `${this.player.options.classPrefix}-transcript-header-left`
|
|
5582
5733
|
});
|
|
5734
|
+
const settingsAriaLabel = i18n.t("transcript.settingsMenu");
|
|
5583
5735
|
this.settingsButton = DOMUtils.createElement("button", {
|
|
5584
5736
|
className: `${this.player.options.classPrefix}-transcript-settings`,
|
|
5585
5737
|
attributes: {
|
|
5586
5738
|
"type": "button",
|
|
5587
|
-
"aria-label":
|
|
5739
|
+
"aria-label": settingsAriaLabel,
|
|
5588
5740
|
"aria-expanded": "false"
|
|
5589
5741
|
}
|
|
5590
5742
|
});
|
|
5591
5743
|
this.settingsButton.appendChild(createIconElement("settings"));
|
|
5744
|
+
DOMUtils.attachTooltip(this.settingsButton, settingsAriaLabel, this.player.options.classPrefix);
|
|
5592
5745
|
this.handlers.settingsClick = (e) => {
|
|
5593
5746
|
e.preventDefault();
|
|
5594
5747
|
e.stopPropagation();
|
|
@@ -5622,8 +5775,7 @@ var VidPly = (() => {
|
|
|
5622
5775
|
const autoscrollLabel = DOMUtils.createElement("label", {
|
|
5623
5776
|
className: `${this.player.options.classPrefix}-transcript-autoscroll-label`,
|
|
5624
5777
|
attributes: {
|
|
5625
|
-
"for": autoscrollId
|
|
5626
|
-
"title": i18n.t("transcript.autoscroll")
|
|
5778
|
+
"for": autoscrollId
|
|
5627
5779
|
}
|
|
5628
5780
|
});
|
|
5629
5781
|
this.autoscrollCheckbox = DOMUtils.createElement("input", {
|
|
@@ -5672,14 +5824,16 @@ var VidPly = (() => {
|
|
|
5672
5824
|
this.languageSelectorWrapper = languageSelectorWrapper;
|
|
5673
5825
|
preventDragOnElement(languageSelectorWrapper);
|
|
5674
5826
|
this.headerLeft.appendChild(languageSelectorWrapper);
|
|
5827
|
+
const closeAriaLabel = i18n.t("transcript.close");
|
|
5675
5828
|
const closeButton = DOMUtils.createElement("button", {
|
|
5676
5829
|
className: `${this.player.options.classPrefix}-transcript-close`,
|
|
5677
5830
|
attributes: {
|
|
5678
5831
|
"type": "button",
|
|
5679
|
-
"aria-label":
|
|
5832
|
+
"aria-label": closeAriaLabel
|
|
5680
5833
|
}
|
|
5681
5834
|
});
|
|
5682
5835
|
closeButton.appendChild(createIconElement("close"));
|
|
5836
|
+
DOMUtils.attachTooltip(closeButton, closeAriaLabel, this.player.options.classPrefix);
|
|
5683
5837
|
closeButton.addEventListener("click", () => this.hideTranscript({ focusButton: true }));
|
|
5684
5838
|
this.transcriptHeader.appendChild(this.headerLeft);
|
|
5685
5839
|
this.transcriptHeader.appendChild(closeButton);
|
|
@@ -6126,7 +6280,7 @@ var VidPly = (() => {
|
|
|
6126
6280
|
console.log("[VidPly Metadata] Focusing element:", targetSelector);
|
|
6127
6281
|
}
|
|
6128
6282
|
this.setManagedTimeout(() => {
|
|
6129
|
-
targetElement.focus();
|
|
6283
|
+
targetElement.focus({ preventScroll: true });
|
|
6130
6284
|
}, 10);
|
|
6131
6285
|
} else if (this.player.options.debug) {
|
|
6132
6286
|
console.warn("[VidPly Metadata] Element not found:", targetSelector);
|
|
@@ -6341,7 +6495,7 @@ var VidPly = (() => {
|
|
|
6341
6495
|
e.stopPropagation();
|
|
6342
6496
|
const enabled = this.toggleResizeMode();
|
|
6343
6497
|
if (enabled) {
|
|
6344
|
-
this.transcriptWindow.focus();
|
|
6498
|
+
this.transcriptWindow.focus({ preventScroll: true });
|
|
6345
6499
|
}
|
|
6346
6500
|
return;
|
|
6347
6501
|
}
|
|
@@ -6382,7 +6536,7 @@ var VidPly = (() => {
|
|
|
6382
6536
|
if (this.settingsMenuVisible) {
|
|
6383
6537
|
this.hideSettingsMenu();
|
|
6384
6538
|
}
|
|
6385
|
-
this.transcriptWindow.focus();
|
|
6539
|
+
this.transcriptWindow.focus({ preventScroll: true });
|
|
6386
6540
|
}
|
|
6387
6541
|
}
|
|
6388
6542
|
/**
|
|
@@ -6425,7 +6579,7 @@ var VidPly = (() => {
|
|
|
6425
6579
|
for (let i = 1; i < menuItems.length; i++) {
|
|
6426
6580
|
menuItems[i].setAttribute("tabindex", "-1");
|
|
6427
6581
|
}
|
|
6428
|
-
menuItems[0].focus();
|
|
6582
|
+
menuItems[0].focus({ preventScroll: true });
|
|
6429
6583
|
}
|
|
6430
6584
|
}, 50);
|
|
6431
6585
|
return;
|
|
@@ -6449,6 +6603,10 @@ var VidPly = (() => {
|
|
|
6449
6603
|
});
|
|
6450
6604
|
keyboardDragOption.setAttribute("role", "switch");
|
|
6451
6605
|
keyboardDragOption.setAttribute("aria-checked", "false");
|
|
6606
|
+
const dragTooltip = keyboardDragOption.querySelector(`.${this.player.options.classPrefix}-tooltip`);
|
|
6607
|
+
if (dragTooltip) dragTooltip.remove();
|
|
6608
|
+
const dragButtonText = keyboardDragOption.querySelector(`.${this.player.options.classPrefix}-button-text`);
|
|
6609
|
+
if (dragButtonText) dragButtonText.remove();
|
|
6452
6610
|
this.dragOptionButton = keyboardDragOption;
|
|
6453
6611
|
this.dragOptionText = keyboardDragOption.querySelector(`.${this.player.options.classPrefix}-settings-text`);
|
|
6454
6612
|
this.updateDragOptionState();
|
|
@@ -6466,6 +6624,10 @@ var VidPly = (() => {
|
|
|
6466
6624
|
}, 50);
|
|
6467
6625
|
}
|
|
6468
6626
|
});
|
|
6627
|
+
const styleTooltip = styleOption.querySelector(`.${this.player.options.classPrefix}-tooltip`);
|
|
6628
|
+
if (styleTooltip) styleTooltip.remove();
|
|
6629
|
+
const styleButtonText = styleOption.querySelector(`.${this.player.options.classPrefix}-button-text`);
|
|
6630
|
+
if (styleButtonText) styleButtonText.remove();
|
|
6469
6631
|
const resizeOption = createMenuItem({
|
|
6470
6632
|
classPrefix: this.player.options.classPrefix,
|
|
6471
6633
|
itemClass: `${this.player.options.classPrefix}-transcript-settings-item`,
|
|
@@ -6480,7 +6642,7 @@ var VidPly = (() => {
|
|
|
6480
6642
|
this.hideSettingsMenu({ focusButton: false });
|
|
6481
6643
|
setTimeout(() => {
|
|
6482
6644
|
if (this.transcriptWindow) {
|
|
6483
|
-
this.transcriptWindow.focus();
|
|
6645
|
+
this.transcriptWindow.focus({ preventScroll: true });
|
|
6484
6646
|
}
|
|
6485
6647
|
}, 20);
|
|
6486
6648
|
} else {
|
|
@@ -6490,6 +6652,10 @@ var VidPly = (() => {
|
|
|
6490
6652
|
});
|
|
6491
6653
|
resizeOption.setAttribute("role", "switch");
|
|
6492
6654
|
resizeOption.setAttribute("aria-checked", "false");
|
|
6655
|
+
const resizeTooltip = resizeOption.querySelector(`.${this.player.options.classPrefix}-tooltip`);
|
|
6656
|
+
if (resizeTooltip) resizeTooltip.remove();
|
|
6657
|
+
const resizeButtonText = resizeOption.querySelector(`.${this.player.options.classPrefix}-button-text`);
|
|
6658
|
+
if (resizeButtonText) resizeButtonText.remove();
|
|
6493
6659
|
this.resizeOptionButton = resizeOption;
|
|
6494
6660
|
this.resizeOptionText = resizeOption.querySelector(`.${this.player.options.classPrefix}-settings-text`);
|
|
6495
6661
|
this.updateResizeOptionState();
|
|
@@ -6505,6 +6671,10 @@ var VidPly = (() => {
|
|
|
6505
6671
|
});
|
|
6506
6672
|
showTimestampsOption.setAttribute("role", "switch");
|
|
6507
6673
|
showTimestampsOption.setAttribute("aria-checked", this.showTimestamps ? "true" : "false");
|
|
6674
|
+
const timestampsTooltip = showTimestampsOption.querySelector(`.${this.player.options.classPrefix}-tooltip`);
|
|
6675
|
+
if (timestampsTooltip) timestampsTooltip.remove();
|
|
6676
|
+
const timestampsButtonText = showTimestampsOption.querySelector(`.${this.player.options.classPrefix}-button-text`);
|
|
6677
|
+
if (timestampsButtonText) timestampsButtonText.remove();
|
|
6508
6678
|
this.showTimestampsButton = showTimestampsOption;
|
|
6509
6679
|
this.showTimestampsText = showTimestampsOption.querySelector(`.${this.player.options.classPrefix}-settings-text`);
|
|
6510
6680
|
this.updateShowTimestampsState();
|
|
@@ -6517,6 +6687,10 @@ var VidPly = (() => {
|
|
|
6517
6687
|
this.hideSettingsMenu();
|
|
6518
6688
|
}
|
|
6519
6689
|
});
|
|
6690
|
+
const closeTooltip = closeOption.querySelector(`.${this.player.options.classPrefix}-tooltip`);
|
|
6691
|
+
if (closeTooltip) closeTooltip.remove();
|
|
6692
|
+
const closeButtonText = closeOption.querySelector(`.${this.player.options.classPrefix}-button-text`);
|
|
6693
|
+
if (closeButtonText) closeButtonText.remove();
|
|
6520
6694
|
this.settingsMenu.appendChild(keyboardDragOption);
|
|
6521
6695
|
this.settingsMenu.appendChild(resizeOption);
|
|
6522
6696
|
this.settingsMenu.appendChild(styleOption);
|
|
@@ -6558,7 +6732,7 @@ var VidPly = (() => {
|
|
|
6558
6732
|
for (let i = 1; i < menuItems.length; i++) {
|
|
6559
6733
|
menuItems[i].setAttribute("tabindex", "-1");
|
|
6560
6734
|
}
|
|
6561
|
-
menuItems[0].focus();
|
|
6735
|
+
menuItems[0].focus({ preventScroll: true });
|
|
6562
6736
|
}
|
|
6563
6737
|
}, 50);
|
|
6564
6738
|
}
|
|
@@ -6632,7 +6806,7 @@ var VidPly = (() => {
|
|
|
6632
6806
|
if (this.settingsButton) {
|
|
6633
6807
|
this.settingsButton.setAttribute("aria-expanded", "false");
|
|
6634
6808
|
if (focusButton) {
|
|
6635
|
-
this.settingsButton.focus();
|
|
6809
|
+
this.settingsButton.focus({ preventScroll: true });
|
|
6636
6810
|
}
|
|
6637
6811
|
}
|
|
6638
6812
|
}
|
|
@@ -6678,7 +6852,6 @@ var VidPly = (() => {
|
|
|
6678
6852
|
const ariaLabel = isEnabled ? i18n.t("transcript.disableDragModeAria") : i18n.t("transcript.enableDragModeAria");
|
|
6679
6853
|
this.dragOptionButton.setAttribute("aria-checked", isEnabled ? "true" : "false");
|
|
6680
6854
|
this.dragOptionButton.setAttribute("aria-label", ariaLabel);
|
|
6681
|
-
this.dragOptionButton.setAttribute("title", text);
|
|
6682
6855
|
if (this.dragOptionText) {
|
|
6683
6856
|
this.dragOptionText.textContent = text;
|
|
6684
6857
|
}
|
|
@@ -6692,7 +6865,6 @@ var VidPly = (() => {
|
|
|
6692
6865
|
const ariaLabel = isEnabled ? i18n.t("transcript.disableResizeModeAria") : i18n.t("transcript.enableResizeModeAria");
|
|
6693
6866
|
this.resizeOptionButton.setAttribute("aria-checked", isEnabled ? "true" : "false");
|
|
6694
6867
|
this.resizeOptionButton.setAttribute("aria-label", ariaLabel);
|
|
6695
|
-
this.resizeOptionButton.setAttribute("title", text);
|
|
6696
6868
|
if (this.resizeOptionText) {
|
|
6697
6869
|
this.resizeOptionText.textContent = text;
|
|
6698
6870
|
}
|
|
@@ -6711,7 +6883,6 @@ var VidPly = (() => {
|
|
|
6711
6883
|
const ariaLabel = this.showTimestamps ? i18n.t("transcript.hideTimestampsAria") : i18n.t("transcript.showTimestampsAria");
|
|
6712
6884
|
this.showTimestampsButton.setAttribute("aria-checked", this.showTimestamps ? "true" : "false");
|
|
6713
6885
|
this.showTimestampsButton.setAttribute("aria-label", ariaLabel);
|
|
6714
|
-
this.showTimestampsButton.setAttribute("title", text);
|
|
6715
6886
|
if (this.showTimestampsText) {
|
|
6716
6887
|
this.showTimestampsText.textContent = text;
|
|
6717
6888
|
}
|
|
@@ -6780,7 +6951,7 @@ var VidPly = (() => {
|
|
|
6780
6951
|
setTimeout(() => {
|
|
6781
6952
|
const firstSelect = this.styleDialog.querySelector("select, input");
|
|
6782
6953
|
if (firstSelect) {
|
|
6783
|
-
firstSelect.focus();
|
|
6954
|
+
firstSelect.focus({ preventScroll: true });
|
|
6784
6955
|
}
|
|
6785
6956
|
}, 0);
|
|
6786
6957
|
return;
|
|
@@ -6845,10 +7016,10 @@ var VidPly = (() => {
|
|
|
6845
7016
|
const lastElement = focusableElements[focusableElements.length - 1];
|
|
6846
7017
|
if (e.shiftKey && document.activeElement === firstElement) {
|
|
6847
7018
|
e.preventDefault();
|
|
6848
|
-
lastElement.focus();
|
|
7019
|
+
lastElement.focus({ preventScroll: true });
|
|
6849
7020
|
} else if (!e.shiftKey && document.activeElement === lastElement) {
|
|
6850
7021
|
e.preventDefault();
|
|
6851
|
-
firstElement.focus();
|
|
7022
|
+
firstElement.focus({ preventScroll: true });
|
|
6852
7023
|
}
|
|
6853
7024
|
}
|
|
6854
7025
|
};
|
|
@@ -6868,7 +7039,7 @@ var VidPly = (() => {
|
|
|
6868
7039
|
setTimeout(() => {
|
|
6869
7040
|
const firstSelect = this.styleDialog.querySelector("select, input");
|
|
6870
7041
|
if (firstSelect) {
|
|
6871
|
-
firstSelect.focus();
|
|
7042
|
+
firstSelect.focus({ preventScroll: true });
|
|
6872
7043
|
}
|
|
6873
7044
|
}, 0);
|
|
6874
7045
|
}
|
|
@@ -6883,7 +7054,7 @@ var VidPly = (() => {
|
|
|
6883
7054
|
document.removeEventListener("keydown", this.handlers.styleDialogKeydown);
|
|
6884
7055
|
}
|
|
6885
7056
|
if (this.settingsButton) {
|
|
6886
|
-
this.settingsButton.focus();
|
|
7057
|
+
this.settingsButton.focus({ preventScroll: true });
|
|
6887
7058
|
}
|
|
6888
7059
|
}
|
|
6889
7060
|
}
|
|
@@ -8447,7 +8618,12 @@ var VidPly = (() => {
|
|
|
8447
8618
|
if (trackConfig.default) {
|
|
8448
8619
|
track.default = true;
|
|
8449
8620
|
}
|
|
8450
|
-
this.element.
|
|
8621
|
+
const firstChild = this.element.firstChild;
|
|
8622
|
+
if (firstChild && firstChild.nodeType === Node.ELEMENT_NODE && firstChild.tagName !== "TRACK") {
|
|
8623
|
+
this.element.insertBefore(track, firstChild);
|
|
8624
|
+
} else {
|
|
8625
|
+
this.element.appendChild(track);
|
|
8626
|
+
}
|
|
8451
8627
|
});
|
|
8452
8628
|
this.invalidateTrackCache();
|
|
8453
8629
|
}
|
|
@@ -9048,6 +9224,11 @@ var VidPly = (() => {
|
|
|
9048
9224
|
});
|
|
9049
9225
|
}
|
|
9050
9226
|
});
|
|
9227
|
+
const hasSrcAttribute = this.element.hasAttribute("src");
|
|
9228
|
+
const srcValue = hasSrcAttribute ? this.element.getAttribute("src") : null;
|
|
9229
|
+
if (hasSrcAttribute) {
|
|
9230
|
+
this.element.removeAttribute("src");
|
|
9231
|
+
}
|
|
9051
9232
|
allSourceElements.forEach((sourceEl) => {
|
|
9052
9233
|
sourceEl.remove();
|
|
9053
9234
|
});
|
|
@@ -9204,7 +9385,10 @@ var VidPly = (() => {
|
|
|
9204
9385
|
newTrackElement.setAttribute(attrName, attributes[attrName]);
|
|
9205
9386
|
}
|
|
9206
9387
|
});
|
|
9207
|
-
|
|
9388
|
+
const firstChild = parent.firstChild;
|
|
9389
|
+
if (firstChild && firstChild.nodeType === Node.ELEMENT_NODE && firstChild.tagName !== "TRACK") {
|
|
9390
|
+
parent.insertBefore(newTrackElement, firstChild);
|
|
9391
|
+
} else if (nextSibling && nextSibling.parentNode) {
|
|
9208
9392
|
parent.insertBefore(newTrackElement, nextSibling);
|
|
9209
9393
|
} else {
|
|
9210
9394
|
parent.appendChild(newTrackElement);
|
|
@@ -9676,6 +9860,11 @@ var VidPly = (() => {
|
|
|
9676
9860
|
});
|
|
9677
9861
|
}
|
|
9678
9862
|
});
|
|
9863
|
+
const hasSrcAttribute = this.element.hasAttribute("src");
|
|
9864
|
+
const srcValue = hasSrcAttribute ? this.element.getAttribute("src") : null;
|
|
9865
|
+
if (hasSrcAttribute) {
|
|
9866
|
+
this.element.removeAttribute("src");
|
|
9867
|
+
}
|
|
9679
9868
|
allSourceElements.forEach((sourceEl) => {
|
|
9680
9869
|
sourceEl.remove();
|
|
9681
9870
|
});
|
|
@@ -9966,15 +10155,17 @@ var VidPly = (() => {
|
|
|
9966
10155
|
const title = DOMUtils.createElement("h3", {
|
|
9967
10156
|
textContent: i18n.t("player.signLanguageVideo")
|
|
9968
10157
|
});
|
|
10158
|
+
const settingsAriaLabel = i18n.t("player.signLanguageSettings");
|
|
9969
10159
|
this.signLanguageSettingsButton = DOMUtils.createElement("button", {
|
|
9970
10160
|
className: `${this.options.classPrefix}-sign-language-settings`,
|
|
9971
10161
|
attributes: {
|
|
9972
10162
|
"type": "button",
|
|
9973
|
-
"aria-label":
|
|
10163
|
+
"aria-label": settingsAriaLabel,
|
|
9974
10164
|
"aria-expanded": "false"
|
|
9975
10165
|
}
|
|
9976
10166
|
});
|
|
9977
10167
|
this.signLanguageSettingsButton.appendChild(createIconElement("settings"));
|
|
10168
|
+
DOMUtils.attachTooltip(this.signLanguageSettingsButton, settingsAriaLabel, this.options.classPrefix);
|
|
9978
10169
|
this.signLanguageSettingsHandlers = {
|
|
9979
10170
|
settingsClick: (e) => {
|
|
9980
10171
|
e.preventDefault();
|
|
@@ -10042,19 +10233,21 @@ var VidPly = (() => {
|
|
|
10042
10233
|
headerLeft.appendChild(signLanguageSelectorWrapper);
|
|
10043
10234
|
}
|
|
10044
10235
|
headerLeft.appendChild(title);
|
|
10236
|
+
const closeAriaLabel = i18n.t("player.closeSignLanguage");
|
|
10045
10237
|
const closeButton = DOMUtils.createElement("button", {
|
|
10046
10238
|
className: `${this.options.classPrefix}-sign-language-close`,
|
|
10047
10239
|
attributes: {
|
|
10048
10240
|
"type": "button",
|
|
10049
|
-
"aria-label":
|
|
10241
|
+
"aria-label": closeAriaLabel
|
|
10050
10242
|
}
|
|
10051
10243
|
});
|
|
10052
10244
|
closeButton.appendChild(createIconElement("close"));
|
|
10245
|
+
DOMUtils.attachTooltip(closeButton, closeAriaLabel, this.options.classPrefix);
|
|
10053
10246
|
closeButton.addEventListener("click", () => {
|
|
10054
10247
|
this.disableSignLanguage();
|
|
10055
10248
|
if (this.controlBar && this.controlBar.controls && this.controlBar.controls.signLanguage) {
|
|
10056
10249
|
setTimeout(() => {
|
|
10057
|
-
this.controlBar.controls.signLanguage.focus();
|
|
10250
|
+
this.controlBar.controls.signLanguage.focus({ preventScroll: true });
|
|
10058
10251
|
}, 0);
|
|
10059
10252
|
}
|
|
10060
10253
|
});
|
|
@@ -10232,7 +10425,7 @@ var VidPly = (() => {
|
|
|
10232
10425
|
e.stopPropagation();
|
|
10233
10426
|
const enabled = this.toggleSignLanguageResizeMode();
|
|
10234
10427
|
if (enabled) {
|
|
10235
|
-
this.signLanguageWrapper.focus();
|
|
10428
|
+
this.signLanguageWrapper.focus({ preventScroll: true });
|
|
10236
10429
|
}
|
|
10237
10430
|
return;
|
|
10238
10431
|
}
|
|
@@ -10250,7 +10443,7 @@ var VidPly = (() => {
|
|
|
10250
10443
|
this.disableSignLanguage();
|
|
10251
10444
|
if (this.controlBar && this.controlBar.controls && this.controlBar.controls.signLanguage) {
|
|
10252
10445
|
setTimeout(() => {
|
|
10253
|
-
this.controlBar.controls.signLanguage.focus();
|
|
10446
|
+
this.controlBar.controls.signLanguage.focus({ preventScroll: true });
|
|
10254
10447
|
}, 0);
|
|
10255
10448
|
}
|
|
10256
10449
|
return;
|
|
@@ -10385,6 +10578,10 @@ var VidPly = (() => {
|
|
|
10385
10578
|
});
|
|
10386
10579
|
keyboardDragOption.setAttribute("role", "switch");
|
|
10387
10580
|
keyboardDragOption.setAttribute("aria-checked", "false");
|
|
10581
|
+
const dragTooltip = keyboardDragOption.querySelector(`.${this.options.classPrefix}-tooltip`);
|
|
10582
|
+
if (dragTooltip) dragTooltip.remove();
|
|
10583
|
+
const dragButtonText = keyboardDragOption.querySelector(`.${this.options.classPrefix}-button-text`);
|
|
10584
|
+
if (dragButtonText) dragButtonText.remove();
|
|
10388
10585
|
this.signLanguageDragOptionButton = keyboardDragOption;
|
|
10389
10586
|
this.signLanguageDragOptionText = keyboardDragOption.querySelector(`.${this.options.classPrefix}-settings-text`);
|
|
10390
10587
|
this.updateSignLanguageDragOptionState();
|
|
@@ -10402,7 +10599,7 @@ var VidPly = (() => {
|
|
|
10402
10599
|
this.hideSignLanguageSettingsMenu({ focusButton: false });
|
|
10403
10600
|
setTimeout(() => {
|
|
10404
10601
|
if (this.signLanguageWrapper) {
|
|
10405
|
-
this.signLanguageWrapper.focus();
|
|
10602
|
+
this.signLanguageWrapper.focus({ preventScroll: true });
|
|
10406
10603
|
}
|
|
10407
10604
|
}, 20);
|
|
10408
10605
|
} else {
|
|
@@ -10412,6 +10609,10 @@ var VidPly = (() => {
|
|
|
10412
10609
|
});
|
|
10413
10610
|
resizeOption.setAttribute("role", "switch");
|
|
10414
10611
|
resizeOption.setAttribute("aria-checked", "false");
|
|
10612
|
+
const resizeTooltip = resizeOption.querySelector(`.${this.options.classPrefix}-tooltip`);
|
|
10613
|
+
if (resizeTooltip) resizeTooltip.remove();
|
|
10614
|
+
const resizeButtonText = resizeOption.querySelector(`.${this.options.classPrefix}-button-text`);
|
|
10615
|
+
if (resizeButtonText) resizeButtonText.remove();
|
|
10415
10616
|
this.signLanguageResizeOptionButton = resizeOption;
|
|
10416
10617
|
this.signLanguageResizeOptionText = resizeOption.querySelector(`.${this.options.classPrefix}-settings-text`);
|
|
10417
10618
|
this.updateSignLanguageResizeOptionState();
|
|
@@ -10424,6 +10625,10 @@ var VidPly = (() => {
|
|
|
10424
10625
|
this.hideSignLanguageSettingsMenu();
|
|
10425
10626
|
}
|
|
10426
10627
|
});
|
|
10628
|
+
const closeTooltip = closeOption.querySelector(`.${this.options.classPrefix}-tooltip`);
|
|
10629
|
+
if (closeTooltip) closeTooltip.remove();
|
|
10630
|
+
const closeButtonText = closeOption.querySelector(`.${this.options.classPrefix}-button-text`);
|
|
10631
|
+
if (closeButtonText) closeButtonText.remove();
|
|
10427
10632
|
this.signLanguageSettingsMenu.appendChild(keyboardDragOption);
|
|
10428
10633
|
this.signLanguageSettingsMenu.appendChild(resizeOption);
|
|
10429
10634
|
this.signLanguageSettingsMenu.appendChild(closeOption);
|
|
@@ -10470,7 +10675,7 @@ var VidPly = (() => {
|
|
|
10470
10675
|
if (this.signLanguageSettingsButton) {
|
|
10471
10676
|
this.signLanguageSettingsButton.setAttribute("aria-expanded", "false");
|
|
10472
10677
|
if (focusButton) {
|
|
10473
|
-
this.signLanguageSettingsButton.focus();
|
|
10678
|
+
this.signLanguageSettingsButton.focus({ preventScroll: true });
|
|
10474
10679
|
}
|
|
10475
10680
|
}
|
|
10476
10681
|
}
|
|
@@ -10559,7 +10764,6 @@ var VidPly = (() => {
|
|
|
10559
10764
|
const ariaLabel = isEnabled ? i18n.t("player.disableSignDragModeAria") : i18n.t("player.enableSignDragModeAria");
|
|
10560
10765
|
this.signLanguageDragOptionButton.setAttribute("aria-checked", isEnabled ? "true" : "false");
|
|
10561
10766
|
this.signLanguageDragOptionButton.setAttribute("aria-label", ariaLabel);
|
|
10562
|
-
this.signLanguageDragOptionButton.setAttribute("title", text);
|
|
10563
10767
|
if (this.signLanguageDragOptionText) {
|
|
10564
10768
|
this.signLanguageDragOptionText.textContent = text;
|
|
10565
10769
|
}
|
|
@@ -10573,7 +10777,6 @@ var VidPly = (() => {
|
|
|
10573
10777
|
const ariaLabel = isEnabled ? i18n.t("player.disableSignResizeModeAria") : i18n.t("player.enableSignResizeModeAria");
|
|
10574
10778
|
this.signLanguageResizeOptionButton.setAttribute("aria-checked", isEnabled ? "true" : "false");
|
|
10575
10779
|
this.signLanguageResizeOptionButton.setAttribute("aria-label", ariaLabel);
|
|
10576
|
-
this.signLanguageResizeOptionButton.setAttribute("title", text);
|
|
10577
10780
|
if (this.signLanguageResizeOptionText) {
|
|
10578
10781
|
this.signLanguageResizeOptionText.textContent = text;
|
|
10579
10782
|
}
|
|
@@ -11007,23 +11210,23 @@ var VidPly = (() => {
|
|
|
11007
11210
|
return;
|
|
11008
11211
|
}
|
|
11009
11212
|
if (target === "alert" && fallbackElement) {
|
|
11010
|
-
fallbackElement.focus();
|
|
11213
|
+
fallbackElement.focus({ preventScroll: true });
|
|
11011
11214
|
return;
|
|
11012
11215
|
}
|
|
11013
11216
|
if (target === "player") {
|
|
11014
11217
|
if (this.container) {
|
|
11015
|
-
this.container.focus();
|
|
11218
|
+
this.container.focus({ preventScroll: true });
|
|
11016
11219
|
}
|
|
11017
11220
|
return;
|
|
11018
11221
|
}
|
|
11019
11222
|
if (target === "media") {
|
|
11020
|
-
this.element.focus();
|
|
11223
|
+
this.element.focus({ preventScroll: true });
|
|
11021
11224
|
return;
|
|
11022
11225
|
}
|
|
11023
11226
|
if (target === "playButton") {
|
|
11024
11227
|
const playButton = (_b = (_a = this.controlBar) == null ? void 0 : _a.controls) == null ? void 0 : _b.playPause;
|
|
11025
11228
|
if (playButton) {
|
|
11026
|
-
playButton.focus();
|
|
11229
|
+
playButton.focus({ preventScroll: true });
|
|
11027
11230
|
}
|
|
11028
11231
|
return;
|
|
11029
11232
|
}
|
|
@@ -11033,7 +11236,7 @@ var VidPly = (() => {
|
|
|
11033
11236
|
if (targetElement.tabIndex === -1 && !targetElement.hasAttribute("tabindex")) {
|
|
11034
11237
|
targetElement.setAttribute("tabindex", "-1");
|
|
11035
11238
|
}
|
|
11036
|
-
targetElement.focus();
|
|
11239
|
+
targetElement.focus({ preventScroll: true });
|
|
11037
11240
|
}
|
|
11038
11241
|
}
|
|
11039
11242
|
}
|
|
@@ -11077,7 +11280,7 @@ var VidPly = (() => {
|
|
|
11077
11280
|
if (element.tabIndex === -1 && !element.hasAttribute("tabindex")) {
|
|
11078
11281
|
element.setAttribute("tabindex", "-1");
|
|
11079
11282
|
}
|
|
11080
|
-
element.focus();
|
|
11283
|
+
element.focus({ preventScroll: true });
|
|
11081
11284
|
}
|
|
11082
11285
|
if (shouldShow && config.autoScroll !== false && options.autoScroll !== false) {
|
|
11083
11286
|
element.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
@@ -11208,8 +11411,7 @@ var VidPly = (() => {
|
|
|
11208
11411
|
targetElement.setAttribute("tabindex", "-1");
|
|
11209
11412
|
}
|
|
11210
11413
|
this.setManagedTimeout(() => {
|
|
11211
|
-
targetElement.focus();
|
|
11212
|
-
targetElement.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
11414
|
+
targetElement.focus({ preventScroll: true });
|
|
11213
11415
|
}, 10);
|
|
11214
11416
|
} else if (this.options.debug) {
|
|
11215
11417
|
this.log("[Metadata] Element not found:", normalizedSelector || targetSelector);
|
|
@@ -11285,6 +11487,8 @@ var VidPly = (() => {
|
|
|
11285
11487
|
this.player.on("pause", this.handlePlaybackStateChange.bind(this));
|
|
11286
11488
|
this.player.on("ended", this.handlePlaybackStateChange.bind(this));
|
|
11287
11489
|
this.player.on("fullscreenchange", this.handleFullscreenChange.bind(this));
|
|
11490
|
+
this.player.on("audiodescriptionenabled", this.handleAudioDescriptionChange.bind(this));
|
|
11491
|
+
this.player.on("audiodescriptiondisabled", this.handleAudioDescriptionChange.bind(this));
|
|
11288
11492
|
if (this.options.showPanel) {
|
|
11289
11493
|
this.createUI();
|
|
11290
11494
|
}
|
|
@@ -11512,6 +11716,52 @@ var VidPly = (() => {
|
|
|
11512
11716
|
this.updatePlaylistVisibilityInFullscreen();
|
|
11513
11717
|
}, 50);
|
|
11514
11718
|
}
|
|
11719
|
+
/**
|
|
11720
|
+
* Handle audio description state changes
|
|
11721
|
+
* Updates duration displays to show audio-described version duration when AD is enabled
|
|
11722
|
+
*/
|
|
11723
|
+
handleAudioDescriptionChange() {
|
|
11724
|
+
const currentTrack = this.getCurrentTrack();
|
|
11725
|
+
if (!currentTrack) return;
|
|
11726
|
+
this.updateTrackInfo(currentTrack);
|
|
11727
|
+
this.updatePlaylistUI();
|
|
11728
|
+
this.updatePlaylistDurations();
|
|
11729
|
+
}
|
|
11730
|
+
/**
|
|
11731
|
+
* Update the visual duration displays in the playlist panel
|
|
11732
|
+
* Called when audio description state changes
|
|
11733
|
+
*/
|
|
11734
|
+
updatePlaylistDurations() {
|
|
11735
|
+
if (!this.playlistPanel) return;
|
|
11736
|
+
const items = this.playlistPanel.querySelectorAll(".vidply-playlist-item");
|
|
11737
|
+
items.forEach((item, index) => {
|
|
11738
|
+
const track = this.tracks[index];
|
|
11739
|
+
if (!track) return;
|
|
11740
|
+
const effectiveDuration = this.getEffectiveDuration(track);
|
|
11741
|
+
const trackDuration = effectiveDuration ? TimeUtils.formatTime(effectiveDuration) : "";
|
|
11742
|
+
const durationBadge = item.querySelector(".vidply-playlist-duration-badge");
|
|
11743
|
+
if (durationBadge) {
|
|
11744
|
+
durationBadge.textContent = trackDuration;
|
|
11745
|
+
}
|
|
11746
|
+
const inlineDuration = item.querySelector(".vidply-playlist-item-duration");
|
|
11747
|
+
if (inlineDuration) {
|
|
11748
|
+
inlineDuration.textContent = trackDuration;
|
|
11749
|
+
}
|
|
11750
|
+
});
|
|
11751
|
+
}
|
|
11752
|
+
/**
|
|
11753
|
+
* Get the effective duration for a track based on audio description state
|
|
11754
|
+
* @param {Object} track - Track object
|
|
11755
|
+
* @returns {number|null} - Duration in seconds or null if not available
|
|
11756
|
+
*/
|
|
11757
|
+
getEffectiveDuration(track) {
|
|
11758
|
+
if (!track) return null;
|
|
11759
|
+
const isAudioDescriptionEnabled = this.player.state.audioDescriptionEnabled;
|
|
11760
|
+
if (isAudioDescriptionEnabled && track.audioDescriptionDuration) {
|
|
11761
|
+
return track.audioDescriptionDuration;
|
|
11762
|
+
}
|
|
11763
|
+
return track.duration || null;
|
|
11764
|
+
}
|
|
11515
11765
|
/**
|
|
11516
11766
|
* Update playlist visibility based on fullscreen and playback state
|
|
11517
11767
|
* In fullscreen: show when paused/not started, hide when playing
|
|
@@ -11569,9 +11819,7 @@ var VidPly = (() => {
|
|
|
11569
11819
|
this.trackInfoElement = DOMUtils.createElement("div", {
|
|
11570
11820
|
className: "vidply-track-info",
|
|
11571
11821
|
attributes: {
|
|
11572
|
-
role: "status"
|
|
11573
|
-
"aria-live": "polite",
|
|
11574
|
-
"aria-atomic": "true"
|
|
11822
|
+
role: "status"
|
|
11575
11823
|
}
|
|
11576
11824
|
});
|
|
11577
11825
|
this.trackInfoElement.style.display = "none";
|
|
@@ -11606,22 +11854,32 @@ var VidPly = (() => {
|
|
|
11606
11854
|
const totalTracks = this.tracks.length;
|
|
11607
11855
|
const trackTitle = track.title || i18n.t("playlist.untitled");
|
|
11608
11856
|
const trackArtist = track.artist || "";
|
|
11857
|
+
const effectiveDuration = this.getEffectiveDuration(track);
|
|
11858
|
+
const trackDuration = effectiveDuration ? TimeUtils.formatTime(effectiveDuration) : "";
|
|
11859
|
+
const trackDurationReadable = effectiveDuration ? TimeUtils.formatDuration(effectiveDuration) : "";
|
|
11609
11860
|
const artistPart = trackArtist ? i18n.t("playlist.by") + trackArtist : "";
|
|
11861
|
+
const durationPart = trackDurationReadable ? `. ${trackDurationReadable}` : "";
|
|
11610
11862
|
const announcement = i18n.t("playlist.nowPlaying", {
|
|
11611
11863
|
current: trackNumber,
|
|
11612
11864
|
total: totalTracks,
|
|
11613
11865
|
title: trackTitle,
|
|
11614
11866
|
artist: artistPart
|
|
11615
|
-
});
|
|
11867
|
+
}) + durationPart;
|
|
11616
11868
|
const trackOfText = i18n.t("playlist.trackOf", {
|
|
11617
11869
|
current: trackNumber,
|
|
11618
11870
|
total: totalTracks
|
|
11619
11871
|
});
|
|
11872
|
+
const durationHtml = trackDuration ? `<span class="vidply-track-duration" aria-hidden="true">${DOMUtils.escapeHTML(trackDuration)}</span>` : "";
|
|
11873
|
+
const trackDescription = track.description || "";
|
|
11620
11874
|
this.trackInfoElement.innerHTML = `
|
|
11621
11875
|
<span class="vidply-sr-only">${DOMUtils.escapeHTML(announcement)}</span>
|
|
11622
|
-
<div class="vidply-track-
|
|
11876
|
+
<div class="vidply-track-header" aria-hidden="true">
|
|
11877
|
+
<span class="vidply-track-number">${DOMUtils.escapeHTML(trackOfText)}</span>
|
|
11878
|
+
${durationHtml}
|
|
11879
|
+
</div>
|
|
11623
11880
|
<div class="vidply-track-title" aria-hidden="true">${DOMUtils.escapeHTML(trackTitle)}</div>
|
|
11624
11881
|
${trackArtist ? `<div class="vidply-track-artist" aria-hidden="true">${DOMUtils.escapeHTML(trackArtist)}</div>` : ""}
|
|
11882
|
+
${trackDescription ? `<div class="vidply-track-description" aria-hidden="true">${DOMUtils.escapeHTML(trackDescription)}</div>` : ""}
|
|
11625
11883
|
`;
|
|
11626
11884
|
this.trackInfoElement.style.display = "block";
|
|
11627
11885
|
this.updateTrackArtwork(track);
|
|
@@ -11663,6 +11921,7 @@ var VidPly = (() => {
|
|
|
11663
11921
|
const list = DOMUtils.createElement("ul", {
|
|
11664
11922
|
className: "vidply-playlist-list",
|
|
11665
11923
|
attributes: {
|
|
11924
|
+
role: "listbox",
|
|
11666
11925
|
"aria-labelledby": `${this.uniqueId}-heading`,
|
|
11667
11926
|
"aria-describedby": `${this.uniqueId}-keyboard-instructions`
|
|
11668
11927
|
}
|
|
@@ -11686,9 +11945,14 @@ var VidPly = (() => {
|
|
|
11686
11945
|
});
|
|
11687
11946
|
const trackTitle = track.title || i18n.t("playlist.trackUntitled", { number: index + 1 });
|
|
11688
11947
|
const trackArtist = track.artist ? i18n.t("playlist.by") + track.artist : "";
|
|
11948
|
+
const effectiveDuration = this.getEffectiveDuration(track);
|
|
11949
|
+
const trackDuration = effectiveDuration ? TimeUtils.formatTime(effectiveDuration) : "";
|
|
11950
|
+
const trackDurationReadable = effectiveDuration ? TimeUtils.formatDuration(effectiveDuration) : "";
|
|
11689
11951
|
const isActive = index === this.currentIndex;
|
|
11690
|
-
|
|
11691
|
-
|
|
11952
|
+
let ariaLabel = `${trackTitle}${trackArtist}`;
|
|
11953
|
+
if (trackDurationReadable) {
|
|
11954
|
+
ariaLabel += `. ${trackDurationReadable}`;
|
|
11955
|
+
}
|
|
11692
11956
|
const item = DOMUtils.createElement("li", {
|
|
11693
11957
|
className: isActive ? "vidply-playlist-item vidply-playlist-item-active" : "vidply-playlist-item",
|
|
11694
11958
|
attributes: {
|
|
@@ -11699,23 +11963,28 @@ var VidPly = (() => {
|
|
|
11699
11963
|
className: "vidply-playlist-item-button",
|
|
11700
11964
|
attributes: {
|
|
11701
11965
|
type: "button",
|
|
11966
|
+
role: "option",
|
|
11702
11967
|
tabIndex: index === 0 ? 0 : -1,
|
|
11703
11968
|
// Only first item is in tab order initially
|
|
11704
|
-
"aria-label":
|
|
11969
|
+
"aria-label": ariaLabel,
|
|
11705
11970
|
"aria-posinset": index + 1,
|
|
11706
|
-
"aria-setsize": this.tracks.length
|
|
11971
|
+
"aria-setsize": this.tracks.length,
|
|
11972
|
+
"aria-checked": isActive ? "true" : "false"
|
|
11707
11973
|
}
|
|
11708
11974
|
});
|
|
11709
11975
|
if (isActive) {
|
|
11710
11976
|
button.setAttribute("aria-current", "true");
|
|
11711
11977
|
button.setAttribute("tabIndex", "0");
|
|
11712
11978
|
}
|
|
11713
|
-
const
|
|
11714
|
-
className: "vidply-playlist-thumbnail",
|
|
11979
|
+
const thumbnailContainer = DOMUtils.createElement("span", {
|
|
11980
|
+
className: "vidply-playlist-thumbnail-container",
|
|
11715
11981
|
attributes: {
|
|
11716
11982
|
"aria-hidden": "true"
|
|
11717
11983
|
}
|
|
11718
11984
|
});
|
|
11985
|
+
const thumbnail = DOMUtils.createElement("span", {
|
|
11986
|
+
className: "vidply-playlist-thumbnail"
|
|
11987
|
+
});
|
|
11719
11988
|
if (track.poster) {
|
|
11720
11989
|
thumbnail.style.backgroundImage = `url(${track.poster})`;
|
|
11721
11990
|
} else {
|
|
@@ -11723,18 +11992,37 @@ var VidPly = (() => {
|
|
|
11723
11992
|
icon.classList.add("vidply-playlist-thumbnail-icon");
|
|
11724
11993
|
thumbnail.appendChild(icon);
|
|
11725
11994
|
}
|
|
11726
|
-
|
|
11995
|
+
thumbnailContainer.appendChild(thumbnail);
|
|
11996
|
+
if (trackDuration && track.poster) {
|
|
11997
|
+
const durationBadge = DOMUtils.createElement("span", {
|
|
11998
|
+
className: "vidply-playlist-duration-badge"
|
|
11999
|
+
});
|
|
12000
|
+
durationBadge.textContent = trackDuration;
|
|
12001
|
+
thumbnailContainer.appendChild(durationBadge);
|
|
12002
|
+
}
|
|
12003
|
+
button.appendChild(thumbnailContainer);
|
|
11727
12004
|
const info = DOMUtils.createElement("span", {
|
|
11728
12005
|
className: "vidply-playlist-item-info",
|
|
11729
12006
|
attributes: {
|
|
11730
12007
|
"aria-hidden": "true"
|
|
11731
12008
|
}
|
|
11732
12009
|
});
|
|
12010
|
+
const titleRow = DOMUtils.createElement("span", {
|
|
12011
|
+
className: "vidply-playlist-item-title-row"
|
|
12012
|
+
});
|
|
11733
12013
|
const title = DOMUtils.createElement("span", {
|
|
11734
12014
|
className: "vidply-playlist-item-title"
|
|
11735
12015
|
});
|
|
11736
12016
|
title.textContent = trackTitle;
|
|
11737
|
-
|
|
12017
|
+
titleRow.appendChild(title);
|
|
12018
|
+
if (trackDuration && !track.poster) {
|
|
12019
|
+
const inlineDuration = DOMUtils.createElement("span", {
|
|
12020
|
+
className: "vidply-playlist-item-duration"
|
|
12021
|
+
});
|
|
12022
|
+
inlineDuration.textContent = trackDuration;
|
|
12023
|
+
titleRow.appendChild(inlineDuration);
|
|
12024
|
+
}
|
|
12025
|
+
info.appendChild(titleRow);
|
|
11738
12026
|
if (track.artist) {
|
|
11739
12027
|
const artist = DOMUtils.createElement("span", {
|
|
11740
12028
|
className: "vidply-playlist-item-artist"
|
|
@@ -11742,6 +12030,13 @@ var VidPly = (() => {
|
|
|
11742
12030
|
artist.textContent = track.artist;
|
|
11743
12031
|
info.appendChild(artist);
|
|
11744
12032
|
}
|
|
12033
|
+
if (track.description) {
|
|
12034
|
+
const description = DOMUtils.createElement("span", {
|
|
12035
|
+
className: "vidply-playlist-item-description"
|
|
12036
|
+
});
|
|
12037
|
+
description.textContent = track.description;
|
|
12038
|
+
info.appendChild(description);
|
|
12039
|
+
}
|
|
11745
12040
|
button.appendChild(info);
|
|
11746
12041
|
const playIcon = createIconElement("play");
|
|
11747
12042
|
playIcon.classList.add("vidply-playlist-item-icon");
|
|
@@ -11825,7 +12120,11 @@ var VidPly = (() => {
|
|
|
11825
12120
|
if (newIndex !== -1 && newIndex !== index) {
|
|
11826
12121
|
buttons[index].setAttribute("tabIndex", "-1");
|
|
11827
12122
|
buttons[newIndex].setAttribute("tabIndex", "0");
|
|
11828
|
-
buttons[newIndex].focus();
|
|
12123
|
+
buttons[newIndex].focus({ preventScroll: false });
|
|
12124
|
+
const item = buttons[newIndex].closest(".vidply-playlist-item");
|
|
12125
|
+
if (item) {
|
|
12126
|
+
item.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
12127
|
+
}
|
|
11829
12128
|
}
|
|
11830
12129
|
if (announcement && this.navigationFeedback) {
|
|
11831
12130
|
this.navigationFeedback.textContent = announcement;
|
|
@@ -11853,21 +12152,29 @@ var VidPly = (() => {
|
|
|
11853
12152
|
});
|
|
11854
12153
|
const trackTitle = track.title || i18n.t("playlist.trackUntitled", { number: index + 1 });
|
|
11855
12154
|
const trackArtist = track.artist ? i18n.t("playlist.by") + track.artist : "";
|
|
12155
|
+
const effectiveDuration = this.getEffectiveDuration(track);
|
|
12156
|
+
const trackDurationReadable = effectiveDuration ? TimeUtils.formatDuration(effectiveDuration) : "";
|
|
11856
12157
|
if (index === this.currentIndex) {
|
|
11857
12158
|
item.classList.add("vidply-playlist-item-active");
|
|
11858
12159
|
button.setAttribute("aria-current", "true");
|
|
12160
|
+
button.setAttribute("aria-checked", "true");
|
|
11859
12161
|
button.setAttribute("tabIndex", "0");
|
|
11860
|
-
|
|
11861
|
-
|
|
11862
|
-
|
|
12162
|
+
let ariaLabel = `${trackTitle}${trackArtist}`;
|
|
12163
|
+
if (trackDurationReadable) {
|
|
12164
|
+
ariaLabel += `. ${trackDurationReadable}`;
|
|
12165
|
+
}
|
|
12166
|
+
button.setAttribute("aria-label", ariaLabel);
|
|
11863
12167
|
item.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
11864
12168
|
} else {
|
|
11865
12169
|
item.classList.remove("vidply-playlist-item-active");
|
|
11866
12170
|
button.removeAttribute("aria-current");
|
|
12171
|
+
button.setAttribute("aria-checked", "false");
|
|
11867
12172
|
button.setAttribute("tabIndex", "-1");
|
|
11868
|
-
|
|
11869
|
-
|
|
11870
|
-
|
|
12173
|
+
let ariaLabel = `${trackTitle}${trackArtist}`;
|
|
12174
|
+
if (trackDurationReadable) {
|
|
12175
|
+
ariaLabel += `. ${trackDurationReadable}`;
|
|
12176
|
+
}
|
|
12177
|
+
button.setAttribute("aria-label", ariaLabel);
|
|
11871
12178
|
}
|
|
11872
12179
|
});
|
|
11873
12180
|
}
|
|
@@ -11966,7 +12273,7 @@ var VidPly = (() => {
|
|
|
11966
12273
|
setTimeout(() => {
|
|
11967
12274
|
const firstItem = this.playlistPanel.querySelector('.vidply-playlist-item[tabindex="0"]');
|
|
11968
12275
|
if (firstItem) {
|
|
11969
|
-
firstItem.focus();
|
|
12276
|
+
firstItem.focus({ preventScroll: true });
|
|
11970
12277
|
}
|
|
11971
12278
|
}, 100);
|
|
11972
12279
|
}
|
|
@@ -11980,7 +12287,7 @@ var VidPly = (() => {
|
|
|
11980
12287
|
if (this.player.controlBar && this.player.controlBar.controls.playlistToggle) {
|
|
11981
12288
|
this.player.controlBar.controls.playlistToggle.setAttribute("aria-expanded", "false");
|
|
11982
12289
|
this.player.controlBar.controls.playlistToggle.setAttribute("aria-pressed", "false");
|
|
11983
|
-
this.player.controlBar.controls.playlistToggle.focus();
|
|
12290
|
+
this.player.controlBar.controls.playlistToggle.focus({ preventScroll: true });
|
|
11984
12291
|
}
|
|
11985
12292
|
}
|
|
11986
12293
|
return this.isPanelVisible;
|