@alfalab/bridge-to-native 1.3.2-beta.9b534a8 → 1.3.2-beta.aecff8b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/bridge-to-native.d.ts +35 -11
- package/client/bridge-to-native.js +43 -12
- package/client/services-and-utils/native-navigation-and-title-service.d.ts +11 -17
- package/client/services-and-utils/native-navigation-and-title-service.js +114 -139
- package/client/types.d.ts +2 -0
- package/package.json +1 -1
- package/query-and-headers-keys.d.ts +1 -1
- package/query-and-headers-keys.js +20 -19
- package/server/prepare-native-app-details-for-client.js +1 -13
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { type BrowserHistoryApiWrappers, type HistoryPushStateParams, type LocationAssignParam, type LogError, type NativeFeatureKey, type PdfType } from './types';
|
|
2
|
+
import { type BrowserHistoryApiWrappers, type HistoryPushStateParams, type HistoryReplaceStateParams, type LocationAssignParam, type LogError, type NativeFeatureKey, type PdfType } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Сервис, предоставляет методы для WA, работающего внутри NA.
|
|
5
5
|
*/
|
|
@@ -90,16 +90,27 @@ export declare class BridgeToNative {
|
|
|
90
90
|
* чтобы в дальнейшем зарегистрировать этот переход в NA.
|
|
91
91
|
*
|
|
92
92
|
* ВАЖНО!
|
|
93
|
-
*
|
|
94
|
-
*
|
|
93
|
+
* До версии `1.4.0` метод назывался `goBackAFewStepsClientSide` и его можно
|
|
94
|
+
* было использовать только в рамках SPA истории.
|
|
95
95
|
*
|
|
96
|
-
*
|
|
96
|
+
* После переименования этот метод можно использовать без ограничей, НО С УСЛОВИЕМ,
|
|
97
|
+
* что в потребителях B2N нет прямых вызовов `history.replaceState` (или оберток над ним,
|
|
98
|
+
* типа `history.replace` из ReactRouter). А вместо прямых вызовов используется
|
|
99
|
+
* метод B2N `replaceHistoryState`. Который под капотом вызывает `history.replaceState`
|
|
100
|
+
* или вашу собственную «обертку» над ним (см. `browserHistoryApiWrappers` в конструкторе).
|
|
101
|
+
*
|
|
102
|
+
* Если это условие не соблюдается, как и раньше, метод можно использовать
|
|
103
|
+
* только в рамках истории по SPA WA.
|
|
97
104
|
*
|
|
98
105
|
* @param stepsNumber Количество шагов назад.
|
|
99
106
|
* Возможно передача как положительного, так и отрицательного числа. `0` будет проигнорирован.
|
|
100
107
|
* @param autoCloseWebview Флаг — закрывать ли WV автоматически,
|
|
101
108
|
* если переданное кол-во шагов будет больше, чем записей в истории.
|
|
102
109
|
*/
|
|
110
|
+
goBackAFewSteps(stepsNumber: number, autoCloseWebview?: boolean): void;
|
|
111
|
+
/**
|
|
112
|
+
* @deprecated Используйте `goBackAFewSteps`.
|
|
113
|
+
*/
|
|
103
114
|
goBackAFewStepsClientSide(stepsNumber: number, autoCloseWebview?: boolean): void;
|
|
104
115
|
/**
|
|
105
116
|
* Вызывает обработчик диплинков NA для обработки переданного диплинка.
|
|
@@ -138,6 +149,7 @@ export declare class BridgeToNative {
|
|
|
138
149
|
*
|
|
139
150
|
* @param url URL для перехода внутри WA client-side навигацией.
|
|
140
151
|
* @param state <https://developer.mozilla.org/en-US/docs/Web/API/History/state> для новой записи в истории.
|
|
152
|
+
* Должен быть объектом или `null`. Примитивы (строка, число и т.п.) будут потеряны.
|
|
141
153
|
* @param nativeTitle Текст заголовка, для «нативной» части WV, пустая строка — отсутствие заголовка.
|
|
142
154
|
*/
|
|
143
155
|
navigateClientSide(url: HistoryPushStateParams[2], state?: HistoryPushStateParams[0], nativeTitle?: string): void;
|
|
@@ -147,8 +159,13 @@ export declare class BridgeToNative {
|
|
|
147
159
|
* экзепляру B2N следующей страницы текущего WA (в случае multi-page application).
|
|
148
160
|
*
|
|
149
161
|
* ВАЖНО!
|
|
150
|
-
* `
|
|
151
|
-
* server-side
|
|
162
|
+
* С версии `1.4.0` появилась возможность использовать `goBackAFewSteps`
|
|
163
|
+
* через границу server-side (hard) навигации (включая переходы на другие origin).
|
|
164
|
+
* Но с условием, см. описание `goBackAFewSteps`.
|
|
165
|
+
*
|
|
166
|
+
* ВАЖНО!
|
|
167
|
+
* До версии `1.4.0` метод имел ограничения, которые останутся, если переходить на WA,
|
|
168
|
+
* которое использует B2N версии < `1.4.0`.
|
|
152
169
|
*
|
|
153
170
|
* @param url URL для перехода внутри WA server-side навигацией.
|
|
154
171
|
* @param nativeTitle Текст заголовка, для «нативной» части WV, пустая строка — отсутствие заголовка.
|
|
@@ -197,13 +214,20 @@ export declare class BridgeToNative {
|
|
|
197
214
|
*/
|
|
198
215
|
openPdf(url: string, type?: PdfType, title?: string): void;
|
|
199
216
|
/**
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
* @param skipReload По умолчанию метод сам делает `location.reload`,
|
|
204
|
-
* но с помощью аргумента можно отключить этот вызов, если нужно.
|
|
217
|
+
* @deprecated Используйте `window.location.reload()` напрямую.
|
|
218
|
+
* B2N больше не требует специального метода для перезагрузки.
|
|
205
219
|
*/
|
|
206
220
|
reload(skipReload?: boolean): void;
|
|
221
|
+
/**
|
|
222
|
+
* Позволяет изменить `history.state` и/или URL текущей записи без потери служебного свойства B2N.
|
|
223
|
+
* Используйте этот метод вместо прямого вызова `history.replaceState`.
|
|
224
|
+
* Прямой вызов `history.replaceState` приведёт к потере `b2n-pageId` и нарушит работу навигации.
|
|
225
|
+
*
|
|
226
|
+
* @param url URL для замены.
|
|
227
|
+
* @param state <https://developer.mozilla.org/en-US/docs/Web/API/History/state>.
|
|
228
|
+
* Должен быть объектом или `null`. Примитивы (строка, число и т.п.) будут потеряны.
|
|
229
|
+
*/
|
|
230
|
+
replaceHistoryState(url?: HistoryReplaceStateParams[2], state?: HistoryReplaceStateParams[0]): void;
|
|
207
231
|
/**
|
|
208
232
|
* Информирует NA, что WA находится на первом экране. Это приведёт к тому,
|
|
209
233
|
* что следующее нажатие на кнопку «Назад» в NA закроет WV.
|
|
@@ -116,18 +116,31 @@ class BridgeToNative {
|
|
|
116
116
|
* чтобы в дальнейшем зарегистрировать этот переход в NA.
|
|
117
117
|
*
|
|
118
118
|
* ВАЖНО!
|
|
119
|
-
*
|
|
120
|
-
*
|
|
119
|
+
* До версии `1.4.0` метод назывался `goBackAFewStepsClientSide` и его можно
|
|
120
|
+
* было использовать только в рамках SPA истории.
|
|
121
121
|
*
|
|
122
|
-
*
|
|
122
|
+
* После переименования этот метод можно использовать без ограничей, НО С УСЛОВИЕМ,
|
|
123
|
+
* что в потребителях B2N нет прямых вызовов `history.replaceState` (или оберток над ним,
|
|
124
|
+
* типа `history.replace` из ReactRouter). А вместо прямых вызовов используется
|
|
125
|
+
* метод B2N `replaceHistoryState`. Который под капотом вызывает `history.replaceState`
|
|
126
|
+
* или вашу собственную «обертку» над ним (см. `browserHistoryApiWrappers` в конструкторе).
|
|
127
|
+
*
|
|
128
|
+
* Если это условие не соблюдается, как и раньше, метод можно использовать
|
|
129
|
+
* только в рамках истории по SPA WA.
|
|
123
130
|
*
|
|
124
131
|
* @param stepsNumber Количество шагов назад.
|
|
125
132
|
* Возможно передача как положительного, так и отрицательного числа. `0` будет проигнорирован.
|
|
126
133
|
* @param autoCloseWebview Флаг — закрывать ли WV автоматически,
|
|
127
134
|
* если переданное кол-во шагов будет больше, чем записей в истории.
|
|
128
135
|
*/
|
|
136
|
+
goBackAFewSteps(stepsNumber, autoCloseWebview = false) {
|
|
137
|
+
this.nativeNavigationAndTitleService.goBackAFewSteps(stepsNumber, autoCloseWebview);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* @deprecated Используйте `goBackAFewSteps`.
|
|
141
|
+
*/
|
|
129
142
|
goBackAFewStepsClientSide(stepsNumber, autoCloseWebview = false) {
|
|
130
|
-
this.
|
|
143
|
+
this.goBackAFewSteps(stepsNumber, autoCloseWebview);
|
|
131
144
|
}
|
|
132
145
|
/**
|
|
133
146
|
* Вызывает обработчик диплинков NA для обработки переданного диплинка.
|
|
@@ -170,6 +183,7 @@ class BridgeToNative {
|
|
|
170
183
|
*
|
|
171
184
|
* @param url URL для перехода внутри WA client-side навигацией.
|
|
172
185
|
* @param state <https://developer.mozilla.org/en-US/docs/Web/API/History/state> для новой записи в истории.
|
|
186
|
+
* Должен быть объектом или `null`. Примитивы (строка, число и т.п.) будут потеряны.
|
|
173
187
|
* @param nativeTitle Текст заголовка, для «нативной» части WV, пустая строка — отсутствие заголовка.
|
|
174
188
|
*/
|
|
175
189
|
navigateClientSide(url, state, nativeTitle = '') {
|
|
@@ -181,8 +195,13 @@ class BridgeToNative {
|
|
|
181
195
|
* экзепляру B2N следующей страницы текущего WA (в случае multi-page application).
|
|
182
196
|
*
|
|
183
197
|
* ВАЖНО!
|
|
184
|
-
* `
|
|
185
|
-
* server-side
|
|
198
|
+
* С версии `1.4.0` появилась возможность использовать `goBackAFewSteps`
|
|
199
|
+
* через границу server-side (hard) навигации (включая переходы на другие origin).
|
|
200
|
+
* Но с условием, см. описание `goBackAFewSteps`.
|
|
201
|
+
*
|
|
202
|
+
* ВАЖНО!
|
|
203
|
+
* До версии `1.4.0` метод имел ограничения, которые останутся, если переходить на WA,
|
|
204
|
+
* которое использует B2N версии < `1.4.0`.
|
|
186
205
|
*
|
|
187
206
|
* @param url URL для перехода внутри WA server-side навигацией.
|
|
188
207
|
* @param nativeTitle Текст заголовка, для «нативной» части WV, пустая строка — отсутствие заголовка.
|
|
@@ -239,14 +258,26 @@ class BridgeToNative {
|
|
|
239
258
|
this.externalLinksService.openPdf(url, type, title);
|
|
240
259
|
}
|
|
241
260
|
/**
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
* @param skipReload По умолчанию метод сам делает `location.reload`,
|
|
246
|
-
* но с помощью аргумента можно отключить этот вызов, если нужно.
|
|
261
|
+
* @deprecated Используйте `window.location.reload()` напрямую.
|
|
262
|
+
* B2N больше не требует специального метода для перезагрузки.
|
|
247
263
|
*/
|
|
264
|
+
// eslint-disable-next-line class-methods-use-this -- метод оставлен для обратной совместимости.
|
|
248
265
|
reload(skipReload) {
|
|
249
|
-
|
|
266
|
+
if (!skipReload) {
|
|
267
|
+
window.location.reload();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Позволяет изменить `history.state` и/или URL текущей записи без потери служебного свойства B2N.
|
|
272
|
+
* Используйте этот метод вместо прямого вызова `history.replaceState`.
|
|
273
|
+
* Прямой вызов `history.replaceState` приведёт к потере `b2n-pageId` и нарушит работу навигации.
|
|
274
|
+
*
|
|
275
|
+
* @param url URL для замены.
|
|
276
|
+
* @param state <https://developer.mozilla.org/en-US/docs/Web/API/History/state>.
|
|
277
|
+
* Должен быть объектом или `null`. Примитивы (строка, число и т.п.) будут потеряны.
|
|
278
|
+
*/
|
|
279
|
+
replaceHistoryState(url, state = null) {
|
|
280
|
+
this.nativeNavigationAndTitleService.replaceHistoryState(url, state);
|
|
250
281
|
}
|
|
251
282
|
/**
|
|
252
283
|
* Информирует NA, что WA находится на первом экране. Это приведёт к тому,
|
|
@@ -11,16 +11,18 @@ export declare class NativeNavigationAndTitleService {
|
|
|
11
11
|
private nativeParamsService;
|
|
12
12
|
private browserHistoryApiWrappers?;
|
|
13
13
|
private logError?;
|
|
14
|
+
private lastSetPageSettingsParams;
|
|
14
15
|
private nativeHistoryStack;
|
|
15
16
|
private numOfBackSteps;
|
|
16
|
-
private
|
|
17
|
+
private isGoBackLocked;
|
|
18
|
+
private isNavigateServerSideLocked;
|
|
17
19
|
constructor(nativeParamsService: NativeParamsService, browserHistoryApiWrappers?: BrowserHistoryApiWrappers | undefined, logError?: LogError | undefined);
|
|
18
20
|
closeWebview(): void;
|
|
19
21
|
goBack(): void;
|
|
20
|
-
|
|
22
|
+
goBackAFewSteps(stepsNumber: number, autoCloseWebview?: boolean): void;
|
|
21
23
|
navigateClientSide(url: HistoryPushStateParams[2], state?: HistoryPushStateParams[0], nativeTitle?: string): void;
|
|
22
24
|
navigateServerSide(link: LocationAssignParam, nativeTitle?: string): void;
|
|
23
|
-
|
|
25
|
+
replaceHistoryState(url?: HistoryPushStateParams[2], state?: HistoryPushStateParams[0]): void;
|
|
24
26
|
setInitialView(nativeTitle?: string): void;
|
|
25
27
|
setTitle(nativeTitle: string): void;
|
|
26
28
|
/**
|
|
@@ -37,22 +39,10 @@ export declare class NativeNavigationAndTitleService {
|
|
|
37
39
|
*/
|
|
38
40
|
private handleClientSideNavigationBack;
|
|
39
41
|
private hasSavedHistoryStack;
|
|
40
|
-
/**
|
|
41
|
-
* Инициализирует `nativeHistoryStack`.
|
|
42
|
-
*
|
|
43
|
-
* Подробное описание каждого сценария см. в {@link ./NAVIGATION_SCENARIOS.md}.
|
|
44
|
-
*/
|
|
45
42
|
private initializeNativeHistoryStack;
|
|
43
|
+
private initializeForBackward;
|
|
46
44
|
private initializeForNewOrigin;
|
|
47
45
|
private initializeForForward;
|
|
48
|
-
private initializeFromBackwardOrReload;
|
|
49
|
-
private stackContainsCrossOriginMarker;
|
|
50
|
-
private truncateToLastCrossOriginMarker;
|
|
51
|
-
/**
|
|
52
|
-
* Читает и парсит `nativeHistoryStack` из SessionStorage.
|
|
53
|
-
* При ошибке чтения или парсинга логирует через `logError` и пробрасывает исключение.
|
|
54
|
-
*/
|
|
55
|
-
private readSavedHistoryStack;
|
|
56
46
|
/**
|
|
57
47
|
* Подготавливает ссылку для корректного перехода server-side навигацией.
|
|
58
48
|
*
|
|
@@ -62,12 +52,16 @@ export declare class NativeNavigationAndTitleService {
|
|
|
62
52
|
*/
|
|
63
53
|
private prepareExternalLinkBeforeOpen;
|
|
64
54
|
/**
|
|
65
|
-
*
|
|
55
|
+
* Читает и парсит `nativeHistoryStack` из SessionStorage.
|
|
56
|
+
* При ошибке чтения или парсинга логирует через `logError` и пробрасывает исключение.
|
|
66
57
|
*/
|
|
58
|
+
private readSavedHistoryStack;
|
|
67
59
|
private saveNativeHistoryStack;
|
|
68
60
|
/**
|
|
69
61
|
* Синхронизирует состояние истории переходов и заголовок с NA в соответствии
|
|
70
62
|
* с `nativeHistoryStack`.
|
|
71
63
|
*/
|
|
72
64
|
private syncHistoryWithNative;
|
|
65
|
+
private setHistoryStatePageId;
|
|
66
|
+
private createStateWithPageId;
|
|
73
67
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint max-lines: ["error", {"max":
|
|
2
|
+
/* eslint max-lines: ["error", {"max": 350, "skipComments": true}] */
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.NativeNavigationAndTitleService = void 0;
|
|
5
5
|
const query_and_headers_keys_1 = require("../../query-and-headers-keys");
|
|
6
6
|
const close_webview_util_1 = require("./close-webview-util");
|
|
7
|
+
const NativeHistoryStackStub = 0;
|
|
7
8
|
/**
|
|
8
9
|
* Сервис, отвечающий за взаимодействие WA с WV компонентами NA —
|
|
9
10
|
* «заголовком» и кнопкой «назад».
|
|
@@ -16,11 +17,22 @@ class NativeNavigationAndTitleService {
|
|
|
16
17
|
this.nativeParamsService = nativeParamsService;
|
|
17
18
|
this.browserHistoryApiWrappers = browserHistoryApiWrappers;
|
|
18
19
|
this.logError = logError;
|
|
19
|
-
// Поле, помогающее правильно обработать переход «назад» на несколько шагов.
|
|
20
|
-
this.numOfBackSteps = 1;
|
|
21
20
|
// Здесь сохраняются параметры, которые в последний раз были отправлены
|
|
22
21
|
// в NA. Помогает предотвратить повторную отправку одинаковых параметров.
|
|
23
22
|
this.lastSetPageSettingsParams = '';
|
|
23
|
+
// Поле для фолбэк сценария, чтобы не ломать обратную совместимость в версии `1.4.0`.
|
|
24
|
+
// Фолбэк сцерий используется для потребителей B2N, которые используют
|
|
25
|
+
// прямые вызовы `history.replaceState` (или обертки над ним, типа `history.replace` из ReactRouter)
|
|
26
|
+
// вместо нового метода B2N `replaceHistoryState`
|
|
27
|
+
this.numOfBackSteps = 1;
|
|
28
|
+
// Предотвращают повторный вызов навигации, пока текущая не завершена.
|
|
29
|
+
// Без блокировки WV-браузер продолжит показывать исходную страницу,
|
|
30
|
+
// и повторный вызов может инициировать нежелательную навигацию.
|
|
31
|
+
// `isGoBackLocked` снимается в `handleClientSideNavigationBack` (popstate) для soft-навигации;
|
|
32
|
+
// при hard-навигации блокировка снимется автоматически при новой инициализации.
|
|
33
|
+
this.isGoBackLocked = false;
|
|
34
|
+
// `isNavigateServerSideLocked` не снимается — после server-side навигации всегда новая инициализация.
|
|
35
|
+
this.isNavigateServerSideLocked = false;
|
|
24
36
|
this.handleClientSideNavigationBack = this.handleClientSideNavigationBack.bind(this);
|
|
25
37
|
window.addEventListener('popstate', this.handleClientSideNavigationBack); // без отписки т.к. Сервис используется в течение всей жизни WA
|
|
26
38
|
this.initializeNativeHistoryStack();
|
|
@@ -30,9 +42,13 @@ class NativeNavigationAndTitleService {
|
|
|
30
42
|
(0, close_webview_util_1.closeWebviewUtil)();
|
|
31
43
|
}
|
|
32
44
|
goBack() {
|
|
33
|
-
this.
|
|
45
|
+
if (this.isGoBackLocked) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
this.isGoBackLocked = true;
|
|
49
|
+
this.goBackAFewSteps(-1, true);
|
|
34
50
|
}
|
|
35
|
-
|
|
51
|
+
goBackAFewSteps(stepsNumber, autoCloseWebview = false) {
|
|
36
52
|
var _a;
|
|
37
53
|
if (!stepsNumber) {
|
|
38
54
|
return;
|
|
@@ -59,40 +75,40 @@ class NativeNavigationAndTitleService {
|
|
|
59
75
|
// Далее сработает подписка на `popstate`, см. метод `handleClientSideNavigationBack`.
|
|
60
76
|
}
|
|
61
77
|
navigateClientSide(url, state = null, nativeTitle = '') {
|
|
62
|
-
var _a
|
|
78
|
+
var _a;
|
|
63
79
|
if ((_a = this.browserHistoryApiWrappers) === null || _a === void 0 ? void 0 : _a.push) {
|
|
64
|
-
|
|
80
|
+
this.browserHistoryApiWrappers.push(url, state);
|
|
65
81
|
}
|
|
66
82
|
else {
|
|
67
83
|
window.history.pushState(state, '', url);
|
|
68
84
|
}
|
|
85
|
+
this.setHistoryStatePageId(true);
|
|
69
86
|
this.nativeHistoryStack.push(nativeTitle);
|
|
70
87
|
this.saveNativeHistoryStack();
|
|
71
88
|
this.syncHistoryWithNative();
|
|
72
89
|
}
|
|
73
90
|
navigateServerSide(link, nativeTitle = '') {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (isCrossOrigin) {
|
|
77
|
-
this.nativeHistoryStack.push(2 /* NativeHistoryStackSpecialValues.ServerSideNavigationNextOrigin */);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
this.nativeHistoryStack.push(nativeTitle);
|
|
91
|
+
if (this.isNavigateServerSideLocked) {
|
|
92
|
+
return;
|
|
81
93
|
}
|
|
94
|
+
this.isNavigateServerSideLocked = true;
|
|
95
|
+
const url = link instanceof URL ? link : new URL(link);
|
|
96
|
+
this.nativeHistoryStack.push(nativeTitle || '');
|
|
82
97
|
if (nativeTitle) {
|
|
83
98
|
url.searchParams.set(query_and_headers_keys_1.QUERY_B2N_TITLE, nativeTitle);
|
|
84
99
|
}
|
|
85
100
|
this.saveNativeHistoryStack();
|
|
86
101
|
window.location.assign(this.prepareExternalLinkBeforeOpen(url));
|
|
87
102
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
this.
|
|
91
|
-
|
|
92
|
-
document.cookie = `${query_and_headers_keys_1.COOKIE_KEY_BRIDGE_TO_NATIVE_RELOAD}=true; Path=/`;
|
|
93
|
-
if (!skipReload) {
|
|
94
|
-
window.location.reload();
|
|
103
|
+
replaceHistoryState(url, state = null) {
|
|
104
|
+
var _a;
|
|
105
|
+
if ((_a = this.browserHistoryApiWrappers) === null || _a === void 0 ? void 0 : _a.replace) {
|
|
106
|
+
this.browserHistoryApiWrappers.replace(url, state);
|
|
95
107
|
}
|
|
108
|
+
else {
|
|
109
|
+
window.history.replaceState(state, '', url);
|
|
110
|
+
}
|
|
111
|
+
this.setHistoryStatePageId();
|
|
96
112
|
}
|
|
97
113
|
setInitialView(nativeTitle = '') {
|
|
98
114
|
this.nativeHistoryStack = [nativeTitle];
|
|
@@ -126,8 +142,16 @@ class NativeNavigationAndTitleService {
|
|
|
126
142
|
* Обработчик для `window.onpopstate` события. Который сработает
|
|
127
143
|
* после нажатия на кнопку «Назад» в NA, вызова `history.back()` и `history.go(-x)`.
|
|
128
144
|
*/
|
|
129
|
-
handleClientSideNavigationBack() {
|
|
130
|
-
|
|
145
|
+
handleClientSideNavigationBack(event) {
|
|
146
|
+
var _a;
|
|
147
|
+
this.isGoBackLocked = false;
|
|
148
|
+
const statePageId = (_a = event === null || event === void 0 ? void 0 : event.state) === null || _a === void 0 ? void 0 : _a[query_and_headers_keys_1.HISTORY_STATE_KEY_B2N_PAGE_ID];
|
|
149
|
+
if (typeof statePageId === 'number') {
|
|
150
|
+
this.nativeHistoryStack = this.nativeHistoryStack.slice(0, statePageId);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
this.nativeHistoryStack = this.nativeHistoryStack.slice(0, -this.numOfBackSteps);
|
|
154
|
+
}
|
|
131
155
|
this.numOfBackSteps = 1;
|
|
132
156
|
if (this.nativeHistoryStack.length < 1) {
|
|
133
157
|
(0, close_webview_util_1.closeWebviewUtil)();
|
|
@@ -140,137 +164,60 @@ class NativeNavigationAndTitleService {
|
|
|
140
164
|
hasSavedHistoryStack() {
|
|
141
165
|
return sessionStorage.getItem(query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK) !== null;
|
|
142
166
|
}
|
|
143
|
-
/**
|
|
144
|
-
* Инициализирует `nativeHistoryStack`.
|
|
145
|
-
*
|
|
146
|
-
* Подробное описание каждого сценария см. в {@link ./NAVIGATION_SCENARIOS.md}.
|
|
147
|
-
*/
|
|
148
167
|
initializeNativeHistoryStack() {
|
|
168
|
+
var _a;
|
|
149
169
|
const { nextPageId, title } = this.nativeParamsService;
|
|
150
170
|
const hasSS = this.hasSavedHistoryStack();
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
console.log('нет nextPageId + есть SS → back-навигация или reload.');
|
|
166
|
-
this.nativeHistoryStack = this.initializeFromBackwardOrReload(title);
|
|
171
|
+
const statePageId = (_a = window.history.state) === null || _a === void 0 ? void 0 : _a[query_and_headers_keys_1.HISTORY_STATE_KEY_B2N_PAGE_ID];
|
|
172
|
+
try {
|
|
173
|
+
if (typeof statePageId === 'number') {
|
|
174
|
+
this.nativeHistoryStack = this.initializeForBackward(statePageId, title);
|
|
175
|
+
}
|
|
176
|
+
else if (nextPageId && !hasSS) {
|
|
177
|
+
this.nativeHistoryStack = this.initializeForNewOrigin(nextPageId, title);
|
|
178
|
+
}
|
|
179
|
+
else if (nextPageId && hasSS) {
|
|
180
|
+
this.nativeHistoryStack = this.initializeForForward(nextPageId, title);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
this.nativeHistoryStack = [title];
|
|
184
|
+
}
|
|
167
185
|
}
|
|
168
|
-
|
|
169
|
-
// нет nextPageId + нет SS → старт нового WV, назад идти некуда.
|
|
170
|
-
console.log('нет nextPageId + нет SS → старт нового WV, назад идти некуда.');
|
|
186
|
+
catch (_b) {
|
|
171
187
|
this.nativeHistoryStack = [title];
|
|
172
188
|
}
|
|
173
189
|
this.saveNativeHistoryStack();
|
|
174
190
|
this.syncHistoryWithNative();
|
|
191
|
+
this.setHistoryStatePageId();
|
|
192
|
+
}
|
|
193
|
+
initializeForBackward(pageId, title) {
|
|
194
|
+
if (!this.hasSavedHistoryStack()) {
|
|
195
|
+
return [title];
|
|
196
|
+
}
|
|
197
|
+
const savedStack = this.readSavedHistoryStack();
|
|
198
|
+
const stack = savedStack.slice(0, pageId);
|
|
199
|
+
stack[stack.length - 1] = title;
|
|
200
|
+
return stack;
|
|
175
201
|
}
|
|
176
202
|
// eslint-disable-next-line class-methods-use-this -- удобней использовать метод в контексте экземпляра.
|
|
177
203
|
initializeForNewOrigin(nextPageId, title) {
|
|
178
|
-
const stack = new Array(nextPageId).fill(
|
|
204
|
+
const stack = new Array(nextPageId).fill(NativeHistoryStackStub);
|
|
179
205
|
stack[stack.length - 1] = title;
|
|
180
|
-
console.log('nextPageId', nextPageId);
|
|
181
|
-
console.log('newStack', stack);
|
|
182
206
|
return stack;
|
|
183
207
|
}
|
|
184
208
|
initializeForForward(nextPageId, title) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (lastSaved === 2 /* NativeHistoryStackSpecialValues.ServerSideNavigationNextOrigin */ &&
|
|
189
|
-
savedStack.length < nextPageId) {
|
|
190
|
-
const stack = new Array(nextPageId).fill(0 /* NativeHistoryStackSpecialValues.ServerSideNavigationStub */);
|
|
191
|
-
for (let i = 0; i < savedStack.length; i++) {
|
|
192
|
-
stack[i] = savedStack[i];
|
|
193
|
-
}
|
|
194
|
-
stack[stack.length - 1] = title;
|
|
195
|
-
console.log('nextPageId', nextPageId);
|
|
196
|
-
console.log('newStack', stack);
|
|
197
|
-
return stack;
|
|
198
|
-
}
|
|
199
|
-
if (savedStack.length === nextPageId) {
|
|
200
|
-
savedStack[savedStack.length - 1] = title;
|
|
201
|
-
console.log('nextPageId', nextPageId);
|
|
202
|
-
console.log('newStack', savedStack);
|
|
203
|
-
return savedStack;
|
|
204
|
-
}
|
|
205
|
-
return this.initializeForNewOrigin(nextPageId, title);
|
|
206
|
-
}
|
|
207
|
-
catch (_a) {
|
|
208
|
-
return this.initializeForNewOrigin(nextPageId, title);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
initializeFromBackwardOrReload(title) {
|
|
212
|
-
try {
|
|
213
|
-
const savedStack = this.readSavedHistoryStack();
|
|
214
|
-
const lastEntry = savedStack[savedStack.length - 1];
|
|
215
|
-
if (lastEntry === 1 /* NativeHistoryStackSpecialValues.TemporaryReloadStub */) {
|
|
216
|
-
savedStack.pop();
|
|
217
|
-
if (savedStack.length === 0) {
|
|
218
|
-
console.log('newStack', [title]);
|
|
219
|
-
return [title];
|
|
220
|
-
}
|
|
221
|
-
console.log('newStack', savedStack);
|
|
222
|
-
return savedStack;
|
|
223
|
-
}
|
|
224
|
-
if (this.stackContainsCrossOriginMarker(savedStack)) {
|
|
225
|
-
console.log('newStack', this.truncateToLastCrossOriginMarker(savedStack));
|
|
226
|
-
return this.truncateToLastCrossOriginMarker(savedStack);
|
|
227
|
-
}
|
|
228
|
-
savedStack.pop();
|
|
229
|
-
if (savedStack.length === 0) {
|
|
230
|
-
console.log('newStack', [title]);
|
|
231
|
-
return [title];
|
|
232
|
-
}
|
|
233
|
-
console.log('newStack', savedStack);
|
|
209
|
+
const savedStack = this.readSavedHistoryStack();
|
|
210
|
+
if (savedStack.length === nextPageId) {
|
|
211
|
+
savedStack[savedStack.length - 1] = title;
|
|
234
212
|
return savedStack;
|
|
235
213
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
// eslint-disable-next-line class-methods-use-this -- удобней использовать метод в контексте экземпляра.
|
|
241
|
-
stackContainsCrossOriginMarker(stack) {
|
|
242
|
-
return stack.find((el) => el === 2 /* NativeHistoryStackSpecialValues.ServerSideNavigationNextOrigin */);
|
|
243
|
-
}
|
|
244
|
-
// eslint-disable-next-line class-methods-use-this -- удобней использовать метод в контексте экземпляра.
|
|
245
|
-
truncateToLastCrossOriginMarker(stack) {
|
|
246
|
-
for (let i = stack.length - 1; i >= 0; i--) {
|
|
247
|
-
if (stack[i] === 2 /* NativeHistoryStackSpecialValues.ServerSideNavigationNextOrigin */) {
|
|
248
|
-
return stack.slice(0, i);
|
|
249
|
-
}
|
|
214
|
+
const stack = new Array(nextPageId).fill(NativeHistoryStackStub);
|
|
215
|
+
for (let i = 0; i < savedStack.length && i < nextPageId; i++) {
|
|
216
|
+
stack[i] = savedStack[i];
|
|
250
217
|
}
|
|
218
|
+
stack[stack.length - 1] = title;
|
|
251
219
|
return stack;
|
|
252
220
|
}
|
|
253
|
-
/**
|
|
254
|
-
* Читает и парсит `nativeHistoryStack` из SessionStorage.
|
|
255
|
-
* При ошибке чтения или парсинга логирует через `logError` и пробрасывает исключение.
|
|
256
|
-
*/
|
|
257
|
-
readSavedHistoryStack() {
|
|
258
|
-
const serialized = sessionStorage.getItem(query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK);
|
|
259
|
-
try {
|
|
260
|
-
if (!serialized) {
|
|
261
|
-
throw new Error(`${query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK} sessionStorage expected not to be null`);
|
|
262
|
-
}
|
|
263
|
-
console.log('serializedStack', serialized);
|
|
264
|
-
return JSON.parse(serialized);
|
|
265
|
-
}
|
|
266
|
-
catch (e) {
|
|
267
|
-
if (this.logError) {
|
|
268
|
-
this.logError(`Клиентский код B2N не смог получить ${query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK} из sessionStorage
|
|
269
|
-
Могут возникнуть проблемы с кнопкой «Назад» в NA.`, e);
|
|
270
|
-
}
|
|
271
|
-
throw e;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
221
|
/**
|
|
275
222
|
* Подготавливает ссылку для корректного перехода server-side навигацией.
|
|
276
223
|
*
|
|
@@ -296,14 +243,27 @@ class NativeNavigationAndTitleService {
|
|
|
296
243
|
return modifiedUrl;
|
|
297
244
|
}
|
|
298
245
|
/**
|
|
299
|
-
*
|
|
246
|
+
* Читает и парсит `nativeHistoryStack` из SessionStorage.
|
|
247
|
+
* При ошибке чтения или парсинга логирует через `logError` и пробрасывает исключение.
|
|
300
248
|
*/
|
|
249
|
+
readSavedHistoryStack() {
|
|
250
|
+
const serialized = sessionStorage.getItem(query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK);
|
|
251
|
+
try {
|
|
252
|
+
if (!serialized) {
|
|
253
|
+
throw new Error(`${query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK} sessionStorage expected not to be null`);
|
|
254
|
+
}
|
|
255
|
+
return JSON.parse(serialized);
|
|
256
|
+
}
|
|
257
|
+
catch (e) {
|
|
258
|
+
if (this.logError) {
|
|
259
|
+
this.logError(`Клиентский код B2N не смог получить ${query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK} из sessionStorage
|
|
260
|
+
Могут возникнуть проблемы с кнопкой «Назад» в NA.`, e);
|
|
261
|
+
}
|
|
262
|
+
throw e;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
301
265
|
saveNativeHistoryStack() {
|
|
302
266
|
const serializedNativeHistoryStack = JSON.stringify(this.nativeHistoryStack);
|
|
303
|
-
console.log('-------');
|
|
304
|
-
console.log('сохраняю стек');
|
|
305
|
-
console.log('стек', this.nativeHistoryStack);
|
|
306
|
-
console.log('сериализованный стек', serializedNativeHistoryStack);
|
|
307
267
|
sessionStorage.setItem(query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK, serializedNativeHistoryStack);
|
|
308
268
|
}
|
|
309
269
|
/**
|
|
@@ -331,5 +291,20 @@ class NativeNavigationAndTitleService {
|
|
|
331
291
|
}
|
|
332
292
|
}
|
|
333
293
|
}
|
|
294
|
+
setHistoryStatePageId(useNextPageId = false) {
|
|
295
|
+
const pageId = useNextPageId
|
|
296
|
+
? this.nativeHistoryStack.length + 1
|
|
297
|
+
: this.nativeHistoryStack.length;
|
|
298
|
+
const newState = this.createStateWithPageId(window.history.state, pageId);
|
|
299
|
+
// `b2n-pageId` всегда записывается на верхний уровень через нативный `replaceState`,
|
|
300
|
+
// а не через wrapper, чтобы wrapper (например, React Router / history) не мог обернуть
|
|
301
|
+
// его внутрь своего формата и скрыть от B2N при чтении `history.state`.
|
|
302
|
+
window.history.replaceState(newState, '');
|
|
303
|
+
}
|
|
304
|
+
// eslint-disable-next-line class-methods-use-this -- удобней использовать метод в контексте экземпляра.
|
|
305
|
+
createStateWithPageId(state, pageId) {
|
|
306
|
+
const isPlainObject = (v) => v !== null && v !== undefined && typeof v === 'object' && !Array.isArray(v);
|
|
307
|
+
return Object.assign(Object.assign({}, (isPlainObject(state) ? state : {})), { [query_and_headers_keys_1.HISTORY_STATE_KEY_B2N_PAGE_ID]: pageId });
|
|
308
|
+
}
|
|
334
309
|
}
|
|
335
310
|
exports.NativeNavigationAndTitleService = NativeNavigationAndTitleService;
|
package/client/types.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
export type BrowserHistoryApiWrappers = {
|
|
2
2
|
push?: (url: HistoryPushStateParams[2], state: HistoryPushStateParams[0]) => void;
|
|
3
3
|
go?: (delta: number) => void;
|
|
4
|
+
replace?: (url: HistoryReplaceStateParams[2], state: HistoryReplaceStateParams[0]) => void;
|
|
4
5
|
};
|
|
5
6
|
export type Environment = 'android' | 'ios';
|
|
6
7
|
export type HistoryPushStateParams = Parameters<typeof window.history.pushState>;
|
|
8
|
+
export type HistoryReplaceStateParams = Parameters<typeof window.history.replaceState>;
|
|
7
9
|
export type LocationAssignParam = Parameters<typeof window.location.assign>[0];
|
|
8
10
|
export type LogError = (b2nErrorMessage: string, originalError: unknown) => void;
|
|
9
11
|
export type NativeFeatureKey = 'geolocation' | 'linksInBrowser' | 'savedBackStack';
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export declare const HEADER_KEY_COOKIE = "cookie";
|
|
2
2
|
export declare const HEADER_KEY_USER_AGENT = "user-agent";
|
|
3
3
|
export declare const COOKIE_KEY_BRIDGE_TO_NATIVE_DATA = "bridgeToNativeData";
|
|
4
|
-
export declare const COOKIE_KEY_BRIDGE_TO_NATIVE_RELOAD = "bridgeToNativeReload";
|
|
5
4
|
export declare const HEADER_KEY_NATIVE_APPVERSION = "app-version";
|
|
6
5
|
export declare const HEADER_KEY_WV_LAUNCH_TIME = "webview-launch-time";
|
|
6
|
+
export declare const HISTORY_STATE_KEY_B2N_PAGE_ID = "b2n-pageId";
|
|
7
7
|
export declare const QUERY_B2N_NEXT_PAGEID = "b2n-next-page-id";
|
|
8
8
|
export declare const QUERY_B2N_TITLE = "b2n-title";
|
|
9
9
|
export declare const QUERY_B2N_TITLE_DEPRECATED = "title";
|
|
@@ -3,32 +3,33 @@
|
|
|
3
3
|
* Ключи стандартных заголовков.
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK = exports.QUERY_NATIVE_THEME = exports.QUERY_NATIVE_IOS_APPVERSION = exports.QUERY_NATIVE_IOS_APPID = exports.QUERY_B2N_TITLE_DEPRECATED = exports.QUERY_B2N_TITLE = exports.QUERY_B2N_NEXT_PAGEID = exports.
|
|
6
|
+
exports.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK = exports.QUERY_NATIVE_THEME = exports.QUERY_NATIVE_IOS_APPVERSION = exports.QUERY_NATIVE_IOS_APPID = exports.QUERY_B2N_TITLE_DEPRECATED = exports.QUERY_B2N_TITLE = exports.QUERY_B2N_NEXT_PAGEID = exports.HISTORY_STATE_KEY_B2N_PAGE_ID = exports.HEADER_KEY_WV_LAUNCH_TIME = exports.HEADER_KEY_NATIVE_APPVERSION = exports.COOKIE_KEY_BRIDGE_TO_NATIVE_DATA = exports.HEADER_KEY_USER_AGENT = exports.HEADER_KEY_COOKIE = void 0;
|
|
7
7
|
exports.HEADER_KEY_COOKIE = 'cookie';
|
|
8
8
|
exports.HEADER_KEY_USER_AGENT = 'user-agent';
|
|
9
9
|
/*
|
|
10
|
-
* Ключи
|
|
10
|
+
* Ключи заголовков, query-параметров и пр., которые использует B2N.
|
|
11
11
|
*/
|
|
12
12
|
// Ключ cookie, с помощью которого серверная часть B2N передаст на клиент информацию об NA.
|
|
13
13
|
exports.COOKIE_KEY_BRIDGE_TO_NATIVE_DATA = 'bridgeToNativeData';
|
|
14
|
-
//
|
|
15
|
-
// Используется для предотвращения перезаписи cookie bridgeToNativeData, чтобы сохранить
|
|
16
|
-
// актуальные параметры нативного приложения
|
|
17
|
-
exports.COOKIE_KEY_BRIDGE_TO_NATIVE_RELOAD = 'bridgeToNativeReload';
|
|
18
|
-
// Нативное приложение на обеих платформах подмешивает этот заголовок к запросу за HTML.
|
|
14
|
+
// NA на обеих платформах подмешивает этот заголовок к запросу за HTML.
|
|
19
15
|
// TODO:
|
|
20
16
|
// * Исследовать, делает ли оно это при запросах к прочим ресурсам;
|
|
21
17
|
// * Есть подозрение на некоторую нестабильность — возможно делает это
|
|
22
18
|
// только для первого документа в вебвью-сессии. Исследовать.
|
|
23
19
|
exports.HEADER_KEY_NATIVE_APPVERSION = 'app-version';
|
|
24
|
-
// Ключ заголовка, в котором
|
|
20
|
+
// Ключ заголовка, в котором NA передаёт время старта открытия WV экрана в формате timestamp.
|
|
25
21
|
exports.HEADER_KEY_WV_LAUNCH_TIME = 'webview-launch-time';
|
|
22
|
+
// Ключ в history.state, который B2N использует для хранения текущего `pageId`
|
|
23
|
+
// чтобы иметь возможность корректно синхронизироваться с NA после back-навигации.
|
|
24
|
+
exports.HISTORY_STATE_KEY_B2N_PAGE_ID = 'b2n-pageId';
|
|
26
25
|
// Флаг, предписывающий клиентскому коду B2N начать связь
|
|
27
26
|
// с нативным приложением с указанного в этом параметре id, а не с 1.
|
|
28
|
-
// Необходимо для server-side навигации.
|
|
27
|
+
// Необходимо для server-side (hard) навигации.
|
|
29
28
|
exports.QUERY_B2N_NEXT_PAGEID = 'b2n-next-page-id';
|
|
30
|
-
// Query-параметр,
|
|
29
|
+
// Query-параметр, который можно подмешать к URL в диплинке на открытие WV,
|
|
30
|
+
// и с помощью которого можно передать начальное значение
|
|
31
31
|
// для нативного заголовка — в область, которую не рендерит веб.
|
|
32
|
+
// Также некоторые методы навигации B2N используют эту сущность.
|
|
32
33
|
exports.QUERY_B2N_TITLE = 'b2n-title';
|
|
33
34
|
// Deprecated вариант query-параметра 'b2n-title'
|
|
34
35
|
// (т.к. `title` часто может использоваться самим веб-приложением).
|
|
@@ -36,18 +37,18 @@ exports.QUERY_B2N_TITLE = 'b2n-title';
|
|
|
36
37
|
exports.QUERY_B2N_TITLE_DEPRECATED = 'title';
|
|
37
38
|
// NA на iOS передаёт в этом параметре схему,
|
|
38
39
|
// под которым оно зарегистрировано в OS.
|
|
39
|
-
//
|
|
40
|
-
// * В старых версиях отсутствует, клиентский код использует хардкод
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
//
|
|
40
|
+
// Некоторые особенности:
|
|
41
|
+
// * В старых версиях отсутствует, клиентский код использует хардкод
|
|
42
|
+
// (см. `VERSION_TO_IOS_APP_ID` в `src/client/constants.ts`);
|
|
43
|
+
// * Тестить WV на iOS надо на группе «B»!!! Иначе NA будет присылать в WA неверную схему,
|
|
44
|
+
// что приведёт к неработоспособности методов, связанных с передачей диплинков в NA.
|
|
45
|
+
// * В сборках для Симулятора, схема всегда `aweassist`.
|
|
44
46
|
exports.QUERY_NATIVE_IOS_APPID = 'applicationId';
|
|
45
|
-
//
|
|
46
|
-
// B2N сознательно переиспользует этот query и для server-side переходов в Android,
|
|
47
|
+
// NA на iOS передаёт в этом параметре свою версию.
|
|
48
|
+
// B2N сознательно переиспользует этот query и для server-side (hard) переходов в Android,
|
|
47
49
|
// чтобы не вводить отдельный служебный параметр только для переноса версии между WA.
|
|
48
50
|
exports.QUERY_NATIVE_IOS_APPVERSION = 'device_app_version';
|
|
49
51
|
// NA на обеих платформах в этом параметре передаёт активную тему (светлая/тёмная).
|
|
50
52
|
exports.QUERY_NATIVE_THEME = 'theme';
|
|
51
|
-
// Ключ
|
|
52
|
-
// при server-side навигации.
|
|
53
|
+
// Ключ sessionStorage,в котором клиентская часть B2N сохраняет состояние синхронизации с NA.
|
|
53
54
|
exports.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK = 'bridgeToNativeHistoryStack';
|
|
@@ -19,21 +19,9 @@ const utils_1 = require("./utils");
|
|
|
19
19
|
function prepareNativeAppDetailsForClient(request, setResponseHeader) {
|
|
20
20
|
// Поскольку вебвью модули имеют особенность сохранять сессионную куку подолгу,
|
|
21
21
|
// даже после перезагрузки устройства или обновления приложения/ОС, ее значение
|
|
22
|
-
// актуализируется при каждом запросе на сервер.
|
|
23
|
-
// В этом случае функция возвращает объект с параметрами, полученными из
|
|
24
|
-
// ранее сохраненной куки, но перезаписываться кука не будет, потому что:
|
|
25
|
-
// 1) Данных NA в запросе с большой вероятностью не будет;
|
|
26
|
-
// 2) клиентская сторона сохранит всё, что нужно в SessionStorage
|
|
22
|
+
// актуализируется при каждом запросе на сервер.
|
|
27
23
|
const cookieHeader = (0, utils_1.getHeaderValue)(request, query_and_headers_keys_1.HEADER_KEY_COOKIE);
|
|
28
24
|
const nativeParamsFromCookie = (0, utils_1.readNativeParamsFromCookie)(cookieHeader);
|
|
29
|
-
const hasReloadFlag = cookieHeader?.includes(`${query_and_headers_keys_1.COOKIE_KEY_BRIDGE_TO_NATIVE_RELOAD}=true`);
|
|
30
|
-
if (hasReloadFlag) {
|
|
31
|
-
setResponseHeader('Set-Cookie', `${query_and_headers_keys_1.COOKIE_KEY_BRIDGE_TO_NATIVE_RELOAD}=false; Max-Age=0; Path=/`);
|
|
32
|
-
if (nativeParamsFromCookie) {
|
|
33
|
-
return nativeParamsFromCookie;
|
|
34
|
-
}
|
|
35
|
-
return buildNativeParams(request);
|
|
36
|
-
}
|
|
37
25
|
const nativeParams = buildNativeParams(request, nativeParamsFromCookie);
|
|
38
26
|
const serializedNativeParams = encodeURIComponent(JSON.stringify(nativeParams));
|
|
39
27
|
setResponseHeader('Set-Cookie', `${query_and_headers_keys_1.COOKIE_KEY_BRIDGE_TO_NATIVE_DATA}=${serializedNativeParams}; Path=/`);
|