@js-toolkit/web-utils 1.47.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 (147) hide show
  1. package/EventEmitterListener.d.ts +58 -0
  2. package/EventEmitterListener.js +1 -0
  3. package/EventEmitterListener.utils.d.ts +30 -0
  4. package/EventEmitterListener.utils.js +1 -0
  5. package/EventListeners.d.ts +8 -0
  6. package/EventListeners.js +1 -0
  7. package/FullscreenController.d.ts +61 -0
  8. package/FullscreenController.js +1 -0
  9. package/LICENSE +21 -0
  10. package/PipController.d.ts +31 -0
  11. package/PipController.js +1 -0
  12. package/README.md +5 -0
  13. package/base64ToDataUrl.d.ts +2 -0
  14. package/base64ToDataUrl.js +1 -0
  15. package/blobToDataUrl.d.ts +2 -0
  16. package/blobToDataUrl.js +1 -0
  17. package/copyToClipboard.d.ts +1 -0
  18. package/copyToClipboard.js +1 -0
  19. package/createLoop.d.ts +8 -0
  20. package/createLoop.js +1 -0
  21. package/createRafLoop.d.ts +10 -0
  22. package/createRafLoop.js +1 -0
  23. package/dataUrlToBlob.d.ts +2 -0
  24. package/dataUrlToBlob.js +1 -0
  25. package/detection/getIOSVersion.d.ts +9 -0
  26. package/detection/getIOSVersion.js +1 -0
  27. package/detection/getUAParserResult.d.ts +2 -0
  28. package/detection/getUAParserResult.js +1 -0
  29. package/detection/isAirPlayAvailable.d.ts +2 -0
  30. package/detection/isAirPlayAvailable.js +1 -0
  31. package/detection/isAndroid.d.ts +2 -0
  32. package/detection/isAndroid.js +1 -0
  33. package/detection/isIOS.d.ts +2 -0
  34. package/detection/isIOS.js +1 -0
  35. package/detection/isMacOS.d.ts +2 -0
  36. package/detection/isMacOS.js +1 -0
  37. package/detection/isMobile.d.ts +2 -0
  38. package/detection/isMobile.js +1 -0
  39. package/detection/isSafari.d.ts +2 -0
  40. package/detection/isSafari.js +1 -0
  41. package/fullscreen.d.ts +29 -0
  42. package/fullscreen.js +1 -0
  43. package/ga/DataLayerProxy.d.ts +8 -0
  44. package/ga/DataLayerProxy.js +1 -0
  45. package/ga/getHandler.d.ts +19 -0
  46. package/ga/getHandler.js +1 -0
  47. package/ga/iframeMessenger.d.ts +7 -0
  48. package/ga/iframeMessenger.js +1 -0
  49. package/ga/types.d.ts +41 -0
  50. package/ga/types.js +1 -0
  51. package/getAppContainer.d.ts +2 -0
  52. package/getAppContainer.js +1 -0
  53. package/getAspectRatio.d.ts +11 -0
  54. package/getAspectRatio.js +1 -0
  55. package/getBrowserLanguage.d.ts +7 -0
  56. package/getBrowserLanguage.js +1 -0
  57. package/getEventAwaiter.d.ts +6 -0
  58. package/getEventAwaiter.js +1 -0
  59. package/getGeoCoordinates.d.ts +2 -0
  60. package/getGeoCoordinates.js +1 -0
  61. package/getGeoLocality.d.ts +5 -0
  62. package/getGeoLocality.js +1 -0
  63. package/getInnerRect.d.ts +6 -0
  64. package/getInnerRect.js +1 -0
  65. package/getInnerXDimensions.d.ts +7 -0
  66. package/getInnerXDimensions.js +1 -0
  67. package/getInnerYDimensions.d.ts +7 -0
  68. package/getInnerYDimensions.js +1 -0
  69. package/getRandomID.d.ts +2 -0
  70. package/getRandomID.js +1 -0
  71. package/getScreenSize.d.ts +6 -0
  72. package/getScreenSize.js +1 -0
  73. package/getSecondsCounter.d.ts +23 -0
  74. package/getSecondsCounter.js +1 -0
  75. package/iframe/getAutoConnectClient.d.ts +15 -0
  76. package/iframe/getAutoConnectClient.js +1 -0
  77. package/iframe/getAutoConnectHost.d.ts +21 -0
  78. package/iframe/getAutoConnectHost.js +1 -0
  79. package/iframe/getAutoConnector.d.ts +32 -0
  80. package/iframe/getAutoConnector.js +1 -0
  81. package/iframe/getOriginFromMessage.d.ts +1 -0
  82. package/iframe/getOriginFromMessage.js +1 -0
  83. package/iframe/isIframeLoaded.d.ts +5 -0
  84. package/iframe/isIframeLoaded.js +1 -0
  85. package/iframe/messages.d.ts +19 -0
  86. package/iframe/messages.js +1 -0
  87. package/iframe/utils.d.ts +3 -0
  88. package/iframe/utils.js +1 -0
  89. package/imageToBlob.d.ts +2 -0
  90. package/imageToBlob.js +1 -0
  91. package/isImageTypeSupported.d.ts +1 -0
  92. package/isImageTypeSupported.js +1 -0
  93. package/isStandaloneApp.d.ts +2 -0
  94. package/isStandaloneApp.js +1 -0
  95. package/isWebPSupported.d.ts +1 -0
  96. package/isWebPSupported.js +1 -0
  97. package/loadImage.d.ts +3 -0
  98. package/loadImage.js +1 -0
  99. package/loadScript.d.ts +4 -0
  100. package/loadScript.js +1 -0
  101. package/media/MediaStreamController.d.ts +15 -0
  102. package/media/MediaStreamController.js +1 -0
  103. package/media/getDurationTime.d.ts +1 -0
  104. package/media/getDurationTime.js +1 -0
  105. package/media/isMediaSeekable.d.ts +1 -0
  106. package/media/isMediaSeekable.js +1 -0
  107. package/media/mse.d.ts +8 -0
  108. package/media/mse.js +1 -0
  109. package/media/resetMedia.d.ts +2 -0
  110. package/media/resetMedia.js +1 -0
  111. package/media/timeRanges.d.ts +3 -0
  112. package/media/timeRanges.js +1 -0
  113. package/media/toggleNativeSubtitles.d.ts +6 -0
  114. package/media/toggleNativeSubtitles.js +1 -0
  115. package/onDOMReady.d.ts +3 -0
  116. package/onDOMReady.js +1 -0
  117. package/onPageReady.d.ts +3 -0
  118. package/onPageReady.js +1 -0
  119. package/package.json +46 -0
  120. package/performance/getNavigationTiming.d.ts +1 -0
  121. package/performance/getNavigationTiming.js +1 -0
  122. package/preventDefault.d.ts +5 -0
  123. package/preventDefault.js +1 -0
  124. package/rafCallback.d.ts +5 -0
  125. package/rafCallback.js +1 -0
  126. package/saveFileAs.d.ts +2 -0
  127. package/saveFileAs.js +1 -0
  128. package/serviceWorker.d.ts +8 -0
  129. package/serviceWorker.js +1 -0
  130. package/stopPropagation.d.ts +4 -0
  131. package/stopPropagation.js +1 -0
  132. package/takeSnapshot.d.ts +9 -0
  133. package/takeSnapshot.js +1 -0
  134. package/toBase64.d.ts +2 -0
  135. package/toBase64.js +1 -0
  136. package/toLocalPoint.d.ts +5 -0
  137. package/toLocalPoint.js +1 -0
  138. package/types/index.d.ts +4 -0
  139. package/types/index.js +1 -0
  140. package/types/refs.d.ts +1 -0
  141. package/types/refs.js +1 -0
  142. package/webrtc/PeerConnection.d.ts +68 -0
  143. package/webrtc/PeerConnection.js +1 -0
  144. package/webrtc/sdputils.d.ts +20 -0
  145. package/webrtc/sdputils.js +1 -0
  146. package/ws/WSController.d.ts +50 -0
  147. package/ws/WSController.js +1 -0
