@js-toolkit/web-utils 1.51.1 → 1.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/EventEmitterListener.d.ts +2 -2
  2. package/EventEmitterListener.utils.d.ts +7 -4
  3. package/getCurrentScriptUrl.d.ts +1 -0
  4. package/getCurrentScriptUrl.js +1 -0
  5. package/isWebPSupported.js +1 -1
  6. package/media/Capabilities.d.ts +11 -0
  7. package/media/Capabilities.js +1 -0
  8. package/media/MediaNotAttachedError.d.ts +4 -0
  9. package/media/MediaNotAttachedError.js +1 -0
  10. package/media/PipController.js +1 -0
  11. package/media/TextTracksController/TextTracksController.d.ts +67 -0
  12. package/media/TextTracksController/TextTracksController.js +1 -0
  13. package/media/TextTracksController/index.d.ts +1 -0
  14. package/media/TextTracksController/index.js +1 -0
  15. package/media/TextTracksController/utils.d.ts +19 -0
  16. package/media/TextTracksController/utils.js +1 -0
  17. package/media/{mse/getMediaSource.d.ts → getMediaSource.d.ts} +2 -3
  18. package/media/getMediaSource.js +1 -0
  19. package/media/parseCueText.d.ts +12 -0
  20. package/media/parseCueText.js +1 -0
  21. package/media/toggleNativeSubtitles.d.ts +1 -1
  22. package/media/toggleNativeSubtitles.js +1 -1
  23. package/onPageReady.d.ts +6 -2
  24. package/onPageReady.js +1 -1
  25. package/package.json +13 -13
  26. package/platform/isChrome.d.ts +1 -0
  27. package/platform/isChrome.js +1 -0
  28. package/platform/isEMESupported.d.ts +2 -0
  29. package/platform/isEMESupported.js +1 -0
  30. package/{media/mse → platform}/isMSESupported.d.ts +1 -0
  31. package/platform/isMSESupported.js +1 -0
  32. package/platform/isMediaCapabilitiesSupported.d.ts +1 -0
  33. package/platform/isMediaCapabilitiesSupported.js +1 -0
  34. package/platform/isMobileSimulation.d.ts +2 -0
  35. package/platform/isMobileSimulation.js +1 -0
  36. package/platform/isTouchSupported.d.ts +1 -0
  37. package/platform/isTouchSupported.js +1 -0
  38. package/serviceWorker/ServiceWorkerInstaller.d.ts +38 -0
  39. package/serviceWorker/ServiceWorkerInstaller.js +1 -0
  40. package/serviceWorker/utils.d.ts +15 -0
  41. package/serviceWorker/utils.js +1 -0
  42. package/PipController.js +0 -1
  43. package/media/mse/getMediaSource.js +0 -1
  44. package/media/mse/index.d.ts +0 -2
  45. package/media/mse/index.js +0 -1
  46. package/media/mse/isMSESupported.js +0 -1
  47. package/serviceWorker.d.ts +0 -8
  48. package/serviceWorker.js +0 -1
  49. /package/{PipController.d.ts → media/PipController.d.ts} +0 -0
@@ -1,4 +1,4 @@
1
- import { type DomEventTarget, type GetEventMap as GetDomEventMap, type EmitterTarget, type GetEventType, type GetEventListener } from './EventEmitterListener.utils';
1
+ import { type DomEventTarget, type GetEventMap, type EmitterTarget, type GetEventType, type GetEventListener } from './EventEmitterListener.utils';
2
2
  type GetOnOptions<T extends EmitterTarget> = T extends DomEventTarget ? boolean | AddEventListenerOptions : unknown;
3
3
  type GetOnceOptions<T extends EmitterTarget> = T extends DomEventTarget ? boolean | OmitStrict<AddEventListenerOptions, 'once'> : undefined;
4
4
  type GetOffOptions<T extends EmitterTarget> = T extends DomEventTarget ? boolean | EventListenerOptions : undefined;
@@ -6,7 +6,7 @@ interface GetListenersOptions {
6
6
  event?: string | undefined;
7
7
  type?: 'normal' | 'capture' | undefined;
8
8
  }
