@f8team/reel-core 1.0.5 → 1.1.1
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/CHANGELOG.md +35 -0
- package/dist/index.cjs +41 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -1
- package/dist/index.d.ts +28 -1
- package/dist/index.js +40 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -798,6 +798,33 @@ interface FocusTrap {
|
|
|
798
798
|
*/
|
|
799
799
|
declare function createFocusTrap(container: HTMLElement): FocusTrap;
|
|
800
800
|
|
|
801
|
+
/**
|
|
802
|
+
* Focus helpers for the auto-hiding controls chrome.
|
|
803
|
+
*
|
|
804
|
+
* The themes keep the controls bar visible while the player matches
|
|
805
|
+
* `:focus-within`, so keyboard users never lose the control they are on.
|
|
806
|
+
* A pointer click focuses that control too, which used to latch the chrome
|
|
807
|
+
* open forever - most visibly after tapping the fullscreen button, the only
|
|
808
|
+
* way into fullscreen. `shouldKeepControlsVisible` tells the auto-hide timer
|
|
809
|
+
* which of the two it is looking at, and `blurFocusInside` releases the
|
|
810
|
+
* pointer-induced focus so `:focus-within` stops matching.
|
|
811
|
+
*/
|
|
812
|
+
/**
|
|
813
|
+
* Clears focus from any focused descendant of `container`.
|
|
814
|
+
*
|
|
815
|
+
* Used on pointer leave of the `[data-reel]` wrapper and when the auto-hide
|
|
816
|
+
* timer fires, so `:focus-within` does not keep the controls bar visible
|
|
817
|
+
* after a mouse click or tap on a control.
|
|
818
|
+
*/
|
|
819
|
+
declare function blurFocusInside(container: Element): void;
|
|
820
|
+
/**
|
|
821
|
+
* `true` when the controls must stay on screen even though the idle timer
|
|
822
|
+
* expired: an open menu, or a control the user reached with the keyboard.
|
|
823
|
+
*
|
|
824
|
+
* Pointer focus deliberately returns `false` - a tap must not pin the chrome.
|
|
825
|
+
*/
|
|
826
|
+
declare function shouldKeepControlsVisible(container: Element): boolean;
|
|
827
|
+
|
|
801
828
|
/**
|
|
802
829
|
* Time helpers shared by the seek bar, transcript markers (G8), and the
|
|
803
830
|
* keyboard / commands layer.
|
|
@@ -870,4 +897,4 @@ declare function looksLikeProgressive(input: string | undefined | null): boolean
|
|
|
870
897
|
*/
|
|
871
898
|
declare function detectSourceType(source: SourceDescriptor): SourceType;
|
|
872
899
|
|
|
873
|
-
export { type AutoplayMode, type BufferedRange, type CommandRegistry, DEFAULT_TOKENS, type Disposer, type KeyboardScope, type MutableStore, type Player, type PlayerError, type PlayerErrorCode, type PlayerEvents, type PlayerHooks, type PlayerOptions, type PlayerState, type PlayerStatus, type PluginHost, type PluginInstance, type PluginMediaAttachment, type QualityLevel, type ReadableStore, type SourceDescriptor, type SourceLoader, type SourceProvider, type SourceTransform, type SourceType, type SubtitleTrack, THEME_PRESETS, TOKEN_TO_CSS_VAR, type ThemeName, type ThemeTokens, type ThumbnailsDescriptor, type UnauthorizedEvent, announce, applyTheme, areSourceDescriptorsEquivalent, createFocusTrap, createPlayer, definePlugin, detectSourceType, formatTime, isSafeMediaUrl, looksLikeHls, looksLikeProgressive, looksLikeYouTube, parseTime, resolveTokens, toSeconds };
|
|
900
|
+
export { type AutoplayMode, type BufferedRange, type CommandRegistry, DEFAULT_TOKENS, type Disposer, type KeyboardScope, type MutableStore, type Player, type PlayerError, type PlayerErrorCode, type PlayerEvents, type PlayerHooks, type PlayerOptions, type PlayerState, type PlayerStatus, type PluginHost, type PluginInstance, type PluginMediaAttachment, type QualityLevel, type ReadableStore, type SourceDescriptor, type SourceLoader, type SourceProvider, type SourceTransform, type SourceType, type SubtitleTrack, THEME_PRESETS, TOKEN_TO_CSS_VAR, type ThemeName, type ThemeTokens, type ThumbnailsDescriptor, type UnauthorizedEvent, announce, applyTheme, areSourceDescriptorsEquivalent, blurFocusInside, createFocusTrap, createPlayer, definePlugin, detectSourceType, formatTime, isSafeMediaUrl, looksLikeHls, looksLikeProgressive, looksLikeYouTube, parseTime, resolveTokens, shouldKeepControlsVisible, toSeconds };
|
package/dist/index.d.ts
CHANGED
|
@@ -798,6 +798,33 @@ interface FocusTrap {
|
|
|
798
798
|
*/
|
|
799
799
|
declare function createFocusTrap(container: HTMLElement): FocusTrap;
|
|
800
800
|
|
|
801
|
+
/**
|
|
802
|
+
* Focus helpers for the auto-hiding controls chrome.
|
|
803
|
+
*
|
|
804
|
+
* The themes keep the controls bar visible while the player matches
|
|
805
|
+
* `:focus-within`, so keyboard users never lose the control they are on.
|
|
806
|
+
* A pointer click focuses that control too, which used to latch the chrome
|
|
807
|
+
* open forever - most visibly after tapping the fullscreen button, the only
|
|
808
|
+
* way into fullscreen. `shouldKeepControlsVisible` tells the auto-hide timer
|
|
809
|
+
* which of the two it is looking at, and `blurFocusInside` releases the
|
|
810
|
+
* pointer-induced focus so `:focus-within` stops matching.
|
|
811
|
+
*/
|
|
812
|
+
/**
|
|
813
|
+
* Clears focus from any focused descendant of `container`.
|
|
814
|
+
*
|
|
815
|
+
* Used on pointer leave of the `[data-reel]` wrapper and when the auto-hide
|
|
816
|
+
* timer fires, so `:focus-within` does not keep the controls bar visible
|
|
817
|
+
* after a mouse click or tap on a control.
|
|
818
|
+
*/
|
|
819
|
+
declare function blurFocusInside(container: Element): void;
|
|
820
|
+
/**
|
|
821
|
+
* `true` when the controls must stay on screen even though the idle timer
|
|
822
|
+
* expired: an open menu, or a control the user reached with the keyboard.
|
|
823
|
+
*
|
|
824
|
+
* Pointer focus deliberately returns `false` - a tap must not pin the chrome.
|
|
825
|
+
*/
|
|
826
|
+
declare function shouldKeepControlsVisible(container: Element): boolean;
|
|
827
|
+
|
|
801
828
|
/**
|
|
802
829
|
* Time helpers shared by the seek bar, transcript markers (G8), and the
|
|
803
830
|
* keyboard / commands layer.
|
|
@@ -870,4 +897,4 @@ declare function looksLikeProgressive(input: string | undefined | null): boolean
|
|
|
870
897
|
*/
|
|
871
898
|
declare function detectSourceType(source: SourceDescriptor): SourceType;
|
|
872
899
|
|
|
873
|
-
export { type AutoplayMode, type BufferedRange, type CommandRegistry, DEFAULT_TOKENS, type Disposer, type KeyboardScope, type MutableStore, type Player, type PlayerError, type PlayerErrorCode, type PlayerEvents, type PlayerHooks, type PlayerOptions, type PlayerState, type PlayerStatus, type PluginHost, type PluginInstance, type PluginMediaAttachment, type QualityLevel, type ReadableStore, type SourceDescriptor, type SourceLoader, type SourceProvider, type SourceTransform, type SourceType, type SubtitleTrack, THEME_PRESETS, TOKEN_TO_CSS_VAR, type ThemeName, type ThemeTokens, type ThumbnailsDescriptor, type UnauthorizedEvent, announce, applyTheme, areSourceDescriptorsEquivalent, createFocusTrap, createPlayer, definePlugin, detectSourceType, formatTime, isSafeMediaUrl, looksLikeHls, looksLikeProgressive, looksLikeYouTube, parseTime, resolveTokens, toSeconds };
|
|
900
|
+
export { type AutoplayMode, type BufferedRange, type CommandRegistry, DEFAULT_TOKENS, type Disposer, type KeyboardScope, type MutableStore, type Player, type PlayerError, type PlayerErrorCode, type PlayerEvents, type PlayerHooks, type PlayerOptions, type PlayerState, type PlayerStatus, type PluginHost, type PluginInstance, type PluginMediaAttachment, type QualityLevel, type ReadableStore, type SourceDescriptor, type SourceLoader, type SourceProvider, type SourceTransform, type SourceType, type SubtitleTrack, THEME_PRESETS, TOKEN_TO_CSS_VAR, type ThemeName, type ThemeTokens, type ThumbnailsDescriptor, type UnauthorizedEvent, announce, applyTheme, areSourceDescriptorsEquivalent, blurFocusInside, createFocusTrap, createPlayer, definePlugin, detectSourceType, formatTime, isSafeMediaUrl, looksLikeHls, looksLikeProgressive, looksLikeYouTube, parseTime, resolveTokens, shouldKeepControlsVisible, toSeconds };
|
package/dist/index.js
CHANGED
|
@@ -398,6 +398,12 @@ var HlsLoader = class {
|
|
|
398
398
|
this.rejectAttach = null;
|
|
399
399
|
this.manifestTimeout = null;
|
|
400
400
|
this.aborted = false;
|
|
401
|
+
/**
|
|
402
|
+
* Bumped by every abort/detach. `detach()` clears `aborted` so the loader can be reused, so a
|
|
403
|
+
* source switch (abort, then detach) used to let an attach that was still awaiting the runtime
|
|
404
|
+
* carry on and bind a stale hls.js instance to the <video>. Each attach keeps its own value.
|
|
405
|
+
*/
|
|
406
|
+
this.generation = 0;
|
|
401
407
|
this.lastLoadingFragmentKey = null;
|
|
402
408
|
this.repeatedFragmentLoadCount = 0;
|
|
403
409
|
this.repeatedFragmentErrorFired = false;
|
|
@@ -416,11 +422,12 @@ var HlsLoader = class {
|
|
|
416
422
|
async attach(video, source) {
|
|
417
423
|
this.detach();
|
|
418
424
|
this.aborted = false;
|
|
425
|
+
const generation = this.generation;
|
|
419
426
|
this.video = video;
|
|
420
427
|
this.currentSource = source;
|
|
421
428
|
this.unauthorizedFired = false;
|
|
422
429
|
const Hls = await (this.options.loadRuntime ?? defaultLoad)();
|
|
423
|
-
if (this.aborted) {
|
|
430
|
+
if (this.aborted || generation !== this.generation) {
|
|
424
431
|
throw makeAbortError();
|
|
425
432
|
}
|
|
426
433
|
if (!Hls.isSupported()) {
|
|
@@ -731,6 +738,7 @@ var HlsLoader = class {
|
|
|
731
738
|
this.abortLiveXhrs();
|
|
732
739
|
}
|
|
733
740
|
abort() {
|
|
741
|
+
this.generation += 1;
|
|
734
742
|
if (this.aborted) return;
|
|
735
743
|
this.aborted = true;
|
|
736
744
|
this.clearManifestTimeout();
|
|
@@ -1064,17 +1072,24 @@ var YouTubeLoader = class {
|
|
|
1064
1072
|
this.duration = 0;
|
|
1065
1073
|
this.rejectAttach = null;
|
|
1066
1074
|
this.aborted = false;
|
|
1075
|
+
/**
|
|
1076
|
+
* Bumped by every abort/detach. `detach()` clears `aborted` so the loader can be reused, so a
|
|
1077
|
+
* source switch (abort, then detach) used to let an attach that was still awaiting the runtime
|
|
1078
|
+
* carry on and mount a second iframe. Each attach keeps the value it started with instead.
|
|
1079
|
+
*/
|
|
1080
|
+
this.generation = 0;
|
|
1067
1081
|
}
|
|
1068
1082
|
async attach(video, source) {
|
|
1069
1083
|
this.detach();
|
|
1070
1084
|
this.aborted = false;
|
|
1085
|
+
const generation = this.generation;
|
|
1071
1086
|
const id = extractYouTubeId(source.src);
|
|
1072
1087
|
if (!id) {
|
|
1073
1088
|
throw new Error(`Cannot extract YouTube videoId from "${source.src}"`);
|
|
1074
1089
|
}
|
|
1075
1090
|
this.video = video;
|
|
1076
1091
|
const YT = await (this.options.loadRuntime ?? defaultLoad2)();
|
|
1077
|
-
if (this.aborted) {
|
|
1092
|
+
if (this.aborted || generation !== this.generation) {
|
|
1078
1093
|
throw makeYtAbortError();
|
|
1079
1094
|
}
|
|
1080
1095
|
const parent = video.parentElement;
|
|
@@ -1170,6 +1185,7 @@ var YouTubeLoader = class {
|
|
|
1170
1185
|
});
|
|
1171
1186
|
}
|
|
1172
1187
|
abort() {
|
|
1188
|
+
this.generation += 1;
|
|
1173
1189
|
if (this.aborted) return;
|
|
1174
1190
|
this.aborted = true;
|
|
1175
1191
|
const reject = this.rejectAttach;
|
|
@@ -2392,6 +2408,27 @@ function createFocusTrap(container) {
|
|
|
2392
2408
|
return { activate, deactivate };
|
|
2393
2409
|
}
|
|
2394
2410
|
|
|
2411
|
+
// src/a11y/controlsFocus.ts
|
|
2412
|
+
var OPEN_MENU_SELECTOR = "[data-reel-menu-open]";
|
|
2413
|
+
function activeElementInside(container) {
|
|
2414
|
+
const active = (container.ownerDocument ?? document).activeElement;
|
|
2415
|
+
if (!(active instanceof HTMLElement)) return null;
|
|
2416
|
+
return container.contains(active) ? active : null;
|
|
2417
|
+
}
|
|
2418
|
+
function blurFocusInside(container) {
|
|
2419
|
+
activeElementInside(container)?.blur();
|
|
2420
|
+
}
|
|
2421
|
+
function shouldKeepControlsVisible(container) {
|
|
2422
|
+
if (container.querySelector(OPEN_MENU_SELECTOR) !== null) return true;
|
|
2423
|
+
const active = activeElementInside(container);
|
|
2424
|
+
if (!active) return false;
|
|
2425
|
+
try {
|
|
2426
|
+
return active.matches(":focus-visible");
|
|
2427
|
+
} catch {
|
|
2428
|
+
return false;
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
|
|
2395
2432
|
// src/util/time.ts
|
|
2396
2433
|
var TIME_RE = /^(?:(\d+):)?(\d{1,2}):(\d{1,2})(?:\.(\d+))?$/;
|
|
2397
2434
|
function parseTime(input) {
|
|
@@ -2425,6 +2462,6 @@ function toSeconds(input) {
|
|
|
2425
2462
|
return parseTime(input);
|
|
2426
2463
|
}
|
|
2427
2464
|
|
|
2428
|
-
export { DEFAULT_TOKENS, THEME_PRESETS, TOKEN_TO_CSS_VAR, announce, applyTheme, areSourceDescriptorsEquivalent, createFocusTrap, createPlayer, definePlugin, detectSourceType, formatTime, isSafeMediaUrl, looksLikeHls, looksLikeProgressive, looksLikeYouTube, parseTime, resolveTokens, toSeconds };
|
|
2465
|
+
export { DEFAULT_TOKENS, THEME_PRESETS, TOKEN_TO_CSS_VAR, announce, applyTheme, areSourceDescriptorsEquivalent, blurFocusInside, createFocusTrap, createPlayer, definePlugin, detectSourceType, formatTime, isSafeMediaUrl, looksLikeHls, looksLikeProgressive, looksLikeYouTube, parseTime, resolveTokens, shouldKeepControlsVisible, toSeconds };
|
|
2429
2466
|
//# sourceMappingURL=index.js.map
|
|
2430
2467
|
//# sourceMappingURL=index.js.map
|