@alfalab/bridge-to-native 1.3.2-beta.0084dcb → 1.3.2-beta.14525ab
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 +5 -11
- package/client/bridge-to-native.js +5 -11
- package/client/services-and-utils/close-webview-util.d.ts +1 -0
- package/client/services-and-utils/close-webview-util.js +11 -0
- package/client/services-and-utils/external-links-service.js +4 -8
- package/client/services-and-utils/native-navigation-and-title-service.d.ts +18 -16
- package/client/services-and-utils/native-navigation-and-title-service.js +138 -82
- package/package.json +1 -1
- package/client/services-and-utils/utils.d.ts +0 -2
- package/client/services-and-utils/utils.js +0 -25
|
@@ -147,15 +147,8 @@ export declare class BridgeToNative {
|
|
|
147
147
|
* экзепляру B2N следующей страницы текущего WA (в случае multi-page application).
|
|
148
148
|
*
|
|
149
149
|
* ВАЖНО!
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* 1. Микс client-side навигации и server-side навигации в рамках одного WA.
|
|
154
|
-
* т.е. одно WA должно использовать либо только `navigateClientSide`, либо только `navigateServerSide`.
|
|
155
|
-
* 2. Старт в WA 1 → переход к WA 2 → переход к WA 1,
|
|
156
|
-
* т.е. при использовании server-side навигации, история переходов разных WA не должна смешиваться.
|
|
157
|
-
*
|
|
158
|
-
* Снять эти ограничения возможно, но нужны доработки.
|
|
150
|
+
* `goBackAFewStepsClientSide` можно использовать только в рамках истории по SPA WA! Движение назад
|
|
151
|
+
* server-side переходом на несколько шагов не поддерживается.
|
|
159
152
|
*
|
|
160
153
|
* @param url URL для перехода внутри WA server-side навигацией.
|
|
161
154
|
* @param nativeTitle Текст заголовка, для «нативной» части WV, пустая строка — отсутствие заголовка.
|
|
@@ -206,8 +199,9 @@ export declare class BridgeToNative {
|
|
|
206
199
|
/**
|
|
207
200
|
* Для перезагрузки страницы необходимо использовать этот метод.
|
|
208
201
|
* Иначе синхронизация состояния с NA будет потеряна.
|
|
209
|
-
*
|
|
210
|
-
*
|
|
202
|
+
*
|
|
203
|
+
* @param skipReload По умолчанию метод сам делает `location.reload`,
|
|
204
|
+
* но с помощью аргумента можно отключить этот вызов, если нужно.
|
|
211
205
|
*/
|
|
212
206
|
reload(skipReload?: boolean): void;
|
|
213
207
|
/**
|
|
@@ -181,15 +181,8 @@ class BridgeToNative {
|
|
|
181
181
|
* экзепляру B2N следующей страницы текущего WA (в случае multi-page application).
|
|
182
182
|
*
|
|
183
183
|
* ВАЖНО!
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
* 1. Микс client-side навигации и server-side навигации в рамках одного WA.
|
|
188
|
-
* т.е. одно WA должно использовать либо только `navigateClientSide`, либо только `navigateServerSide`.
|
|
189
|
-
* 2. Старт в WA 1 → переход к WA 2 → переход к WA 1,
|
|
190
|
-
* т.е. при использовании server-side навигации, история переходов разных WA не должна смешиваться.
|
|
191
|
-
*
|
|
192
|
-
* Снять эти ограничения возможно, но нужны доработки.
|
|
184
|
+
* `goBackAFewStepsClientSide` можно использовать только в рамках истории по SPA WA! Движение назад
|
|
185
|
+
* server-side переходом на несколько шагов не поддерживается.
|
|
193
186
|
*
|
|
194
187
|
* @param url URL для перехода внутри WA server-side навигацией.
|
|
195
188
|
* @param nativeTitle Текст заголовка, для «нативной» части WV, пустая строка — отсутствие заголовка.
|
|
@@ -248,8 +241,9 @@ class BridgeToNative {
|
|
|
248
241
|
/**
|
|
249
242
|
* Для перезагрузки страницы необходимо использовать этот метод.
|
|
250
243
|
* Иначе синхронизация состояния с NA будет потеряна.
|
|
251
|
-
*
|
|
252
|
-
*
|
|
244
|
+
*
|
|
245
|
+
* @param skipReload По умолчанию метод сам делает `location.reload`,
|
|
246
|
+
* но с помощью аргумента можно отключить этот вызов, если нужно.
|
|
253
247
|
*/
|
|
254
248
|
reload(skipReload) {
|
|
255
249
|
this.nativeNavigationAndTitleService.reload(skipReload);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const closeWebviewUtil: () => void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.closeWebviewUtil = void 0;
|
|
4
|
+
const QUERY_CLOSE_WEBVIEW_KEY = 'closeWebView';
|
|
5
|
+
const QUERY_CLOSE_WEBVIEW_VALUE = 'true';
|
|
6
|
+
const closeWebviewUtil = () => {
|
|
7
|
+
const originalPageUrl = new URL(window.location.href);
|
|
8
|
+
originalPageUrl.searchParams.set(QUERY_CLOSE_WEBVIEW_KEY, QUERY_CLOSE_WEBVIEW_VALUE);
|
|
9
|
+
window.location.href = originalPageUrl.toString();
|
|
10
|
+
};
|
|
11
|
+
exports.closeWebviewUtil = closeWebviewUtil;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ExternalLinksService = void 0;
|
|
4
4
|
const query_and_headers_keys_1 = require("../../query-and-headers-keys");
|
|
5
5
|
const constants_1 = require("../constants");
|
|
6
|
-
const
|
|
6
|
+
const close_webview_util_1 = require("./close-webview-util");
|
|
7
7
|
const QUERY_OPEN_IN_BROWSER_KEY = 'openInBrowser';
|
|
8
8
|
const QUERY_OPEN_IN_BROWSER_VALUE = 'true';
|
|
9
9
|
/**
|
|
@@ -16,19 +16,15 @@ class ExternalLinksService {
|
|
|
16
16
|
}
|
|
17
17
|
handleNativeDeeplink(deeplink, closeWebviewBeforeCallNativeDeeplinkHandler = false) {
|
|
18
18
|
const clearedDeeplinkPath = deeplink.replace(constants_1.DEEP_LINK_PATTERN, '');
|
|
19
|
-
const nativeUrl = `${this.nativeParamsService.appId}://${clearedDeeplinkPath}`;
|
|
20
|
-
const replaceUrl = this.nativeParamsService.environment === 'ios'
|
|
21
|
-
? (0, utils_1.appendFromCurrentQueryParamForIos)(nativeUrl)
|
|
22
|
-
: nativeUrl;
|
|
23
19
|
if (closeWebviewBeforeCallNativeDeeplinkHandler &&
|
|
24
20
|
this.nativeParamsService.canUseNativeFeature('savedBackStack')) {
|
|
25
|
-
(0,
|
|
21
|
+
(0, close_webview_util_1.closeWebviewUtil)();
|
|
26
22
|
// Проверено, ОС получает диплинк и передаёт его NA, не смотря на то,
|
|
27
23
|
// что это происходит в следующей макрозадаче после команды на закрытие WV.
|
|
28
|
-
setTimeout(() => window.location.replace(
|
|
24
|
+
setTimeout(() => window.location.replace(`${this.nativeParamsService.appId}://${clearedDeeplinkPath}`), 0);
|
|
29
25
|
return;
|
|
30
26
|
}
|
|
31
|
-
window.location.replace(
|
|
27
|
+
window.location.replace(`${this.nativeParamsService.appId}://${clearedDeeplinkPath}`);
|
|
32
28
|
}
|
|
33
29
|
getHrefToOpenInBrowser(link) {
|
|
34
30
|
if (!this.nativeParamsService.canUseNativeFeature('linksInBrowser')) {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
|
|
2
1
|
import { type BrowserHistoryApiWrappers, type HistoryPushStateParams, type LocationAssignParam, type LogError } from '../types';
|
|
3
2
|
import { type NativeParamsService } from './native-params-service';
|
|
4
3
|
/**
|
|
5
4
|
* Сервис, отвечающий за взаимодействие WA с WV компонентами NA —
|
|
6
5
|
* «заголовком» и кнопкой «назад».
|
|
6
|
+
*
|
|
7
|
+
* Подробное описание сценариев навигации и логики восстановления состояния при hard навигации
|
|
8
|
+
* см. в документе {@link ./NAVIGATION_SCENARIOS.md}.
|
|
7
9
|
*/
|
|
8
10
|
export declare class NativeNavigationAndTitleService {
|
|
9
11
|
private nativeParamsService;
|
|
@@ -34,14 +36,23 @@ export declare class NativeNavigationAndTitleService {
|
|
|
34
36
|
* после нажатия на кнопку «Назад» в NA, вызова `history.back()` и `history.go(-x)`.
|
|
35
37
|
*/
|
|
36
38
|
private handleClientSideNavigationBack;
|
|
37
|
-
private
|
|
39
|
+
private hasSavedHistoryStack;
|
|
38
40
|
/**
|
|
39
|
-
* Инициализирует `nativeHistoryStack
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* - Инициализация при server-side переходе «назад» по истории (Сценарий 3).
|
|
41
|
+
* Инициализирует `nativeHistoryStack`.
|
|
42
|
+
*
|
|
43
|
+
* Подробное описание каждого сценария см. в {@link ./NAVIGATION_SCENARIOS.md}.
|
|
43
44
|
*/
|
|
44
45
|
private initializeNativeHistoryStack;
|
|
46
|
+
private initializeForNewOrigin;
|
|
47
|
+
private initializeForForward;
|
|
48
|
+
private initializeFromBackwardOrReload;
|
|
49
|
+
private stackContainsCrossOriginMarker;
|
|
50
|
+
private truncateToLastCrossOriginMarker;
|
|
51
|
+
/**
|
|
52
|
+
* Читает и парсит `nativeHistoryStack` из SessionStorage.
|
|
53
|
+
* При ошибке чтения или парсинга логирует через `logError` и пробрасывает исключение.
|
|
54
|
+
*/
|
|
55
|
+
private readSavedHistoryStack;
|
|
45
56
|
/**
|
|
46
57
|
* Подготавливает ссылку для корректного перехода server-side навигацией.
|
|
47
58
|
*
|
|
@@ -50,17 +61,8 @@ export declare class NativeNavigationAndTitleService {
|
|
|
50
61
|
* экзепляра B2N следующей страницы текущего WA
|
|
51
62
|
*/
|
|
52
63
|
private prepareExternalLinkBeforeOpen;
|
|
53
|
-
private static shouldInitializeFromNextPageId;
|
|
54
|
-
/**
|
|
55
|
-
* Читает сохраннённый в sessionStorage `nativeHistoryStack`,
|
|
56
|
-
* снова сохраняет его в sessionStorage, уменьшая список на одну запись,
|
|
57
|
-
* на случай, если будет дальнейший переход назад server-side навигацией.
|
|
58
|
-
*
|
|
59
|
-
* @returns Актуальное состояние `nativeHistoryStack` из sessionStorage.
|
|
60
|
-
*/
|
|
61
|
-
private readAndUpdateNativeHistoryStackSessionStorage;
|
|
62
64
|
/**
|
|
63
|
-
*
|
|
65
|
+
* Сохраняет `nativeHistoryStack` в SessionStorage.
|
|
64
66
|
*/
|
|
65
67
|
private saveNativeHistoryStack;
|
|
66
68
|
/**
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint max-lines: ["error", {"skipComments": true}] */
|
|
2
|
+
/* eslint max-lines: ["error", {"max": 400, "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
|
-
const
|
|
6
|
+
const close_webview_util_1 = require("./close-webview-util");
|
|
7
7
|
/**
|
|
8
8
|
* Сервис, отвечающий за взаимодействие WA с WV компонентами NA —
|
|
9
9
|
* «заголовком» и кнопкой «назад».
|
|
10
|
+
*
|
|
11
|
+
* Подробное описание сценариев навигации и логики восстановления состояния при hard навигации
|
|
12
|
+
* см. в документе {@link ./NAVIGATION_SCENARIOS.md}.
|
|
10
13
|
*/
|
|
11
14
|
class NativeNavigationAndTitleService {
|
|
12
15
|
constructor(nativeParamsService, browserHistoryApiWrappers, logError) {
|
|
@@ -24,7 +27,7 @@ class NativeNavigationAndTitleService {
|
|
|
24
27
|
}
|
|
25
28
|
// eslint-disable-next-line class-methods-use-this -- удобней использовать метод в контексте экземпляра.
|
|
26
29
|
closeWebview() {
|
|
27
|
-
(0,
|
|
30
|
+
(0, close_webview_util_1.closeWebviewUtil)();
|
|
28
31
|
}
|
|
29
32
|
goBack() {
|
|
30
33
|
this.goBackAFewStepsClientSide(-1, true);
|
|
@@ -38,7 +41,7 @@ class NativeNavigationAndTitleService {
|
|
|
38
41
|
const maxStepsToBack = this.nativeHistoryStack.length - 1;
|
|
39
42
|
if (stepsToBack > maxStepsToBack) {
|
|
40
43
|
if (autoCloseWebview) {
|
|
41
|
-
(0,
|
|
44
|
+
(0, close_webview_util_1.closeWebviewUtil)();
|
|
42
45
|
return;
|
|
43
46
|
}
|
|
44
47
|
this.numOfBackSteps = maxStepsToBack;
|
|
@@ -64,20 +67,26 @@ class NativeNavigationAndTitleService {
|
|
|
64
67
|
window.history.pushState(state, '', url);
|
|
65
68
|
}
|
|
66
69
|
this.nativeHistoryStack.push(nativeTitle);
|
|
70
|
+
this.saveNativeHistoryStack();
|
|
67
71
|
this.syncHistoryWithNative();
|
|
68
72
|
}
|
|
69
73
|
navigateServerSide(link, nativeTitle = '') {
|
|
70
74
|
const url = link instanceof URL ? link : new URL(link);
|
|
75
|
+
const isCrossOrigin = url.origin !== window.location.origin;
|
|
76
|
+
if (isCrossOrigin) {
|
|
77
|
+
this.nativeHistoryStack.push(2 /* NativeHistoryStackSpecialValues.ServerSideNavigationNextOrigin */);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
this.nativeHistoryStack.push(nativeTitle);
|
|
81
|
+
}
|
|
71
82
|
if (nativeTitle) {
|
|
72
83
|
url.searchParams.set(query_and_headers_keys_1.QUERY_B2N_TITLE, nativeTitle);
|
|
73
84
|
}
|
|
74
|
-
// TODO: Предыдущая реализация на iOS открывала новое WV. Возможно, что-то плохо работало,
|
|
75
|
-
// обязательно протестировать.
|
|
76
85
|
this.saveNativeHistoryStack();
|
|
77
86
|
window.location.assign(this.prepareExternalLinkBeforeOpen(url));
|
|
78
87
|
}
|
|
79
88
|
reload(skipReload = false) {
|
|
80
|
-
this.nativeHistoryStack.push(1 /* NativeHistoryStackSpecialValues.TemporaryReloadStub */);
|
|
89
|
+
this.nativeHistoryStack.push(1 /* NativeHistoryStackSpecialValues.TemporaryReloadStub */);
|
|
81
90
|
this.saveNativeHistoryStack();
|
|
82
91
|
// информация для серверной стороны B2N, что происходит `reload` и парсить запрос на предмет NA параметров не нужно (в нем их скорее всего не будет)
|
|
83
92
|
document.cookie = `${query_and_headers_keys_1.COOKIE_KEY_BRIDGE_TO_NATIVE_RELOAD}=true; Path=/`;
|
|
@@ -87,10 +96,12 @@ class NativeNavigationAndTitleService {
|
|
|
87
96
|
}
|
|
88
97
|
setInitialView(nativeTitle = '') {
|
|
89
98
|
this.nativeHistoryStack = [nativeTitle];
|
|
99
|
+
this.saveNativeHistoryStack();
|
|
90
100
|
this.syncHistoryWithNative();
|
|
91
101
|
}
|
|
92
102
|
setTitle(nativeTitle) {
|
|
93
103
|
this.nativeHistoryStack[this.nativeHistoryStack.length - 1] = nativeTitle;
|
|
104
|
+
this.saveNativeHistoryStack();
|
|
94
105
|
this.syncHistoryWithNative();
|
|
95
106
|
}
|
|
96
107
|
/**
|
|
@@ -119,49 +130,137 @@ class NativeNavigationAndTitleService {
|
|
|
119
130
|
this.nativeHistoryStack = this.nativeHistoryStack.slice(0, -this.numOfBackSteps);
|
|
120
131
|
this.numOfBackSteps = 1;
|
|
121
132
|
if (this.nativeHistoryStack.length < 1) {
|
|
122
|
-
(0,
|
|
133
|
+
(0, close_webview_util_1.closeWebviewUtil)();
|
|
123
134
|
return;
|
|
124
135
|
}
|
|
136
|
+
this.saveNativeHistoryStack();
|
|
125
137
|
this.syncHistoryWithNative();
|
|
126
138
|
}
|
|
127
|
-
|
|
139
|
+
// eslint-disable-next-line class-methods-use-this -- удобней использовать метод в контексте экземпляра.
|
|
140
|
+
hasSavedHistoryStack() {
|
|
128
141
|
return sessionStorage.getItem(query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK) !== null;
|
|
129
142
|
}
|
|
130
143
|
/**
|
|
131
|
-
* Инициализирует `nativeHistoryStack
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* - Инициализация при server-side переходе «назад» по истории (Сценарий 3).
|
|
144
|
+
* Инициализирует `nativeHistoryStack`.
|
|
145
|
+
*
|
|
146
|
+
* Подробное описание каждого сценария см. в {@link ./NAVIGATION_SCENARIOS.md}.
|
|
135
147
|
*/
|
|
136
148
|
initializeNativeHistoryStack() {
|
|
137
149
|
const { nextPageId, title } = this.nativeParamsService;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
//
|
|
143
|
-
|
|
144
|
-
this.nativeHistoryStack =
|
|
145
|
-
this.nativeHistoryStack[this.nativeHistoryStack.length - 1] = title;
|
|
150
|
+
const hasSS = this.hasSavedHistoryStack();
|
|
151
|
+
console.log('-------');
|
|
152
|
+
console.log('Инициализируюсь');
|
|
153
|
+
if (nextPageId && !hasSS) {
|
|
154
|
+
// есть nextPageId + нет SS → на этом origin ранее не были.
|
|
155
|
+
console.log('есть nextPageId + нет SS → на этом origin ранее не были.');
|
|
156
|
+
this.nativeHistoryStack = this.initializeForNewOrigin(nextPageId, title);
|
|
146
157
|
}
|
|
147
|
-
else if (
|
|
148
|
-
//
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
158
|
+
else if (nextPageId && hasSS) {
|
|
159
|
+
// есть nextPageId + есть SS → forward навигация.
|
|
160
|
+
console.log('есть nextPageId + есть SS → forward навигация.');
|
|
161
|
+
this.nativeHistoryStack = this.initializeForForward(nextPageId, title);
|
|
162
|
+
}
|
|
163
|
+
else if (!nextPageId && hasSS) {
|
|
164
|
+
// нет nextPageId + есть SS → back-навигация или reload.
|
|
165
|
+
console.log('нет nextPageId + есть SS → back-навигация или reload.');
|
|
166
|
+
this.nativeHistoryStack = this.initializeFromBackwardOrReload(title);
|
|
157
167
|
}
|
|
158
168
|
else {
|
|
159
|
-
//
|
|
160
|
-
|
|
169
|
+
// нет nextPageId + нет SS → старт нового WV, назад идти некуда.
|
|
170
|
+
console.log('нет nextPageId + нет SS → старт нового WV, назад идти некуда.');
|
|
161
171
|
this.nativeHistoryStack = [title];
|
|
162
172
|
}
|
|
173
|
+
this.saveNativeHistoryStack();
|
|
163
174
|
this.syncHistoryWithNative();
|
|
164
175
|
}
|
|
176
|
+
// eslint-disable-next-line class-methods-use-this -- удобней использовать метод в контексте экземпляра.
|
|
177
|
+
initializeForNewOrigin(nextPageId, title) {
|
|
178
|
+
const stack = new Array(nextPageId).fill(0 /* NativeHistoryStackSpecialValues.ServerSideNavigationStub */);
|
|
179
|
+
stack[stack.length - 1] = title;
|
|
180
|
+
console.log('nextPageId', nextPageId);
|
|
181
|
+
console.log('newStack', stack);
|
|
182
|
+
return stack;
|
|
183
|
+
}
|
|
184
|
+
initializeForForward(nextPageId, title) {
|
|
185
|
+
try {
|
|
186
|
+
const savedStack = this.readSavedHistoryStack();
|
|
187
|
+
const lastSaved = savedStack[savedStack.length - 1];
|
|
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
|
+
savedStack.pop();
|
|
215
|
+
if (savedStack.length === 0) {
|
|
216
|
+
console.log('newStack', [title]);
|
|
217
|
+
return [title];
|
|
218
|
+
}
|
|
219
|
+
if (typeof savedStack[savedStack.length - 1] !== 'string') {
|
|
220
|
+
console.log('newStack', this.truncateToLastCrossOriginMarker(savedStack));
|
|
221
|
+
return this.truncateToLastCrossOriginMarker(savedStack);
|
|
222
|
+
}
|
|
223
|
+
console.log('newStack', savedStack);
|
|
224
|
+
return savedStack;
|
|
225
|
+
}
|
|
226
|
+
catch (_a) {
|
|
227
|
+
return [title];
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// eslint-disable-next-line class-methods-use-this -- удобней использовать метод в контексте экземпляра.
|
|
231
|
+
stackContainsCrossOriginMarker(stack) {
|
|
232
|
+
return stack.find((el) => el === 2 /* NativeHistoryStackSpecialValues.ServerSideNavigationNextOrigin */);
|
|
233
|
+
}
|
|
234
|
+
// eslint-disable-next-line class-methods-use-this -- удобней использовать метод в контексте экземпляра.
|
|
235
|
+
truncateToLastCrossOriginMarker(stack) {
|
|
236
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
237
|
+
if (stack[i] === 2 /* NativeHistoryStackSpecialValues.ServerSideNavigationNextOrigin */) {
|
|
238
|
+
return stack.slice(0, i);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return stack;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Читает и парсит `nativeHistoryStack` из SessionStorage.
|
|
245
|
+
* При ошибке чтения или парсинга логирует через `logError` и пробрасывает исключение.
|
|
246
|
+
*/
|
|
247
|
+
readSavedHistoryStack() {
|
|
248
|
+
const serialized = sessionStorage.getItem(query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK);
|
|
249
|
+
try {
|
|
250
|
+
if (!serialized) {
|
|
251
|
+
throw new Error(`${query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK} sessionStorage expected not to be null`);
|
|
252
|
+
}
|
|
253
|
+
console.log('serializedStack', serialized);
|
|
254
|
+
return JSON.parse(serialized);
|
|
255
|
+
}
|
|
256
|
+
catch (e) {
|
|
257
|
+
if (this.logError) {
|
|
258
|
+
this.logError(`Клиентский код B2N не смог получить ${query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK} из sessionStorage
|
|
259
|
+
Могут возникнуть проблемы с кнопкой «Назад» в NA.`, e);
|
|
260
|
+
}
|
|
261
|
+
throw e;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
165
264
|
/**
|
|
166
265
|
* Подготавливает ссылку для корректного перехода server-side навигацией.
|
|
167
266
|
*
|
|
@@ -183,61 +282,18 @@ class NativeNavigationAndTitleService {
|
|
|
183
282
|
// Таким образом гарантируется, что версию приложения будет видеть следующее WA
|
|
184
283
|
// (заголовок `app-version` может отсутствовать при server-side переходах).
|
|
185
284
|
modifiedUrl.searchParams.set(query_and_headers_keys_1.QUERY_NATIVE_IOS_APPVERSION, appVersion);
|
|
186
|
-
modifiedUrl.searchParams.set(query_and_headers_keys_1.QUERY_B2N_NEXT_PAGEID,
|
|
285
|
+
modifiedUrl.searchParams.set(query_and_headers_keys_1.QUERY_B2N_NEXT_PAGEID, currentPageId.toString());
|
|
187
286
|
return modifiedUrl;
|
|
188
287
|
}
|
|
189
|
-
static shouldInitializeFromNextPageId(nextPageId) {
|
|
190
|
-
if (!NativeNavigationAndTitleService.hasSavedHistoryStack()) {
|
|
191
|
-
return true;
|
|
192
|
-
}
|
|
193
|
-
try {
|
|
194
|
-
const serializedNativeHistoryStack = sessionStorage.getItem(query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK);
|
|
195
|
-
if (!serializedNativeHistoryStack) {
|
|
196
|
-
return true;
|
|
197
|
-
}
|
|
198
|
-
return (nextPageId ===
|
|
199
|
-
JSON.parse(serializedNativeHistoryStack).length +
|
|
200
|
-
1);
|
|
201
|
-
}
|
|
202
|
-
catch (_a) {
|
|
203
|
-
return true;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Читает сохраннённый в sessionStorage `nativeHistoryStack`,
|
|
208
|
-
* снова сохраняет его в sessionStorage, уменьшая список на одну запись,
|
|
209
|
-
* на случай, если будет дальнейший переход назад server-side навигацией.
|
|
210
|
-
*
|
|
211
|
-
* @returns Актуальное состояние `nativeHistoryStack` из sessionStorage.
|
|
212
|
-
*/
|
|
213
|
-
readAndUpdateNativeHistoryStackSessionStorage() {
|
|
214
|
-
try {
|
|
215
|
-
const serializedNativeHistoryStack = sessionStorage.getItem(query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK);
|
|
216
|
-
if (!serializedNativeHistoryStack) {
|
|
217
|
-
throw new Error();
|
|
218
|
-
}
|
|
219
|
-
const nativeHistoryStack = JSON.parse(serializedNativeHistoryStack); // происходит внутри оператора `catch`, поэтому кастинг типа приемлем
|
|
220
|
-
const nativeHistoryStackToSerialize = nativeHistoryStack.slice(0, -1);
|
|
221
|
-
sessionStorage.setItem(query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK, JSON.stringify(nativeHistoryStackToSerialize));
|
|
222
|
-
if (nativeHistoryStack[nativeHistoryStack.length - 1] ===
|
|
223
|
-
1 /* NativeHistoryStackSpecialValues.TemporaryReloadStub */) {
|
|
224
|
-
return nativeHistoryStack.slice(0, -1);
|
|
225
|
-
}
|
|
226
|
-
return nativeHistoryStack;
|
|
227
|
-
}
|
|
228
|
-
catch (e) {
|
|
229
|
-
if (this.logError) {
|
|
230
|
-
this.logError('Клиентский код B2N не смог восстановить `nativeHistoryStack` из sessionStorage. ' +
|
|
231
|
-
'Могут возникнуть проблемы с кнопкой «Назад» в NA.', e);
|
|
232
|
-
}
|
|
233
|
-
throw new Error();
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
288
|
/**
|
|
237
|
-
*
|
|
289
|
+
* Сохраняет `nativeHistoryStack` в SessionStorage.
|
|
238
290
|
*/
|
|
239
291
|
saveNativeHistoryStack() {
|
|
240
292
|
const serializedNativeHistoryStack = JSON.stringify(this.nativeHistoryStack);
|
|
293
|
+
console.log('-------');
|
|
294
|
+
console.log('сохраняю стек');
|
|
295
|
+
console.log('стек', this.nativeHistoryStack);
|
|
296
|
+
console.log('сериализованный стек', serializedNativeHistoryStack);
|
|
241
297
|
sessionStorage.setItem(query_and_headers_keys_1.SS_KEY_BRIDGE_TO_NATIVE_HISTORY_STACK, serializedNativeHistoryStack);
|
|
242
298
|
}
|
|
243
299
|
/**
|
package/package.json
CHANGED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.closeWebviewUtil = void 0;
|
|
4
|
-
exports.appendFromCurrentQueryParamForIos = appendFromCurrentQueryParamForIos;
|
|
5
|
-
const QUERY_CLOSE_WEBVIEW_KEY = 'closeWebView';
|
|
6
|
-
const QUERY_CLOSE_WEBVIEW_VALUE = 'true';
|
|
7
|
-
const QUERY_FROM_CURRENT_KEY = 'fromCurrent';
|
|
8
|
-
const QUERY_FROM_CURRENT_VALUE = 'true';
|
|
9
|
-
function appendFromCurrentQueryParamForIos(nativeUrl) {
|
|
10
|
-
const qIndex = nativeUrl.indexOf('?');
|
|
11
|
-
if (qIndex === -1) {
|
|
12
|
-
return `${nativeUrl}?${QUERY_FROM_CURRENT_KEY}=${QUERY_FROM_CURRENT_VALUE}`;
|
|
13
|
-
}
|
|
14
|
-
const base = nativeUrl.slice(0, qIndex);
|
|
15
|
-
const query = nativeUrl.slice(qIndex + 1);
|
|
16
|
-
const params = new URLSearchParams(query);
|
|
17
|
-
params.set(QUERY_FROM_CURRENT_KEY, QUERY_FROM_CURRENT_VALUE);
|
|
18
|
-
return `${base}?${params.toString()}`;
|
|
19
|
-
}
|
|
20
|
-
const closeWebviewUtil = () => {
|
|
21
|
-
const originalPageUrl = new URL(window.location.href);
|
|
22
|
-
originalPageUrl.searchParams.set(QUERY_CLOSE_WEBVIEW_KEY, QUERY_CLOSE_WEBVIEW_VALUE);
|
|
23
|
-
window.location.href = originalPageUrl.toString();
|
|
24
|
-
};
|
|
25
|
-
exports.closeWebviewUtil = closeWebviewUtil;
|