vidply 1.0.22 → 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 +184 -4
- 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 +184 -4
- 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.esm.js
CHANGED
|
@@ -406,6 +406,63 @@ var DOMUtils = {
|
|
|
406
406
|
const safeHtml = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "").replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, "").replace(/on\w+\s*=/gi, "").replace(/javascript:/gi, "");
|
|
407
407
|
temp.innerHTML = safeHtml;
|
|
408
408
|
return temp.innerHTML;
|
|
409
|
+
},
|
|
410
|
+
/**
|
|
411
|
+
* Create a tooltip element that is aria-hidden (not read by screen readers)
|
|
412
|
+
* @param {string} text - Tooltip text
|
|
413
|
+
* @param {string} classPrefix - Class prefix for styling
|
|
414
|
+
* @returns {HTMLElement} Tooltip element
|
|
415
|
+
*/
|
|
416
|
+
createTooltip(text, classPrefix = "vidply") {
|
|
417
|
+
const tooltip = this.createElement("span", {
|
|
418
|
+
className: `${classPrefix}-tooltip`,
|
|
419
|
+
textContent: text,
|
|
420
|
+
attributes: {
|
|
421
|
+
"aria-hidden": "true"
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
return tooltip;
|
|
425
|
+
},
|
|
426
|
+
/**
|
|
427
|
+
* Attach a tooltip to an element
|
|
428
|
+
* @param {HTMLElement} element - Element to attach tooltip to
|
|
429
|
+
* @param {string} text - Tooltip text
|
|
430
|
+
* @param {string} classPrefix - Class prefix for styling
|
|
431
|
+
*/
|
|
432
|
+
attachTooltip(element, text, classPrefix = "vidply") {
|
|
433
|
+
if (!element || !text) return;
|
|
434
|
+
const existingTooltip = element.querySelector(`.${classPrefix}-tooltip`);
|
|
435
|
+
if (existingTooltip) {
|
|
436
|
+
existingTooltip.remove();
|
|
437
|
+
}
|
|
438
|
+
const tooltip = this.createTooltip(text, classPrefix);
|
|
439
|
+
element.appendChild(tooltip);
|
|
440
|
+
const showTooltip = () => {
|
|
441
|
+
tooltip.classList.add(`${classPrefix}-tooltip-visible`);
|
|
442
|
+
};
|
|
443
|
+
const hideTooltip = () => {
|
|
444
|
+
tooltip.classList.remove(`${classPrefix}-tooltip-visible`);
|
|
445
|
+
};
|
|
446
|
+
element.addEventListener("mouseenter", showTooltip);
|
|
447
|
+
element.addEventListener("mouseleave", hideTooltip);
|
|
448
|
+
element.addEventListener("focus", showTooltip);
|
|
449
|
+
element.addEventListener("blur", hideTooltip);
|
|
450
|
+
},
|
|
451
|
+
/**
|
|
452
|
+
* Create visible button text that is hidden by CSS but visible when CSS is disabled
|
|
453
|
+
* @param {string} text - Button text
|
|
454
|
+
* @param {string} classPrefix - Class prefix for styling
|
|
455
|
+
* @returns {HTMLElement} Button text element
|
|
456
|
+
*/
|
|
457
|
+
createButtonText(text, classPrefix = "vidply") {
|
|
458
|
+
const buttonText = this.createElement("span", {
|
|
459
|
+
className: `${classPrefix}-button-text`,
|
|
460
|
+
textContent: text,
|
|
461
|
+
attributes: {
|
|
462
|
+
"aria-hidden": "true"
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
return buttonText;
|
|
409
466
|
}
|
|
410
467
|
};
|
|
411
468
|
|
|
@@ -572,7 +629,11 @@ var en = {
|
|
|
572
629
|
nowPlaying: "Now playing: Track {current} of {total}. {title}{artist}",
|
|
573
630
|
by: " by ",
|
|
574
631
|
untitled: "Untitled",
|
|
575
|
-
trackUntitled: "Track {number}"
|
|
632
|
+
trackUntitled: "Track {number}",
|
|
633
|
+
currentlyPlaying: "Currently playing",
|
|
634
|
+
notPlaying: "Not playing",
|
|
635
|
+
pressEnterPlay: "Press Enter to play",
|
|
636
|
+
pressEnterRestart: "Press Enter to restart"
|
|
576
637
|
}
|
|
577
638
|
};
|
|
578
639
|
|
|
@@ -739,7 +800,11 @@ var de = {
|
|
|
739
800
|
nowPlaying: "L\xE4uft gerade: Titel {current} von {total}. {title}{artist}",
|
|
740
801
|
by: " von ",
|
|
741
802
|
untitled: "Ohne Titel",
|
|
742
|
-
trackUntitled: "Titel {number}"
|
|
803
|
+
trackUntitled: "Titel {number}",
|
|
804
|
+
currentlyPlaying: "Wird gerade abgespielt",
|
|
805
|
+
notPlaying: "Nicht aktiv",
|
|
806
|
+
pressEnterPlay: "Eingabetaste zum Abspielen",
|
|
807
|
+
pressEnterRestart: "Eingabetaste zum Neustart"
|
|
743
808
|
}
|
|
744
809
|
};
|
|
745
810
|
|
|
@@ -906,7 +971,11 @@ var es = {
|
|
|
906
971
|
nowPlaying: "Reproduciendo ahora: Pista {current} de {total}. {title}{artist}",
|
|
907
972
|
by: " por ",
|
|
908
973
|
untitled: "Sin t\xEDtulo",
|
|
909
|
-
trackUntitled: "Pista {number}"
|
|
974
|
+
trackUntitled: "Pista {number}",
|
|
975
|
+
currentlyPlaying: "Reproduciendo actualmente",
|
|
976
|
+
notPlaying: "Sin reproducir",
|
|
977
|
+
pressEnterPlay: "Pulsa Enter para reproducir",
|
|
978
|
+
pressEnterRestart: "Pulsa Enter para reiniciar"
|
|
910
979
|
}
|
|
911
980
|
};
|
|
912
981
|
|
|
@@ -1073,7 +1142,11 @@ var fr = {
|
|
|
1073
1142
|
nowPlaying: "Lecture en cours : Piste {current} sur {total}. {title}{artist}",
|
|
1074
1143
|
by: " par ",
|
|
1075
1144
|
untitled: "Sans titre",
|
|
1076
|
-
trackUntitled: "Piste {number}"
|
|
1145
|
+
trackUntitled: "Piste {number}",
|
|
1146
|
+
currentlyPlaying: "En cours de lecture",
|
|
1147
|
+
notPlaying: "Non en lecture",
|
|
1148
|
+
pressEnterPlay: "Appuyez sur Entr\xE9e pour lire",
|
|
1149
|
+
pressEnterRestart: "Appuyez sur Entr\xE9e pour recommencer"
|
|
1077
1150
|
}
|
|
1078
1151
|
};
|
|
1079
1152
|
|
|
@@ -1240,7 +1313,11 @@ var ja = {
|
|
|
1240
1313
|
nowPlaying: "\u518D\u751F\u4E2D: \u30C8\u30E9\u30C3\u30AF {current}/{total}. {title}{artist}",
|
|
1241
1314
|
by: " - ",
|
|
1242
1315
|
untitled: "\u30BF\u30A4\u30C8\u30EB\u306A\u3057",
|
|
1243
|
-
trackUntitled: "\u30C8\u30E9\u30C3\u30AF {number}"
|
|
1316
|
+
trackUntitled: "\u30C8\u30E9\u30C3\u30AF {number}",
|
|
1317
|
+
currentlyPlaying: "\u518D\u751F\u4E2D",
|
|
1318
|
+
notPlaying: "\u505C\u6B62\u4E2D",
|
|
1319
|
+
pressEnterPlay: "Enter\u30AD\u30FC\u3067\u518D\u751F",
|
|
1320
|
+
pressEnterRestart: "Enter\u30AD\u30FC\u3067\u6700\u521D\u304B\u3089\u518D\u751F"
|
|
1244
1321
|
}
|
|
1245
1322
|
};
|
|
1246
1323
|
|
|
@@ -1949,13 +2026,15 @@ var ControlBar = class {
|
|
|
1949
2026
|
e.preventDefault();
|
|
1950
2027
|
e.stopPropagation();
|
|
1951
2028
|
const nextIndex = (currentIndex + 1) % menuItems.length;
|
|
1952
|
-
menuItems[nextIndex].focus();
|
|
2029
|
+
menuItems[nextIndex].focus({ preventScroll: false });
|
|
2030
|
+
menuItems[nextIndex].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
1953
2031
|
break;
|
|
1954
2032
|
case "ArrowUp":
|
|
1955
2033
|
e.preventDefault();
|
|
1956
2034
|
e.stopPropagation();
|
|
1957
2035
|
const prevIndex = (currentIndex - 1 + menuItems.length) % menuItems.length;
|
|
1958
|
-
menuItems[prevIndex].focus();
|
|
2036
|
+
menuItems[prevIndex].focus({ preventScroll: false });
|
|
2037
|
+
menuItems[prevIndex].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
1959
2038
|
break;
|
|
1960
2039
|
case "ArrowLeft":
|
|
1961
2040
|
case "ArrowRight":
|
|
@@ -1965,12 +2044,14 @@ var ControlBar = class {
|
|
|
1965
2044
|
case "Home":
|
|
1966
2045
|
e.preventDefault();
|
|
1967
2046
|
e.stopPropagation();
|
|
1968
|
-
menuItems[0].focus();
|
|
2047
|
+
menuItems[0].focus({ preventScroll: false });
|
|
2048
|
+
menuItems[0].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
1969
2049
|
break;
|
|
1970
2050
|
case "End":
|
|
1971
2051
|
e.preventDefault();
|
|
1972
2052
|
e.stopPropagation();
|
|
1973
|
-
menuItems[menuItems.length - 1].focus();
|
|
2053
|
+
menuItems[menuItems.length - 1].focus({ preventScroll: false });
|
|
2054
|
+
menuItems[menuItems.length - 1].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
1974
2055
|
break;
|
|
1975
2056
|
case "Enter":
|
|
1976
2057
|
case " ":
|
|
@@ -2121,20 +2202,27 @@ var ControlBar = class {
|
|
|
2121
2202
|
buttonContainer.appendChild(leftButtons);
|
|
2122
2203
|
buttonContainer.appendChild(this.rightButtons);
|
|
2123
2204
|
this.element.appendChild(buttonContainer);
|
|
2124
|
-
this.
|
|
2205
|
+
this.ensureButtonTooltips(buttonContainer);
|
|
2125
2206
|
}
|
|
2126
2207
|
/**
|
|
2127
2208
|
* Ensure all buttons in the controls have title attributes
|
|
2128
2209
|
* Uses aria-label as title if title is not present
|
|
2129
2210
|
*/
|
|
2130
|
-
|
|
2211
|
+
ensureButtonTooltips(container) {
|
|
2131
2212
|
const buttons = container.querySelectorAll("button");
|
|
2132
2213
|
buttons.forEach((button) => {
|
|
2133
|
-
if (
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2214
|
+
if (button.querySelector(`.${this.player.options.classPrefix}-tooltip`)) {
|
|
2215
|
+
return;
|
|
2216
|
+
}
|
|
2217
|
+
if (button.querySelector(`.${this.player.options.classPrefix}-button-text`)) {
|
|
2218
|
+
return;
|
|
2219
|
+
}
|
|
2220
|
+
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`)) {
|
|
2221
|
+
return;
|
|
2222
|
+
}
|
|
2223
|
+
const ariaLabel = button.getAttribute("aria-label");
|
|
2224
|
+
if (ariaLabel) {
|
|
2225
|
+
DOMUtils.attachTooltip(button, ariaLabel, this.player.options.classPrefix);
|
|
2138
2226
|
}
|
|
2139
2227
|
});
|
|
2140
2228
|
}
|
|
@@ -2234,7 +2322,6 @@ var ControlBar = class {
|
|
|
2234
2322
|
if (!this.isDraggingProgress) {
|
|
2235
2323
|
const { time } = updateProgress(e.clientX);
|
|
2236
2324
|
this.controls.progressTooltip.textContent = TimeUtils.formatTime(time);
|
|
2237
|
-
this.controls.progressTooltip.setAttribute("aria-label", TimeUtils.formatDuration(time));
|
|
2238
2325
|
this.controls.progressTooltip.style.left = `${e.clientX - progress.getBoundingClientRect().left}px`;
|
|
2239
2326
|
this.controls.progressTooltip.style.display = "block";
|
|
2240
2327
|
}
|
|
@@ -2707,7 +2794,7 @@ var ControlBar = class {
|
|
|
2707
2794
|
setTimeout(() => {
|
|
2708
2795
|
const firstItem = menu.querySelector(`.${this.player.options.classPrefix}-menu-item`);
|
|
2709
2796
|
if (firstItem) {
|
|
2710
|
-
firstItem.focus();
|
|
2797
|
+
firstItem.focus({ preventScroll: true });
|
|
2711
2798
|
}
|
|
2712
2799
|
}, 0);
|
|
2713
2800
|
}
|
|
@@ -2722,16 +2809,17 @@ var ControlBar = class {
|
|
|
2722
2809
|
this.attachMenuCloseHandler(menu, button);
|
|
2723
2810
|
}
|
|
2724
2811
|
createQualityButton() {
|
|
2812
|
+
const ariaLabel = i18n.t("player.quality");
|
|
2725
2813
|
const button = DOMUtils.createElement("button", {
|
|
2726
2814
|
className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-quality`,
|
|
2727
2815
|
attributes: {
|
|
2728
2816
|
"type": "button",
|
|
2729
|
-
"aria-label":
|
|
2730
|
-
"aria-expanded": "false"
|
|
2731
|
-
"title": i18n.t("player.quality")
|
|
2817
|
+
"aria-label": ariaLabel,
|
|
2818
|
+
"aria-expanded": "false"
|
|
2732
2819
|
}
|
|
2733
2820
|
});
|
|
2734
2821
|
button.appendChild(createIconElement("hd"));
|
|
2822
|
+
DOMUtils.attachTooltip(button, ariaLabel, this.player.options.classPrefix);
|
|
2735
2823
|
const qualityText = DOMUtils.createElement("span", {
|
|
2736
2824
|
className: `${this.player.options.classPrefix}-quality-text`,
|
|
2737
2825
|
textContent: ""
|
|
@@ -2830,7 +2918,7 @@ var ControlBar = class {
|
|
|
2830
2918
|
setTimeout(() => {
|
|
2831
2919
|
const focusTarget = activeItem || menu.querySelector(`.${this.player.options.classPrefix}-menu-item`);
|
|
2832
2920
|
if (focusTarget) {
|
|
2833
|
-
focusTarget.focus();
|
|
2921
|
+
focusTarget.focus({ preventScroll: true });
|
|
2834
2922
|
}
|
|
2835
2923
|
}, 0);
|
|
2836
2924
|
}
|
|
@@ -2852,13 +2940,13 @@ var ControlBar = class {
|
|
|
2852
2940
|
this.attachMenuCloseHandler(menu, button);
|
|
2853
2941
|
}
|
|
2854
2942
|
createCaptionStyleButton() {
|
|
2943
|
+
const ariaLabel = i18n.t("player.captionStyling");
|
|
2855
2944
|
const button = DOMUtils.createElement("button", {
|
|
2856
2945
|
className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-caption-style`,
|
|
2857
2946
|
attributes: {
|
|
2858
2947
|
"type": "button",
|
|
2859
|
-
"aria-label":
|
|
2860
|
-
"aria-expanded": "false"
|
|
2861
|
-
"title": i18n.t("player.captionStyling")
|
|
2948
|
+
"aria-label": ariaLabel,
|
|
2949
|
+
"aria-expanded": "false"
|
|
2862
2950
|
}
|
|
2863
2951
|
});
|
|
2864
2952
|
const textIcon = DOMUtils.createElement("span", {
|
|
@@ -2869,6 +2957,7 @@ var ControlBar = class {
|
|
|
2869
2957
|
}
|
|
2870
2958
|
});
|
|
2871
2959
|
button.appendChild(textIcon);
|
|
2960
|
+
DOMUtils.attachTooltip(button, ariaLabel, this.player.options.classPrefix);
|
|
2872
2961
|
button.addEventListener("click", () => {
|
|
2873
2962
|
this.showCaptionStyleMenu(button);
|
|
2874
2963
|
});
|
|
@@ -3221,7 +3310,7 @@ var ControlBar = class {
|
|
|
3221
3310
|
setTimeout(() => {
|
|
3222
3311
|
const focusTarget = activeItem || menu.querySelector(`.${this.player.options.classPrefix}-menu-item`);
|
|
3223
3312
|
if (focusTarget) {
|
|
3224
|
-
focusTarget.focus();
|
|
3313
|
+
focusTarget.focus({ preventScroll: true });
|
|
3225
3314
|
}
|
|
3226
3315
|
}, 0);
|
|
3227
3316
|
}
|
|
@@ -3324,7 +3413,7 @@ var ControlBar = class {
|
|
|
3324
3413
|
setTimeout(() => {
|
|
3325
3414
|
const focusTarget = activeItem || menu.querySelector(`.${this.player.options.classPrefix}-menu-item`);
|
|
3326
3415
|
if (focusTarget) {
|
|
3327
|
-
focusTarget.focus();
|
|
3416
|
+
focusTarget.focus({ preventScroll: true });
|
|
3328
3417
|
}
|
|
3329
3418
|
}, 0);
|
|
3330
3419
|
}
|
|
@@ -3359,17 +3448,18 @@ var ControlBar = class {
|
|
|
3359
3448
|
this.controls.transcript.setAttribute("aria-expanded", isVisible ? "true" : "false");
|
|
3360
3449
|
}
|
|
3361
3450
|
createAudioDescriptionButton() {
|
|
3451
|
+
const ariaLabel = i18n.t("player.audioDescription");
|
|
3362
3452
|
const button = DOMUtils.createElement("button", {
|
|
3363
3453
|
className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-audio-description`,
|
|
3364
3454
|
attributes: {
|
|
3365
3455
|
"type": "button",
|
|
3366
|
-
"aria-label":
|
|
3456
|
+
"aria-label": ariaLabel,
|
|
3367
3457
|
"role": "switch",
|
|
3368
|
-
"aria-checked": "false"
|
|
3369
|
-
"title": i18n.t("player.audioDescription")
|
|
3458
|
+
"aria-checked": "false"
|
|
3370
3459
|
}
|
|
3371
3460
|
});
|
|
3372
3461
|
button.appendChild(createIconElement("audioDescription"));
|
|
3462
|
+
DOMUtils.attachTooltip(button, ariaLabel, this.player.options.classPrefix);
|
|
3373
3463
|
button.addEventListener("click", async () => {
|
|
3374
3464
|
await this.player.toggleAudioDescription();
|
|
3375
3465
|
this.updateAudioDescriptionButton();
|
|
@@ -3385,16 +3475,17 @@ var ControlBar = class {
|
|
|
3385
3475
|
this.controls.audioDescription.setAttribute("aria-checked", isEnabled ? "true" : "false");
|
|
3386
3476
|
}
|
|
3387
3477
|
createSignLanguageButton() {
|
|
3478
|
+
const ariaLabel = i18n.t("player.signLanguage");
|
|
3388
3479
|
const button = DOMUtils.createElement("button", {
|
|
3389
3480
|
className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-sign-language`,
|
|
3390
3481
|
attributes: {
|
|
3391
3482
|
"type": "button",
|
|
3392
|
-
"aria-label":
|
|
3393
|
-
"aria-expanded": "false"
|
|
3394
|
-
"title": i18n.t("player.signLanguage")
|
|
3483
|
+
"aria-label": ariaLabel,
|
|
3484
|
+
"aria-expanded": "false"
|
|
3395
3485
|
}
|
|
3396
3486
|
});
|
|
3397
3487
|
button.appendChild(createIconElement("signLanguage"));
|
|
3488
|
+
DOMUtils.attachTooltip(button, ariaLabel, this.player.options.classPrefix);
|
|
3398
3489
|
button.addEventListener("click", () => {
|
|
3399
3490
|
this.player.toggleSignLanguage();
|
|
3400
3491
|
this.updateSignLanguageButton();
|
|
@@ -3413,6 +3504,60 @@ var ControlBar = class {
|
|
|
3413
3504
|
isEnabled ? i18n.t("signLanguage.hide") : i18n.t("signLanguage.show")
|
|
3414
3505
|
);
|
|
3415
3506
|
}
|
|
3507
|
+
/**
|
|
3508
|
+
* Update accessibility buttons visibility based on current track data.
|
|
3509
|
+
* Called when loading a new playlist track to show/hide buttons accordingly.
|
|
3510
|
+
*/
|
|
3511
|
+
updateAccessibilityButtons() {
|
|
3512
|
+
const hasAudioDescription = this.hasAudioDescription();
|
|
3513
|
+
const hasSignLanguage = this.hasSignLanguage();
|
|
3514
|
+
if (hasAudioDescription) {
|
|
3515
|
+
if (!this.controls.audioDescription && this.player.options.audioDescriptionButton !== false) {
|
|
3516
|
+
const btn = this.createAudioDescriptionButton();
|
|
3517
|
+
btn.dataset.overflowPriority = "2";
|
|
3518
|
+
btn.dataset.overflowPriorityMobile = "3";
|
|
3519
|
+
const transcriptBtn = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-transcript`);
|
|
3520
|
+
const playlistBtn = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-playlist-toggle`);
|
|
3521
|
+
const insertBefore = transcriptBtn || playlistBtn || null;
|
|
3522
|
+
if (insertBefore) {
|
|
3523
|
+
this.rightButtons.insertBefore(btn, insertBefore);
|
|
3524
|
+
} else {
|
|
3525
|
+
this.rightButtons.appendChild(btn);
|
|
3526
|
+
}
|
|
3527
|
+
this.setupOverflowMenu();
|
|
3528
|
+
}
|
|
3529
|
+
if (this.controls.audioDescription) {
|
|
3530
|
+
this.controls.audioDescription.style.display = "";
|
|
3531
|
+
}
|
|
3532
|
+
} else {
|
|
3533
|
+
if (this.controls.audioDescription) {
|
|
3534
|
+
this.controls.audioDescription.style.display = "none";
|
|
3535
|
+
}
|
|
3536
|
+
}
|
|
3537
|
+
if (hasSignLanguage) {
|
|
3538
|
+
if (!this.controls.signLanguage && this.player.options.signLanguageButton !== false) {
|
|
3539
|
+
const btn = this.createSignLanguageButton();
|
|
3540
|
+
btn.dataset.overflowPriority = "3";
|
|
3541
|
+
btn.dataset.overflowPriorityMobile = "3";
|
|
3542
|
+
const qualityBtn = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-quality`);
|
|
3543
|
+
const fullscreenBtn = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-fullscreen`);
|
|
3544
|
+
const insertBefore = qualityBtn || fullscreenBtn || null;
|
|
3545
|
+
if (insertBefore) {
|
|
3546
|
+
this.rightButtons.insertBefore(btn, insertBefore);
|
|
3547
|
+
} else {
|
|
3548
|
+
this.rightButtons.appendChild(btn);
|
|
3549
|
+
}
|
|
3550
|
+
this.setupOverflowMenu();
|
|
3551
|
+
}
|
|
3552
|
+
if (this.controls.signLanguage) {
|
|
3553
|
+
this.controls.signLanguage.style.display = "";
|
|
3554
|
+
}
|
|
3555
|
+
} else {
|
|
3556
|
+
if (this.controls.signLanguage) {
|
|
3557
|
+
this.controls.signLanguage.style.display = "none";
|
|
3558
|
+
}
|
|
3559
|
+
}
|
|
3560
|
+
}
|
|
3416
3561
|
createSettingsButton() {
|
|
3417
3562
|
const button = DOMUtils.createElement("button", {
|
|
3418
3563
|
className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-settings`,
|
|
@@ -3489,7 +3634,7 @@ var ControlBar = class {
|
|
|
3489
3634
|
icon.innerHTML = isPlaying ? createIconElement("pause").innerHTML : createIconElement("play").innerHTML;
|
|
3490
3635
|
const newAriaLabel = isPlaying ? i18n.t("player.pause") : i18n.t("player.play");
|
|
3491
3636
|
this.controls.playPause.setAttribute("aria-label", newAriaLabel);
|
|
3492
|
-
this.controls.playPause
|
|
3637
|
+
DOMUtils.attachTooltip(this.controls.playPause, newAriaLabel, this.player.options.classPrefix);
|
|
3493
3638
|
}
|
|
3494
3639
|
updateProgress() {
|
|
3495
3640
|
if (!this.controls.played) return;
|
|
@@ -3545,7 +3690,7 @@ var ControlBar = class {
|
|
|
3545
3690
|
icon.innerHTML = createIconElement(iconName).innerHTML;
|
|
3546
3691
|
const newMuteAriaLabel = this.player.state.muted ? i18n.t("player.unmute") : i18n.t("player.mute");
|
|
3547
3692
|
this.controls.mute.setAttribute("aria-label", newMuteAriaLabel);
|
|
3548
|
-
this.controls.mute
|
|
3693
|
+
DOMUtils.attachTooltip(this.controls.mute, newMuteAriaLabel, this.player.options.classPrefix);
|
|
3549
3694
|
}
|
|
3550
3695
|
}
|
|
3551
3696
|
if (this.controls.volumeSlider) {
|
|
@@ -3657,16 +3802,17 @@ var ControlBar = class {
|
|
|
3657
3802
|
showControls();
|
|
3658
3803
|
}
|
|
3659
3804
|
createOverflowMenuButton() {
|
|
3805
|
+
const ariaLabel = i18n.t("player.moreOptions");
|
|
3660
3806
|
const button = DOMUtils.createElement("button", {
|
|
3661
3807
|
className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-overflow-menu`,
|
|
3662
3808
|
attributes: {
|
|
3663
3809
|
"type": "button",
|
|
3664
|
-
"aria-label":
|
|
3665
|
-
"aria-expanded": "false"
|
|
3666
|
-
"title": i18n.t("player.moreOptions")
|
|
3810
|
+
"aria-label": ariaLabel,
|
|
3811
|
+
"aria-expanded": "false"
|
|
3667
3812
|
}
|
|
3668
3813
|
});
|
|
3669
3814
|
button.appendChild(createIconElement("moreVertical"));
|
|
3815
|
+
DOMUtils.attachTooltip(button, ariaLabel, this.player.options.classPrefix);
|
|
3670
3816
|
button.addEventListener("click", () => {
|
|
3671
3817
|
this.showOverflowMenu(button);
|
|
3672
3818
|
});
|
|
@@ -3748,7 +3894,7 @@ var ControlBar = class {
|
|
|
3748
3894
|
setTimeout(() => {
|
|
3749
3895
|
const firstItem = menu.querySelector(`.${this.player.options.classPrefix}-menu-item`);
|
|
3750
3896
|
if (firstItem && firstItem.tagName === "BUTTON") {
|
|
3751
|
-
firstItem.focus();
|
|
3897
|
+
firstItem.focus({ preventScroll: true });
|
|
3752
3898
|
}
|
|
3753
3899
|
}, 0);
|
|
3754
3900
|
}
|
|
@@ -4679,7 +4825,8 @@ function attachMenuKeyboardNavigation(menu, button, itemSelector, onClose) {
|
|
|
4679
4825
|
menuItems.forEach((item, idx) => {
|
|
4680
4826
|
item.setAttribute("tabindex", idx === nextIndex ? "0" : "-1");
|
|
4681
4827
|
});
|
|
4682
|
-
menuItems[nextIndex].focus();
|
|
4828
|
+
menuItems[nextIndex].focus({ preventScroll: false });
|
|
4829
|
+
menuItems[nextIndex].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
4683
4830
|
break;
|
|
4684
4831
|
case "ArrowUp":
|
|
4685
4832
|
e.preventDefault();
|
|
@@ -4688,7 +4835,8 @@ function attachMenuKeyboardNavigation(menu, button, itemSelector, onClose) {
|
|
|
4688
4835
|
menuItems.forEach((item, idx) => {
|
|
4689
4836
|
item.setAttribute("tabindex", idx === prevIndex ? "0" : "-1");
|
|
4690
4837
|
});
|
|
4691
|
-
menuItems[prevIndex].focus();
|
|
4838
|
+
menuItems[prevIndex].focus({ preventScroll: false });
|
|
4839
|
+
menuItems[prevIndex].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
4692
4840
|
break;
|
|
4693
4841
|
case "Home":
|
|
4694
4842
|
e.preventDefault();
|
|
@@ -4696,7 +4844,8 @@ function attachMenuKeyboardNavigation(menu, button, itemSelector, onClose) {
|
|
|
4696
4844
|
menuItems.forEach((item, idx) => {
|
|
4697
4845
|
item.setAttribute("tabindex", idx === 0 ? "0" : "-1");
|
|
4698
4846
|
});
|
|
4699
|
-
menuItems[0].focus();
|
|
4847
|
+
menuItems[0].focus({ preventScroll: false });
|
|
4848
|
+
menuItems[0].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
4700
4849
|
break;
|
|
4701
4850
|
case "End":
|
|
4702
4851
|
e.preventDefault();
|
|
@@ -4705,7 +4854,8 @@ function attachMenuKeyboardNavigation(menu, button, itemSelector, onClose) {
|
|
|
4705
4854
|
menuItems.forEach((item, idx) => {
|
|
4706
4855
|
item.setAttribute("tabindex", idx === lastIndex ? "0" : "-1");
|
|
4707
4856
|
});
|
|
4708
|
-
menuItems[lastIndex].focus();
|
|
4857
|
+
menuItems[lastIndex].focus({ preventScroll: false });
|
|
4858
|
+
menuItems[lastIndex].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
4709
4859
|
break;
|
|
4710
4860
|
case "Enter":
|
|
4711
4861
|
case " ":
|
|
@@ -4743,6 +4893,7 @@ function focusFirstMenuItem(menu, itemSelector, delay = 0) {
|
|
|
4743
4893
|
item.setAttribute("tabindex", index === 0 ? "0" : "-1");
|
|
4744
4894
|
});
|
|
4745
4895
|
focusElement(menuItems[0], { delay: 0 });
|
|
4896
|
+
menuItems[0].scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
4746
4897
|
}
|
|
4747
4898
|
}, delay);
|
|
4748
4899
|
}
|
|
@@ -5535,7 +5686,7 @@ var TranscriptManager = class {
|
|
|
5535
5686
|
if (focusButton) {
|
|
5536
5687
|
const transcriptButton = (_b = (_a = this.player.controlBar) == null ? void 0 : _a.controls) == null ? void 0 : _b.transcript;
|
|
5537
5688
|
if (transcriptButton && typeof transcriptButton.focus === "function") {
|
|
5538
|
-
transcriptButton.focus();
|
|
5689
|
+
transcriptButton.focus({ preventScroll: true });
|
|
5539
5690
|
}
|
|
5540
5691
|
}
|
|
5541
5692
|
}
|
|
@@ -5560,15 +5711,17 @@ var TranscriptManager = class {
|
|
|
5560
5711
|
this.headerLeft = DOMUtils.createElement("div", {
|
|
5561
5712
|
className: `${this.player.options.classPrefix}-transcript-header-left`
|
|
5562
5713
|
});
|
|
5714
|
+
const settingsAriaLabel = i18n.t("transcript.settingsMenu");
|
|
5563
5715
|
this.settingsButton = DOMUtils.createElement("button", {
|
|
5564
5716
|
className: `${this.player.options.classPrefix}-transcript-settings`,
|
|
5565
5717
|
attributes: {
|
|
5566
5718
|
"type": "button",
|
|
5567
|
-
"aria-label":
|
|
5719
|
+
"aria-label": settingsAriaLabel,
|
|
5568
5720
|
"aria-expanded": "false"
|
|
5569
5721
|
}
|
|
5570
5722
|
});
|
|
5571
5723
|
this.settingsButton.appendChild(createIconElement("settings"));
|
|
5724
|
+
DOMUtils.attachTooltip(this.settingsButton, settingsAriaLabel, this.player.options.classPrefix);
|
|
5572
5725
|
this.handlers.settingsClick = (e) => {
|
|
5573
5726
|
e.preventDefault();
|
|
5574
5727
|
e.stopPropagation();
|
|
@@ -5602,8 +5755,7 @@ var TranscriptManager = class {
|
|
|
5602
5755
|
const autoscrollLabel = DOMUtils.createElement("label", {
|
|
5603
5756
|
className: `${this.player.options.classPrefix}-transcript-autoscroll-label`,
|
|
5604
5757
|
attributes: {
|
|
5605
|
-
"for": autoscrollId
|
|
5606
|
-
"title": i18n.t("transcript.autoscroll")
|
|
5758
|
+
"for": autoscrollId
|
|
5607
5759
|
}
|
|
5608
5760
|
});
|
|
5609
5761
|
this.autoscrollCheckbox = DOMUtils.createElement("input", {
|
|
@@ -5652,14 +5804,16 @@ var TranscriptManager = class {
|
|
|
5652
5804
|
this.languageSelectorWrapper = languageSelectorWrapper;
|
|
5653
5805
|
preventDragOnElement(languageSelectorWrapper);
|
|
5654
5806
|
this.headerLeft.appendChild(languageSelectorWrapper);
|
|
5807
|
+
const closeAriaLabel = i18n.t("transcript.close");
|
|
5655
5808
|
const closeButton = DOMUtils.createElement("button", {
|
|
5656
5809
|
className: `${this.player.options.classPrefix}-transcript-close`,
|
|
5657
5810
|
attributes: {
|
|
5658
5811
|
"type": "button",
|
|
5659
|
-
"aria-label":
|
|
5812
|
+
"aria-label": closeAriaLabel
|
|
5660
5813
|
}
|
|
5661
5814
|
});
|
|
5662
5815
|
closeButton.appendChild(createIconElement("close"));
|
|
5816
|
+
DOMUtils.attachTooltip(closeButton, closeAriaLabel, this.player.options.classPrefix);
|
|
5663
5817
|
closeButton.addEventListener("click", () => this.hideTranscript({ focusButton: true }));
|
|
5664
5818
|
this.transcriptHeader.appendChild(this.headerLeft);
|
|
5665
5819
|
this.transcriptHeader.appendChild(closeButton);
|
|
@@ -6106,7 +6260,7 @@ var TranscriptManager = class {
|
|
|
6106
6260
|
console.log("[VidPly Metadata] Focusing element:", targetSelector);
|
|
6107
6261
|
}
|
|
6108
6262
|
this.setManagedTimeout(() => {
|
|
6109
|
-
targetElement.focus();
|
|
6263
|
+
targetElement.focus({ preventScroll: true });
|
|
6110
6264
|
}, 10);
|
|
6111
6265
|
} else if (this.player.options.debug) {
|
|
6112
6266
|
console.warn("[VidPly Metadata] Element not found:", targetSelector);
|
|
@@ -6321,7 +6475,7 @@ var TranscriptManager = class {
|
|
|
6321
6475
|
e.stopPropagation();
|
|
6322
6476
|
const enabled = this.toggleResizeMode();
|
|
6323
6477
|
if (enabled) {
|
|
6324
|
-
this.transcriptWindow.focus();
|
|
6478
|
+
this.transcriptWindow.focus({ preventScroll: true });
|
|
6325
6479
|
}
|
|
6326
6480
|
return;
|
|
6327
6481
|
}
|
|
@@ -6362,7 +6516,7 @@ var TranscriptManager = class {
|
|
|
6362
6516
|
if (this.settingsMenuVisible) {
|
|
6363
6517
|
this.hideSettingsMenu();
|
|
6364
6518
|
}
|
|
6365
|
-
this.transcriptWindow.focus();
|
|
6519
|
+
this.transcriptWindow.focus({ preventScroll: true });
|
|
6366
6520
|
}
|
|
6367
6521
|
}
|
|
6368
6522
|
/**
|
|
@@ -6405,7 +6559,7 @@ var TranscriptManager = class {
|
|
|
6405
6559
|
for (let i = 1; i < menuItems.length; i++) {
|
|
6406
6560
|
menuItems[i].setAttribute("tabindex", "-1");
|
|
6407
6561
|
}
|
|
6408
|
-
menuItems[0].focus();
|
|
6562
|
+
menuItems[0].focus({ preventScroll: true });
|
|
6409
6563
|
}
|
|
6410
6564
|
}, 50);
|
|
6411
6565
|
return;
|
|
@@ -6429,6 +6583,10 @@ var TranscriptManager = class {
|
|
|
6429
6583
|
});
|
|
6430
6584
|
keyboardDragOption.setAttribute("role", "switch");
|
|
6431
6585
|
keyboardDragOption.setAttribute("aria-checked", "false");
|
|
6586
|
+
const dragTooltip = keyboardDragOption.querySelector(`.${this.player.options.classPrefix}-tooltip`);
|
|
6587
|
+
if (dragTooltip) dragTooltip.remove();
|
|
6588
|
+
const dragButtonText = keyboardDragOption.querySelector(`.${this.player.options.classPrefix}-button-text`);
|
|
6589
|
+
if (dragButtonText) dragButtonText.remove();
|
|
6432
6590
|
this.dragOptionButton = keyboardDragOption;
|
|
6433
6591
|
this.dragOptionText = keyboardDragOption.querySelector(`.${this.player.options.classPrefix}-settings-text`);
|
|
6434
6592
|
this.updateDragOptionState();
|
|
@@ -6446,6 +6604,10 @@ var TranscriptManager = class {
|
|
|
6446
6604
|
}, 50);
|
|
6447
6605
|
}
|
|
6448
6606
|
});
|
|
6607
|
+
const styleTooltip = styleOption.querySelector(`.${this.player.options.classPrefix}-tooltip`);
|
|
6608
|
+
if (styleTooltip) styleTooltip.remove();
|
|
6609
|
+
const styleButtonText = styleOption.querySelector(`.${this.player.options.classPrefix}-button-text`);
|
|
6610
|
+
if (styleButtonText) styleButtonText.remove();
|
|
6449
6611
|
const resizeOption = createMenuItem({
|
|
6450
6612
|
classPrefix: this.player.options.classPrefix,
|
|
6451
6613
|
itemClass: `${this.player.options.classPrefix}-transcript-settings-item`,
|
|
@@ -6460,7 +6622,7 @@ var TranscriptManager = class {
|
|
|
6460
6622
|
this.hideSettingsMenu({ focusButton: false });
|
|
6461
6623
|
setTimeout(() => {
|
|
6462
6624
|
if (this.transcriptWindow) {
|
|
6463
|
-
this.transcriptWindow.focus();
|
|
6625
|
+
this.transcriptWindow.focus({ preventScroll: true });
|
|
6464
6626
|
}
|
|
6465
6627
|
}, 20);
|
|
6466
6628
|
} else {
|
|
@@ -6470,6 +6632,10 @@ var TranscriptManager = class {
|
|
|
6470
6632
|
});
|
|
6471
6633
|
resizeOption.setAttribute("role", "switch");
|
|
6472
6634
|
resizeOption.setAttribute("aria-checked", "false");
|
|
6635
|
+
const resizeTooltip = resizeOption.querySelector(`.${this.player.options.classPrefix}-tooltip`);
|
|
6636
|
+
if (resizeTooltip) resizeTooltip.remove();
|
|
6637
|
+
const resizeButtonText = resizeOption.querySelector(`.${this.player.options.classPrefix}-button-text`);
|
|
6638
|
+
if (resizeButtonText) resizeButtonText.remove();
|
|
6473
6639
|
this.resizeOptionButton = resizeOption;
|
|
6474
6640
|
this.resizeOptionText = resizeOption.querySelector(`.${this.player.options.classPrefix}-settings-text`);
|
|
6475
6641
|
this.updateResizeOptionState();
|
|
@@ -6485,6 +6651,10 @@ var TranscriptManager = class {
|
|
|
6485
6651
|
});
|
|
6486
6652
|
showTimestampsOption.setAttribute("role", "switch");
|
|
6487
6653
|
showTimestampsOption.setAttribute("aria-checked", this.showTimestamps ? "true" : "false");
|
|
6654
|
+
const timestampsTooltip = showTimestampsOption.querySelector(`.${this.player.options.classPrefix}-tooltip`);
|
|
6655
|
+
if (timestampsTooltip) timestampsTooltip.remove();
|
|
6656
|
+
const timestampsButtonText = showTimestampsOption.querySelector(`.${this.player.options.classPrefix}-button-text`);
|
|
6657
|
+
if (timestampsButtonText) timestampsButtonText.remove();
|
|
6488
6658
|
this.showTimestampsButton = showTimestampsOption;
|
|
6489
6659
|
this.showTimestampsText = showTimestampsOption.querySelector(`.${this.player.options.classPrefix}-settings-text`);
|
|
6490
6660
|
this.updateShowTimestampsState();
|
|
@@ -6497,6 +6667,10 @@ var TranscriptManager = class {
|
|
|
6497
6667
|
this.hideSettingsMenu();
|
|
6498
6668
|
}
|
|
6499
6669
|
});
|
|
6670
|
+
const closeTooltip = closeOption.querySelector(`.${this.player.options.classPrefix}-tooltip`);
|
|
6671
|
+
if (closeTooltip) closeTooltip.remove();
|
|
6672
|
+
const closeButtonText = closeOption.querySelector(`.${this.player.options.classPrefix}-button-text`);
|
|
6673
|
+
if (closeButtonText) closeButtonText.remove();
|
|
6500
6674
|
this.settingsMenu.appendChild(keyboardDragOption);
|
|
6501
6675
|
this.settingsMenu.appendChild(resizeOption);
|
|
6502
6676
|
this.settingsMenu.appendChild(styleOption);
|
|
@@ -6538,7 +6712,7 @@ var TranscriptManager = class {
|
|
|
6538
6712
|
for (let i = 1; i < menuItems.length; i++) {
|
|
6539
6713
|
menuItems[i].setAttribute("tabindex", "-1");
|
|
6540
6714
|
}
|
|
6541
|
-
menuItems[0].focus();
|
|
6715
|
+
menuItems[0].focus({ preventScroll: true });
|
|
6542
6716
|
}
|
|
6543
6717
|
}, 50);
|
|
6544
6718
|
}
|
|
@@ -6612,7 +6786,7 @@ var TranscriptManager = class {
|
|
|
6612
6786
|
if (this.settingsButton) {
|
|
6613
6787
|
this.settingsButton.setAttribute("aria-expanded", "false");
|
|
6614
6788
|
if (focusButton) {
|
|
6615
|
-
this.settingsButton.focus();
|
|
6789
|
+
this.settingsButton.focus({ preventScroll: true });
|
|
6616
6790
|
}
|
|
6617
6791
|
}
|
|
6618
6792
|
}
|
|
@@ -6658,7 +6832,6 @@ var TranscriptManager = class {
|
|
|
6658
6832
|
const ariaLabel = isEnabled ? i18n.t("transcript.disableDragModeAria") : i18n.t("transcript.enableDragModeAria");
|
|
6659
6833
|
this.dragOptionButton.setAttribute("aria-checked", isEnabled ? "true" : "false");
|
|
6660
6834
|
this.dragOptionButton.setAttribute("aria-label", ariaLabel);
|
|
6661
|
-
this.dragOptionButton.setAttribute("title", text);
|
|
6662
6835
|
if (this.dragOptionText) {
|
|
6663
6836
|
this.dragOptionText.textContent = text;
|
|
6664
6837
|
}
|
|
@@ -6672,7 +6845,6 @@ var TranscriptManager = class {
|
|
|
6672
6845
|
const ariaLabel = isEnabled ? i18n.t("transcript.disableResizeModeAria") : i18n.t("transcript.enableResizeModeAria");
|
|
6673
6846
|
this.resizeOptionButton.setAttribute("aria-checked", isEnabled ? "true" : "false");
|
|
6674
6847
|
this.resizeOptionButton.setAttribute("aria-label", ariaLabel);
|
|
6675
|
-
this.resizeOptionButton.setAttribute("title", text);
|
|
6676
6848
|
if (this.resizeOptionText) {
|
|
6677
6849
|
this.resizeOptionText.textContent = text;
|
|
6678
6850
|
}
|
|
@@ -6691,7 +6863,6 @@ var TranscriptManager = class {
|
|
|
6691
6863
|
const ariaLabel = this.showTimestamps ? i18n.t("transcript.hideTimestampsAria") : i18n.t("transcript.showTimestampsAria");
|
|
6692
6864
|
this.showTimestampsButton.setAttribute("aria-checked", this.showTimestamps ? "true" : "false");
|
|
6693
6865
|
this.showTimestampsButton.setAttribute("aria-label", ariaLabel);
|
|
6694
|
-
this.showTimestampsButton.setAttribute("title", text);
|
|
6695
6866
|
if (this.showTimestampsText) {
|
|
6696
6867
|
this.showTimestampsText.textContent = text;
|
|
6697
6868
|
}
|
|
@@ -6760,7 +6931,7 @@ var TranscriptManager = class {
|
|
|
6760
6931
|
setTimeout(() => {
|
|
6761
6932
|
const firstSelect = this.styleDialog.querySelector("select, input");
|
|
6762
6933
|
if (firstSelect) {
|
|
6763
|
-
firstSelect.focus();
|
|
6934
|
+
firstSelect.focus({ preventScroll: true });
|
|
6764
6935
|
}
|
|
6765
6936
|
}, 0);
|
|
6766
6937
|
return;
|
|
@@ -6825,10 +6996,10 @@ var TranscriptManager = class {
|
|
|
6825
6996
|
const lastElement = focusableElements[focusableElements.length - 1];
|
|
6826
6997
|
if (e.shiftKey && document.activeElement === firstElement) {
|
|
6827
6998
|
e.preventDefault();
|
|
6828
|
-
lastElement.focus();
|
|
6999
|
+
lastElement.focus({ preventScroll: true });
|
|
6829
7000
|
} else if (!e.shiftKey && document.activeElement === lastElement) {
|
|
6830
7001
|
e.preventDefault();
|
|
6831
|
-
firstElement.focus();
|
|
7002
|
+
firstElement.focus({ preventScroll: true });
|
|
6832
7003
|
}
|
|
6833
7004
|
}
|
|
6834
7005
|
};
|
|
@@ -6848,7 +7019,7 @@ var TranscriptManager = class {
|
|
|
6848
7019
|
setTimeout(() => {
|
|
6849
7020
|
const firstSelect = this.styleDialog.querySelector("select, input");
|
|
6850
7021
|
if (firstSelect) {
|
|
6851
|
-
firstSelect.focus();
|
|
7022
|
+
firstSelect.focus({ preventScroll: true });
|
|
6852
7023
|
}
|
|
6853
7024
|
}, 0);
|
|
6854
7025
|
}
|
|
@@ -6863,7 +7034,7 @@ var TranscriptManager = class {
|
|
|
6863
7034
|
document.removeEventListener("keydown", this.handlers.styleDialogKeydown);
|
|
6864
7035
|
}
|
|
6865
7036
|
if (this.settingsButton) {
|
|
6866
|
-
this.settingsButton.focus();
|
|
7037
|
+
this.settingsButton.focus({ preventScroll: true });
|
|
6867
7038
|
}
|
|
6868
7039
|
}
|
|
6869
7040
|
}
|
|
@@ -8427,7 +8598,12 @@ var Player = class _Player extends EventEmitter {
|
|
|
8427
8598
|
if (trackConfig.default) {
|
|
8428
8599
|
track.default = true;
|
|
8429
8600
|
}
|
|
8430
|
-
this.element.
|
|
8601
|
+
const firstChild = this.element.firstChild;
|
|
8602
|
+
if (firstChild && firstChild.nodeType === Node.ELEMENT_NODE && firstChild.tagName !== "TRACK") {
|
|
8603
|
+
this.element.insertBefore(track, firstChild);
|
|
8604
|
+
} else {
|
|
8605
|
+
this.element.appendChild(track);
|
|
8606
|
+
}
|
|
8431
8607
|
});
|
|
8432
8608
|
this.invalidateTrackCache();
|
|
8433
8609
|
}
|
|
@@ -9028,6 +9204,11 @@ var Player = class _Player extends EventEmitter {
|
|
|
9028
9204
|
});
|
|
9029
9205
|
}
|
|
9030
9206
|
});
|
|
9207
|
+
const hasSrcAttribute = this.element.hasAttribute("src");
|
|
9208
|
+
const srcValue = hasSrcAttribute ? this.element.getAttribute("src") : null;
|
|
9209
|
+
if (hasSrcAttribute) {
|
|
9210
|
+
this.element.removeAttribute("src");
|
|
9211
|
+
}
|
|
9031
9212
|
allSourceElements.forEach((sourceEl) => {
|
|
9032
9213
|
sourceEl.remove();
|
|
9033
9214
|
});
|
|
@@ -9184,7 +9365,10 @@ var Player = class _Player extends EventEmitter {
|
|
|
9184
9365
|
newTrackElement.setAttribute(attrName, attributes[attrName]);
|
|
9185
9366
|
}
|
|
9186
9367
|
});
|
|
9187
|
-
|
|
9368
|
+
const firstChild = parent.firstChild;
|
|
9369
|
+
if (firstChild && firstChild.nodeType === Node.ELEMENT_NODE && firstChild.tagName !== "TRACK") {
|
|
9370
|
+
parent.insertBefore(newTrackElement, firstChild);
|
|
9371
|
+
} else if (nextSibling && nextSibling.parentNode) {
|
|
9188
9372
|
parent.insertBefore(newTrackElement, nextSibling);
|
|
9189
9373
|
} else {
|
|
9190
9374
|
parent.appendChild(newTrackElement);
|
|
@@ -9656,6 +9840,11 @@ var Player = class _Player extends EventEmitter {
|
|
|
9656
9840
|
});
|
|
9657
9841
|
}
|
|
9658
9842
|
});
|
|
9843
|
+
const hasSrcAttribute = this.element.hasAttribute("src");
|
|
9844
|
+
const srcValue = hasSrcAttribute ? this.element.getAttribute("src") : null;
|
|
9845
|
+
if (hasSrcAttribute) {
|
|
9846
|
+
this.element.removeAttribute("src");
|
|
9847
|
+
}
|
|
9659
9848
|
allSourceElements.forEach((sourceEl) => {
|
|
9660
9849
|
sourceEl.remove();
|
|
9661
9850
|
});
|
|
@@ -9946,15 +10135,17 @@ var Player = class _Player extends EventEmitter {
|
|
|
9946
10135
|
const title = DOMUtils.createElement("h3", {
|
|
9947
10136
|
textContent: i18n.t("player.signLanguageVideo")
|
|
9948
10137
|
});
|
|
10138
|
+
const settingsAriaLabel = i18n.t("player.signLanguageSettings");
|
|
9949
10139
|
this.signLanguageSettingsButton = DOMUtils.createElement("button", {
|
|
9950
10140
|
className: `${this.options.classPrefix}-sign-language-settings`,
|
|
9951
10141
|
attributes: {
|
|
9952
10142
|
"type": "button",
|
|
9953
|
-
"aria-label":
|
|
10143
|
+
"aria-label": settingsAriaLabel,
|
|
9954
10144
|
"aria-expanded": "false"
|
|
9955
10145
|
}
|
|
9956
10146
|
});
|
|
9957
10147
|
this.signLanguageSettingsButton.appendChild(createIconElement("settings"));
|
|
10148
|
+
DOMUtils.attachTooltip(this.signLanguageSettingsButton, settingsAriaLabel, this.options.classPrefix);
|
|
9958
10149
|
this.signLanguageSettingsHandlers = {
|
|
9959
10150
|
settingsClick: (e) => {
|
|
9960
10151
|
e.preventDefault();
|
|
@@ -10022,19 +10213,21 @@ var Player = class _Player extends EventEmitter {
|
|
|
10022
10213
|
headerLeft.appendChild(signLanguageSelectorWrapper);
|
|
10023
10214
|
}
|
|
10024
10215
|
headerLeft.appendChild(title);
|
|
10216
|
+
const closeAriaLabel = i18n.t("player.closeSignLanguage");
|
|
10025
10217
|
const closeButton = DOMUtils.createElement("button", {
|
|
10026
10218
|
className: `${this.options.classPrefix}-sign-language-close`,
|
|
10027
10219
|
attributes: {
|
|
10028
10220
|
"type": "button",
|
|
10029
|
-
"aria-label":
|
|
10221
|
+
"aria-label": closeAriaLabel
|
|
10030
10222
|
}
|
|
10031
10223
|
});
|
|
10032
10224
|
closeButton.appendChild(createIconElement("close"));
|
|
10225
|
+
DOMUtils.attachTooltip(closeButton, closeAriaLabel, this.options.classPrefix);
|
|
10033
10226
|
closeButton.addEventListener("click", () => {
|
|
10034
10227
|
this.disableSignLanguage();
|
|
10035
10228
|
if (this.controlBar && this.controlBar.controls && this.controlBar.controls.signLanguage) {
|
|
10036
10229
|
setTimeout(() => {
|
|
10037
|
-
this.controlBar.controls.signLanguage.focus();
|
|
10230
|
+
this.controlBar.controls.signLanguage.focus({ preventScroll: true });
|
|
10038
10231
|
}, 0);
|
|
10039
10232
|
}
|
|
10040
10233
|
});
|
|
@@ -10212,7 +10405,7 @@ var Player = class _Player extends EventEmitter {
|
|
|
10212
10405
|
e.stopPropagation();
|
|
10213
10406
|
const enabled = this.toggleSignLanguageResizeMode();
|
|
10214
10407
|
if (enabled) {
|
|
10215
|
-
this.signLanguageWrapper.focus();
|
|
10408
|
+
this.signLanguageWrapper.focus({ preventScroll: true });
|
|
10216
10409
|
}
|
|
10217
10410
|
return;
|
|
10218
10411
|
}
|
|
@@ -10230,7 +10423,7 @@ var Player = class _Player extends EventEmitter {
|
|
|
10230
10423
|
this.disableSignLanguage();
|
|
10231
10424
|
if (this.controlBar && this.controlBar.controls && this.controlBar.controls.signLanguage) {
|
|
10232
10425
|
setTimeout(() => {
|
|
10233
|
-
this.controlBar.controls.signLanguage.focus();
|
|
10426
|
+
this.controlBar.controls.signLanguage.focus({ preventScroll: true });
|
|
10234
10427
|
}, 0);
|
|
10235
10428
|
}
|
|
10236
10429
|
return;
|
|
@@ -10365,6 +10558,10 @@ var Player = class _Player extends EventEmitter {
|
|
|
10365
10558
|
});
|
|
10366
10559
|
keyboardDragOption.setAttribute("role", "switch");
|
|
10367
10560
|
keyboardDragOption.setAttribute("aria-checked", "false");
|
|
10561
|
+
const dragTooltip = keyboardDragOption.querySelector(`.${this.options.classPrefix}-tooltip`);
|
|
10562
|
+
if (dragTooltip) dragTooltip.remove();
|
|
10563
|
+
const dragButtonText = keyboardDragOption.querySelector(`.${this.options.classPrefix}-button-text`);
|
|
10564
|
+
if (dragButtonText) dragButtonText.remove();
|
|
10368
10565
|
this.signLanguageDragOptionButton = keyboardDragOption;
|
|
10369
10566
|
this.signLanguageDragOptionText = keyboardDragOption.querySelector(`.${this.options.classPrefix}-settings-text`);
|
|
10370
10567
|
this.updateSignLanguageDragOptionState();
|
|
@@ -10382,7 +10579,7 @@ var Player = class _Player extends EventEmitter {
|
|
|
10382
10579
|
this.hideSignLanguageSettingsMenu({ focusButton: false });
|
|
10383
10580
|
setTimeout(() => {
|
|
10384
10581
|
if (this.signLanguageWrapper) {
|
|
10385
|
-
this.signLanguageWrapper.focus();
|
|
10582
|
+
this.signLanguageWrapper.focus({ preventScroll: true });
|
|
10386
10583
|
}
|
|
10387
10584
|
}, 20);
|
|
10388
10585
|
} else {
|
|
@@ -10392,6 +10589,10 @@ var Player = class _Player extends EventEmitter {
|
|
|
10392
10589
|
});
|
|
10393
10590
|
resizeOption.setAttribute("role", "switch");
|
|
10394
10591
|
resizeOption.setAttribute("aria-checked", "false");
|
|
10592
|
+
const resizeTooltip = resizeOption.querySelector(`.${this.options.classPrefix}-tooltip`);
|
|
10593
|
+
if (resizeTooltip) resizeTooltip.remove();
|
|
10594
|
+
const resizeButtonText = resizeOption.querySelector(`.${this.options.classPrefix}-button-text`);
|
|
10595
|
+
if (resizeButtonText) resizeButtonText.remove();
|
|
10395
10596
|
this.signLanguageResizeOptionButton = resizeOption;
|
|
10396
10597
|
this.signLanguageResizeOptionText = resizeOption.querySelector(`.${this.options.classPrefix}-settings-text`);
|
|
10397
10598
|
this.updateSignLanguageResizeOptionState();
|
|
@@ -10404,6 +10605,10 @@ var Player = class _Player extends EventEmitter {
|
|
|
10404
10605
|
this.hideSignLanguageSettingsMenu();
|
|
10405
10606
|
}
|
|
10406
10607
|
});
|
|
10608
|
+
const closeTooltip = closeOption.querySelector(`.${this.options.classPrefix}-tooltip`);
|
|
10609
|
+
if (closeTooltip) closeTooltip.remove();
|
|
10610
|
+
const closeButtonText = closeOption.querySelector(`.${this.options.classPrefix}-button-text`);
|
|
10611
|
+
if (closeButtonText) closeButtonText.remove();
|
|
10407
10612
|
this.signLanguageSettingsMenu.appendChild(keyboardDragOption);
|
|
10408
10613
|
this.signLanguageSettingsMenu.appendChild(resizeOption);
|
|
10409
10614
|
this.signLanguageSettingsMenu.appendChild(closeOption);
|
|
@@ -10450,7 +10655,7 @@ var Player = class _Player extends EventEmitter {
|
|
|
10450
10655
|
if (this.signLanguageSettingsButton) {
|
|
10451
10656
|
this.signLanguageSettingsButton.setAttribute("aria-expanded", "false");
|
|
10452
10657
|
if (focusButton) {
|
|
10453
|
-
this.signLanguageSettingsButton.focus();
|
|
10658
|
+
this.signLanguageSettingsButton.focus({ preventScroll: true });
|
|
10454
10659
|
}
|
|
10455
10660
|
}
|
|
10456
10661
|
}
|
|
@@ -10539,7 +10744,6 @@ var Player = class _Player extends EventEmitter {
|
|
|
10539
10744
|
const ariaLabel = isEnabled ? i18n.t("player.disableSignDragModeAria") : i18n.t("player.enableSignDragModeAria");
|
|
10540
10745
|
this.signLanguageDragOptionButton.setAttribute("aria-checked", isEnabled ? "true" : "false");
|
|
10541
10746
|
this.signLanguageDragOptionButton.setAttribute("aria-label", ariaLabel);
|
|
10542
|
-
this.signLanguageDragOptionButton.setAttribute("title", text);
|
|
10543
10747
|
if (this.signLanguageDragOptionText) {
|
|
10544
10748
|
this.signLanguageDragOptionText.textContent = text;
|
|
10545
10749
|
}
|
|
@@ -10553,7 +10757,6 @@ var Player = class _Player extends EventEmitter {
|
|
|
10553
10757
|
const ariaLabel = isEnabled ? i18n.t("player.disableSignResizeModeAria") : i18n.t("player.enableSignResizeModeAria");
|
|
10554
10758
|
this.signLanguageResizeOptionButton.setAttribute("aria-checked", isEnabled ? "true" : "false");
|
|
10555
10759
|
this.signLanguageResizeOptionButton.setAttribute("aria-label", ariaLabel);
|
|
10556
|
-
this.signLanguageResizeOptionButton.setAttribute("title", text);
|
|
10557
10760
|
if (this.signLanguageResizeOptionText) {
|
|
10558
10761
|
this.signLanguageResizeOptionText.textContent = text;
|
|
10559
10762
|
}
|
|
@@ -10987,23 +11190,23 @@ var Player = class _Player extends EventEmitter {
|
|
|
10987
11190
|
return;
|
|
10988
11191
|
}
|
|
10989
11192
|
if (target === "alert" && fallbackElement) {
|
|
10990
|
-
fallbackElement.focus();
|
|
11193
|
+
fallbackElement.focus({ preventScroll: true });
|
|
10991
11194
|
return;
|
|
10992
11195
|
}
|
|
10993
11196
|
if (target === "player") {
|
|
10994
11197
|
if (this.container) {
|
|
10995
|
-
this.container.focus();
|
|
11198
|
+
this.container.focus({ preventScroll: true });
|
|
10996
11199
|
}
|
|
10997
11200
|
return;
|
|
10998
11201
|
}
|
|
10999
11202
|
if (target === "media") {
|
|
11000
|
-
this.element.focus();
|
|
11203
|
+
this.element.focus({ preventScroll: true });
|
|
11001
11204
|
return;
|
|
11002
11205
|
}
|
|
11003
11206
|
if (target === "playButton") {
|
|
11004
11207
|
const playButton = (_b = (_a = this.controlBar) == null ? void 0 : _a.controls) == null ? void 0 : _b.playPause;
|
|
11005
11208
|
if (playButton) {
|
|
11006
|
-
playButton.focus();
|
|
11209
|
+
playButton.focus({ preventScroll: true });
|
|
11007
11210
|
}
|
|
11008
11211
|
return;
|
|
11009
11212
|
}
|
|
@@ -11013,7 +11216,7 @@ var Player = class _Player extends EventEmitter {
|
|
|
11013
11216
|
if (targetElement.tabIndex === -1 && !targetElement.hasAttribute("tabindex")) {
|
|
11014
11217
|
targetElement.setAttribute("tabindex", "-1");
|
|
11015
11218
|
}
|
|
11016
|
-
targetElement.focus();
|
|
11219
|
+
targetElement.focus({ preventScroll: true });
|
|
11017
11220
|
}
|
|
11018
11221
|
}
|
|
11019
11222
|
}
|
|
@@ -11057,7 +11260,7 @@ var Player = class _Player extends EventEmitter {
|
|
|
11057
11260
|
if (element.tabIndex === -1 && !element.hasAttribute("tabindex")) {
|
|
11058
11261
|
element.setAttribute("tabindex", "-1");
|
|
11059
11262
|
}
|
|
11060
|
-
element.focus();
|
|
11263
|
+
element.focus({ preventScroll: true });
|
|
11061
11264
|
}
|
|
11062
11265
|
if (shouldShow && config.autoScroll !== false && options.autoScroll !== false) {
|
|
11063
11266
|
element.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
@@ -11188,8 +11391,7 @@ var Player = class _Player extends EventEmitter {
|
|
|
11188
11391
|
targetElement.setAttribute("tabindex", "-1");
|
|
11189
11392
|
}
|
|
11190
11393
|
this.setManagedTimeout(() => {
|
|
11191
|
-
targetElement.focus();
|
|
11192
|
-
targetElement.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
11394
|
+
targetElement.focus({ preventScroll: true });
|
|
11193
11395
|
}, 10);
|
|
11194
11396
|
} else if (this.options.debug) {
|
|
11195
11397
|
this.log("[Metadata] Element not found:", normalizedSelector || targetSelector);
|
|
@@ -11265,6 +11467,8 @@ var PlaylistManager = class {
|
|
|
11265
11467
|
this.player.on("pause", this.handlePlaybackStateChange.bind(this));
|
|
11266
11468
|
this.player.on("ended", this.handlePlaybackStateChange.bind(this));
|
|
11267
11469
|
this.player.on("fullscreenchange", this.handleFullscreenChange.bind(this));
|
|
11470
|
+
this.player.on("audiodescriptionenabled", this.handleAudioDescriptionChange.bind(this));
|
|
11471
|
+
this.player.on("audiodescriptiondisabled", this.handleAudioDescriptionChange.bind(this));
|
|
11268
11472
|
if (this.options.showPanel) {
|
|
11269
11473
|
this.createUI();
|
|
11270
11474
|
}
|
|
@@ -11492,6 +11696,52 @@ var PlaylistManager = class {
|
|
|
11492
11696
|
this.updatePlaylistVisibilityInFullscreen();
|
|
11493
11697
|
}, 50);
|
|
11494
11698
|
}
|
|
11699
|
+
/**
|
|
11700
|
+
* Handle audio description state changes
|
|
11701
|
+
* Updates duration displays to show audio-described version duration when AD is enabled
|
|
11702
|
+
*/
|
|
11703
|
+
handleAudioDescriptionChange() {
|
|
11704
|
+
const currentTrack = this.getCurrentTrack();
|
|
11705
|
+
if (!currentTrack) return;
|
|
11706
|
+
this.updateTrackInfo(currentTrack);
|
|
11707
|
+
this.updatePlaylistUI();
|
|
11708
|
+
this.updatePlaylistDurations();
|
|
11709
|
+
}
|
|
11710
|
+
/**
|
|
11711
|
+
* Update the visual duration displays in the playlist panel
|
|
11712
|
+
* Called when audio description state changes
|
|
11713
|
+
*/
|
|
11714
|
+
updatePlaylistDurations() {
|
|
11715
|
+
if (!this.playlistPanel) return;
|
|
11716
|
+
const items = this.playlistPanel.querySelectorAll(".vidply-playlist-item");
|
|
11717
|
+
items.forEach((item, index) => {
|
|
11718
|
+
const track = this.tracks[index];
|
|
11719
|
+
if (!track) return;
|
|
11720
|
+
const effectiveDuration = this.getEffectiveDuration(track);
|
|
11721
|
+
const trackDuration = effectiveDuration ? TimeUtils.formatTime(effectiveDuration) : "";
|
|
11722
|
+
const durationBadge = item.querySelector(".vidply-playlist-duration-badge");
|
|
11723
|
+
if (durationBadge) {
|
|
11724
|
+
durationBadge.textContent = trackDuration;
|
|
11725
|
+
}
|
|
11726
|
+
const inlineDuration = item.querySelector(".vidply-playlist-item-duration");
|
|
11727
|
+
if (inlineDuration) {
|
|
11728
|
+
inlineDuration.textContent = trackDuration;
|
|
11729
|
+
}
|
|
11730
|
+
});
|
|
11731
|
+
}
|
|
11732
|
+
/**
|
|
11733
|
+
* Get the effective duration for a track based on audio description state
|
|
11734
|
+
* @param {Object} track - Track object
|
|
11735
|
+
* @returns {number|null} - Duration in seconds or null if not available
|
|
11736
|
+
*/
|
|
11737
|
+
getEffectiveDuration(track) {
|
|
11738
|
+
if (!track) return null;
|
|
11739
|
+
const isAudioDescriptionEnabled = this.player.state.audioDescriptionEnabled;
|
|
11740
|
+
if (isAudioDescriptionEnabled && track.audioDescriptionDuration) {
|
|
11741
|
+
return track.audioDescriptionDuration;
|
|
11742
|
+
}
|
|
11743
|
+
return track.duration || null;
|
|
11744
|
+
}
|
|
11495
11745
|
/**
|
|
11496
11746
|
* Update playlist visibility based on fullscreen and playback state
|
|
11497
11747
|
* In fullscreen: show when paused/not started, hide when playing
|
|
@@ -11549,9 +11799,7 @@ var PlaylistManager = class {
|
|
|
11549
11799
|
this.trackInfoElement = DOMUtils.createElement("div", {
|
|
11550
11800
|
className: "vidply-track-info",
|
|
11551
11801
|
attributes: {
|
|
11552
|
-
role: "status"
|
|
11553
|
-
"aria-live": "polite",
|
|
11554
|
-
"aria-atomic": "true"
|
|
11802
|
+
role: "status"
|
|
11555
11803
|
}
|
|
11556
11804
|
});
|
|
11557
11805
|
this.trackInfoElement.style.display = "none";
|
|
@@ -11586,22 +11834,32 @@ var PlaylistManager = class {
|
|
|
11586
11834
|
const totalTracks = this.tracks.length;
|
|
11587
11835
|
const trackTitle = track.title || i18n.t("playlist.untitled");
|
|
11588
11836
|
const trackArtist = track.artist || "";
|
|
11837
|
+
const effectiveDuration = this.getEffectiveDuration(track);
|
|
11838
|
+
const trackDuration = effectiveDuration ? TimeUtils.formatTime(effectiveDuration) : "";
|
|
11839
|
+
const trackDurationReadable = effectiveDuration ? TimeUtils.formatDuration(effectiveDuration) : "";
|
|
11589
11840
|
const artistPart = trackArtist ? i18n.t("playlist.by") + trackArtist : "";
|
|
11841
|
+
const durationPart = trackDurationReadable ? `. ${trackDurationReadable}` : "";
|
|
11590
11842
|
const announcement = i18n.t("playlist.nowPlaying", {
|
|
11591
11843
|
current: trackNumber,
|
|
11592
11844
|
total: totalTracks,
|
|
11593
11845
|
title: trackTitle,
|
|
11594
11846
|
artist: artistPart
|
|
11595
|
-
});
|
|
11847
|
+
}) + durationPart;
|
|
11596
11848
|
const trackOfText = i18n.t("playlist.trackOf", {
|
|
11597
11849
|
current: trackNumber,
|
|
11598
11850
|
total: totalTracks
|
|
11599
11851
|
});
|
|
11852
|
+
const durationHtml = trackDuration ? `<span class="vidply-track-duration" aria-hidden="true">${DOMUtils.escapeHTML(trackDuration)}</span>` : "";
|
|
11853
|
+
const trackDescription = track.description || "";
|
|
11600
11854
|
this.trackInfoElement.innerHTML = `
|
|
11601
11855
|
<span class="vidply-sr-only">${DOMUtils.escapeHTML(announcement)}</span>
|
|
11602
|
-
<div class="vidply-track-
|
|
11856
|
+
<div class="vidply-track-header" aria-hidden="true">
|
|
11857
|
+
<span class="vidply-track-number">${DOMUtils.escapeHTML(trackOfText)}</span>
|
|
11858
|
+
${durationHtml}
|
|
11859
|
+
</div>
|
|
11603
11860
|
<div class="vidply-track-title" aria-hidden="true">${DOMUtils.escapeHTML(trackTitle)}</div>
|
|
11604
11861
|
${trackArtist ? `<div class="vidply-track-artist" aria-hidden="true">${DOMUtils.escapeHTML(trackArtist)}</div>` : ""}
|
|
11862
|
+
${trackDescription ? `<div class="vidply-track-description" aria-hidden="true">${DOMUtils.escapeHTML(trackDescription)}</div>` : ""}
|
|
11605
11863
|
`;
|
|
11606
11864
|
this.trackInfoElement.style.display = "block";
|
|
11607
11865
|
this.updateTrackArtwork(track);
|
|
@@ -11643,6 +11901,7 @@ var PlaylistManager = class {
|
|
|
11643
11901
|
const list = DOMUtils.createElement("ul", {
|
|
11644
11902
|
className: "vidply-playlist-list",
|
|
11645
11903
|
attributes: {
|
|
11904
|
+
role: "listbox",
|
|
11646
11905
|
"aria-labelledby": `${this.uniqueId}-heading`,
|
|
11647
11906
|
"aria-describedby": `${this.uniqueId}-keyboard-instructions`
|
|
11648
11907
|
}
|
|
@@ -11666,9 +11925,14 @@ var PlaylistManager = class {
|
|
|
11666
11925
|
});
|
|
11667
11926
|
const trackTitle = track.title || i18n.t("playlist.trackUntitled", { number: index + 1 });
|
|
11668
11927
|
const trackArtist = track.artist ? i18n.t("playlist.by") + track.artist : "";
|
|
11928
|
+
const effectiveDuration = this.getEffectiveDuration(track);
|
|
11929
|
+
const trackDuration = effectiveDuration ? TimeUtils.formatTime(effectiveDuration) : "";
|
|
11930
|
+
const trackDurationReadable = effectiveDuration ? TimeUtils.formatDuration(effectiveDuration) : "";
|
|
11669
11931
|
const isActive = index === this.currentIndex;
|
|
11670
|
-
|
|
11671
|
-
|
|
11932
|
+
let ariaLabel = `${trackTitle}${trackArtist}`;
|
|
11933
|
+
if (trackDurationReadable) {
|
|
11934
|
+
ariaLabel += `. ${trackDurationReadable}`;
|
|
11935
|
+
}
|
|
11672
11936
|
const item = DOMUtils.createElement("li", {
|
|
11673
11937
|
className: isActive ? "vidply-playlist-item vidply-playlist-item-active" : "vidply-playlist-item",
|
|
11674
11938
|
attributes: {
|
|
@@ -11679,23 +11943,28 @@ var PlaylistManager = class {
|
|
|
11679
11943
|
className: "vidply-playlist-item-button",
|
|
11680
11944
|
attributes: {
|
|
11681
11945
|
type: "button",
|
|
11946
|
+
role: "option",
|
|
11682
11947
|
tabIndex: index === 0 ? 0 : -1,
|
|
11683
11948
|
// Only first item is in tab order initially
|
|
11684
|
-
"aria-label":
|
|
11949
|
+
"aria-label": ariaLabel,
|
|
11685
11950
|
"aria-posinset": index + 1,
|
|
11686
|
-
"aria-setsize": this.tracks.length
|
|
11951
|
+
"aria-setsize": this.tracks.length,
|
|
11952
|
+
"aria-checked": isActive ? "true" : "false"
|
|
11687
11953
|
}
|
|
11688
11954
|
});
|
|
11689
11955
|
if (isActive) {
|
|
11690
11956
|
button.setAttribute("aria-current", "true");
|
|
11691
11957
|
button.setAttribute("tabIndex", "0");
|
|
11692
11958
|
}
|
|
11693
|
-
const
|
|
11694
|
-
className: "vidply-playlist-thumbnail",
|
|
11959
|
+
const thumbnailContainer = DOMUtils.createElement("span", {
|
|
11960
|
+
className: "vidply-playlist-thumbnail-container",
|
|
11695
11961
|
attributes: {
|
|
11696
11962
|
"aria-hidden": "true"
|
|
11697
11963
|
}
|
|
11698
11964
|
});
|
|
11965
|
+
const thumbnail = DOMUtils.createElement("span", {
|
|
11966
|
+
className: "vidply-playlist-thumbnail"
|
|
11967
|
+
});
|
|
11699
11968
|
if (track.poster) {
|
|
11700
11969
|
thumbnail.style.backgroundImage = `url(${track.poster})`;
|
|
11701
11970
|
} else {
|
|
@@ -11703,18 +11972,37 @@ var PlaylistManager = class {
|
|
|
11703
11972
|
icon.classList.add("vidply-playlist-thumbnail-icon");
|
|
11704
11973
|
thumbnail.appendChild(icon);
|
|
11705
11974
|
}
|
|
11706
|
-
|
|
11975
|
+
thumbnailContainer.appendChild(thumbnail);
|
|
11976
|
+
if (trackDuration && track.poster) {
|
|
11977
|
+
const durationBadge = DOMUtils.createElement("span", {
|
|
11978
|
+
className: "vidply-playlist-duration-badge"
|
|
11979
|
+
});
|
|
11980
|
+
durationBadge.textContent = trackDuration;
|
|
11981
|
+
thumbnailContainer.appendChild(durationBadge);
|
|
11982
|
+
}
|
|
11983
|
+
button.appendChild(thumbnailContainer);
|
|
11707
11984
|
const info = DOMUtils.createElement("span", {
|
|
11708
11985
|
className: "vidply-playlist-item-info",
|
|
11709
11986
|
attributes: {
|
|
11710
11987
|
"aria-hidden": "true"
|
|
11711
11988
|
}
|
|
11712
11989
|
});
|
|
11990
|
+
const titleRow = DOMUtils.createElement("span", {
|
|
11991
|
+
className: "vidply-playlist-item-title-row"
|
|
11992
|
+
});
|
|
11713
11993
|
const title = DOMUtils.createElement("span", {
|
|
11714
11994
|
className: "vidply-playlist-item-title"
|
|
11715
11995
|
});
|
|
11716
11996
|
title.textContent = trackTitle;
|
|
11717
|
-
|
|
11997
|
+
titleRow.appendChild(title);
|
|
11998
|
+
if (trackDuration && !track.poster) {
|
|
11999
|
+
const inlineDuration = DOMUtils.createElement("span", {
|
|
12000
|
+
className: "vidply-playlist-item-duration"
|
|
12001
|
+
});
|
|
12002
|
+
inlineDuration.textContent = trackDuration;
|
|
12003
|
+
titleRow.appendChild(inlineDuration);
|
|
12004
|
+
}
|
|
12005
|
+
info.appendChild(titleRow);
|
|
11718
12006
|
if (track.artist) {
|
|
11719
12007
|
const artist = DOMUtils.createElement("span", {
|
|
11720
12008
|
className: "vidply-playlist-item-artist"
|
|
@@ -11722,6 +12010,13 @@ var PlaylistManager = class {
|
|
|
11722
12010
|
artist.textContent = track.artist;
|
|
11723
12011
|
info.appendChild(artist);
|
|
11724
12012
|
}
|
|
12013
|
+
if (track.description) {
|
|
12014
|
+
const description = DOMUtils.createElement("span", {
|
|
12015
|
+
className: "vidply-playlist-item-description"
|
|
12016
|
+
});
|
|
12017
|
+
description.textContent = track.description;
|
|
12018
|
+
info.appendChild(description);
|
|
12019
|
+
}
|
|
11725
12020
|
button.appendChild(info);
|
|
11726
12021
|
const playIcon = createIconElement("play");
|
|
11727
12022
|
playIcon.classList.add("vidply-playlist-item-icon");
|
|
@@ -11805,7 +12100,11 @@ var PlaylistManager = class {
|
|
|
11805
12100
|
if (newIndex !== -1 && newIndex !== index) {
|
|
11806
12101
|
buttons[index].setAttribute("tabIndex", "-1");
|
|
11807
12102
|
buttons[newIndex].setAttribute("tabIndex", "0");
|
|
11808
|
-
buttons[newIndex].focus();
|
|
12103
|
+
buttons[newIndex].focus({ preventScroll: false });
|
|
12104
|
+
const item = buttons[newIndex].closest(".vidply-playlist-item");
|
|
12105
|
+
if (item) {
|
|
12106
|
+
item.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
12107
|
+
}
|
|
11809
12108
|
}
|
|
11810
12109
|
if (announcement && this.navigationFeedback) {
|
|
11811
12110
|
this.navigationFeedback.textContent = announcement;
|
|
@@ -11833,21 +12132,29 @@ var PlaylistManager = class {
|
|
|
11833
12132
|
});
|
|
11834
12133
|
const trackTitle = track.title || i18n.t("playlist.trackUntitled", { number: index + 1 });
|
|
11835
12134
|
const trackArtist = track.artist ? i18n.t("playlist.by") + track.artist : "";
|
|
12135
|
+
const effectiveDuration = this.getEffectiveDuration(track);
|
|
12136
|
+
const trackDurationReadable = effectiveDuration ? TimeUtils.formatDuration(effectiveDuration) : "";
|
|
11836
12137
|
if (index === this.currentIndex) {
|
|
11837
12138
|
item.classList.add("vidply-playlist-item-active");
|
|
11838
12139
|
button.setAttribute("aria-current", "true");
|
|
12140
|
+
button.setAttribute("aria-checked", "true");
|
|
11839
12141
|
button.setAttribute("tabIndex", "0");
|
|
11840
|
-
|
|
11841
|
-
|
|
11842
|
-
|
|
12142
|
+
let ariaLabel = `${trackTitle}${trackArtist}`;
|
|
12143
|
+
if (trackDurationReadable) {
|
|
12144
|
+
ariaLabel += `. ${trackDurationReadable}`;
|
|
12145
|
+
}
|
|
12146
|
+
button.setAttribute("aria-label", ariaLabel);
|
|
11843
12147
|
item.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
11844
12148
|
} else {
|
|
11845
12149
|
item.classList.remove("vidply-playlist-item-active");
|
|
11846
12150
|
button.removeAttribute("aria-current");
|
|
12151
|
+
button.setAttribute("aria-checked", "false");
|
|
11847
12152
|
button.setAttribute("tabIndex", "-1");
|
|
11848
|
-
|
|
11849
|
-
|
|
11850
|
-
|
|
12153
|
+
let ariaLabel = `${trackTitle}${trackArtist}`;
|
|
12154
|
+
if (trackDurationReadable) {
|
|
12155
|
+
ariaLabel += `. ${trackDurationReadable}`;
|
|
12156
|
+
}
|
|
12157
|
+
button.setAttribute("aria-label", ariaLabel);
|
|
11851
12158
|
}
|
|
11852
12159
|
});
|
|
11853
12160
|
}
|
|
@@ -11946,7 +12253,7 @@ var PlaylistManager = class {
|
|
|
11946
12253
|
setTimeout(() => {
|
|
11947
12254
|
const firstItem = this.playlistPanel.querySelector('.vidply-playlist-item[tabindex="0"]');
|
|
11948
12255
|
if (firstItem) {
|
|
11949
|
-
firstItem.focus();
|
|
12256
|
+
firstItem.focus({ preventScroll: true });
|
|
11950
12257
|
}
|
|
11951
12258
|
}, 100);
|
|
11952
12259
|
}
|
|
@@ -11960,7 +12267,7 @@ var PlaylistManager = class {
|
|
|
11960
12267
|
if (this.player.controlBar && this.player.controlBar.controls.playlistToggle) {
|
|
11961
12268
|
this.player.controlBar.controls.playlistToggle.setAttribute("aria-expanded", "false");
|
|
11962
12269
|
this.player.controlBar.controls.playlistToggle.setAttribute("aria-pressed", "false");
|
|
11963
|
-
this.player.controlBar.controls.playlistToggle.focus();
|
|
12270
|
+
this.player.controlBar.controls.playlistToggle.focus({ preventScroll: true });
|
|
11964
12271
|
}
|
|
11965
12272
|
}
|
|
11966
12273
|
return this.isPanelVisible;
|