9
- export declare class EventEmitterListener<T extends EmitterTarget, M extends AnyObject = GetDomEventMap<T>> {
9
+ export declare class EventEmitterListener<T extends EmitterTarget, M extends AnyObject = GetEventMap<T>> {
10
10
  readonly target: T;
11
11
  private readonly interceptor?;
12
12
  private readonly normalListeners;
@@ -1,3 +1,4 @@
1
+ import type { DataEventEmitter } from '@js-toolkit/utils/DataEventEmitter';
1
2
  export type DomEventTarget = EventTarget;
2
3
  export type EventTargetLike = {
3
4
  addEventListener: EventEmitterLike['on'];
@@ -19,12 +20,14 @@ export type GetEventType<T extends EmitterTarget> = T extends DomEventTarget ? G
19
20
  } ? K : string : T extends EventTargetLike ? T['addEventListener'] extends {
20
21
  (type: infer K, listener: AnyFunction, ...rest: unknown[]): unknown;
21
22
  } ? K : string : string;
22
- export type GetEventListener<T extends EmitterTarget, E, EM extends AnyObject = GetEventMap<T>> = T extends DomEventTarget ? IfExtends<EM, EmptyObject, EventListener, GetDomEventListener<E, EM>> : IfExtends<EM, EmptyObject, Parameters<T extends EventTargetLike ? T['addEventListener'] : T extends EventEmitterLike ? T['on'] : AnyFunction>['1'], (event: E extends keyof EM ? EM[E] : unknown, ...rest: any[]) => unknown>;
23
- export type GetEventMap<T> = T extends Document ? DocumentEventMap : T extends HTMLBodyElement ? HTMLBodyElementEventMap : T extends HTMLVideoElement ? HTMLVideoElementEventMap : T extends HTMLMediaElement ? HTMLMediaElementEventMap : T extends TextTrackList ? TextTrackListEventMap : T extends HTMLElement ? HTMLElementEventMap : T extends Element ? ElementEventMap : T extends Animation ? AnimationEventMap : T extends AbortSignal ? AbortSignalEventMap : T extends BroadcastChannel ? BroadcastChannelEventMap : T extends WebSocket ? WebSocketEventMap : T extends MediaStreamTrack ? MediaStreamTrackEventMap : T extends MediaStream ? MediaStreamEventMap : T extends EventSource ? EventSourceEventMap : T extends SourceBuffer ? SourceBufferEventMap : T extends SourceBufferList ? SourceBufferListEventMap : T extends {
24
- EventMap: Record<string, any>;
25
- } ? T['EventMap'] : EmptyObject;
23
+ export type GetEventListener<T extends EmitterTarget, E, EM extends AnyObject = GetEventMap<T>> = T extends DomEventTarget ? IfExtends<EM, EmptyObject, EventListener, GetDomEventListener<E, EM>> : IfExtends<EM, EmptyObject, Parameters<T extends EventEmitterLike ? T['on'] : T extends EventTargetLike ? T['addEventListener'] : AnyFunction>['1'], (event: E extends keyof EM ? EM[E] : unknown, ...rest: any[]) => unknown>;
24
+ type ListenersMapToEventMap<T extends Record<string, AnyFunction[]>> = {
25
+ [P in keyof T]: Parameters<T[P][number]>[0];
26
+ };
27
+ export type GetEventMap<T> = T extends Document ? DocumentEventMap : T extends HTMLBodyElement ? HTMLBodyElementEventMap : T extends HTMLVideoElement ? HTMLVideoElementEventMap : T extends HTMLMediaElement ? HTMLMediaElementEventMap : T extends TextTrackList ? TextTrackListEventMap : T extends HTMLElement ? HTMLElementEventMap : T extends Element ? ElementEventMap : T extends Animation ? AnimationEventMap : T extends AbortSignal ? AbortSignalEventMap : T extends BroadcastChannel ? BroadcastChannelEventMap : T extends WebSocket ? WebSocketEventMap : T extends MediaStreamTrack ? MediaStreamTrackEventMap : T extends MediaStream ? MediaStreamEventMap : T extends EventSource ? EventSourceEventMap : T extends SourceBuffer ? SourceBufferEventMap : T extends SourceBufferList ? SourceBufferListEventMap : T extends DataEventEmitter<any, any> ? ListenersMapToEventMap<ReturnType<T['listenersMap']>> : EmptyObject;
26
28
  export declare function isEventTargetLike(target: EmitterTarget): target is EventTargetLike;
27
29
  export declare function isDomEventTarget(target: EmitterTarget): target is DomEventTarget;
28
30
  export declare function isEventEmitterLike(target: EmitterTarget): target is EventEmitterLike;
29
31
  export declare function isPassiveSupported(): boolean;
30
32
  export declare function normalizeOptions(options: boolean | AddEventListenerOptions | undefined): typeof options;
33
+ export {};
@@ -0,0 +1 @@
1
+ export declare function getCurrentScriptUrl(url?: string | URL | undefined): URL;
@@ -0,0 +1 @@
1
+ const{currentScript:currentScript}=document;export function getCurrentScriptUrl(r){return new URL(null!=r?r:"",null==currentScript?void 0:currentScript.src)}
@@ -1 +1 @@
1
- import{__awaiter}from"tslib";export function isWebPSupported(A="lossy"){return __awaiter(this,void 0,void 0,(function*(){const o={lossy:"UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",lossless:"UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",alpha:"UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",animation:"UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"},i=new Image;return new Promise((Q=>{i.onload=()=>Q(i.width>0&&i.height>0),i.onerror=()=>Q(!1),i.src=`data:image/webp;base64,${o[A]}`}))}))}
1
+ import{__awaiter}from"tslib";export function isWebPSupported(){return __awaiter(this,arguments,void 0,(function*(A="lossy"){const o={lossy:"UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",lossless:"UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",alpha:"UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",animation:"UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"},Q=new Image;return new Promise((i=>{Q.onload=()=>i(Q.width>0&&Q.height>0),Q.onerror=()=>i(!1),Q.src=`data:image/webp;base64,${o[A]}`}))}))}
@@ -0,0 +1,11 @@
1
+ export declare abstract class Capabilities {
2
+ private static readonly supportMap;
3
+ private static readonly canPlayMap;
4
+ private static tmpVideo;
5
+ private static cacheTimer;
6
+ /** Check video element. Mime type and optional codecs. */
7
+ static isCanPlayType(type: string): boolean;
8
+ /** Check MediaSource. */
9
+ static isTypeSupported(type: string): boolean;
10
+ static reset(): void;
11
+ }
@@ -0,0 +1 @@
1
+ import{getMediaSource}from"./getMediaSource";export class Capabilities{static isCanPlayType(t){if(this.canPlayMap.has(t))return!!this.canPlayMap.get(t);this.tmpVideo||(this.tmpVideo=document.getElementsByTagName("video")[0]||document.createElement("video"),window.clearTimeout(this.cacheTimer),this.cacheTimer=window.setTimeout((()=>{this.tmpVideo=void 0}),1e3));const e=!!this.tmpVideo.canPlayType(t);return this.supportMap.set(t,e),e}static isTypeSupported(t){if(this.supportMap.has(t))return!!this.supportMap.get(t);const e=getMediaSource();if(e){const i=e.isTypeSupported(t);return this.supportMap.set(t,i),i}return!1}static reset(){window.clearTimeout(this.cacheTimer),this.tmpVideo=void 0,this.supportMap.clear(),this.canPlayMap.clear()}}Capabilities.supportMap=new Map,Capabilities.canPlayMap=new Map;
@@ -0,0 +1,4 @@
1
+ import { ErrorCompat } from '@js-toolkit/utils/ErrorCompat';
2
+ export declare class MediaNotAttachedError extends ErrorCompat {
3
+ constructor(message?: string, options?: ErrorOptions | undefined);
4
+ }
@@ -0,0 +1 @@
1
+ import{ErrorCompat}from"@js-toolkit/utils/ErrorCompat";export class MediaNotAttachedError extends ErrorCompat{constructor(t="Media element is not attached yet.",r=void 0){super(MediaNotAttachedError,t,Object.assign(Object.assign({},r),{name:"MediaNotAttachedError "}))}}
@@ -0,0 +1 @@
1
+ import{EventEmitter}from"eventemitter3";import{EventEmitterListener}from"../EventEmitterListener";const getPipUnavailableError=()=>new Error("PiP is not available");export class PipController extends EventEmitter{static isApiEnabled(){return!!HTMLVideoElement.prototype.requestPictureInPicture&&!!document.exitPictureInPicture&&!!document.pictureInPictureEnabled}static isWebkitApiEnabled(e){return!!e.webkitSupportsPresentationMode&&e.webkitSupportsPresentationMode("picture-in-picture")}static isAvailable(e){return this.isApiEnabled()&&!e.disablePictureInPicture||this.isWebkitApiEnabled(e)}get Events(){return PipController.Events}constructor(e){if(super(),this.listener=new EventEmitterListener(e),PipController.isAvailable(e)){const e=()=>{this.emit(this.Events.Change,{pip:!0})},t=()=>{this.emit(this.Events.Change,{pip:!1})};PipController.isApiEnabled()?(this.listener.on("enterpictureinpicture",e),this.listener.on("leavepictureinpicture",t)):this.listener.on("webkitpresentationmodechanged",(()=>{let i=this.listener.target.webkitPresentationMode;return()=>{"picture-in-picture"===this.listener.target.webkitPresentationMode?e():"picture-in-picture"===i&&t(),i=this.listener.target.webkitPresentationMode}})(),!0)}}destroy(){return this.exit().finally((()=>{this.removeAllListeners(),this.listener.removeAllListeners()}))}isPip(){return PipController.isApiEnabled()?document.pictureInPictureElement===this.listener.target:"picture-in-picture"===this.listener.target.webkitPresentationMode}getCurrentElement(){return this.isPip()?this.listener.target:null}request(){return new Promise(((e,t)=>{if(this.isPip())e();else{if(!PipController.isAvailable(this.listener.target))throw getPipUnavailableError();PipController.isApiEnabled()?this.listener.target.requestPictureInPicture().then((()=>e()),t):(this.listener.once("webkitpresentationmodechanged",(()=>{"picture-in-picture"===this.listener.target.webkitPresentationMode?e():t(new Error("Something went wrong."))}),!0),this.listener.target.webkitSetPresentationMode("picture-in-picture"))}}))}exit(){return new Promise(((e,t)=>{if(this.isPip()){if(!PipController.isAvailable(this.listener.target))throw getPipUnavailableError();PipController.isApiEnabled()?document.exitPictureInPicture().then(e,t):(this.listener.once("webkitpresentationmodechanged",(()=>{"picture-in-picture"!==this.listener.target.webkitPresentationMode?e():t(new Error("Something went wrong."))}),!0),this.listener.target.webkitSetPresentationMode("inline"))}else e()}))}}!function(e){let t;!function(e){e.Change="change"}(t=e.Events||(e.Events={}))}(PipController||(PipController={}));
@@ -0,0 +1,67 @@
1
+ import { EventEmitter } from 'eventemitter3';
2
+ import type { BaseMediaController } from '../BaseMediaController';
3
+ import { type ActivateTextTrackInfo, type TextTrackInfo, type TextTrackItem } from './utils';
4
+ declare global {
5
+ interface HTMLMediaElementEventMap extends TextTracksEventMap {
6
+ }
7
+ }
8
+ interface TextTracksEventMap {
9
+ texttracklistchange: CustomEvent<TextTracksController.EventMap[TextTracksController.Events.TextTrackListChanged][0]>;
10
+ texttrackchange: CustomEvent<TextTracksController.EventMap[TextTracksController.Events.CurrentTextTrackChanged][0]>;
11
+ texttrackcuechange: CustomEvent<TextTracksController.EventMap[TextTracksController.Events.TextTrackCueChanged][0]>;
12
+ }
13
+ export interface Cue extends PartialBut<OmitStrict<VTTCue, keyof EventTarget | 'onenter' | 'onexit' | 'track' | 'pauseOnExit'>, 'id' | 'text' | 'startTime'> {
14
+ readonly rows: string[];
15
+ }
16
+ export type { TextTrackInfo, ActivateTextTrackInfo, TextTrackItem };
17
+ export declare class TextTracksController extends EventEmitter<TextTracksController.EventMap> implements BaseMediaController {
18
+ private readonly options;
19
+ private readonly eventListeners;
20
+ private addedTracks;
21
+ private textTrackList;
22
+ private media;
23
+ private textTrack;
24
+ private nextTextTrack;
25
+ get Events(): typeof TextTracksController.Events;
26
+ constructor(options?: TextTracksController.Options | undefined);
27
+ isAttached(): boolean;
28
+ getMediaElement(): HTMLMediaElement;
29
+ detach(): void;
30
+ attach(media: HTMLMediaElement): void;
31
+ setTextTracks(textTrackList: readonly TextTrackItem[]): void;
32
+ getActiveTextTrack(): TextTrackInfo | undefined;
33
+ setActiveTextTrack(tt: ActivateTextTrackInfo | undefined): void;
34
+ destroy(): void;
35
+ }
36
+ export declare namespace TextTracksController {
37
+ interface Options {
38
+ /** Default `true`. */
39
+ readonly emitNativeEvents?: boolean | undefined;
40
+ /** Default `true`. */
41
+ readonly hideActiveTrack?: boolean | undefined;
42
+ }
43
+ enum Events {
44
+ TextTrackListChanged = "TrackListChanged",
45
+ CurrentTextTrackChanged = "CurrentTextTrackChanged",
46
+ TextTrackCueChanged = "TextTrackCueChanged"
47
+ }
48
+ type EventMap = DefineAll<Events, {
49
+ [Events.TextTrackListChanged]: [
50
+ {
51
+ readonly textTracks: readonly TextTrackInfo[];
52
+ }
53
+ ];
54
+ [Events.CurrentTextTrackChanged]: [
55
+ {
56
+ readonly textTrack: TextTrackInfo | undefined;
57
+ readonly index: number;
58
+ }
59
+ ];
60
+ [Events.TextTrackCueChanged]: [
61
+ {
62
+ readonly textTrack: TextTrack;
63
+ readonly cues: readonly Cue[];
64
+ }
65
+ ];
66
+ }>;
67
+ }
@@ -0,0 +1 @@
1
+ import{EventEmitter}from"eventemitter3";import{EventListeners}from"../../EventListeners";import{MediaNotAttachedError}from"../MediaNotAttachedError";import{parseTextTracks,setActiveTextTrack,addTextTracks,isIOSFullscreen,splitRows,buildCueId}from"./utils";function dispatchNativeEvent(t,e,i){t.dispatchEvent(new CustomEvent(e,{detail:i}))}export class TextTracksController extends EventEmitter{get Events(){return TextTracksController.Events}constructor(t){var e,i;super(),this.eventListeners=new EventListeners,this.addedTracks=[],this.textTrackList=[],this.options=Object.assign(Object.assign({},t),{emitNativeEvents:null===(e=null==t?void 0:t.emitNativeEvents)||void 0===e||e,hideActiveTrack:null===(i=null==t?void 0:t.hideActiveTrack)||void 0===i||i})}isAttached(){return!!this.media}getMediaElement(){if(!this.media)throw new MediaNotAttachedError;return this.media}detach(){this.eventListeners.removeAllListeners(),this.media=void 0,this.addedTracks=[],this.textTrackList=[],this.textTrack=void 0,this.nextTextTrack=void 0}attach(t){this.detach(),this.media=t;const{textTracks:e}=t;let i=!1;const s=(()=>{const e=[];return i=>{var s;const{activeCues:n}=i.target;if(!n)return;let a=e.length!==n.length;const r=new Array(n.length);for(let t=0;t<r.length;t+=1){const i=n[t];i.id=i.id||buildCueId(i,t),r[t]=i,r[t].rows=splitRows(i.text),a||(null===(s=e[t])||void 0===s?void 0:s.id)===i.id||(a=!0),e[t]=i}e.length>r.length&&e.splice(r.length-e.length),a&&(this.emit(this.Events.TextTrackCueChanged,{textTrack:i.target,cues:r}),this.options.emitNativeEvents&&dispatchNativeEvent(t,"texttrackcuechange",{textTrack:i.target,cues:r}))}})(),n=()=>{var e;this.textTrackList=parseTextTracks(t),this.emit(this.Events.TextTrackListChanged,{textTracks:this.textTrackList}),this.options.emitNativeEvents&&dispatchNativeEvent(t,"texttracklistchange",{textTracks:this.textTrackList}),setActiveTextTrack(t,null!==(e=this.textTrack)&&void 0!==e?e:this.nextTextTrack,this.options.hideActiveTrack||isIOSFullscreen(t))},a=t=>{i||n(),this.eventListeners.scope(t).on("cuechange",s)},r=t=>{n(),this.eventListeners.scope(t).off("cuechange",s)};if(this.eventListeners.scope(e).on("change",(()=>{var e,i,s;const{textTracks:n}=t,{nextTextTrack:a}=this;let r=-1;for(let e=0;e<n.length;e+=1){const i=n[e];if(i.language===(null==a?void 0:a.language)&&i.kind===(null==a?void 0:a.kind)||isIOSFullscreen(t)||(i.mode="disabled"),"disabled"!==i.mode&&r>=0&&(i.mode="disabled"),"disabled"!==i.mode){if(r=e,!i.native&&!isIOSFullscreen(t)){const t=this.options.hideActiveTrack?"hidden":"showing";i.mode!==t&&(i.mode=t)}i.native&&i.language===(null==a?void 0:a.language)&&i.kind===a.kind&&(i.mode="showing")}}const c=n[r]&&(null!==(e=this.textTrackList[r])&&void 0!==e?e:{id:n[r].id,kind:n[r].kind,language:n[r].language,label:n[r].label});(null===(i=this.textTrack)||void 0===i?void 0:i.language)===(null==c?void 0:c.language)&&(null===(s=this.textTrack)||void 0===s?void 0:s.kind)===(null==c?void 0:c.kind)||(this.textTrack=c,this.nextTextTrack=this.textTrack,this.emit(this.Events.CurrentTextTrackChanged,{textTrack:this.textTrack,index:r}),this.options.emitNativeEvents&&dispatchNativeEvent(t,"texttrackchange",{textTrack:this.textTrack,index:r}))})).on("addtrack",(({track:t})=>t&&a(t))).on("removetrack",(({track:t})=>t&&r(t))),e.length>0){i=!0;try{Array.prototype.forEach.call(e,a),n()}finally{i=!1}}}setTextTracks(t){const e=this.getMediaElement();if(this.eventListeners.scope(e,"@@setTextTracks").removeAllListeners(),this.addedTracks.forEach((t=>t.remove())),0===t.length)return;const i=()=>{addTextTracks(e,t,(t=>this.addedTracks.push(t)))};e.readyState>=e.HAVE_CURRENT_DATA?i():this.eventListeners.scope(e,"@@setTextTracks").once("loadeddata",i)}getActiveTextTrack(){return this.textTrack}setActiveTextTrack(t){const e=this.getMediaElement();this.nextTextTrack=t&&this.textTrackList.find((e=>e.language===t.language&&(!t.kind||e.kind===t.kind))),setActiveTextTrack(e,this.nextTextTrack,this.options.hideActiveTrack||isIOSFullscreen(e))}destroy(){this.detach(),this.removeAllListeners()}}!function(t){let e;!function(t){t.TextTrackListChanged="TrackListChanged",t.CurrentTextTrackChanged="CurrentTextTrackChanged",t.TextTrackCueChanged="TextTrackCueChanged"}(e=t.Events||(t.Events={}))}(TextTracksController||(TextTracksController={}));
@@ -0,0 +1 @@
1
+ export * from './TextTracksController';
@@ -0,0 +1 @@
1
+ export*from"./TextTracksController";
@@ -0,0 +1,19 @@
1
+ declare global {
2
+ interface TextTrack {
3
+ customGroupId?: string | undefined;
4
+ }
5
+ }
6
+ export type TextTrackItem = Readonly<PartialSome<RequiredStrict<Pick<HTMLTrackElement, 'src' | 'default'> & Pick<TextTrack, 'kind' | 'label' | 'language'>>, 'default' | 'kind'>>;
7
+ export interface TextTrackInfo extends Pick<TextTrackItem, 'kind' | 'language' | 'label'> {
8
+ readonly id: string;
9
+ }
10
+ export type ActivateTextTrackInfo = OptionalToUndefined<PartialBut<Pick<TextTrackInfo, 'kind' | 'language'>, 'language'>>;
11
+ /** Hack: MSE can't remove texttracks on detaching because of no browser api for that. */
12
+ export declare function fakeDetachTextTracks(media: HTMLMediaElement): void;
13
+ export declare function parseTextTracks(media: HTMLMediaElement): TextTrackInfo[];
14
+ export declare function isIOSFullscreen(media: HTMLMediaElement): boolean;
15
+ export declare function setActiveTextTrack(media: HTMLMediaElement, tt: ActivateTextTrackInfo | undefined, hideActiveTrack: boolean): void;
16
+ /** Dynamically add text tracks */
17
+ export declare function addTextTracks(media: HTMLMediaElement, textTrackList: readonly TextTrackItem[], onAdd: (el: HTMLTrackElement) => void): void;
18
+ export declare function buildCueId(cue: Pick<TextTrackCue, 'startTime'>, index: number): string;
19
+ export declare function splitRows(text: string): string[];
@@ -0,0 +1 @@
1
+ import{isIOS}from"../../platform/isIOS";const DETACHED_GROUP_ID="__detached__";export function fakeDetachTextTracks(e){[].forEach.call(e.textTracks,(e=>{const t=e;t.customGroupId&&(t.customGroupId="__detached__")}))}export function parseTextTracks(e){return 0===e.textTracks.length?[]:Array.prototype.filter.call(e.textTracks,(e=>"__detached__"!==e.customGroupId&&!!e.language)).map((({id:e,kind:t,language:n,label:a})=>({id:e,kind:t,language:n,label:null!=a?a:""})))}export function isIOSFullscreen(e){return isIOS()&&!!e.webkitDisplayingFullscreen}export function setActiveTextTrack(e,t,n){const{textTracks:a}=e;if(0===a.length)return;let r=!1;for(let e=0;e<a.length;e+=1){const l=a[e];if(r||l.language!==(null==t?void 0:t.language)||t.kind&&l.kind!==t.kind)l.mode="disabled";else{const e=n?"hidden":"showing";l.mode=e,r=!0}}}export function addTextTracks(e,t,n){const a=Array.prototype.reduce.call(e.textTracks,((e,t)=>(t.language&&(e[t.language]=t),e)),{});t.forEach((t=>{var r;if(!a[t.language]){const a=document.createElement("track");a.src=t.src,a.srclang=t.language,a.label=t.label,a.kind=null!==(r=t.kind)&&void 0!==r?r:"captions",a.default=!1,n(e.appendChild(a))}}))}export function buildCueId(e,t){return`${e.startTime}-${t}`}export function splitRows(e){return e.split(/\r?\n/)}
@@ -11,8 +11,7 @@ declare global {
11
11
  removeEventListener<K extends keyof ManagedMediaSourceEventMap>(type: K, listener: (this: MediaSource, ev: ManagedMediaSourceEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
12
12
  }
13
13
  interface Window {
14
- WebKitMediaSource?: typeof MediaSource;
15
- ManagedMediaSource?: ManagedMediaSource;
14
+ ManagedMediaSource?: ManagedMediaSource & typeof MediaSource;
16
15
  }
17
16
  }
18
- export declare function getMediaSource(): typeof MediaSource | undefined;
17
+ export declare function getMediaSource(managedMediaSource?: 'prefer' | 'maybe' | undefined): typeof MediaSource | undefined;
@@ -0,0 +1 @@
1
+ export function getMediaSource(e){return"prefer"===e&&window.ManagedMediaSource||"maybe"===e&&window.ManagedMediaSource&&!window.MediaSource?window.ManagedMediaSource:window.MediaSource}
@@ -0,0 +1,12 @@
1
+ export interface CueSegment {
2
+ readonly id: string;
3
+ readonly startTime: number | undefined;
4
+ readonly tag: keyof typeof TAG_NAME;
5
+ readonly node: Element;
6
+ }
7
+ declare const TAG_NAME: Record<string, string>;
8
+ export interface ParseCueTextResult<P extends CueSegment> {
9
+ readonly segments: P[];
10
+ }
11
+ export declare function parseCueText<P extends CueSegment>(input0: string, map?: (segment: CueSegment) => P): ParseCueTextResult<P>;
12
+ export {};
@@ -0,0 +1 @@
1
+ const ESCAPE={"&amp;":"&","&lt;":"<","&gt;":">","&lrm;":"‎","&rlm;":"‏","&nbsp;":" "},TAG_NAME={c:"span",i:"i",b:"b",u:"u",ruby:"ruby",rt:"rt",lang:"span"},TAG_ANNOTATION={v:"title",lang:"lang"},NEEDS_PARENT={rt:"ruby"};function computeSeconds(e,t,n,o){return 3600*(+e||0)+60*(+t||0)+(+n||0)+(+o||0)/1e3}function parseTimeStamp(e){const t=e.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);if(!t)return;const[,n,o,r,c]=t;return c?computeSeconds(n,o,r.replace(":",""),c):+n>59?computeSeconds(n,o,"",c):computeSeconds("",n,o,c)}function unescape(e){let t,n=e;for(;t=n.match(/&(amp|lt|gt|lrm|rlm|nbsp);/);)n=n.replace(t[0],(e=>ESCAPE[e]));return n}function nextToken(e){if(!e)return[e,void 0];const t=e.match(/^([^<]*)(<[^>]+>?)?/);if(!t)return[e,void 0];const n=t[1]?t[1]:t[2];return[e.substring(n.length),n]}function shouldAdd(e,t){return!NEEDS_PARENT[t.localName]||NEEDS_PARENT[t.localName]===e.localName}function createHtmlNode(e,t){const n=TAG_NAME[e];if(!n)return;const o=window.document.createElement(n),r=TAG_ANNOTATION[e];return r&&t&&(o[r]=t.trim()),o}export function parseCueText(e,t){let n,o,r=e,c=-1;const s=[],l=[],u=e=>{var o;const r=null!==(o=s.pop())&&void 0!==o?o:"",u=n;if(n=u.parentElement||void 0,null==n){const n={id:e,startTime:c>=0?c:void 0,tag:r,node:u};l.push(t?t(n):n),c=-1}};for(;null!=([r,o]=nextToken(r),o);){const e=String(l.length+1);if("<"===o[0])if("/"===o[1])s.at(-1)===o.substring(2).replace(">","")&&u(e);else{const e=parseTimeStamp(o.substring(1,o.length-1));if(e)c=e;else{const e=o.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/),t=e&&createHtmlNode(e[1],e[3]);!t||n&&!shouldAdd(n,t)||(e[2]&&(t.className=e[2].substring(1).replace("."," ")),s.push(e[1]),null==n||n.appendChild(t),n=t)}}else{if(null==n){const n=createHtmlNode("c","");if(n){n.appendChild(window.document.createTextNode(unescape(o)));const r={id:e,node:n,tag:"c",startTime:void 0};l.push(t?t(r):r)}}n&&n.appendChild(window.document.createTextNode(unescape(o)))}}return{segments:l}}
@@ -1,6 +1,6 @@
1
1
  declare global {
2
2
  interface TextTrack {
3
- ignoreChange?: boolean | undefined;
3
+ native?: boolean | undefined;
4
4
  }
5
5
  }
6
6
  export declare function toggleNativeSubtitles(native: boolean, textTracks: TextTrackList): void;
@@ -1 +1 @@
1
- export function toggleNativeSubtitles(e,o){for(let n=0;n<o.length;n+=1){const t=o[n];e?t.ignoreChange=!0:delete t.ignoreChange,e&&"hidden"===t.mode?t.mode="showing":e||"showing"!==t.mode||(t.mode="hidden")}}
1
+ export function toggleNativeSubtitles(e,t){for(let o=0;o<t.length;o+=1){const n=t[o];e?n.native=!0:delete n.native,e&&"hidden"===n.mode?n.mode="showing":e||"showing"!==n.mode||(n.mode="hidden")}}
package/onPageReady.d.ts CHANGED
@@ -1,3 +1,7 @@
1
1
  export declare function isPageReady(): boolean;
2
- /** @returns cancel wait function */
3
- export declare function onPageReady(callback: VoidFunction): VoidFunction;
2
+ interface Options {
3
+ readonly timeout?: number | undefined;
4
+ }
5
+ /** @returns cancel wait function. */
6
+ export declare function onPageReady(callback: VoidFunction, options?: Options): VoidFunction;
7
+ export {};
package/onPageReady.js CHANGED
@@ -1 +1 @@
1
- export function isPageReady(){return"complete"===document.readyState}export function onPageReady(e){return isPageReady()?e():window.addEventListener("load",e,{once:!0}),()=>{window.removeEventListener("load",e)}}
1
+ import{delay}from"@js-toolkit/utils/delay";export function isPageReady(){return"complete"===document.readyState}export function onPageReady(e,t){let o;const n=()=>{window.removeEventListener("load",a),null==o||o.cancel()},a=()=>{n(),e()};return isPageReady()?e():(window.addEventListener("load",a,{once:!0}),(null==t?void 0:t.timeout)&&(o=delay(a,t.timeout))),n}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@js-toolkit/web-utils",
3
- "version": "1.51.1",
3
+ "version": "1.53.0",
4
4
  "description": "Web utils",
5
5
  "author": "VZH",
6
6
  "license": "MIT",
@@ -20,26 +20,26 @@
20
20
  "@js-toolkit/node-utils": "^1.2.0"
21
21
  },
