@tma.js/sdk 1.4.4 → 1.4.7

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 (298) hide show
  1. package/README.md +2 -2
  2. package/dist/dts/bridge/env/index.d.ts +0 -1
  3. package/dist/dts/bridge/events/events.d.ts +16 -16
  4. package/dist/dts/bridge/methods/methods.d.ts +27 -27
  5. package/dist/dts/bridge/methods/popup.d.ts +1 -1
  6. package/dist/dts/index.d.ts +3 -3
  7. package/dist/dts/init-data/types.d.ts +3 -3
  8. package/dist/dts/launch-params/index.d.ts +1 -4
  9. package/dist/dts/launch-params/retrieveFromLocation.d.ts +2 -2
  10. package/dist/dts/launch-params/retrieveFromPerformance.d.ts +3 -4
  11. package/dist/dts/launch-params/retrieveFromUrl.d.ts +3 -2
  12. package/dist/dts/launch-params/retrieveLaunchData.d.ts +1 -0
  13. package/dist/dts/launch-params/retrieveLaunchParams.d.ts +6 -0
  14. package/dist/dts/launch-params/storage.d.ts +3 -5
  15. package/dist/dts/launch-params/types.d.ts +1 -1
  16. package/dist/dts/{launch-params → misc}/getFirstNavigationEntry.d.ts +1 -1
  17. package/dist/dts/misc/index.d.ts +3 -0
  18. package/dist/dts/{bridge/env → misc}/isIframe.d.ts +1 -1
  19. package/dist/dts/misc/isPageReload.d.ts +5 -0
  20. package/dist/dts/theme-params/types.d.ts +1 -1
  21. package/dist/index.cjs +1 -2
  22. package/dist/index.iife.js +1 -2
  23. package/dist/index.mjs +841 -866
  24. package/package.json +2 -3
  25. package/dist/dts/launch-params/computeLaunchData.d.ts +0 -6
  26. package/dist/dts/launch-params/computePageReload.d.ts +0 -6
  27. package/dist/dts/launch-params/retrieveCurrent.d.ts +0 -5
  28. package/dist/index.cjs.map +0 -1
  29. package/dist/index.iife.js.map +0 -1
  30. package/dist/index.mjs.map +0 -1
  31. package/src/__tests__/globals.ts +0 -39
  32. package/src/back-button/BackButton.ts +0 -90
  33. package/src/back-button/__tests__/BackButton.ts +0 -129
  34. package/src/back-button/index.ts +0 -2
  35. package/src/back-button/types.ts +0 -14
  36. package/src/bridge/__tests__/parseMessage.ts +0 -23
  37. package/src/bridge/__tests__/request.ts +0 -236
  38. package/src/bridge/env/__tests__/hasExternalNotify.ts +0 -15
  39. package/src/bridge/env/__tests__/hasWebviewProxy.ts +0 -15
  40. package/src/bridge/env/__tests__/isIframe.ts +0 -30
  41. package/src/bridge/env/hasExternalNotify.ts +0 -19
  42. package/src/bridge/env/hasWebviewProxy.ts +0 -19
  43. package/src/bridge/env/index.ts +0 -3
  44. package/src/bridge/env/isIframe.ts +0 -11
  45. package/src/bridge/errors/MethodUnsupportedError.ts +0 -13
  46. package/src/bridge/errors/ParameterUnsupportedError.ts +0 -13
  47. package/src/bridge/errors/index.ts +0 -2
  48. package/src/bridge/events/__tests__/createEmitter.ts +0 -143
  49. package/src/bridge/events/__tests__/off.ts +0 -34
  50. package/src/bridge/events/__tests__/on.ts +0 -49
  51. package/src/bridge/events/__tests__/onTelegramEvent.ts +0 -49
  52. package/src/bridge/events/__tests__/once.ts +0 -64
  53. package/src/bridge/events/__tests__/singletonEmitter.ts +0 -22
  54. package/src/bridge/events/__tests__/subscribe.ts +0 -49
  55. package/src/bridge/events/__tests__/unsubscribe.ts +0 -34
  56. package/src/bridge/events/createEmitter.ts +0 -108
  57. package/src/bridge/events/events.ts +0 -170
  58. package/src/bridge/events/index.ts +0 -9
  59. package/src/bridge/events/off.ts +0 -14
  60. package/src/bridge/events/on.ts +0 -19
  61. package/src/bridge/events/onTelegramEvent.ts +0 -81
  62. package/src/bridge/events/once.ts +0 -18
  63. package/src/bridge/events/parsers/__tests__/clipboardTextReceived.ts +0 -21
  64. package/src/bridge/events/parsers/__tests__/invoiceClosed.ts +0 -12
  65. package/src/bridge/events/parsers/__tests__/popupClosed.ts +0 -10
  66. package/src/bridge/events/parsers/__tests__/qrTextReceived.ts +0 -9
  67. package/src/bridge/events/parsers/__tests__/theme-changed.ts +0 -42
  68. package/src/bridge/events/parsers/__tests__/viewportChanged.ts +0 -49
  69. package/src/bridge/events/parsers/clipboardTextReceived.ts +0 -26
  70. package/src/bridge/events/parsers/customMethodInvoked.ts +0 -25
  71. package/src/bridge/events/parsers/index.ts +0 -9
  72. package/src/bridge/events/parsers/invoiceClosed.ts +0 -26
  73. package/src/bridge/events/parsers/phoneRequested.ts +0 -14
  74. package/src/bridge/events/parsers/popupClosed.ts +0 -19
  75. package/src/bridge/events/parsers/qrTextReceived.ts +0 -14
  76. package/src/bridge/events/parsers/theme-changed.ts +0 -58
  77. package/src/bridge/events/parsers/viewportChanged.ts +0 -33
  78. package/src/bridge/events/parsers/writeAccessRequested.ts +0 -14
  79. package/src/bridge/events/singletonEmitter.ts +0 -19
  80. package/src/bridge/events/subscribe.ts +0 -15
  81. package/src/bridge/events/unsubscribe.ts +0 -10
  82. package/src/bridge/index.ts +0 -7
  83. package/src/bridge/invokeCustomMethod.ts +0 -56
  84. package/src/bridge/methods/__tests__/createPostEvent.ts +0 -37
  85. package/src/bridge/methods/__tests__/postEvent.ts +0 -137
  86. package/src/bridge/methods/createPostEvent.ts +0 -40
  87. package/src/bridge/methods/custom-methods.ts +0 -68
  88. package/src/bridge/methods/haptic.ts +0 -52
  89. package/src/bridge/methods/index.ts +0 -6
  90. package/src/bridge/methods/methods.ts +0 -370
  91. package/src/bridge/methods/popup.ts +0 -53
  92. package/src/bridge/methods/postEvent.ts +0 -101
  93. package/src/bridge/parseMessage.ts +0 -28
  94. package/src/bridge/request.ts +0 -176
  95. package/src/classnames/__tests__/classNames.ts +0 -20
  96. package/src/classnames/__tests__/mergeClassNames.ts +0 -21
  97. package/src/classnames/classNames.ts +0 -34
  98. package/src/classnames/index.ts +0 -2
  99. package/src/classnames/mergeClassNames.ts +0 -60
  100. package/src/closing-behavior/ClosingBehavior.ts +0 -64
  101. package/src/closing-behavior/__tests__/ClosingBehavior.ts +0 -86
  102. package/src/closing-behavior/index.ts +0 -2
  103. package/src/closing-behavior/types.ts +0 -12
  104. package/src/cloud-storage/CloudStorage.ts +0 -138
  105. package/src/cloud-storage/index.ts +0 -1
  106. package/src/colors/__tests__/isColorDark.ts +0 -12
  107. package/src/colors/__tests__/isRGB.ts +0 -13
  108. package/src/colors/__tests__/isRGBShort.ts +0 -13
  109. package/src/colors/__tests__/toRGB.ts +0 -23
  110. package/src/colors/index.ts +0 -5
  111. package/src/colors/isColorDark.ts +0 -22
  112. package/src/colors/isRGB.ts +0 -9
  113. package/src/colors/isRGBShort.ts +0 -9
  114. package/src/colors/toRGB.ts +0 -49
  115. package/src/colors/types.ts +0 -9
  116. package/src/css/__tests__/bindMiniAppCSSVars.ts +0 -175
  117. package/src/css/__tests__/bindThemeCSSVars.ts +0 -52
  118. package/src/css/__tests__/bindViewportCSSVars.ts +0 -55
  119. package/src/css/__tests__/setCSSVar.ts +0 -14
  120. package/src/css/bindMiniAppCSSVars.ts +0 -51
  121. package/src/css/bindThemeCSSVars.ts +0 -31
  122. package/src/css/bindViewportCSSVars.ts +0 -36
  123. package/src/css/index.ts +0 -4
  124. package/src/css/setCSSVar.ts +0 -8
  125. package/src/event-emitter/EventEmitter.ts +0 -146
  126. package/src/event-emitter/__tests__/EventEmitter.ts +0 -145
  127. package/src/event-emitter/index.ts +0 -2
  128. package/src/event-emitter/types.ts +0 -60
  129. package/src/globals.ts +0 -38
  130. package/src/haptic-feedback/HapticFeedback.ts +0 -70
  131. package/src/haptic-feedback/__tests__/HapticFeedback.ts +0 -68
  132. package/src/haptic-feedback/index.ts +0 -1
  133. package/src/index.ts +0 -185
  134. package/src/init/catchCustomStyles.ts +0 -17
  135. package/src/init/creators/__tests__/createViewport.ts +0 -96
  136. package/src/init/creators/createBackButton.ts +0 -25
  137. package/src/init/creators/createClosingBehavior.ts +0 -24
  138. package/src/init/creators/createMainButton.ts +0 -51
  139. package/src/init/creators/createMiniApp.ts +0 -48
  140. package/src/init/creators/createRequestIdGenerator.ts +0 -13
  141. package/src/init/creators/createSettingsButton.ts +0 -25
  142. package/src/init/creators/createThemeParams.ts +0 -11
  143. package/src/init/creators/createViewport.ts +0 -94
  144. package/src/init/creators/index.ts +0 -8
  145. package/src/init/css/index.ts +0 -1
  146. package/src/init/css/processCSSVarsOption.ts +0 -55
  147. package/src/init/index.ts +0 -2
  148. package/src/init/init.ts +0 -134
  149. package/src/init/types.ts +0 -94
  150. package/src/init-data/InitData.ts +0 -96
  151. package/src/init-data/__tests__/InitData.ts +0 -98
  152. package/src/init-data/__tests__/chatParser.ts +0 -102
  153. package/src/init-data/__tests__/initDataParser.ts +0 -136
  154. package/src/init-data/__tests__/parseInitData.ts +0 -136
  155. package/src/init-data/__tests__/userParser.ts +0 -96
  156. package/src/init-data/chatParser.ts +0 -19
  157. package/src/init-data/index.ts +0 -6
  158. package/src/init-data/initDataParser.ts +0 -41
  159. package/src/init-data/parseInitData.ts +0 -10
  160. package/src/init-data/types.ts +0 -164
  161. package/src/init-data/userParser.ts +0 -45
  162. package/src/invoice/Invoice.ts +0 -123
  163. package/src/invoice/index.ts +0 -2
  164. package/src/invoice/types.ts +0 -11
  165. package/src/launch-params/__tests__/retrieveFromUrl.ts +0 -19
  166. package/src/launch-params/computeLaunchData.ts +0 -81
  167. package/src/launch-params/computePageReload.ts +0 -13
  168. package/src/launch-params/getFirstNavigationEntry.ts +0 -10
  169. package/src/launch-params/index.ts +0 -13
  170. package/src/launch-params/launchParamsParser.ts +0 -45
  171. package/src/launch-params/parseLaunchParams.ts +0 -10
  172. package/src/launch-params/retrieveCurrent.ts +0 -27
  173. package/src/launch-params/retrieveFromLocation.ts +0 -10
  174. package/src/launch-params/retrieveFromPerformance.ts +0 -18
  175. package/src/launch-params/retrieveFromUrl.ts +0 -19
  176. package/src/launch-params/retrieveLaunchData.ts +0 -30
  177. package/src/launch-params/serializeLaunchParams.ts +0 -37
  178. package/src/launch-params/storage.ts +0 -33
  179. package/src/launch-params/types.ts +0 -62
  180. package/src/logger/Logger.ts +0 -72
  181. package/src/logger/__tests__/Logger.ts +0 -107
  182. package/src/logger/index.ts +0 -1
  183. package/src/main-button/MainButton.ts +0 -239
  184. package/src/main-button/__tests__/MainButton.ts +0 -346
  185. package/src/main-button/index.ts +0 -2
  186. package/src/main-button/types.ts +0 -26
  187. package/src/mini-app/MiniApp.ts +0 -348
  188. package/src/mini-app/__tests__/MiniApp.ts +0 -140
  189. package/src/mini-app/contactParser.ts +0 -29
  190. package/src/mini-app/index.ts +0 -2
  191. package/src/mini-app/types.ts +0 -38
  192. package/src/misc/__tests__/isRecord.ts +0 -21
  193. package/src/misc/index.ts +0 -2
  194. package/src/misc/isRecord.ts +0 -7
  195. package/src/misc/isTMA.ts +0 -13
  196. package/src/navigation/HashNavigator/HashNavigator.ts +0 -220
  197. package/src/navigation/HashNavigator/__tests__/HashNavigator.ts +0 -144
  198. package/src/navigation/HashNavigator/__tests__/drop.ts +0 -42
  199. package/src/navigation/HashNavigator/__tests__/go.ts +0 -9
  200. package/src/navigation/HashNavigator/drop.ts +0 -36
  201. package/src/navigation/HashNavigator/go.ts +0 -28
  202. package/src/navigation/HashNavigator/index.ts +0 -2
  203. package/src/navigation/HashNavigator/types.ts +0 -41
  204. package/src/navigation/Navigator/Navigator.ts +0 -282
  205. package/src/navigation/Navigator/index.ts +0 -2
  206. package/src/navigation/Navigator/types.ts +0 -55
  207. package/src/navigation/ensurePrefix.ts +0 -9
  208. package/src/navigation/getHash.ts +0 -17
  209. package/src/navigation/index.ts +0 -4
  210. package/src/parsing/ArrayValueParser.ts +0 -79
  211. package/src/parsing/ParseError.ts +0 -27
  212. package/src/parsing/ParseSchemaFieldError.ts +0 -21
  213. package/src/parsing/ValueParser.ts +0 -71
  214. package/src/parsing/__tests__/ArrayValueParser.ts +0 -18
  215. package/src/parsing/__tests__/toRecord.ts +0 -10
  216. package/src/parsing/createValueParserGenerator.ts +0 -16
  217. package/src/parsing/index.ts +0 -10
  218. package/src/parsing/parseBySchema.ts +0 -65
  219. package/src/parsing/parsers/__tests__/array.ts +0 -39
  220. package/src/parsing/parsers/__tests__/boolean.ts +0 -31
  221. package/src/parsing/parsers/__tests__/date.ts +0 -25
  222. package/src/parsing/parsers/__tests__/json.ts +0 -80
  223. package/src/parsing/parsers/__tests__/number.ts +0 -23
  224. package/src/parsing/parsers/__tests__/rgb.ts +0 -22
  225. package/src/parsing/parsers/__tests__/searchParams.ts +0 -105
  226. package/src/parsing/parsers/__tests__/string.ts +0 -25
  227. package/src/parsing/parsers/array.ts +0 -9
  228. package/src/parsing/parsers/boolean.ts +0 -22
  229. package/src/parsing/parsers/date.ts +0 -11
  230. package/src/parsing/parsers/index.ts +0 -8
  231. package/src/parsing/parsers/json.ts +0 -17
  232. package/src/parsing/parsers/number.ts +0 -21
  233. package/src/parsing/parsers/rgb.ts +0 -10
  234. package/src/parsing/parsers/searchParams.ts +0 -24
  235. package/src/parsing/parsers/string.ts +0 -12
  236. package/src/parsing/toRecord.ts +0 -27
  237. package/src/parsing/types.ts +0 -32
  238. package/src/parsing/unexpectedTypeError.ts +0 -6
  239. package/src/popup/Popup.ts +0 -91
  240. package/src/popup/__tests__/Popup.ts +0 -130
  241. package/src/popup/__tests__/preparePopupParams.ts +0 -85
  242. package/src/popup/index.ts +0 -2
  243. package/src/popup/preparePopupParams.ts +0 -59
  244. package/src/popup/types.ts +0 -69
  245. package/src/qr-scanner/QRScanner.ts +0 -95
  246. package/src/qr-scanner/index.ts +0 -2
  247. package/src/qr-scanner/types.ts +0 -11
  248. package/src/settings-button/SettingsButton.ts +0 -85
  249. package/src/settings-button/index.ts +0 -2
  250. package/src/settings-button/types.ts +0 -15
  251. package/src/state/State.ts +0 -67
  252. package/src/state/index.ts +0 -2
  253. package/src/state/types.ts +0 -31
  254. package/src/storage.ts +0 -69
  255. package/src/supports/__tests__/supports.ts +0 -123
  256. package/src/supports/createSupportsFunc.ts +0 -18
  257. package/src/supports/createSupportsParamFunc.ts +0 -27
  258. package/src/supports/index.ts +0 -4
  259. package/src/supports/supports.ts +0 -84
  260. package/src/supports/types.ts +0 -1
  261. package/src/theme-params/ThemeParams.ts +0 -131
  262. package/src/theme-params/__tests__/keys.ts +0 -19
  263. package/src/theme-params/__tests__/parseThemeParams.ts +0 -29
  264. package/src/theme-params/__tests__/serializeThemeParams.ts +0 -29
  265. package/src/theme-params/__tests__/themeParamsParser.ts +0 -29
  266. package/src/theme-params/index.ts +0 -6
  267. package/src/theme-params/keys.ts +0 -24
  268. package/src/theme-params/parseThemeParams.ts +0 -10
  269. package/src/theme-params/requestThemeParams.ts +0 -13
  270. package/src/theme-params/serializeThemeParams.ts +0 -20
  271. package/src/theme-params/themeParamsParser.ts +0 -22
  272. package/src/theme-params/types.ts +0 -33
  273. package/src/timeout/TimeoutError.ts +0 -6
  274. package/src/timeout/__tests__/isTimeoutError.ts +0 -9
  275. package/src/timeout/__tests__/withTimeout.ts +0 -28
  276. package/src/timeout/index.ts +0 -4
  277. package/src/timeout/isTimeoutError.ts +0 -9
  278. package/src/timeout/sleep.ts +0 -10
  279. package/src/timeout/withTimeout.ts +0 -24
  280. package/src/types/index.ts +0 -4
  281. package/src/types/methods.ts +0 -18
  282. package/src/types/platform.ts +0 -14
  283. package/src/types/request-id.ts +0 -10
  284. package/src/types/utils.ts +0 -50
  285. package/src/utils/Utils.ts +0 -107
  286. package/src/utils/index.ts +0 -1
  287. package/src/version/__tests__/compareVersions.ts +0 -19
  288. package/src/version/compareVersions.ts +0 -28
  289. package/src/version/index.ts +0 -2
  290. package/src/version/types.ts +0 -4
  291. package/src/viewport/Viewport.ts +0 -171
  292. package/src/viewport/__tests__/isStableViewportPlatform.ts +0 -15
  293. package/src/viewport/__tests__/utils.ts +0 -12
  294. package/src/viewport/index.ts +0 -4
  295. package/src/viewport/isStableViewportPlatform.ts +0 -10
  296. package/src/viewport/requestViewport.ts +0 -23
  297. package/src/viewport/types.ts +0 -23
  298. package/src/viewport/utils.ts +0 -7