@@ -0,0 +1,58 @@
1
+ import { type DomEventTarget, type GetEventMap as GetDomEventMap, type EmitterTarget, type GetEventType, type GetEventListener } from './EventEmitterListener.utils';
2
+ type GetOnOptions<T extends EmitterTarget> = T extends DomEventTarget ? boolean | AddEventListenerOptions : unknown;
3
+ type GetOnceOptions<T extends EmitterTarget> = T extends DomEventTarget ? boolean | OmitStrict<AddEventListenerOptions, 'once'> : undefined;
4
+ type GetOffOptions<T extends EmitterTarget> = T extends DomEventTarget ? boolean | EventListenerOptions : undefined;
5
+ interface GetListenersOptions {
6
+ event?: string | undefined;
7
+ type?: 'normal' | 'capture' | undefined;
8
+ }
9
+ export declare class EventEmitterListener<T extends EmitterTarget, M extends AnyObject = GetDomEventMap<T>> {
10
+ readonly target: T;
11
+ private readonly interceptor?;
12
+ private readonly normalListeners;
13
+ private readonly captureListeners;
14
+ readonly passiveSupported: boolean;
15
+ constructor(target: T, interceptor?: ((...args: any[]) => [...args: unknown[]] | undefined) | undefined);
16
+ private createWrapper;
17
+ getListenerList<L = unknown>({ event, type }?: GetListenersOptions): L[];
18
+ getListeners<L = unknown>({ event, type }?: GetListenersOptions): Record<string, L[]>;
19
+ has<K extends GetEventType<T>>(type: K, listener?: GetEventListener<T, K, M> | undefined, ...rest: [
20
+ ...(T extends DomEventTarget ? [options?: GetOffOptions<T> | undefined] : []),
21
+ ...unknown[]
22
+ ]): boolean;
23
+ has(type: string, listener?: GetEventListener<T, string, M> | undefined, ...rest: [
24
+ ...(T extends DomEventTarget ? [options?: GetOffOptions<T> | undefined] : []),
25
+ ...unknown[]
26
+ ]): boolean;
27
+ on<K extends GetEventType<T>>(type: K, listener: GetEventListener<T, K, M>, ...rest: [
28
+ ...(T extends DomEventTarget ? [options?: GetOnOptions<T> | undefined] : []),
29
+ ...unknown[]
30
+ ]): this;
31
+ on(type: string, listener: GetEventListener<T, string, M>, ...rest: [
32
+ ...(T extends DomEventTarget ? [options?: GetOnOptions<T> | undefined] : []),
33
+ ...unknown[]
34
+ ]): this;
35
+ once<K extends GetEventType<T>>(type: K, listener: GetEventListener<T, K, M>, ...rest: [
36
+ ...(T extends DomEventTarget ? [options?: GetOnceOptions<T> | undefined] : []),
37
+ ...unknown[]
38
+ ]): this;
39
+ once(type: string, listener: GetEventListener<T, string, M>, ...rest: [
40
+ ...(T extends DomEventTarget ? [options?: GetOnceOptions<T> | undefined] : []),
41
+ ...unknown[]
42
+ ]): this;
43
+ off<K extends GetEventType<T>>(type: K, listener: GetEventListener<T, K, M>, ...rest: [
44
+ ...(T extends DomEventTarget ? [options?: GetOffOptions<T> | undefined] : []),
45
+ ...unknown[]
46
+ ]): this;
47
+ off(type: string, listener: GetEventListener<T, string, M>, ...rest: [
48
+ ...(T extends DomEventTarget ? [options?: GetOffOptions<T> | undefined] : []),
49
+ ...unknown[]
50
+ ]): this;
51
+ removeAllListeners<K extends GetEventType<T>>(type?: K | undefined): this;
52
+ removeAllListeners(type?: string | undefined): this;
53
+ removeAllListenersBut<K extends GetEventType<T>>(...types: K[]): this;
54
+ removeAllListenersBut(...types: string[]): this;
55
+ emit<K extends GetEventType<T>>(type: K, ...args: Parameters<GetEventListener<T, K, M>>): this;
56
+ emit(type: string, ...args: Parameters<GetEventListener<T, string, M>>): this;
57
+ }
58
+ export default EventEmitterListener;
@@ -0,0 +1 @@
1
+ import{isPassiveSupported,isDomEventTarget,isEventTargetLike,normalizeOptions}from"./EventEmitterListener.utils";export class EventEmitterListener{constructor(t,e){this.target=t,this.interceptor=e,this.normalListeners={},this.captureListeners={},this.passiveSupported=isPassiveSupported(),this.target=t}createWrapper(t,e,s,...r){return(...i)=>{s&&this.off(t,e,...r);const n=this.interceptor&&this.interceptor(...i)||i;e(...n)}}getListenerList({event:t,type:e}={}){const s="normal"===e&&this.normalListeners||"capture"===e&&this.captureListeners||void 0;if(s){const e=t?s[t]&&{[t]:s[t]}:s;return e?Object.values(e).flatMap((t=>t?Array.from(t.keys()):[])):[]}return this.getListenerList({event:t,type:"normal"}).concat(this.getListenerList({event:t,type:"capture"}))}getListeners({event:t,type:e}={}){const s="normal"===e&&this.normalListeners||"capture"===e&&this.captureListeners||void 0;if(!s){const e=this.getListeners({event:t,type:"normal"}),s=this.getListeners({event:t,type:"capture"}),r={},i=([t,e])=>{const s=r[t];r[t]=s?s.concat(e):e};return Object.entries(e).forEach(i),Object.entries(s).forEach(i),r}const r=t?s[t]&&{[t]:s[t]}:s;return r?Object.entries(r).reduce(((t,[e,s])=>{const r=s?Array.from(s.keys()):[];return r.length>0&&(t[e]=r),t}),{}):{}}has(t,e,...s){var r;if(!isDomEventTarget(this.target)){const s=this.normalListeners[t];return!!s&&(e?s.has(e):s.size>0)}const i=s[0],n=!0===i||i&&"object"==typeof i&&null!==(r=i.capture)&&void 0!==r&&r?this.captureListeners[t]:this.normalListeners[t];return!!n&&(e?n.has(e):n.size>0)}on(t,e,...s){var r,i,n,o,a,h,l,c;if(!isDomEventTarget(this.target)){const n=null!==(r=this.normalListeners[t])&&void 0!==r?r:new Map;this.normalListeners[t]=n;const o=null!==(i=n.get(e))&&void 0!==i?i:this.interceptor?this.createWrapper(t,e,!1):e;return!n.has(e)&&n.set(e,o),isEventTargetLike(this.target)?this.target.addEventListener(t,o,...s):this.target.on(t,o,...s),this}const u=s[0],p=!0===u||u&&"object"==typeof u&&null!==(n=u.capture)&&void 0!==n&&n,v=null!==(o=u&&"object"==typeof u&&u.once)&&void 0!==o&&o;if(p){const s=null!==(a=this.captureListeners[t])&&void 0!==a?a:new Map;this.captureListeners[t]=s;const r=null!==(h=s.get(e))&&void 0!==h?h:this.createWrapper(t,e,v,u);!s.has(e)&&s.set(e,r),this.target.addEventListener(t,r,normalizeOptions(u))}else{const s=null!==(l=this.normalListeners[t])&&void 0!==l?l:new Map;this.normalListeners[t]=s;const r=null!==(c=s.get(e))&&void 0!==c?c:this.createWrapper(t,e,v,u);!s.has(e)&&s.set(e,r),this.target.addEventListener(t,r,normalizeOptions(u))}return this}once(t,e,...s){var r,i;if(!isDomEventTarget(this.target)){const n=null!==(r=this.normalListeners[t])&&void 0!==r?r:new Map;this.normalListeners[t]=n;const o=null!==(i=n.get(e))&&void 0!==i?i:this.createWrapper(t,e,!0,...s);return!n.has(e)&&n.set(e,o),isEventTargetLike(this.target)?this.target.addEventListener(t,o,...s):this.target.once?this.target.once(t,o,...s):this.target.on(t,o,...s),this}const n=s[0];return this.on(t,e,Object.assign(Object.assign({},"object"==typeof n?n:null!=n&&{capture:n}),{once:!0}))}off(t,e,...s){var r;if(!isDomEventTarget(this.target)){const r=this.normalListeners[t],i=null==r?void 0:r.get(e);return r&&i&&r.delete(e),0===(null==r?void 0:r.size)&&delete this.normalListeners[t],isEventTargetLike(this.target)?this.target.removeEventListener(t,null!=i?i:e,...s):this.target.off(t,null!=i?i:e,...s),this}const i=s[0],n=!0===i||i&&"object"==typeof i&&null!==(r=i.capture)&&void 0!==r&&r,o=n?this.captureListeners[t]:this.normalListeners[t],a=null==o?void 0:o.get(e);return o&&a&&o.delete(e),0===(null==o?void 0:o.size)&&(n?delete this.captureListeners[t]:delete this.normalListeners[t]),this.target.removeEventListener(t,null!=a?a:e,normalizeOptions(i)),this}removeAllListeners(t){if(t){const e=this.normalListeners[t];e&&e.forEach(((e,s)=>this.off(t,s)));const s=this.captureListeners[t];s&&s.forEach(((e,s)=>this.off(t,s,!0)))}else Object.keys(this.normalListeners).forEach((t=>this.removeAllListeners(t))),Object.keys(this.captureListeners).forEach((t=>this.removeAllListeners(t)));return this}removeAllListenersBut(...t){return 0===t.length?this.removeAllListeners():(Object.keys(this.normalListeners).forEach((e=>!t.includes(e)&&this.removeAllListeners(e))),Object.keys(this.captureListeners).forEach((e=>!t.includes(e)&&this.removeAllListeners(e))),this)}emit(t,...e){const[s,...r]=e;return this.getListenerList({event:t}).forEach((t=>{t(s,...r)})),this}}export default EventEmitterListener;
@@ -0,0 +1,30 @@
1
+ export type DomEventTarget = EventTarget;
2
+ export type EventTargetLike = {
3
+ addEventListener: EventEmitterLike['on'];
4
+ removeEventListener: EventEmitterLike['off'];
5
+ };
6
+ export type EventEmitterLike = {
7
+ on: (type: any, listener: AnyFunction, ...rest: any[]) => void;
8
+ once?: ((type: any, listener: AnyFunction, ...rest: any[]) => void) | undefined;
9
+ off: (type: any, listener: AnyFunction, ...rest: any[]) => void;
10
+ };
11
+ export type EmitterTarget = DomEventTarget | EventTargetLike | EventEmitterLike;
12
+ export type GetDomEventType<T extends DomEventTarget> = T['addEventListener'] extends {
13
+ (type: infer K, listener: (this: T, ev: any) => any, options?: boolean | AddEventListenerOptions | undefined): void;
14
+ (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void;
15
+ } ? K : string;
16
+ export type GetDomEventListener<E, EM extends AnyObject> = (ev: E extends keyof EM ? EM[E] : Event, ...rest: unknown[]) => unknown;
17
+ export type GetEventType<T extends EmitterTarget> = T extends DomEventTarget ? GetDomEventType<T> : T extends EventEmitterLike ? T['on'] extends {
18
+ (type: infer K, listener: AnyFunction, ...rest: unknown[]): unknown;
19
+ } ? K : string : T extends EventTargetLike ? T['addEventListener'] extends {
20
+ (type: infer K, listener: AnyFunction, ...rest: unknown[]): unknown;
21
+ } ? 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;
26
+ export declare function isEventTargetLike(target: EmitterTarget): target is EventTargetLike;
27
+ export declare function isDomEventTarget(target: EmitterTarget): target is DomEventTarget;
28
+ export declare function isEventEmitterLike(target: EmitterTarget): target is EventEmitterLike;
29
+ export declare function isPassiveSupported(): boolean;
30
+ export declare function normalizeOptions(options: boolean | AddEventListenerOptions | undefined): typeof options;
@@ -0,0 +1 @@
1
+ import{__rest}from"tslib";import isEmptyObject from"@jstoolkit/utils/isEmptyObject";export function isEventTargetLike(t){return void 0!==t.addEventListener&&void 0!==t.removeEventListener}export function isDomEventTarget(t){return isEventTargetLike(t)&&void 0!==t.dispatchEvent}export function isEventEmitterLike(t){return!isEventTargetLike(t)&&!isDomEventTarget(t)&&void 0!==t.on&&void 0!==t.once&&void 0!==t.off}let passiveSupported=!1;export function isPassiveSupported(){return passiveSupported}try{const t={get passive(){return passiveSupported=!0,!1}};window.addEventListener("__testpassive__",null,t)}catch(e){}export function normalizeOptions(t){if(t&&"object"==typeof t){let e=t;if("passive"in t&&!passiveSupported){const{passive:i}=t;e=__rest(t,["passive"])}return isEmptyObject(e)?void 0:e}return t}
@@ -0,0 +1,8 @@
1
+ import { EventEmitterListener } from './EventEmitterListener';
2
+ import type { EmitterTarget, GetEventMap } from './EventEmitterListener.utils';
3
+ export declare class EventListeners {
4
+ private readonly listeners;
5
+ scope<T extends EmitterTarget, M extends AnyObject = GetEventMap<T>>(target: T, scope?: string): EventEmitterListener<T, M>;
6
+ removeAllListeners<T extends EmitterTarget>(target?: T | undefined, scope?: string): this;
7
+ }
8
+ export default EventListeners;
@@ -0,0 +1 @@
1
+ import{EventEmitterListener}from"./EventEmitterListener";export class EventListeners{constructor(){this.listeners=new Map}scope(e,t){var s,l;const r=null!=t?t:"",n=null!==(s=this.listeners.get(e))&&void 0!==s?s:new Map;!this.listeners.has(e)&&this.listeners.set(e,n);const i=null!==(l=n.get(r))&&void 0!==l?l:new EventEmitterListener(e);return!n.has(r)&&n.set(r,i),i}removeAllListeners(e,t){var s;if(e)if(t){const l=this.listeners.get(e);null===(s=null==l?void 0:l.get(t))||void 0===s||s.removeAllListeners(),null==l||l.delete(t),0===(null==l?void 0:l.size)&&this.listeners.delete(e)}else{const t=this.listeners.get(e);null==t||t.forEach((e=>e.removeAllListeners())),null==t||t.clear(),this.listeners.delete(e)}else this.listeners.forEach((e=>{e.forEach((e=>e.removeAllListeners())),e.clear()})),this.listeners.clear();return this}}export default EventListeners;
@@ -0,0 +1,61 @@
1
+ import { EventEmitter } from 'eventemitter3';
2
+ declare global {
3
+ interface HTMLMediaElement {
4
+ webkitEnterFullscreen?: VoidFunction | undefined;
5
+ webkitExitFullscreen?: VoidFunction | undefined;
6
+ webkitDisplayingFullscreen?: boolean | undefined;
7
+ }
8
+ }
9
+ export declare function enterPseudoFullscreen(element: Element & ElementCSSInlineStyle): VoidFunction;
10
+ export declare class FullscreenController extends EventEmitter<FullscreenController.EventMap> {
11
+ private readonly element;
12
+ private video?;
13
+ get Events(): typeof FullscreenController.Events;
14
+ private exitPseudoFullscreen;
15
+ constructor(element: Element, video?: HTMLVideoElement | undefined);
16
+ private unbindVideo;
17
+ setVideoElement(video: HTMLVideoElement | undefined): void;
18
+ destroy(): Promise<void>;
19
+ get isFullscreenEnabled(): boolean;
20
+ get isAnyFullscreenEnabled(): boolean;
21
+ get isFullscreen(): boolean;
22
+ get isPseudoFullscreen(): boolean;
23
+ get currentElement(): Element | null;
24
+ private changeHandler;
25
+ private errorHandler;
26
+ private beginFullscreenHandler;
27
+ private endFullscreenHandler;
28
+ request(options?: FullscreenController.RequestOptions): Promise<void>;
29
+ exit(): Promise<void>;
30
+ }
31
+ export declare namespace FullscreenController {
32
+ enum Events {
33
+ Change = "change",
34
+ Error = "error"
35
+ }
36
+ type EventMap = DefineAll<Events, {
37
+ [Events.Change]: [
38
+ {
39
+ isFullscreen: boolean;
40
+ video?: boolean | undefined;
41
+ pseudo?: boolean | undefined;
42
+ }
43
+ ];
44
+ [Events.Error]: [
45
+ {
46
+ error: unknown;
47
+ video?: boolean | undefined;
48
+ pseudo?: boolean | undefined;
49
+ }
50
+ ];
51
+ }>;
52
+ interface RequestOptions extends Readonly<FullscreenOptions> {
53
+ /** Used for iOS */
54
+ readonly toggleNativeVideoSubtitles?: boolean | undefined;
55
+ readonly pseudoFullscreenFallback?: boolean | undefined;
56
+ }
57
+ type EventHandler<T extends Events = Events> = EventEmitter.EventListener<EventMap, T>;
58
+ type EventHandlerMap<T extends Events = Events> = {
59
+ [P in T]: EventHandler<P>;
60
+ };
61
+ }
@@ -0,0 +1 @@
1
+ import{__rest}from"tslib";import{EventEmitter}from"eventemitter3";import{fullscreen}from"./fullscreen";import{toggleNativeSubtitles}from"./media/toggleNativeSubtitles";export function enterPseudoFullscreen(e){let t,i;return t={position:e.style.position,left:e.style.left,top:e.style.top,width:e.style.width,height:e.style.height,maxWidth:e.style.maxWidth,maxHeight:e.style.maxHeight,zIndex:e.style.zIndex},i=e,i.style.position="fixed",i.style.left="0px",i.style.top="0px",i.style.width="100%",i.style.height="100%",i.style.maxWidth="100%",i.style.maxHeight="100%",i.style.zIndex="99999",()=>{t&&i&&(i.style.position=t.position,i.style.left=t.left,i.style.top=t.top,i.style.width=t.width,i.style.height=t.height,i.style.maxWidth=t.maxWidth,i.style.maxHeight=t.maxHeight,i.style.zIndex=t.zIndex),t=void 0,i=void 0}}export class FullscreenController extends EventEmitter{get Events(){return FullscreenController.Events}constructor(e,t){if(super(),this.element=e,this.video=t,this.changeHandler=()=>{this.emit(this.Events.Change,{isFullscreen:this.isFullscreen})},this.errorHandler=e=>{this.emit(this.Events.Error,{error:e})},this.beginFullscreenHandler=()=>{this.emit(this.Events.Change,{isFullscreen:!0,video:!0})},this.endFullscreenHandler=()=>{this.emit(this.Events.Change,{isFullscreen:!1,video:!0})},fullscreen.names){const{names:t}=fullscreen;e.addEventListener(t.changeEventName,this.changeHandler),e.addEventListener(t.errorEventName,this.errorHandler)}t&&this.setVideoElement(t)}unbindVideo(){this.video&&(this.video.removeEventListener("webkitbeginfullscreen",this.beginFullscreenHandler),this.video.removeEventListener("webkitendfullscreen",this.endFullscreenHandler),this.video=void 0)}setVideoElement(e){this.unbindVideo(),this.video=e,this.video&&!fullscreen.names&&(this.video.addEventListener("webkitbeginfullscreen",this.beginFullscreenHandler),this.video.addEventListener("webkitendfullscreen",this.endFullscreenHandler))}destroy(){return this.exit().finally((()=>{if(this.removeAllListeners(),this.unbindVideo(),fullscreen.names){const{names:e}=fullscreen;this.element.removeEventListener(e.changeEventName,this.changeHandler),this.element.removeEventListener(e.errorEventName,this.errorHandler)}}))}get isFullscreenEnabled(){return fullscreen.isEnabled()}get isAnyFullscreenEnabled(){var e;return this.isFullscreenEnabled||!!(null===(e=this.video)||void 0===e?void 0:e.webkitEnterFullscreen)}get isFullscreen(){return!!this.currentElement}get isPseudoFullscreen(){return this.isFullscreen&&!!this.exitPseudoFullscreen}get currentElement(){var e;if(fullscreen.isSupported()){if(fullscreen.getElement()===this.element)return this.element}else{if(null===(e=this.video)||void 0===e?void 0:e.webkitDisplayingFullscreen)return this.video;if(this.exitPseudoFullscreen)return this.element}return null}request(e={}){return new Promise(((t,i)=>{if(this.isFullscreen)return void t();const{toggleNativeVideoSubtitles:n,pseudoFullscreenFallback:s}=e,l=__rest(e,["toggleNativeVideoSubtitles","pseudoFullscreenFallback"]);if(fullscreen.isEnabled())return void fullscreen.request(this.element,l).then(t,i);const{video:r}=this;if(null==r?void 0:r.webkitEnterFullscreen){if(n&&r.textTracks.length>0){toggleNativeSubtitles(!0,r.textTracks);const e=()=>{r.removeEventListener("webkitendfullscreen",e),toggleNativeSubtitles(!1,r.textTracks)};r.addEventListener("webkitendfullscreen",e)}const e=()=>{r.removeEventListener("webkitbeginfullscreen",e),t()};return r.addEventListener("webkitbeginfullscreen",e),void r.webkitEnterFullscreen()}if(s)return this.exitPseudoFullscreen=enterPseudoFullscreen(this.element),this.emit(this.Events.Change,{isFullscreen:!0,pseudo:!0}),void t();i(new fullscreen.UnavailableError)}))}exit(){return new Promise(((e,t)=>{if(!this.isFullscreen)return void e();if(fullscreen.isEnabled())return void fullscreen.exit().then(e,t);const{video:i}=this;if(null==i?void 0:i.webkitExitFullscreen){const t=()=>{i.removeEventListener("webkitendfullscreen",t),e()};return i.addEventListener("webkitendfullscreen",t),void i.webkitExitFullscreen()}if(this.exitPseudoFullscreen)return this.exitPseudoFullscreen(),this.exitPseudoFullscreen=void 0,this.emit(this.Events.Change,{isFullscreen:!1,pseudo:!0}),void e();t(new fullscreen.UnavailableError)}))}}!function(e){let t;!function(e){e.Change="change",e.Error="error"}(t=e.Events||(e.Events={}))}(FullscreenController||(FullscreenController={}));
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Vladimir Zhukov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,31 @@
1
+ import { EventEmitter } from 'eventemitter3';
2
+ declare global {
3
+ type VideoPresentationMode = 'inline' | 'picture-in-picture' | 'fullscreen';
4
+ interface HTMLVideoElement {
5
+ webkitSupportsPresentationMode?: ((mode: VideoPresentationMode) => boolean) | undefined;
6
+ webkitPresentationMode: VideoPresentationMode;
7
+ webkitSetPresentationMode: (mode: VideoPresentationMode) => void;
8
+ }
9
+ }
10
+ export declare class PipController extends EventEmitter<PipController.EventMap> {
11
+ private static get isSupported();
12
+ static isEnabled(video: HTMLVideoElement): boolean;
13
+ get Events(): typeof PipController.Events;
14
+ private readonly listener;
15
+ constructor(video: HTMLVideoElement);
16
+ destroy(): Promise<void>;
17
+ get isPip(): boolean;
18
+ get currentElement(): HTMLVideoElement | null;
19
+ request(): Promise<void>;
20
+ exit(): Promise<void>;
21
+ }
22
+ export declare namespace PipController {
23
+ enum Events {
24
+ Change = "change"
25
+ }
26
+ type EventMap = {
27
+ [Events.Change]: [{
28
+ isPip: boolean;
29
+ }];
30
+ };
31
+ }
@@ -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 get isSupported(){return!!HTMLVideoElement.prototype.requestPictureInPicture&&!!document.exitPictureInPicture&&!!document.pictureInPictureEnabled}static isEnabled(e){return this.isSupported||!!e.webkitSupportsPresentationMode&&e.webkitSupportsPresentationMode("picture-in-picture")}get Events(){return PipController.Events}constructor(e){if(super(),this.listener=new EventEmitterListener(e),PipController.isEnabled(e)){const e=()=>{this.emit(this.Events.Change,{isPip:!0})},t=()=>{this.emit(this.Events.Change,{isPip:!1})};PipController.isSupported?(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()}))}get isPip(){return PipController.isSupported?document.pictureInPictureElement===this.listener.target:"picture-in-picture"===this.listener.target.webkitPresentationMode}get currentElement(){return this.isPip?this.listener.target:null}request(){return new Promise(((e,t)=>{if(this.isPip)e();else if(PipController.isSupported)this.listener.target.requestPictureInPicture().then((()=>e()),t);else{if(!PipController.isEnabled(this.listener.target))throw getPipUnavailableError();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.isSupported)document.exitPictureInPicture().then(e,t);else{if(!PipController.isEnabled(this.listener.target))throw getPipUnavailableError();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={}));
package/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # Web Utils
2
+
3
+ [![npm package](https://img.shields.io/npm/v/@js-toolkit/web-utils.svg?style=flat-square)](https://www.npmjs.org/package/@js-toolkit/web-utils)
4
+
5
+ Useful utils for browser environment.
@@ -0,0 +1,2 @@
1
+ export declare function base64ToDataUrl(base64: string, type?: string): string;
2
+ export default base64ToDataUrl;
@@ -0,0 +1 @@
1
+ export function base64ToDataUrl(a,e="image/png"){return`data:${e};base64,${a}`}export default base64ToDataUrl;
@@ -0,0 +1,2 @@
1
+ export declare function blobToDataUrl(blob: Blob): Promise<string>;
2
+ export default blobToDataUrl;
@@ -0,0 +1 @@
1
+ export function blobToDataUrl(e){return new Promise(((o,r)=>{const a=new FileReader;a.onload=()=>{o(a.result)},a.onerror=r,a.readAsDataURL(e)}))}export default blobToDataUrl;
@@ -0,0 +1 @@
1
+ export declare function copyToClipboard(text: string): Promise<void>;
@@ -0,0 +1 @@
1
+ export function copyToClipboard(e){return navigator.clipboard?navigator.clipboard.writeText(e):new Promise(((o,t)=>{const n=document.createElement("textarea");n.textContent=e,n.style.position="fixed",n.style.bottom="-100px",n.readOnly=!0,document.body.appendChild(n);const c=document.createRange();c.selectNode(n);const a=window.getSelection();if(a){a.removeAllRanges(),a.addRange(c),n.setSelectionRange(0,999999);try{document.execCommand("copy",!1),o()}catch(e){t(e)}finally{a.removeAllRanges(),document.body.removeChild(n)}}else t(new Error("No selection for copy to clipboard."))}))}
@@ -0,0 +1,8 @@
1
+ export interface Loop {
2
+ start: (callback: FrameRequestCallback, wait: number) => void;
3
+ stop: VoidFunction;
4
+ call: VoidFunction;
5
+ isActive: () => boolean;
6
+ }
7
+ export declare function createLoop(): Loop;
8
+ export default createLoop;
package/createLoop.js ADDED
@@ -0,0 +1 @@
1
+ export function createLoop(){let e,t,a,n=!1;const o=()=>{n&&a&&(t&&cancelAnimationFrame(t),t=requestAnimationFrame(a))};return{start:(t,r)=>{a=t,n||(n=!0,e=window.setInterval(o,r))},stop:()=>{n&&(n=!1,window.clearInterval(e),t&&cancelAnimationFrame(t))},call:o,isActive:()=>n}}export default createLoop;
@@ -0,0 +1,10 @@
1
+ export interface RafLoopStartOptions {
2
+ readonly suspendTimeout?: number | undefined;
3
+ readonly scope?: AnimationFrameProvider | undefined;
4
+ }
5
+ export interface RafLoop {
6
+ start: (callback: FrameRequestCallback, options?: RafLoopStartOptions | undefined) => void;
7
+ stop: VoidFunction;
8
+ isActive: () => boolean;
9
+ }
10
+ export declare function createRafLoop(): RafLoop;
@@ -0,0 +1 @@
1
+ export function createRafLoop(){let e,o,t,i=!1,n=0,a=window;const r=()=>{o=a.requestAnimationFrame(s)},s=o=>{i&&t&&(t(o),n>0?e=window.setTimeout(r,n):r())};return{start:(e,{suspendTimeout:o=0,scope:s=window}={})=>{t=e,n=o,a=s,i||(i=!0,r())},stop:()=>{i&&(i=!1,window.clearTimeout(e),o&&cancelAnimationFrame(o),o=void 0,n=0,e=void 0)},isActive:()=>i}}
@@ -0,0 +1,2 @@
1
+ export declare function dataUrlToBlob(dataUrl: string): Blob;
2
+ export default dataUrlToBlob;
@@ -0,0 +1 @@
1
+ export function dataUrlToBlob(t){const[e,o]=t.split(","),r=window.atob(o),l=e.split(":")[1].split(";")[0],n=new ArrayBuffer(r.length),a=new Uint8Array(n);for(let t=0;t<r.length;t+=1)a[t]=r.charCodeAt(t);return new Blob([n],{type:l})}export default dataUrlToBlob;
@@ -0,0 +1,9 @@
1
+ declare class Semver {
2
+ readonly major: number;
3
+ readonly minor: number;
4
+ readonly patch: number;
5
+ constructor(major: number, minor: number, patch: number);
6
+ toString(): string;
7
+ }
8
+ export declare function getIOSVersion(): Semver | undefined;
9
+ export default getIOSVersion;
@@ -0,0 +1 @@
1
+ import{getUAParserResult}from"./getUAParserResult";import{isIOS}from"./isIOS";class Semver{constructor(e,t,r){this.major=e,this.minor=t,this.patch=r}toString(){return`${this.major}_${this.minor}_${this.patch}`}}let memo;export function getIOSVersion(){if(void 0===memo){const{os:e}=getUAParserResult(),t=isIOS()&&e.version&&/(\d+)\.(\d+)(?:\.(\d+))?/.exec(e.version);memo=t?new Semver(parseInt(t[1],10)||0,parseInt(t[2],10)||0,parseInt(t[3],10)||0):null}return null!=memo?memo:void 0}export default getIOSVersion;
@@ -0,0 +1,2 @@
1
+ /// <reference types="ua-parser-js" />
2
+ export declare function getUAParserResult(): DeepReadonly<UAParser.IResult>;
@@ -0,0 +1 @@
1
+ import{UAParser}from"ua-parser-js";let result;export function getUAParserResult(){if(null==result){const r=new UAParser(navigator.userAgent);result=r.getResult()}return result}
@@ -0,0 +1,2 @@
1
+ export declare function isAirPlayAvailable(): boolean;
2
+ export default isAirPlayAvailable;
@@ -0,0 +1 @@
1
+ export function isAirPlayAvailable(){return!!window.WebKitPlaybackTargetAvailabilityEvent}export default isAirPlayAvailable;
@@ -0,0 +1,2 @@
1
+ export declare function isAndroid(): boolean;
2
+ export default isAndroid;
@@ -0,0 +1 @@
1
+ import{getUAParserResult}from"./getUAParserResult";export function isAndroid(){const r=getUAParserResult().os.name;return"Android"===r||"Android-x86"===r}export default isAndroid;
@@ -0,0 +1,2 @@
1
+ export declare function isIOS(): boolean;
2
+ export default isIOS;
@@ -0,0 +1 @@
1
+ import{getUAParserResult}from"./getUAParserResult";export function isIOS(){return"iOS"===getUAParserResult().os.name}export default isIOS;
@@ -0,0 +1,2 @@
1
+ export declare function isMacOS(): boolean;
2
+ export default isMacOS;
@@ -0,0 +1 @@
1
+ import{getUAParserResult}from"./getUAParserResult";export function isMacOS(){return"Mac OS"===getUAParserResult().os.name}export default isMacOS;
@@ -0,0 +1,2 @@
1
+ export declare function isMobile(): boolean;
2
+ export default isMobile;
@@ -0,0 +1 @@
1
+ import{getUAParserResult}from"./getUAParserResult";export function isMobile(){const e=getUAParserResult().device.type;return"mobile"===e||"tablet"===e}export default isMobile;
@@ -0,0 +1,2 @@
1
+ export declare function isSafari(): boolean;
2
+ export default isSafari;
@@ -0,0 +1 @@
1
+ import{getUAParserResult}from"./getUAParserResult";export function isSafari(){const r=getUAParserResult().browser.name;return"Safari"===r||"Mobile Safari"===r}export default isSafari;
@@ -0,0 +1,29 @@
1
+ export declare class FullscreenUnavailableError extends Error {
2
+ constructor();
3
+ }
4
+ export declare namespace fullscreen {
5
+ interface FnNames {
6
+ readonly requestFullscreenName: string;
7
+ readonly exitFullscreenName: string;
8
+ readonly fullscreenElementName: string;
9
+ readonly fullscreenEnabledName: string;
10
+ readonly changeEventName: string;
11
+ readonly errorEventName: string;
12
+ }
13
+ export const names: FnNames | undefined;
14
+ export type EventType = 'change' | 'error';
15
+ export const UnavailableError: typeof FullscreenUnavailableError;
16
+ export function isSupported(): boolean;
17
+ export function isEnabled(): boolean;
18
+ export function isFullscreen(): boolean;
19
+ export function getElement(): Element | null | undefined;
20
+ export function on(type: EventType, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void;
21
+ export function off(type: EventType, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions | undefined): void;
22
+ export function request(elem: Element, options?: FullscreenOptions | undefined): Promise<void>;
23
+ export function exit(): Promise<void>;
24
+ export function toggle(elem: Element): Promise<void>;
25
+ export function onChange(listener: EventListenerOrEventListenerObject): void;
26
+ export function onError(listener: EventListenerOrEventListenerObject): void;
27
+ export {};
28
+ }
29
+ export default fullscreen;
package/fullscreen.js ADDED
@@ -0,0 +1 @@
1
+ import es5ErrorCompat from"@jstoolkit/utils/es5ErrorCompat";export class FullscreenUnavailableError extends Error{constructor(){super("Fullscreen is not available"),es5ErrorCompat(this,FullscreenUnavailableError)}}export var fullscreen;!function(e){e.names=[{requestFullscreenName:"requestFullscreen",exitFullscreenName:"exitFullscreen",fullscreenElementName:"fullscreenElement",fullscreenEnabledName:"fullscreenEnabled",changeEventName:"fullscreenchange",errorEventName:"fullscreenerror"},{requestFullscreenName:"webkitRequestFullscreen",exitFullscreenName:"webkitExitFullscreen",fullscreenElementName:"webkitFullscreenElement",fullscreenEnabledName:"webkitFullscreenEnabled",changeEventName:"webkitfullscreenchange",errorEventName:"webkitfullscreenerror"},{requestFullscreenName:"webkitRequestFullScreen",exitFullscreenName:"webkitCancelFullScreen",fullscreenElementName:"webkitCurrentFullScreenElement",fullscreenEnabledName:"webkitCancelFullScreen",changeEventName:"webkitfullscreenchange",errorEventName:"webkitfullscreenerror"},{requestFullscreenName:"mozRequestFullScreen",exitFullscreenName:"mozCancelFullScreen",fullscreenElementName:"mozFullScreenElement",fullscreenEnabledName:"mozFullScreenEnabled",changeEventName:"mozfullscreenchange",errorEventName:"mozfullscreenerror"},{requestFullscreenName:"msRequestFullscreen",exitFullscreenName:"msExitFullscreen",fullscreenElementName:"msFullscreenElement",fullscreenEnabledName:"msFullscreenEnabled",changeEventName:"MSFullscreenChange",errorEventName:"MSFullscreenError"}].find((({exitFullscreenName:e})=>e in document));const n={change:null===e.names||void 0===e.names?void 0:e.names.changeEventName,error:null===e.names||void 0===e.names?void 0:e.names.errorEventName};function r(){if(!e.names)throw new e.UnavailableError;return Boolean(document[e.names.fullscreenElementName])}function l(e,r,l){const a=n[e];a&&document.addEventListener(a,r,l)}function a(e,r,l){const a=n[e];a&&document.removeEventListener(a,r,l)}function t(n,r){return new Promise(((t,s)=>{if(!e.names)throw new e.UnavailableError;const c=()=>{a("change",c),a("error",u),t()},u=e=>{a("change",c),a("error",u),s(e)};l("change",c),l("error",u);const o=n[e.names.requestFullscreenName](r);o instanceof Promise&&o.then(c,u)}))}function s(){return new Promise(((n,t)=>{if(!e.names)throw new e.UnavailableError;if(!r)return void n();const s=()=>{a("change",s),a("error",c),n()},c=e=>{a("change",s),a("error",c),t(e)};l("change",s),l("error",c);const u=document[e.names.exitFullscreenName]();u instanceof Promise&&u.then(s,c)}))}e.UnavailableError=FullscreenUnavailableError,e.isSupported=function(){return!!e.names},e.isEnabled=function(){return!!e.names&&Boolean(document[e.names.fullscreenEnabledName])},e.isFullscreen=r,e.getElement=function(){if(!e.names)throw new e.UnavailableError;return document[e.names.fullscreenElementName]},e.on=l,e.off=a,e.request=t,e.exit=s,e.toggle=function(e){return Promise.resolve().then((()=>r()?s():t(e)))},e.onChange=function(e){l("change",e)},e.onError=function(e){l("error",e)}}(fullscreen||(fullscreen={}));export default fullscreen;
@@ -0,0 +1,8 @@
1
+ import { type GAEventData, type GAEventDataTransformerMap } from './getHandler';
2
+ export type { GAEventData };
3
+ export declare class DataLayerProxy<D extends GAEventData> {
4
+ private readonly handler;
5
+ constructor(transformers: GAEventDataTransformerMap<D>);
6
+ push(data: D): void;
7
+ }
8
+ export default DataLayerProxy;
@@ -0,0 +1 @@
1
+ import getHandler,{}from"./getHandler";export class DataLayerProxy{constructor(r){const a=getHandler("auto",r);if(!a)throw new Error("Data layer for Google Analytics is undefined.");this.handler=a}push(r){this.handler(r)}}export default DataLayerProxy;
@@ -0,0 +1,19 @@
1
+ import { type GAEventMessage } from './iframeMessenger';
2
+ import './types';
3
+ export interface GAEventData {
4
+ eventCategory: string;
5
+ action: string;
6
+ label: string | undefined;
7
+ trackingId: string | undefined;
8
+ }
9
+ export interface GADataHandler<D extends GAEventData> {
10
+ (data: D): void;
11
+ }
12
+ type GALibType = 'gtm' | 'gtag' | 'ga' | 'iframe' | 'auto';
13
+ export type GAEventDataTransformer<D extends GAEventData, L extends Extract<GALibType, 'gtm' | 'iframe'>> = (data: D) => {
14
+ gtm: GTMEventData;
15
+ iframe: GAEventMessage<string, D>;
16
+ }[L];
17
+ export type GAEventDataTransformerMap<D extends GAEventData, L extends Extract<GALibType, 'gtm' | 'iframe'> = Extract<GALibType, 'gtm' | 'iframe'>> = L extends L ? Record<L, GAEventDataTransformer<D, L>> : never;
18
+ export declare function getHandler<D extends GAEventData, L extends GALibType>(gaLib: L, transformers: L extends 'auto' | 'gtm' | 'iframe' ? GAEventDataTransformerMap<D> : undefined): GADataHandler<D> | undefined;
19
+ export default getHandler;
@@ -0,0 +1 @@
1
+ import iframeMessenger,{}from"./iframeMessenger";import"./types";function gtmHandler(e,n,t){e.push(n(t))}function gtagHandler(e,n){const{action:t,eventCategory:a,trackingId:o,label:i}=n;e("event",t,{send_to:o,event_category:a,event_label:i,value:void 0})}function gaHandler(e,n,t){const a=window[e];if(!a)return;const{action:o,eventCategory:i,trackingId:r,label:d}=t,g={hitType:"event",eventCategory:i,eventAction:o,eventLabel:d,eventValue:void 0};if(r){const e=()=>{var e;const t=null!==(e=n[r])&&void 0!==e?e:a.getAll().find((e=>e.get("trackingId")===r));t&&(n[r]=t,t.send(g))};a.loaded?e():a(e)}else a("send",g)}export function getHandler(e,n){switch(e){case"auto":return window.gtag?getHandler("gtag",void 0):window.GoogleAnalyticsObject&&window[window.GoogleAnalyticsObject]||window.ga?getHandler("ga",void 0):window.dataLayer?getHandler("gtm",n):window.parent!==window?getHandler("iframe",n):void 0;case"iframe":return e=>{const t=n.iframe(e);iframeMessenger(t.type,t.event)};case"gtm":{const{dataLayer:e}=window;return e?t=>{gtmHandler(e,n.gtm,t)}:void 0}case"gtag":return window.gtag?gtagHandler.bind(void 0,window.gtag):void 0;case"ga":{const e=window.GoogleAnalyticsObject||"ga";return window[e]?gaHandler.bind(void 0,e,{}):void 0}default:throw new Error(`Unknown GA lib type '${e}'.`)}}export default getHandler;
@@ -0,0 +1,7 @@
1
+ import type { GAEventData } from './getHandler';
2
+ export interface GAEventMessage<T extends string = string, D extends GAEventData = GAEventData> {
3
+ type: T;
4
+ event: D;
5
+ }
6
+ export declare function iframeMessenger<T extends string, D extends GAEventData>(type: T, data: D): void;
7
+ export default iframeMessenger;
@@ -0,0 +1 @@
1
+ export function iframeMessenger(e,t){window.parent.postMessage({type:e,event:t},"*")}export default iframeMessenger;
package/ga/types.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ interface GTMEventData {
2
+ event: string;
3
+ }
4
+ interface GTMDataLayer<D extends GTMEventData> {
5
+ push: (data: D) => unknown;
6
+ }
7
+ interface GTagEventData {
8
+ event_category: string;
9
+ event_label: string | undefined;
10
+ value: number | undefined;
11
+ send_to: string | undefined;
12
+ }
13
+ type GTagParams = [type: 'event', event: string, data: GTagEventData];
14
+ interface GAObjectEventData {
15
+ hitType: 'event';
16
+ eventCategory: string;
17
+ eventAction: string;
18
+ eventLabel: string | undefined;
19
+ eventValue: number | undefined;
20
+ }
21
+ type GACommandParams = [command: 'send', data: GAObjectEventData];
22
+ interface GATracker {
23
+ get(field: string): unknown;
24
+ send(data: GAObjectEventData): void;
25
+ }
26
+ interface GAObject {
27
+ readonly loaded?: boolean | undefined;
28
+ getAll(): GATracker[];
29
+ (...params: GACommandParams): void;
30
+ (readyCallback: VoidFunction): void;
31
+ }
32
+ interface Window {
33
+ /** Universal Analytics object name, default `ga`. */
34
+ GoogleAnalyticsObject?: string | undefined;
35
+ /** Universal Analytics without gtag. */
36
+ ga?: GAObject | undefined;
37
+ /** Global Site Tag */
38
+ gtag?: ((...params: GTagParams) => void) | undefined;
39
+ /** Google Tag Manager */
40
+ dataLayer?: GTMDataLayer<GTMEventData> | undefined;
41
+ }
package/ga/types.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,2 @@
1
+ export declare function getAppContainer(id?: string): HTMLElement;
2
+ export default getAppContainer;
@@ -0,0 +1 @@
1
+ export function getAppContainer(t="root"){const n=document.getElementById(t);if(!n)throw new Error(`Container "${t}" for app not found.`);return n}export default getAppContainer;
@@ -0,0 +1,11 @@
1
+ export interface AspectRatio {
2
+ /** Approximate width ratio */
3
+ width: number;
4
+ /** Approximate height ratio */
5
+ height: number;
6
+ /** Actual ratio value */
7
+ ratio: number;
8
+ }
9
+ /** Approximate aspect ratio */
10
+ export declare function getAspectRatio(width: number, height: number): AspectRatio;
11
+ export default getAspectRatio;
@@ -0,0 +1 @@
1
+ import farey from"@jstoolkit/utils/farey";export function getAspectRatio(t,e){const o=t/e,[r,i]=farey(o,50);return{width:r,height:i,ratio:o}}export default getAspectRatio;
@@ -0,0 +1,7 @@
1
+ declare global {
2
+ interface Navigator {
3
+ userLanguage: string;
4
+ }
5
+ }
6
+ export declare function getBrowserLanguage(): string | undefined;
7
+ export default getBrowserLanguage;
@@ -0,0 +1 @@
1
+ export function getBrowserLanguage(){if("undefined"!=typeof window&&"navigator"in window){return(navigator.languages&&navigator.languages.length>0?navigator.languages[0]:navigator.language||navigator.userLanguage).split("-")[0]}}export default getBrowserLanguage;
@@ -0,0 +1,6 @@
1
+ import { type Awaiter } from '@jstoolkit/utils/getAwaiter';
2
+ import { type EmitterTarget, type GetEventType } from './EventEmitterListener.utils';
3
+ export type EventAwaiter = Awaiter<void>;
4
+ export declare function getEventAwaiter<T extends EmitterTarget, E extends GetEventType<T>>(target: T, resolveEvent: E | E[], rejectEvent?: E | E[],
5
+ /** If it returns null or undefined then reject is ignored. */
6
+ eventToError?: (event: any) => unknown): EventAwaiter;
@@ -0,0 +1 @@
1
+ import{getAwaiter}from"@jstoolkit/utils/getAwaiter";import{EventEmitterListener}from"./EventEmitterListener";import{isEventEmitterLike}from"./EventEmitterListener.utils";export function getEventAwaiter(t,e,r,i){const o=getAwaiter({lazy:!0}),n=Array.isArray(e)?e:[e],s=Array.isArray(r)?r:[r],E=isEventEmitterLike(t)?t:new EventEmitterListener(t),a=()=>{n.forEach((t=>E.off(t,m))),s.forEach((t=>E.off(t,m)))},c=o.resolve;o.resolve=(...t)=>{a(),c(...t)};const f=o.reject;o.reject=(...t)=>{f(...t),a()};const m=()=>{o.resolve()},v=t=>{const e=i?i(t):t;null!=e&&o.reject(e)};return n.forEach((t=>E.on(t,m))),s.forEach((t=>E.on(t,v))),o}
@@ -0,0 +1,2 @@
1
+ export declare function getGeoCoordinates({ timeout, maximumAge, ...rest }?: PositionOptions): Promise<GeolocationPosition>;
2
+ export default getGeoCoordinates;
@@ -0,0 +1 @@
1
+ import{__rest}from"tslib";export function getGeoCoordinates(e={}){var{timeout:t=1e4,maximumAge:o=6e4}=e,i=__rest(e,["timeout","maximumAge"]);return new Promise(((e,m)=>{navigator.geolocation.getCurrentPosition((t=>e(t)),(e=>m(e)),Object.assign({timeout:t,maximumAge:o},i))}))}export default getGeoCoordinates;
@@ -0,0 +1,5 @@
1
+ export interface GeoLocalityOptions extends Pick<GeolocationCoordinates, 'longitude' | 'latitude'> {
2
+ lang?: string | undefined;
3
+ }
4
+ export declare function getGeoLocality({ longitude, latitude, lang }: GeoLocalityOptions): Promise<string>;
5
+ export default getGeoLocality;
@@ -0,0 +1 @@
1
+ export function getGeoLocality({longitude:e,latitude:r,lang:t}){const o=new URL("https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode");return o.searchParams.set("f","json"),o.searchParams.set("featureTypes","Locality"),o.searchParams.set("location",`{ x: ${e}, y: ${r} }`),t&&o.searchParams.set("langCode",t),window.fetch(o.toString()).then((e=>e.json())).then((e=>{const{address:r,error:t}=e;if(t)throw new Error(t.message);return r.PlaceName||r.LongLabel||r.ShortLabel||""}))}export default getGeoLocality;
@@ -0,0 +1,6 @@
1
+ import { type InnerXDimensions } from './getInnerXDimensions';
2
+ import { type InnerYDimensions } from './getInnerYDimensions';
3
+ export interface InnerRect extends InnerXDimensions, InnerYDimensions {
4
+ }
5
+ export declare function getInnerRect(elementOrComputedStyle: Element | CSSStyleDeclaration): InnerRect;
6
+ export default getInnerRect;