22
22
  "devDependencies": {
23
- "@js-toolkit/configs": "^3.90.0",
24
- "@js-toolkit/utils": "^1.51.0",
25
- "@types/uuid": "^9.0.7",
26
- "@typescript-eslint/eslint-plugin": "^6.19.1",
27
- "@typescript-eslint/parser": "^6.19.1",
23
+ "@js-toolkit/configs": "^3.92.0",
24
+ "@js-toolkit/utils": "^1.53.1",
25
+ "@types/uuid": "^9.0.8",
26
+ "@typescript-eslint/eslint-plugin": "^7.10.0",
27
+ "@typescript-eslint/parser": "^7.10.0",
28
28
  "copyfiles": "^2.4.1",
29
- "eslint": "^8.56.0",
29
+ "eslint": "^8.57.0",
30
30
  "eslint-config-airbnb-base": "^15.0.0",
31
31
  "eslint-config-prettier": "^9.1.0",
32
32
  "eslint-plugin-import": "^2.29.1",
33
33
  "eslint-plugin-prettier": "^5.1.3",
34
34
  "eventemitter3": "^5.0.1",
35
- "prettier": "^3.2.4",
35
+ "prettier": "^3.2.5",
36
36
  "reconnecting-websocket": "^4.4.0",
37
- "rimraf": "^5.0.5",
38
- "terser": "^5.27.0",
39
- "typescript": "^5.3.3",
40
- "ua-parser-js": "^2.0.0-beta.1",
37
+ "rimraf": "^5.0.7",
38
+ "terser": "^5.31.0",
39
+ "typescript": "^5.4.5",
40
+ "ua-parser-js": "^2.0.0-beta.2",
41
41
  "uuid": "^9.0.1",
42
- "webpack": "^5.90.0",
42
+ "webpack": "^5.91.0",
43
43
  "yargs": "^17.7.2"
44
44
  }