@@ -1,220 +0,0 @@
1
- import { off, on, postEvent } from '~/bridge/index.js';
2
- import { EventEmitter } from '~/event-emitter/index.js';
3
-
4
- import { drop } from './drop.js';
5
- import { go } from './go.js';
6
- import type {
7
- HashNavigatorEventsMap,
8
- HashNavigatorOptions,
9
- } from './types.js';
10
- import { Navigator } from '../Navigator/index.js';
11
- import type {
12
- NavigationEntry,
13
- NavigatorConEntry,
14
- PerformGoOptions,
15
- PerformPushOptions,
16
- PerformReplaceOptions,
17
- } from '../Navigator/types.js';
18
-
19
- const CURSOR_VOID = 0;
20
- const CURSOR_BACK = 1;
21
- const CURSOR_FORWARD = 2;
22
-
23
- export class HashNavigator extends Navigator<Promise<void>> {
24
- /**
25
- * Creates navigator from current window location hash.
26
- * @param options - options passed to constructor.
27
- */
28
- static fromLocation(options?: HashNavigatorOptions): HashNavigator {
29
- const {
30
- search,
31
- pathname,
32
- hash,
33
- } = new URL(
34
- window.location.hash.slice(1),
35
- window.location.href,
36
- );
37
-
38
- return new HashNavigator([{ search, pathname, hash }], 0, options);
39
- }
40
-
41
- private readonly ee = new EventEmitter<HashNavigatorEventsMap>();
42
-
43
- private attached = false;
44
-
45
- constructor(
46
- entries: NavigatorConEntry[],
47
- entriesCursor: number,
48
- options: HashNavigatorOptions = {},
49
- ) {
50
- super(entries, entriesCursor, {
51
- ...options,
52
- loggerPrefix: 'HashNavigator',
53
- });
54
- }
55
-
56
- /**
57
- * Handles window "popstate" event.
58
- * @param state - event state.
59
- */
60
- private onPopState = async ({ state }: PopStateEvent) => {
61
- this.logger.log('"popstate" event received. State:', state);
62
-
63
- // In case state is null, we recognize current event as occurring whenever user clicks
64
- // any anchor.
65
- // TODO: Should we do it?
66
- if (state === null) {
67
- return this.push(window.location.hash.slice(1));
68
- }
69
-
70
- // There is only one case when state can be CURSOR_VOID - when history contains
71
- // only one element. In this case, we should return user to the current history element.
72
- if (state === CURSOR_VOID) {
73
- this.logger.log('Void reached. Moving history forward');
74
- window.history.forward();
75
- return;
76
- }
77
-
78
- // User pressed Back button.
79
- if (state === CURSOR_BACK) {
80
- return this.back();
81
- }
82
-
83
- // User pressed Forward button.
84
- if (state === CURSOR_FORWARD) {
85
- return this.forward();
86
- }
87
- };
88
-
89
- protected async performGo(options: PerformGoOptions): Promise<void> {
90
- if (!options.updated) {
91
- return;
92
- }
93
-
94
- if (this.attached) {
95
- await this.syncHistory();
96
- }
97
-
98
- this.emitChanged(options.before, options.after);
99
- }
100
-
101
- protected async performPush({ before, after }: PerformPushOptions): Promise<void> {
102
- if (this.attached) {
103
- await this.syncHistory();
104
- }
105
-
106
- this.emitChanged(before, after);
107
- }
108
-
109
- protected async performReplace(options: PerformReplaceOptions): Promise<void> {
110
- if (!options.updated) {
111
- return;
112
- }
113
-
114
- if (this.attached) {
115
- window.history.replaceState(null, '', `#${this.path}`);
116
- }
117
-
118
- this.emitChanged(options.before, options.after);
119
- }
120
-
121
- /**
122
- * Synchronizes current navigator state with browser history.
123
- */
124
- private async syncHistory(): Promise<void> {
125
- // Remove history change event listener to get rid of side effects related to possible
126
- // future calls of history.go.
127
- window.removeEventListener('popstate', this.onPopState);
128
-
129
- const hash = `#${this.path}`;
130
-
131
- // Drop the browser history and work with the clean one.
132
- await drop();
133
-
134
- // Actualize Telegram Mini Apps BackButton state.
135
- postEvent('web_app_setup_back_button', { is_visible: this.canGoBack });
136
-
137
- if (this.canGoBack && this.canGoForward) {
138
- // We have both previous and next elements. History should be:
139
- // [back, *current*, forward]
140
- this.logger.log('Setting up history: [<-, *, ->]');
141
-
142
- window.history.replaceState(CURSOR_BACK, '');
143
- window.history.pushState(null, '', hash);
144
- window.history.pushState(CURSOR_FORWARD, '');
145
-
146
- await go(-1);
147
- } else if (this.canGoBack) {
148
- // We have only previous element. History should be:
149
- // [back, *current*]
150
- this.logger.log('Setting up history: [<-, *]');
151
-
152
- window.history.replaceState(CURSOR_BACK, '');
153
- window.history.pushState(null, '', hash);
154
- } else if (this.canGoForward) {
155
- // We have only next element. History should be:
156
- // [*current*, forward]
157
- this.logger.log('Setting up history: [*, ->]');
158
-
159
- window.history.replaceState(null, hash);
160
- window.history.pushState(CURSOR_FORWARD, '');
161
-
162
- await go(-1);
163
- } else {
164
- // We have no back and next elements. History should be:
165
- // [void, *current*]
166
- this.logger.log('Setting up history: [~, *]');
167
-
168
- window.history.replaceState(CURSOR_VOID, '');
169
- window.history.pushState(null, '', hash);
170
- }
171
-
172
- window.addEventListener('popstate', this.onPopState);
173
- }
174
-
175
- private emitChanged(from: NavigationEntry, to: NavigationEntry) {
176
- this.ee.emit('change', {
177
- navigator: this,
178
- from,
179
- to,
180
- });
181
- }
182
-
183
- /**
184
- * Attaches current navigator to the browser history allowing navigator to manipulate it.
185
- */
186
- async attach(): Promise<void> {
187
- if (this.attached) {
188
- return;
189
- }
190
- this.logger.log('Attaching', this);
191
- this.attached = true;
192
- on('back_button_pressed', this.back);
193
- return this.syncHistory();
194
- }
195
-
196
- back = () => super.back();
197
-
198
- /**
199
- * Detaches current navigator from the browser history.
200
- */
201
- detach() {
202
- if (!this.attached) {
203
- return;
204
- }
205
- this.logger.log('Detaching', this);
206
- this.attached = false;
207
- window.removeEventListener('popstate', this.onPopState);
208
- off('back_button_pressed', this.back);
209
- }
210
-
211
- /**
212
- * Adds new event listener.
213
- */
214
- on = this.ee.on.bind(this.ee);
215
-
216
- /**
217
- * Removes event listener.
218
- */
219
- off = this.ee.off.bind(this.ee);
220
- }
@@ -1,144 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
-
3
- import { HashNavigator } from '../HashNavigator';
4
-
5
- // TODO: Add more tests.
6
-
7
- describe('constructor', () => {
8
- it('should throw an error if entries list is empty', () => {
9
- expect(() => new HashNavigator([], 0)).toThrow('Entries list should not be empty.');
10
- });
11
-
12
- it('should throw an error if cursor equals to higher than entries count', () => {
13
- expect(() => new HashNavigator([{ pathname: '/' }], 1))
14
- .toThrow('Cursor should be less than entries count.');
15
- expect(() => new HashNavigator([{ pathname: '/' }], 2))
16
- .toThrow('Cursor should be less than entries count.');
17
- });
18
- });
19
-
20
- describe('methods', () => {
21
- // describe('go', () => {
22
- // });
23
- //
24
- // describe('forward', () => {
25
- // });
26
- //
27
- // describe('back', () => {
28
- // });
29
-
30
- describe('getEntries', () => {
31
- it('should return deep clone of navigator entries', () => {
32
- const initialEntries = [{
33
- search: '?b',
34
- hash: '#c',
35
- pathname: '/a',
36
- }];
37
- const navigator = new HashNavigator(initialEntries, 0);
38
- const entries = navigator.getEntries();
39
-
40
- expect(entries).toStrictEqual(initialEntries);
41
- expect(entries).not.toBe(initialEntries);
42
-
43
- expect(entries[0]).toStrictEqual(initialEntries[0]);
44
- expect(entries[0]).not.toBe(initialEntries[0]);
45
- });
46
- });
47
-
48
- // describe('push', () => {
49
- // });
50
- //
51
- describe('replace', () => {
52
- it('should replace current entry', () => {
53
- const navigator = new HashNavigator([{
54
- search: '?b',
55
- hash: '#c',
56
- pathname: '/a',
57
- }], 0);
58
- const [prevEntry] = navigator.getEntries();
59
-
60
- expect(navigator.cursor).toBe(0);
61
- navigator.replace('/b');
62
- const [entry] = navigator.getEntries();
63
-
64
- expect(prevEntry).not.toStrictEqual(entry);
65
- expect(navigator.cursor).toBe(0);
66
- });
67
- });
68
- });
69
-
70
- describe('getters', () => {
71
- describe('pathname', () => {
72
- it('should return current entry pathname', () => {
73
- expect(new HashNavigator([{ pathname: '/abc' }], 0).pathname).toBe('/abc');
74
- });
75
- });
76
-
77
- describe('search', () => {
78
- it('should return current entry search', () => {
79
- expect(
80
- new HashNavigator([{
81
- search: '?a=1',
82
- pathname: '/',
83
- }], 0).search,
84
- ).toBe('?a=1');
85
- });
86
- });
87
-
88
- describe('hash', () => {
89
- it('should return current entry hash', () => {
90
- expect(
91
- new HashNavigator([{
92
- hash: '#abc',
93
- pathname: '/',
94
- }], 0).hash,
95
- ).toBe('#abc');
96
- });
97
- });
98
-
99
- describe('path', () => {
100
- it('should combine current entry pathname, search and hash', () => {
101
- expect(
102
- new HashNavigator([{
103
- search: '?b',
104
- hash: '#c',
105
- pathname: '/a',
106
- }], 0).path,
107
- ).toBe('/a?b#c');
108
- });
109
- });
110
-
111
- describe('canGoBack', () => {
112
- it('should return false if cursor === 0', () => {
113
- expect(
114
- new HashNavigator([{ pathname: '/' }], 0).canGoBack,
115
- ).toBe(false);
116
- });
117
-
118
- it('should return true if cursor > 0', () => {
119
- expect(
120
- new HashNavigator([
121
- { pathname: '/a' },
122
- { pathname: '/b' },
123
- ], 1).canGoBack,
124
- ).toBe(true);
125
- });
126
- });
127
-
128
- describe('canGoForward', () => {
129
- it('should return false if cursor === entries.length - 1', () => {
130
- expect(
131
- new HashNavigator([{ pathname: '/' }], 0).canGoForward,
132
- ).toBe(false);
133
- });
134
-
135
- it('should return true if cursor < entries.length - 1', () => {
136
- expect(
137
- new HashNavigator([
138
- { pathname: '/a' },
139
- { pathname: '/b' },
140
- ], 0).canGoForward,
141
- ).toBe(true);
142
- });
143
- });
144
- });
@@ -1,42 +0,0 @@
1
- import { afterEach, expect, it, vi } from 'vitest';
2
-
3
- import { drop } from '../drop';
4
-
5
- // TODO: Add more tests.
6
-
7
- function mockHistoryLength(length: number) {
8
- vi
9
- .spyOn(window.history, 'length', 'get')
10
- .mockImplementation(() => length);
11
- }
12
-
13
- function mockPushState(impl?: History['pushState']) {
14
- const spy = vi.spyOn(window.history, 'pushState');
15
-
16
- if (impl) {
17
- spy.mockImplementation(impl);
18
- }
19
- }
20
-
21
- afterEach(() => {
22
- vi.restoreAllMocks();
23
- });
24
-
25
- it('should do nothing in case, history contains only 1 element', () => {
26
- const pushStateSpy = vi.fn();
27
- mockHistoryLength(1);
28
- mockPushState(pushStateSpy);
29
-
30
- expect(pushStateSpy).not.toHaveBeenCalled();
31
- });
32
-
33
- it('should push empty state', () => {
34
- const pushStateSpy = vi.fn();
35
- mockHistoryLength(2);
36
- mockPushState(pushStateSpy);
37
-
38
- drop();
39
-
40
- expect(pushStateSpy).toHaveBeenCalledOnce();
41
- expect(pushStateSpy).toHaveBeenCalledWith(null, '');
42
- });
@@ -1,9 +0,0 @@
1
- import { expect, it } from 'vitest';
2
-
3
- import { go } from '../go';
4
-
5
- // TODO: Add more tests.
6
-
7
- it('should return true if delta is 0', () => {
8
- expect(go(0)).resolves.toBe(true);
9
- });
@@ -1,36 +0,0 @@
1
- import { go } from './go.js';
2
-
3
- /**
4
- * Drops current browser history switching browser history cursor to the first one entry.
5
- */
6
- export async function drop(): Promise<void> {
7
- if (window.history.length <= 1) {
8
- return;
9
- }
10
-
11
- // Push empty state to cut states we have no access to.
12
- window.history.pushState(null, '');
13
-
14
- // By this line of code we cover the most recent case, when application is opened in WebView,
15
- // but not in iframe. Applications opened in WebView have simple browser history containing
16
- // only entries belonging to the current web application.
17
- const goPerformed = await go(1 - window.history.length);
18
- if (goPerformed) {
19
- return;
20
- }
21
-
22
- // Nevertheless, iframe works a bit different in context of browser history. Calling
23
- // window.history.length in iframe will return browser history information related to the
24
- // external web environment too (e.g. browser tab). So, iframe shares the browser history with
25
- // the external application, but has no access to its history entries. Calling window.history.go
26
- // pointing out to the entry belonging to the external application will have no impact, so the
27
- // previous idea with go(1 - ...) will not work.
28
- //
29
- // This is the reason why we iteratively call go(-1) to meet the entry which is recognized as
30
- // the initial one for the current iframe.
31
- let shouldGoBack = await go(-1);
32
- while (shouldGoBack) {
33
- // eslint-disable-next-line no-await-in-loop
34
- shouldGoBack = await go(-1);
35
- }
36
- }
@@ -1,28 +0,0 @@
1
- /**
2
- * Performs window.history.go operation waiting for it to be completed.
3
- * @param delta - history change delta.
4
- */
5
- export async function go(delta: number): Promise<boolean> {
6
- if (delta === 0) {
7
- return true;
8
- }
9
-
10
- // We expect popstate event to occur during some time. Yeah, this seems tricky and not stable,
11
- // but it seems like we have no other way out. Waiting for Navigation API to be implemented in
12
- // browsers.
13
- return Promise.race<boolean>([
14
- new Promise((res) => {
15
- window.addEventListener('popstate', function listener() {
16
- window.removeEventListener('popstate', listener);
17
- res(true);
18
- });
19
-
20
- window.history.go(delta);
21
- }),
22
-
23
- // Usually, it takes about 1ms to emit this event, but we use some buffer.
24
- new Promise((res) => {
25
- setTimeout(res, 50, false);
26
- }),
27
- ]);
28
- }
@@ -1,2 +0,0 @@
1
- export * from './HashNavigator.js';
2
- export * from './types.js';
@@ -1,41 +0,0 @@
1
- import type { HashNavigator } from './HashNavigator.js';
2
- import type { NavigatorOptions } from '../Navigator/index.js';
3
- import type { NavigationEntry } from '../Navigator/types.js';
4
-
5
- export type HashNavigatorOptions = Omit<NavigatorOptions, 'loggerPrefix'>;
6
-
7
- interface ChangeEventPayload {
8
- /**
9
- * Navigator instance.
10
- */
11
- navigator: HashNavigator;
12
-
13
- /**
14
- * Previous navigation state.
15
- */
16
- from: NavigationEntry;
17
-
18
- /**
19
- * Current navigation state.
20
- */
21
- to: NavigationEntry;
22
- }
23
-
24
- export interface HashNavigatorEventsMap {
25
- /**
26
- * Being called whenever current history changes.
27
- * @param event - generated event.
28
- */
29
- change: (event: ChangeEventPayload) => void;
30
- }
31
-
32
- /**
33
- * Navigator event name.
34
- */
35
- export type HashNavigatorEventName = keyof HashNavigatorEventsMap;
36
-
37
- /**
38
- * Navigator event listener.
39
- */
40
- export type HashNavigatorEventListener<E extends HashNavigatorEventName> =
41
- HashNavigatorEventsMap[E];