45
45
  }
@@ -0,0 +1 @@
1
+ export declare function isChrome(): boolean;
@@ -0,0 +1 @@
1
+ import{getCachedPlatformInfo}from"./getPlatformInfo";export function isChrome(){const o=getCachedPlatformInfo();if(!o)return!1;const r=o.browser.name;return"Chrome"===r||"Mobile Chrome"===r}
@@ -0,0 +1,2 @@
1
+ /** Encrypted Media Extensions */
2
+ export declare function isEMESupported(): boolean;
@@ -0,0 +1 @@
1
+ export function isEMESupported(){return!!(window.MediaKeys&&window.navigator&&window.navigator.requestMediaKeySystemAccess&&window.MediaKeySystemAccess&&window.MediaKeySystemAccess.prototype.getConfiguration)}
@@ -1 +1,2 @@
1
+ /** Media Source Extensions */
1
2
  export declare function isMSESupported(): boolean;
@@ -0,0 +1 @@
1
+ import{getMediaSource}from"../media/getMediaSource";function getSourceBuffer(){return window.SourceBuffer}export function isMSESupported(){var e;if(!(null===(e=getMediaSource())||void 0===e?void 0:e.isTypeSupported))return!1;const o=getSourceBuffer();return!o||o.prototype&&"function"==typeof o.prototype.appendBuffer&&"function"==typeof o.prototype.remove}
@@ -0,0 +1 @@
1
+ export declare function isMediaCapabilitiesSupported(): boolean;
@@ -0,0 +1 @@
1
+ export function isMediaCapabilitiesSupported(){var i;return!!window.MediaCapabilities&&!!window.navigator&&!!(null===(i=window.navigator.mediaCapabilities)||void 0===i?void 0:i.decodingInfo)}
@@ -0,0 +1,2 @@
1
+ /** Detect mobile simulation in Chrome DevTools. */
2
+ export declare function isMobileSimulation(): boolean;
@@ -0,0 +1 @@
1
+ import{isTouchSupported}from"./isTouchSupported";export function isMobileSimulation(){return isTouchSupported()&&1===navigator.maxTouchPoints}
@@ -0,0 +1 @@
1
+ export declare function isTouchSupported(): boolean;
@@ -0,0 +1 @@
1
+ export function isTouchSupported(){return window.matchMedia("(any-pointer: coarse) and (any-hover: none)").matches}
@@ -0,0 +1,38 @@
1
+ import { DataEventEmitter } from '@js-toolkit/utils/DataEventEmitter';
2
+ import { ErrorCompat } from '@js-toolkit/utils/ErrorCompat';
3
+ export declare class ServiceWorkerUnavailableError extends ErrorCompat {
4
+ constructor();
5
+ }
6
+ export declare class ServiceWorkerInstaller extends DataEventEmitter<{
7
+ registered: [{
8
+ registration: ServiceWorkerRegistration;
9
+ }];
10
+ unregistered: [{
11
+ registration: ServiceWorkerRegistration;
12
+ }];
13
+ updatePending: [{
14
+ registration: ServiceWorkerRegistration;
15
+ }];
16
+ updated: [{
17
+ registration: ServiceWorkerRegistration;
18
+ }];
19
+ error: [{
20
+ error: unknown;
21
+ }];
22
+ }, ServiceWorkerInstaller> {
23
+ static isAvailable(): boolean;
24
+ private registration;
25
+ private cancelDefferedRegister;
26
+ constructor();
27
+ destroy(): void;
28
+ register(swUrl: string | URL, options?: ServiceWorkerInstaller.RegistrationOptions | undefined): void;
29
+ unregister(): void;
30
+ }
31
+ export declare namespace ServiceWorkerInstaller {
32
+ interface Options {
33
+ }
34
+ interface RegistrationOptions extends globalThis.RegistrationOptions {
35
+ /** Wait for page ready. */
36
+ readonly deffered?: boolean | number;
37
+ }
38
+ }
@@ -0,0 +1 @@
1
+ import{__awaiter,__rest}from"tslib";import{DataEventEmitter}from"@js-toolkit/utils/DataEventEmitter";import{ErrorCompat}from"@js-toolkit/utils/ErrorCompat";import{onPageReady}from"../onPageReady";import{isLocalhost}from"./utils";export class ServiceWorkerUnavailableError extends ErrorCompat{constructor(){super(ServiceWorkerUnavailableError,"ServiceWorker is not available",{name:"ServiceWorkerUnavailableError"})}}export class ServiceWorkerInstaller extends DataEventEmitter{static isAvailable(){return"serviceWorker"in navigator}constructor(){super()}destroy(){this.cancelDefferedRegister&&this.cancelDefferedRegister(),this.removeAllListeners()}register(r,e){if(!ServiceWorkerInstaller.isAvailable())throw new ServiceWorkerUnavailableError;const t=null!=e?e:{},{deffered:i}=t,o=__rest(t,["deffered"]),s=()=>__awaiter(this,void 0,void 0,(function*(){try{if(isLocalhost()){const e=yield fetch(r);if(!e.ok)throw new Error(`No service worker found at '${e.url}'.`,{cause:`Response: ${e.status} ${e.statusText}`})}const e=yield navigator.serviceWorker.register(r,o);this.registration=e,this.emit("registered",{registration:e}),e.onupdatefound=()=>{const r=e.installing;null!=r&&(r.onstatechange=()=>{"installed"===r.state&&(navigator.serviceWorker.controller?this.emit("updatePending",{registration:e}):this.emit("updated",{registration:e}))},r.onerror=r=>{const e=new Error("Error during service worker installation",{cause:r});this.emit("error",{error:e})})}}catch(r){const e=new Error("Error during service worker registration",{cause:r});this.emit("error",{error:e})}}));i?this.cancelDefferedRegister=onPageReady(s,"number"==typeof i?{timeout:i}:void 0):s()}unregister(){var r;this.cancelDefferedRegister&&this.cancelDefferedRegister(),null===(r=this.registration)||void 0===r||r.unregister().catch((r=>{const e=new Error("Error during service worker unregister",{cause:r});this.emit("error",{error:e})}))}}
@@ -0,0 +1,15 @@
1
+ /// <reference lib="webworker" />
2
+ export declare function isLocalhost(hostname?: string): boolean;
3
+ /** Delete all caches that aren't named in `caches`. */
4
+ export declare function removeUnknownCaches<T extends Record<string, string>>(expectedCaches: T): Promise<unknown>;
5
+ export declare function addResourcesToCache(cacheName: string, resources: readonly RequestInfo[]): Promise<void>;
6
+ interface CacheFirstOptions extends Pick<FetchEvent, 'request'> {
7
+ readonly fallbackUrl?: string | undefined;
8
+ readonly logger?: Pick<Console, 'error' | 'debug'> | undefined;
9
+ readonly saveToCache?: ((options: {
10
+ request: Request;
11
+ response: Response;
12
+ }) => boolean) | undefined;
13
+ }
14
+ export declare function cacheFirst(cacheName: string, { request, fallbackUrl, saveToCache, logger }: CacheFirstOptions): Promise<Response>;
15
+ export {};
@@ -0,0 +1 @@
1
+ import{__awaiter}from"tslib";import{getErrorMessage}from"@js-toolkit/utils/getErrorMessage";export function isLocalhost(e=window.location.hostname){return!("localhost"!==e&&"[::1]"!==e&&!e.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/))}export function removeUnknownCaches(e){return caches.keys().then((r=>{const o=new Set(Object.values(e));return Promise.all(r.map((e=>{if(!o.has(e))return caches.delete(e)})))}))}export function addResourcesToCache(e,r){return __awaiter(this,void 0,void 0,(function*(){const o=yield caches.open(e);yield o.addAll(r)}))}export function cacheFirst(e,r){return __awaiter(this,arguments,void 0,(function*(e,{request:r,fallbackUrl:o,saveToCache:t,logger:n=console}){const s=yield caches.open(e),c=yield s.match(r);if(c)return n.debug("Found response in cache:",c),c;n.debug("No response for %s found in cache. About to fetch from network...",r.url);try{const e=yield fetch(r.clone());return n.debug("Response for %s from network is: %O",r.url,e),e.status<400&&(!t||t({request:r,response:e}))?(n.debug("Caching the response to",r.url),s.put(r,e.clone()).catch((e=>{n.error(getErrorMessage(new Error(`Caching error of ${r.url}`,{cause:e})))}))):n.debug("Not caching the response to",r.url),e}catch(e){const r=o&&(yield s.match(o));if(r)return r;throw n.error("Error in fetch handler:",e),e}}))}
package/PipController.js DELETED
@@ -1 +0,0 @@
1
- import{EventEmitter}from"eventemitter3";import{EventEmitterListener}from"./EventEmitterListener";const getPipUnavailableError=()=>new Error("PiP is not available");export class PipController extends EventEmitter{static isApiEnabled(){return!!HTMLVideoElement.prototype.requestPictureInPicture&&!!document.exitPictureInPicture&&!!document.pictureInPictureEnabled}static isWebkitApiEnabled(e){return!!e.webkitSupportsPresentationMode&&e.webkitSupportsPresentationMode("picture-in-picture")}static isAvailable(e){return this.isApiEnabled()&&!e.disablePictureInPicture||this.isWebkitApiEnabled(e)}get Events(){return PipController.Events}constructor(e){if(super(),this.listener=new EventEmitterListener(e),PipController.isAvailable(e)){const e=()=>{this.emit(this.Events.Change,{pip:!0})},t=()=>{this.emit(this.Events.Change,{pip:!1})};PipController.isApiEnabled()?(this.listener.on("enterpictureinpicture",e),this.listener.on("leavepictureinpicture",t)):this.listener.on("webkitpresentationmodechanged",(()=>{let i=this.listener.target.webkitPresentationMode;return()=>{"picture-in-picture"===this.listener.target.webkitPresentationMode?e():"picture-in-picture"===i&&t(),i=this.listener.target.webkitPresentationMode}})(),!0)}}destroy(){return this.exit().finally((()=>{this.removeAllListeners(),this.listener.removeAllListeners()}))}isPip(){return PipController.isApiEnabled()?document.pictureInPictureElement===this.listener.target:"picture-in-picture"===this.listener.target.webkitPresentationMode}getCurrentElement(){return this.isPip()?this.listener.target:null}request(){return new Promise(((e,t)=>{if(this.isPip())e();else{if(!PipController.isAvailable(this.listener.target))throw getPipUnavailableError();PipController.isApiEnabled()?this.listener.target.requestPictureInPicture().then((()=>e()),t):(this.listener.once("webkitpresentationmodechanged",(()=>{"picture-in-picture"===this.listener.target.webkitPresentationMode?e():t(new Error("Something went wrong."))}),!0),this.listener.target.webkitSetPresentationMode("picture-in-picture"))}}))}exit(){return new Promise(((e,t)=>{if(this.isPip()){if(!PipController.isAvailable(this.listener.target))throw getPipUnavailableError();PipController.isApiEnabled()?document.exitPictureInPicture().then(e,t):(this.listener.once("webkitpresentationmodechanged",(()=>{"picture-in-picture"!==this.listener.target.webkitPresentationMode?e():t(new Error("Something went wrong."))}),!0),this.listener.target.webkitSetPresentationMode("inline"))}else e()}))}}!function(e){let t;!function(e){e.Change="change"}(t=e.Events||(e.Events={}))}(PipController||(PipController={}));
@@ -1 +0,0 @@
1
- export function getMediaSource(){return window.MediaSource||window.WebKitMediaSource}
@@ -1,2 +0,0 @@
1
- export * from './getMediaSource';
2
- export * from './isMSESupported';
@@ -1 +0,0 @@
1
- export*from"./getMediaSource";export*from"./isMSESupported";
@@ -1 +0,0 @@
1
- import{getMediaSource}from"./getMediaSource";export function isMSESupported(){var e;return!!(null===(e=getMediaSource())||void 0===e?void 0:e.isTypeSupported)}
@@ -1,8 +0,0 @@
1
- export interface Config {
2
- onUpdate?(registration: ServiceWorkerRegistration): void;
3
- onSuccess?(registration: ServiceWorkerRegistration): void;
4
- }
5
- export declare const UpdateEventType = "SW:UPDATE";
6
- export declare function register(config?: Config | undefined): void;
7
- export declare function unregister(): void;
8
- export declare function addUpdateListener(callback: VoidFunction): void;
package/serviceWorker.js DELETED
@@ -1 +0,0 @@
1
- import appEnv from"@js-toolkit/configs/appEnv";import buildConfig from"@js-toolkit/configs/buildConfig";const logPrefix="SW:";export const UpdateEventType="SW:UPDATE";const isLocalhost=Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||new RegExp(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/).exec(window.location.hostname));function registerValidSW(e,o){navigator.serviceWorker.register(e).then((e=>{e.onupdatefound=()=>{const r=e.installing;null!=r&&(r.onstatechange=()=>{"installed"===r.state&&(navigator.serviceWorker.controller?(console.log(logPrefix,"New content is available and will be used when all tabs for this page are closed. See https://cra.link/PWA."),window.dispatchEvent(new Event(UpdateEventType)),o&&o.onUpdate&&o.onUpdate(e)):(console.log(logPrefix,"Content is cached for offline use."),o&&o.onSuccess&&o.onSuccess(e)))},r.onerror=e=>{console.error(logPrefix,"Installing worker:",e)})}})).catch((e=>{console.error(logPrefix,"Error during service worker registration:",e.message||e)}))}function checkValidServiceWorker(e,o){return fetch(e,{headers:{"Service-Worker":"script"}}).then((r=>{const n=r.headers.get("content-type");404===r.status||null!=n&&!n.includes("javascript")?navigator.serviceWorker.ready.then((e=>{e.unregister().then((()=>{window.location.reload()}))})):registerValidSW(e,o)})).catch((()=>{console.log(logPrefix,"No internet connection found. App is running in offline mode.")}))}export function register(e){if(appEnv.prod&&"serviceWorker"in navigator){const o=buildConfig.client||buildConfig.default.client;if(new URL(o.output.publicPath,window.location.href).origin!==window.location.origin)return void console.warn(logPrefix,"Origins are different.");window.addEventListener("load",(()=>{const r=`${o.output.publicPath}${o.output.sw.swDest}`;isLocalhost?(checkValidServiceWorker(r,e),navigator.serviceWorker.ready.then((()=>{console.log(logPrefix,"This web app is being served cache-first by a service worker. To learn more, visit https://bit.ly/CRA-PWA")}))):registerValidSW(r,e)}))}}export function unregister(){"serviceWorker"in navigator&&navigator.serviceWorker.ready.then((e=>e.unregister())).catch((e=>{console.error(logPrefix,"Error during service worker unregister:",e.message||e)}))}export function addUpdateListener(e){window.addEventListener(UpdateEventType,e)}