@alfalab/bridge-to-native 0.2.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/bridge-to-native.d.ts +220 -0
- package/client/bridge-to-native.js +267 -0
- package/client/constants.d.ts +13 -0
- package/client/constants.js +30 -0
- 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.d.ts +15 -0
- package/client/services-and-utils/external-links-service.js +71 -0
- package/client/services-and-utils/native-navigation-and-title-service.d.ts +70 -0
- package/client/services-and-utils/native-navigation-and-title-service.js +234 -0
- package/client/services-and-utils/native-params-service.d.ts +24 -0
- package/client/services-and-utils/native-params-service.js +79 -0
- package/client/types.d.ts +19 -0
- package/client/types.js +2 -0
- package/package.json +79 -79
- package/query-and-headers-keys.d.ts +11 -0
- package/query-and-headers-keys.js +45 -0
- package/server/extract-native-service-queries.d.ts +9 -0
- package/server/extract-native-service-queries.js +41 -0
- package/server/index.d.ts +2 -0
- package/server/index.js +7 -0
- package/server/is-webview-env.d.ts +7 -0
- package/server/is-webview-env.js +29 -0
- package/server/prepare-native-app-details-for-client.d.ts +13 -0
- package/server/prepare-native-app-details-for-client.js +78 -0
- package/server/regexp-patterns.d.ts +4 -0
- package/server/regexp-patterns.js +10 -0
- package/server/types.d.ts +2 -0
- package/server/types.js +2 -0
- package/server/utils.d.ts +24 -0
- package/server/utils.js +44 -0
- package/types.d.ts +1 -32
- package/bridge-to-native.d.ts +0 -63
- package/bridge-to-native.js +0 -147
- package/constants.d.ts +0 -15
- package/constants.js +0 -32
- package/esm/bridge-to-native.d.ts +0 -63
- package/esm/bridge-to-native.js +0 -154
- package/esm/constants.d.ts +0 -15
- package/esm/constants.js +0 -29
- package/esm/index.d.ts +0 -2
- package/esm/native-fallbacks.d.ts +0 -64
- package/esm/native-fallbacks.js +0 -119
- package/esm/native-navigation-and-title.d.ts +0 -147
- package/esm/native-navigation-and-title.js +0 -326
- package/esm/types.d.ts +0 -39
- package/esm/types.js +0 -1
- package/esm/utils.d.ts +0 -23
- package/esm/utils.js +0 -62
- package/index.d.ts +0 -2
- package/native-fallbacks.d.ts +0 -64
- package/native-fallbacks.js +0 -124
- package/native-navigation-and-title.d.ts +0 -147
- package/native-navigation-and-title.js +0 -329
- package/utils.d.ts +0 -23
- package/utils.js +0 -70
- /package/{esm/index.js → client/index.d.ts} +0 -0
- /package/{index.js → client/index.js} +0 -0
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { HandleRedirect } from './types';
|
|
2
|
-
import { BridgeToNative } from './bridge-to-native';
|
|
3
|
-
/**
|
|
4
|
-
* Класс, отвечающий за взаимодействие с нативными элементами в приложении – заголовком и нативной кнопкой назад.
|
|
5
|
-
*/
|
|
6
|
-
export declare class NativeNavigationAndTitle {
|
|
7
|
-
private b2n;
|
|
8
|
-
private nativeHistoryStack;
|
|
9
|
-
private numOfBackSteps;
|
|
10
|
-
private lastSetPageSettingsParams;
|
|
11
|
-
private readonly _handleWindowRedirect;
|
|
12
|
-
constructor(b2n: BridgeToNative, pageId: number | null, initialNativeTitle: string | undefined, handleWindowRedirect: HandleRedirect);
|
|
13
|
-
/**
|
|
14
|
-
* Метод, вызывающий `history.back()` или закрывающий вебвью, если нет записей
|
|
15
|
-
* в истории переходов.
|
|
16
|
-
*/
|
|
17
|
-
goBack(): void;
|
|
18
|
-
/**
|
|
19
|
-
* Метод, вызывающий history.go(-колл. шагов назад) и модифицирует внутреннее
|
|
20
|
-
* состояние, чтобы в дальнейшем зарегистрировать этот переход в приложении.
|
|
21
|
-
*
|
|
22
|
-
* @param stepsNumber Количество шагов назад.
|
|
23
|
-
* Возможно передача как положительного, так и отрицательного числа.
|
|
24
|
-
* 0 будет проигнорирован.
|
|
25
|
-
* @param autoCloseWebview Флаг – закрывать ли вебвью автоматически,
|
|
26
|
-
* если переданное кол-во шагов будет больше чем записей в истории.
|
|
27
|
-
*/
|
|
28
|
-
goBackAFewSteps(stepsNumber: number, autoCloseWebview?: boolean): void;
|
|
29
|
-
/**
|
|
30
|
-
* @param path Путь для перехода на функциональность внутри приложения.
|
|
31
|
-
* @param historyState (https://developer.mozilla.org/en-US/docs/Web/API/History/state) для новой записи в истории.
|
|
32
|
-
*/
|
|
33
|
-
handleRedirect(path: string, historyState?: Record<string, unknown>): void;
|
|
34
|
-
/**
|
|
35
|
-
* В этом варианте аргументы 2,3,4 соответствуют аргументам 1,2,3 метода `src/shared/utils/handle-redirect`.
|
|
36
|
-
*
|
|
37
|
-
* @param pageTitle Заголовок, который нужно отрисовать в приложении.
|
|
38
|
-
* @param appName См. первый параметр `src/handle-redirect.ts`.
|
|
39
|
-
* @param path См. второй параметр `src/handle-redirect.ts`.
|
|
40
|
-
* @param params См. третий параметр `src/handle-redirect.ts`.
|
|
41
|
-
* @param historyState (https://developer.mozilla.org/en-US/docs/Web/API/History/state) для новой записи в истории.
|
|
42
|
-
*/
|
|
43
|
-
handleRedirect(pageTitle: string, appName: string, path?: string, params?: Record<string, string>, historyState?: Record<string, unknown>): void;
|
|
44
|
-
/**
|
|
45
|
-
* Информирует натив, что веб находится на первом экране (сбрасывает историю переходов, не влияя на браузерную
|
|
46
|
-
* историю), а значит следующее нажатие на кнопку "Назад" в нативе закроет вебвью.
|
|
47
|
-
*
|
|
48
|
-
* @param pageTitle Заголовок, который нужно отрисовать в нативе.
|
|
49
|
-
*/
|
|
50
|
-
setInitialView(pageTitle?: string): void;
|
|
51
|
-
/**
|
|
52
|
-
* Метод для смены заголовка в нативе без влияния на историю переходов.
|
|
53
|
-
*
|
|
54
|
-
* @param pageTitle Заголовок, который нужно отрисовать в нативе.
|
|
55
|
-
*/
|
|
56
|
-
setTitle(pageTitle: string): void;
|
|
57
|
-
/**
|
|
58
|
-
* Метод для открытия второго web приложения в рамках одной вебвью сессии.
|
|
59
|
-
* Сохраняет все текущее состояние текущего экземпляра bridgeToAm и AmNavigationAndTitle в sessionStorage, а
|
|
60
|
-
* так же наполняет url необходимыми query параметрами. Работает только в Android окружении.
|
|
61
|
-
* В IOS окружении будет открыто новое webview поверх текущего.
|
|
62
|
-
*
|
|
63
|
-
* @param url адрес второго web приложения, к которому перед переходом на него будут добавлены
|
|
64
|
-
* все initial query параметры от натива и параметр nextPageId (Android)
|
|
65
|
-
*/
|
|
66
|
-
navigateInsideASharedSession(url: string): void;
|
|
67
|
-
/**
|
|
68
|
-
* Безопасный способ для перезагрузки страницы.
|
|
69
|
-
*/
|
|
70
|
-
pseudoReloadPage(): void;
|
|
71
|
-
/**
|
|
72
|
-
* Вызывает обработчик deeplinks в нативе (АМ) и передает туда переданный deeplink.
|
|
73
|
-
* На Android текущее webview будет закрыто из-за технических особенностей.
|
|
74
|
-
* На IOS нативная фича открывается в следующем по стеку экране и при выходе из нее пользователь вернется обратно в webview.
|
|
75
|
-
* На IOS есть возможность закрыть webview перед открытием нативной фичи, передав второй параметр closeIOSWebviewBeforeCallNativeDeeplinkHandler = true
|
|
76
|
-
* @param deeplink диплинк на нативную АМ фичу в AM
|
|
77
|
-
* @param [closeIOSWebviewBeforeCallNativeDeeplinkHandler = false] закрыть текущее webview после открытия нативной фичи (применимо только для IOS на Android по техническим причинам webview всегда будет закрываться)
|
|
78
|
-
*/
|
|
79
|
-
handleNativeDeeplink(deeplink: string, closeIOSWebviewBeforeCallNativeDeeplinkHandler?: boolean): void;
|
|
80
|
-
/**
|
|
81
|
-
* Метод для сохранения текущего состояния NativeNavigationAndTitle в sessionStorage.
|
|
82
|
-
*/
|
|
83
|
-
private saveCurrentState;
|
|
84
|
-
/**
|
|
85
|
-
* Метод, вычисляющий `pageId`, который нужно послать в приложение
|
|
86
|
-
* для правильной синхронизации с нативной-кнопкой "Назад".
|
|
87
|
-
*
|
|
88
|
-
* @param purpose Цель взаимодействия с приложением.
|
|
89
|
-
* @returns Правильный pageId.
|
|
90
|
-
*/
|
|
91
|
-
private getNativePageId;
|
|
92
|
-
/**
|
|
93
|
-
* Вспомогательный метод для `getNativePageId` initialization кейса.
|
|
94
|
-
*
|
|
95
|
-
* @returns Правильный pageId.
|
|
96
|
-
*/
|
|
97
|
-
private getNativePageIdForInitialization;
|
|
98
|
-
/**
|
|
99
|
-
* Вспомогательный метод для `getNativePageId` navigation кейса.
|
|
100
|
-
*
|
|
101
|
-
* @returns Правильный pageId.
|
|
102
|
-
*/
|
|
103
|
-
private getNativePageIdForNavigation;
|
|
104
|
-
/**
|
|
105
|
-
* Вспомогательный метод для `getNativePageId` only-title кейса.
|
|
106
|
-
*
|
|
107
|
-
* @returns Правильный pageId.
|
|
108
|
-
*/
|
|
109
|
-
private getNativePageIdForTitleReplacing;
|
|
110
|
-
/**
|
|
111
|
-
* Обработчик для `window.onpopstate` события. Который сработает
|
|
112
|
-
* после нажатия на кнопку "Назад" в нативе, вызова `history.back()` и `history.go(-x)`.
|
|
113
|
-
*/
|
|
114
|
-
private handleBack;
|
|
115
|
-
/**
|
|
116
|
-
* Синхронизирует состояние истории переходов и заголовок с приложением.
|
|
117
|
-
*
|
|
118
|
-
* @param pageTitle Заголовок, который нужно отрисовать в приложении.
|
|
119
|
-
* @param purpose Цель взаимодействия с приложением.
|
|
120
|
-
*/
|
|
121
|
-
private syncHistoryWithNative;
|
|
122
|
-
/**
|
|
123
|
-
* Метод для перехода в веб из другого веб приложения в рамках
|
|
124
|
-
* одной вебвью сессии
|
|
125
|
-
* @param pageId - Номер текущего page который нужно отправить в приложение
|
|
126
|
-
* @param title - Title текущего page который нужно отправить в приложение
|
|
127
|
-
*/
|
|
128
|
-
private supportSharedSession;
|
|
129
|
-
/**
|
|
130
|
-
* Восстанавливает свое предыдущее состояние nativeHistoryStack и title из sessionStorage
|
|
131
|
-
*/
|
|
132
|
-
private restorePreviousState;
|
|
133
|
-
/**
|
|
134
|
-
* Вспомогательный метод для setInitialView, supportSharedSession
|
|
135
|
-
* переназначает обработчик @handleBack для `window.onpopstate` события
|
|
136
|
-
*/
|
|
137
|
-
private reassignPopstateListener;
|
|
138
|
-
/**
|
|
139
|
-
* Вспомогательный метод для navigateInsideASharedSession.
|
|
140
|
-
* Подготавливает внешнюю ссылку в рамках контракта для совместной работы веб-приложений в
|
|
141
|
-
* рамках одной вебвью сессии
|
|
142
|
-
* @param url - url иного веб приложения
|
|
143
|
-
* @return подготовленная согласно контракту ссылка на иное веб приложение с initial query
|
|
144
|
-
* параметрами от натива, а так же nextPageId.
|
|
145
|
-
*/
|
|
146
|
-
private prepareExternalLinkBeforeOpen;
|
|
147
|
-
}
|
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NativeNavigationAndTitle = void 0;
|
|
4
|
-
const constants_1 = require("./constants");
|
|
5
|
-
const utils_1 = require("./utils");
|
|
6
|
-
/**
|
|
7
|
-
* Класс, отвечающий за взаимодействие с нативными элементами в приложении – заголовком и нативной кнопкой назад.
|
|
8
|
-
*/
|
|
9
|
-
class NativeNavigationAndTitle {
|
|
10
|
-
constructor(b2n, pageId, initialNativeTitle = '', handleWindowRedirect) {
|
|
11
|
-
this.b2n = b2n;
|
|
12
|
-
this.nativeHistoryStack = [''];
|
|
13
|
-
this.numOfBackSteps = 1;
|
|
14
|
-
// Тут сохраняются параметры, которые в последний раз были отправлены в приложение.
|
|
15
|
-
// Просто, чтобы не слать одинаковые сигналы в приложение.
|
|
16
|
-
this.lastSetPageSettingsParams = '';
|
|
17
|
-
this.handleBack = this.handleBack.bind(this);
|
|
18
|
-
this._handleWindowRedirect = handleWindowRedirect;
|
|
19
|
-
const previousState = !!sessionStorage.getItem(constants_1.PREVIOUS_NATIVE_NAVIGATION_AND_TITLE_STATE_STORAGE_KEY);
|
|
20
|
-
if (pageId) {
|
|
21
|
-
this.supportSharedSession(pageId, initialNativeTitle);
|
|
22
|
-
}
|
|
23
|
-
else if (previousState) {
|
|
24
|
-
this.restorePreviousState();
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
this.setInitialView(initialNativeTitle);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Метод, вызывающий `history.back()` или закрывающий вебвью, если нет записей
|
|
32
|
-
* в истории переходов.
|
|
33
|
-
*/
|
|
34
|
-
goBack() {
|
|
35
|
-
this.goBackAFewSteps(-1, true);
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Метод, вызывающий history.go(-колл. шагов назад) и модифицирует внутреннее
|
|
39
|
-
* состояние, чтобы в дальнейшем зарегистрировать этот переход в приложении.
|
|
40
|
-
*
|
|
41
|
-
* @param stepsNumber Количество шагов назад.
|
|
42
|
-
* Возможно передача как положительного, так и отрицательного числа.
|
|
43
|
-
* 0 будет проигнорирован.
|
|
44
|
-
* @param autoCloseWebview Флаг – закрывать ли вебвью автоматически,
|
|
45
|
-
* если переданное кол-во шагов будет больше чем записей в истории.
|
|
46
|
-
*/
|
|
47
|
-
goBackAFewSteps(stepsNumber, autoCloseWebview = false) {
|
|
48
|
-
if (!stepsNumber) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
const stepsToBack = Math.abs(stepsNumber);
|
|
52
|
-
const maxStepsToBack = this.nativeHistoryStack.length - 1;
|
|
53
|
-
if (stepsToBack > maxStepsToBack) {
|
|
54
|
-
if (autoCloseWebview) {
|
|
55
|
-
this.b2n.closeWebview();
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
this.numOfBackSteps = maxStepsToBack;
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
this.numOfBackSteps = stepsToBack;
|
|
62
|
-
}
|
|
63
|
-
window.history.go(-this.numOfBackSteps);
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Метод вызывает `src/shared/utils/handle-redirect` из `newclick-host-ui`
|
|
67
|
-
* и регистрирует этот переход в приложении, чтобы кнопка «Назад» в Нативе вызывала
|
|
68
|
-
* переход назад в вебе.
|
|
69
|
-
*/
|
|
70
|
-
handleRedirect(pageTitleOrPath, appNameOrHistoryState, path, params, historyState) {
|
|
71
|
-
const checkAppNameArgument = (argument) => Boolean(appNameOrHistoryState && typeof appNameOrHistoryState === 'string');
|
|
72
|
-
const isAppNameArgument = checkAppNameArgument(appNameOrHistoryState);
|
|
73
|
-
if (isAppNameArgument) {
|
|
74
|
-
this._handleWindowRedirect(appNameOrHistoryState, path, params, historyState);
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
const { appName: extractedAppName, path: extractedPath, query: extractedQuery, } = (0, utils_1.extractAppNameRouteAndQuery)(pageTitleOrPath);
|
|
78
|
-
this._handleWindowRedirect(extractedAppName, extractedPath, extractedQuery, appNameOrHistoryState);
|
|
79
|
-
}
|
|
80
|
-
const title = isAppNameArgument ? pageTitleOrPath : '';
|
|
81
|
-
this.nativeHistoryStack.push(title);
|
|
82
|
-
this.syncHistoryWithNative(title, 'navigation');
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Информирует натив, что веб находится на первом экране (сбрасывает историю переходов, не влияя на браузерную
|
|
86
|
-
* историю), а значит следующее нажатие на кнопку "Назад" в нативе закроет вебвью.
|
|
87
|
-
*
|
|
88
|
-
* @param pageTitle Заголовок, который нужно отрисовать в нативе.
|
|
89
|
-
*/
|
|
90
|
-
setInitialView(pageTitle = '') {
|
|
91
|
-
this.nativeHistoryStack = [pageTitle];
|
|
92
|
-
this.syncHistoryWithNative(pageTitle, 'initialization');
|
|
93
|
-
this.reassignPopstateListener();
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Метод для смены заголовка в нативе без влияния на историю переходов.
|
|
97
|
-
*
|
|
98
|
-
* @param pageTitle Заголовок, который нужно отрисовать в нативе.
|
|
99
|
-
*/
|
|
100
|
-
setTitle(pageTitle) {
|
|
101
|
-
this.nativeHistoryStack[this.nativeHistoryStack.length - 1] = pageTitle;
|
|
102
|
-
this.syncHistoryWithNative(pageTitle, 'title-replacing');
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Метод для открытия второго web приложения в рамках одной вебвью сессии.
|
|
106
|
-
* Сохраняет все текущее состояние текущего экземпляра bridgeToAm и AmNavigationAndTitle в sessionStorage, а
|
|
107
|
-
* так же наполняет url необходимыми query параметрами. Работает только в Android окружении.
|
|
108
|
-
* В IOS окружении будет открыто новое webview поверх текущего.
|
|
109
|
-
*
|
|
110
|
-
* @param url адрес второго web приложения, к которому перед переходом на него будут добавлены
|
|
111
|
-
* все initial query параметры от натива и параметр nextPageId (Android)
|
|
112
|
-
*/
|
|
113
|
-
navigateInsideASharedSession(url) {
|
|
114
|
-
if (this.b2n.environment === 'ios') {
|
|
115
|
-
const nativeDeeplink = `/webFeature?type=recommendation&url=${encodeURIComponent(url)}`;
|
|
116
|
-
this.handleNativeDeeplink(nativeDeeplink);
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
// В b2n этот метод отмечен модификатором доступа private, но тут его нужно вызвать
|
|
120
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
121
|
-
// @ts-ignore
|
|
122
|
-
this.b2n.saveCurrentState();
|
|
123
|
-
window.location.assign(this.prepareExternalLinkBeforeOpen(url));
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Безопасный способ для перезагрузки страницы.
|
|
127
|
-
*/
|
|
128
|
-
pseudoReloadPage() {
|
|
129
|
-
// В b2n этот метод отмечен модификатором доступа private, но тут его нужно вызвать
|
|
130
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
131
|
-
// @ts-ignore
|
|
132
|
-
this.handleRedirect(this.b2n._blankPagePath);
|
|
133
|
-
this.goBack();
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Вызывает обработчик deeplinks в нативе (АМ) и передает туда переданный deeplink.
|
|
137
|
-
* На Android текущее webview будет закрыто из-за технических особенностей.
|
|
138
|
-
* На IOS нативная фича открывается в следующем по стеку экране и при выходе из нее пользователь вернется обратно в webview.
|
|
139
|
-
* На IOS есть возможность закрыть webview перед открытием нативной фичи, передав второй параметр closeIOSWebviewBeforeCallNativeDeeplinkHandler = true
|
|
140
|
-
* @param deeplink диплинк на нативную АМ фичу в AM
|
|
141
|
-
* @param [closeIOSWebviewBeforeCallNativeDeeplinkHandler = false] закрыть текущее webview после открытия нативной фичи (применимо только для IOS на Android по техническим причинам webview всегда будет закрываться)
|
|
142
|
-
*/
|
|
143
|
-
handleNativeDeeplink(deeplink, closeIOSWebviewBeforeCallNativeDeeplinkHandler = false) {
|
|
144
|
-
const clearedDeeplinkPath = deeplink.replace(constants_1.DEEP_LINK_PATTERN, '');
|
|
145
|
-
if (this.b2n.environment === 'ios') {
|
|
146
|
-
if (closeIOSWebviewBeforeCallNativeDeeplinkHandler) {
|
|
147
|
-
this.b2n.closeWebview();
|
|
148
|
-
setTimeout(() => window.location.replace(`${this.b2n.iosAppId}://${clearedDeeplinkPath}`), 0);
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
window.location.replace(`${this.b2n.iosAppId}://${clearedDeeplinkPath}`);
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
window.location.replace(`alfabank://${clearedDeeplinkPath}`);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Метод для сохранения текущего состояния NativeNavigationAndTitle в sessionStorage.
|
|
159
|
-
*/
|
|
160
|
-
saveCurrentState() {
|
|
161
|
-
const currentState = {
|
|
162
|
-
title: this.nativeHistoryStack[this.nativeHistoryStack.length - 1],
|
|
163
|
-
nativeHistoryStack: this.nativeHistoryStack,
|
|
164
|
-
};
|
|
165
|
-
sessionStorage.setItem(constants_1.PREVIOUS_NATIVE_NAVIGATION_AND_TITLE_STATE_STORAGE_KEY, JSON.stringify(currentState));
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Метод, вычисляющий `pageId`, который нужно послать в приложение
|
|
169
|
-
* для правильной синхронизации с нативной-кнопкой "Назад".
|
|
170
|
-
*
|
|
171
|
-
* @param purpose Цель взаимодействия с приложением.
|
|
172
|
-
* @returns Правильный pageId.
|
|
173
|
-
*/
|
|
174
|
-
getNativePageId(purpose) {
|
|
175
|
-
function assertUnreachable(val) {
|
|
176
|
-
throw new Error(`Unexpected value "${val}"`);
|
|
177
|
-
}
|
|
178
|
-
let pageId;
|
|
179
|
-
switch (purpose) {
|
|
180
|
-
case 'initialization':
|
|
181
|
-
pageId = this.getNativePageIdForInitialization();
|
|
182
|
-
break;
|
|
183
|
-
case 'navigation':
|
|
184
|
-
pageId = this.getNativePageIdForNavigation();
|
|
185
|
-
break;
|
|
186
|
-
case 'title-replacing':
|
|
187
|
-
pageId = this.getNativePageIdForTitleReplacing();
|
|
188
|
-
break;
|
|
189
|
-
default:
|
|
190
|
-
assertUnreachable(purpose);
|
|
191
|
-
}
|
|
192
|
-
return pageId;
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Вспомогательный метод для `getNativePageId` initialization кейса.
|
|
196
|
-
*
|
|
197
|
-
* @returns Правильный pageId.
|
|
198
|
-
*/
|
|
199
|
-
getNativePageIdForInitialization() {
|
|
200
|
-
// * В iOS для "первой" страницы не нужно слать `pageId`.
|
|
201
|
-
// * В Android важно, чтобы `pageId` "первой" страницы
|
|
202
|
-
// всегда был одинаковый.
|
|
203
|
-
return this.b2n.environment === 'ios' ? null : 1;
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Вспомогательный метод для `getNativePageId` navigation кейса.
|
|
207
|
-
*
|
|
208
|
-
* @returns Правильный pageId.
|
|
209
|
-
*/
|
|
210
|
-
getNativePageIdForNavigation() {
|
|
211
|
-
const stackSize = this.nativeHistoryStack.length;
|
|
212
|
-
// Нажимая на кнопку назад, можно дойти до "первой" страницы,
|
|
213
|
-
// в iOS для "первой" страницы не нужно слать `pageId`.
|
|
214
|
-
return this.b2n.environment === 'ios' && stackSize <= 1 ? null : stackSize;
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* Вспомогательный метод для `getNativePageId` only-title кейса.
|
|
218
|
-
*
|
|
219
|
-
* @returns Правильный pageId.
|
|
220
|
-
*/
|
|
221
|
-
getNativePageIdForTitleReplacing() {
|
|
222
|
-
const stackSize = this.nativeHistoryStack.length;
|
|
223
|
-
if (this.b2n.environment === 'android') {
|
|
224
|
-
// Для смены заголовка в Андроид просто повторяем текущий `pageId`.
|
|
225
|
-
// В отличии от iOS, если не послать `pageId` первой страницы,
|
|
226
|
-
// Вебвью не будет закрываться по клику на нативный «Назад».
|
|
227
|
-
return stackSize <= 1 ? 1 : stackSize;
|
|
228
|
-
}
|
|
229
|
-
// Если в iOS не послать `pageId`, следующее нажатие на
|
|
230
|
-
// нативную кнопку назад закроет webview.
|
|
231
|
-
return stackSize <= 1 ? null : stackSize;
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Обработчик для `window.onpopstate` события. Который сработает
|
|
235
|
-
* после нажатия на кнопку "Назад" в нативе, вызова `history.back()` и `history.go(-x)`.
|
|
236
|
-
*/
|
|
237
|
-
handleBack() {
|
|
238
|
-
const previousState = !!sessionStorage.getItem(constants_1.PREVIOUS_NATIVE_NAVIGATION_AND_TITLE_STATE_STORAGE_KEY);
|
|
239
|
-
if (previousState) {
|
|
240
|
-
// В b2n этот метод отмечен модификатором доступа private дабы не торчал наружу, но тут его нужно вызвать
|
|
241
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
242
|
-
// @ts-ignore
|
|
243
|
-
this.b2n.restorePreviousState();
|
|
244
|
-
}
|
|
245
|
-
this.nativeHistoryStack = this.nativeHistoryStack.slice(0, -this.numOfBackSteps);
|
|
246
|
-
this.numOfBackSteps = 1;
|
|
247
|
-
if (this.nativeHistoryStack.length < 1) {
|
|
248
|
-
this.b2n.closeWebview();
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
const pageTitle = this.nativeHistoryStack[this.nativeHistoryStack.length - 1];
|
|
252
|
-
this.syncHistoryWithNative(pageTitle, 'navigation');
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Синхронизирует состояние истории переходов и заголовок с приложением.
|
|
256
|
-
*
|
|
257
|
-
* @param pageTitle Заголовок, который нужно отрисовать в приложении.
|
|
258
|
-
* @param purpose Цель взаимодействия с приложением.
|
|
259
|
-
*/
|
|
260
|
-
syncHistoryWithNative(pageTitle, purpose) {
|
|
261
|
-
var _a;
|
|
262
|
-
const pageId = this.getNativePageId(purpose);
|
|
263
|
-
if (this.b2n.environment === 'android') {
|
|
264
|
-
const pageSettingsObj = { pageTitle };
|
|
265
|
-
if (pageId) {
|
|
266
|
-
pageSettingsObj.pageId = pageId;
|
|
267
|
-
}
|
|
268
|
-
const paramsToSend = JSON.stringify(pageSettingsObj);
|
|
269
|
-
if (this.lastSetPageSettingsParams !== paramsToSend) {
|
|
270
|
-
(_a = this.b2n.AndroidBridge) === null || _a === void 0 ? void 0 : _a.setPageSettings(paramsToSend);
|
|
271
|
-
this.lastSetPageSettingsParams = paramsToSend;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
else {
|
|
275
|
-
const pageTitleStr = `?pageTitle=${encodeURIComponent(pageTitle)}`;
|
|
276
|
-
const pageIdStr = pageId ? `&pageId=${pageId}` : '';
|
|
277
|
-
const paramsToSend = `ios:setPageSettings/${pageTitleStr + pageIdStr}`;
|
|
278
|
-
if (this.lastSetPageSettingsParams !== paramsToSend) {
|
|
279
|
-
window.location.replace(paramsToSend);
|
|
280
|
-
this.lastSetPageSettingsParams = paramsToSend;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
/**
|
|
285
|
-
* Метод для перехода в веб из другого веб приложения в рамках
|
|
286
|
-
* одной вебвью сессии
|
|
287
|
-
* @param pageId - Номер текущего page который нужно отправить в приложение
|
|
288
|
-
* @param title - Title текущего page который нужно отправить в приложение
|
|
289
|
-
*/
|
|
290
|
-
supportSharedSession(pageId, title) {
|
|
291
|
-
this.nativeHistoryStack = new Array(pageId).fill('');
|
|
292
|
-
this.syncHistoryWithNative(title, 'title-replacing');
|
|
293
|
-
this.reassignPopstateListener();
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Восстанавливает свое предыдущее состояние nativeHistoryStack и title из sessionStorage
|
|
297
|
-
*/
|
|
298
|
-
restorePreviousState() {
|
|
299
|
-
const previousState = JSON.parse(sessionStorage.getItem(constants_1.PREVIOUS_NATIVE_NAVIGATION_AND_TITLE_STATE_STORAGE_KEY) || '');
|
|
300
|
-
this.nativeHistoryStack = previousState.nativeHistoryStack;
|
|
301
|
-
this.syncHistoryWithNative(previousState.title, 'title-replacing');
|
|
302
|
-
this.reassignPopstateListener();
|
|
303
|
-
sessionStorage.removeItem(constants_1.PREVIOUS_NATIVE_NAVIGATION_AND_TITLE_STATE_STORAGE_KEY);
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* Вспомогательный метод для setInitialView, supportSharedSession
|
|
307
|
-
* переназначает обработчик @handleBack для `window.onpopstate` события
|
|
308
|
-
*/
|
|
309
|
-
reassignPopstateListener() {
|
|
310
|
-
window.removeEventListener('popstate', this.handleBack);
|
|
311
|
-
window.addEventListener('popstate', this.handleBack);
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Вспомогательный метод для navigateInsideASharedSession.
|
|
315
|
-
* Подготавливает внешнюю ссылку в рамках контракта для совместной работы веб-приложений в
|
|
316
|
-
* рамках одной вебвью сессии
|
|
317
|
-
* @param url - url иного веб приложения
|
|
318
|
-
* @return подготовленная согласно контракту ссылка на иное веб приложение с initial query
|
|
319
|
-
* параметрами от натива, а так же nextPageId.
|
|
320
|
-
*/
|
|
321
|
-
prepareExternalLinkBeforeOpen(url) {
|
|
322
|
-
const currentPageId = this.nativeHistoryStack.length;
|
|
323
|
-
const divider = new URL(url).searchParams.toString() ? '&' : '?';
|
|
324
|
-
const link = new URL(`${url}${divider}${this.b2n.originalWebviewParams}`);
|
|
325
|
-
link.searchParams.set('nextPageId', (currentPageId + 1).toString());
|
|
326
|
-
return link.toString();
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
exports.NativeNavigationAndTitle = NativeNavigationAndTitle;
|
package/utils.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Environment } from './types';
|
|
2
|
-
/**
|
|
3
|
-
* Разделяет веб ссылку на компоненты
|
|
4
|
-
* @param route внутренний путь для навигации
|
|
5
|
-
* @return объект с appName, route, query
|
|
6
|
-
*/
|
|
7
|
-
export declare const extractAppNameRouteAndQuery: (route: string) => {
|
|
8
|
-
appName: string;
|
|
9
|
-
path: string;
|
|
10
|
-
query: Record<string, string> | undefined;
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* Возвращает экземпляр `URL` из ссылки, докидывая `https://` при отсутствии.
|
|
14
|
-
*/
|
|
15
|
-
export declare const getUrlInstance: (link: string) => URL;
|
|
16
|
-
/**
|
|
17
|
-
* Проверяет, что переданная строка содержит версию приложения в правильном формате.
|
|
18
|
-
*
|
|
19
|
-
* @param version Строка с версией для проверки.
|
|
20
|
-
* @returns Правильный формат или нет.
|
|
21
|
-
*/
|
|
22
|
-
export declare const isValidVersionFormat: (version?: string | undefined) => boolean;
|
|
23
|
-
export declare const getAppId: (environment: Environment, iosAppId?: string | undefined) => string | null;
|
package/utils.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getAppId = exports.isValidVersionFormat = exports.getUrlInstance = exports.extractAppNameRouteAndQuery = void 0;
|
|
4
|
-
const constants_1 = require("./constants");
|
|
5
|
-
/**
|
|
6
|
-
* Разделяет веб ссылку на компоненты
|
|
7
|
-
* @param route внутренний путь для навигации
|
|
8
|
-
* @return объект с appName, route, query
|
|
9
|
-
*/
|
|
10
|
-
const extractAppNameRouteAndQuery = (route) => {
|
|
11
|
-
var _a;
|
|
12
|
-
let appName = '';
|
|
13
|
-
let path = '';
|
|
14
|
-
let query;
|
|
15
|
-
const clearedPath = route.replace(/(?:^\/)|(?:\/$)/g, '');
|
|
16
|
-
const segments = clearedPath.split('/');
|
|
17
|
-
const queryByPath = clearedPath.split('?')[1];
|
|
18
|
-
appName = ((_a = segments.shift()) === null || _a === void 0 ? void 0 : _a.split('?')[0]) || '';
|
|
19
|
-
if (queryByPath) {
|
|
20
|
-
query = Array.from(new URLSearchParams(queryByPath).entries()).reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {});
|
|
21
|
-
}
|
|
22
|
-
path = segments.join('/').replace(`?${queryByPath}`, '');
|
|
23
|
-
return { appName, path, query };
|
|
24
|
-
};
|
|
25
|
-
exports.extractAppNameRouteAndQuery = extractAppNameRouteAndQuery;
|
|
26
|
-
/**
|
|
27
|
-
* Возвращает экземпляр `URL` из ссылки, докидывая `https://` при отсутствии.
|
|
28
|
-
*/
|
|
29
|
-
const getUrlInstance = (link) => {
|
|
30
|
-
const protocolRequiredPattern = /^https?:\/\//;
|
|
31
|
-
let url;
|
|
32
|
-
if (protocolRequiredPattern.test(link)) {
|
|
33
|
-
url = new URL(link);
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
try {
|
|
37
|
-
// Пробуем докинуть `https://`, как правило, это помогает.
|
|
38
|
-
url = new URL(`https://${link}`);
|
|
39
|
-
}
|
|
40
|
-
catch (e) {
|
|
41
|
-
// Кажется, добавив протокол, сюда мы больше не сможем вывалиться, но на всякий случай...
|
|
42
|
-
url = new URL('about:blank');
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return url;
|
|
46
|
-
};
|
|
47
|
-
exports.getUrlInstance = getUrlInstance;
|
|
48
|
-
/**
|
|
49
|
-
* Проверяет, что переданная строка содержит версию приложения в правильном формате.
|
|
50
|
-
*
|
|
51
|
-
* @param version Строка с версией для проверки.
|
|
52
|
-
* @returns Правильный формат или нет.
|
|
53
|
-
*/
|
|
54
|
-
const isValidVersionFormat = (version) => {
|
|
55
|
-
if (!version)
|
|
56
|
-
return false;
|
|
57
|
-
const versionPattern = /^\d+\.\d+\.\d+$/;
|
|
58
|
-
return versionPattern.test(version);
|
|
59
|
-
};
|
|
60
|
-
exports.isValidVersionFormat = isValidVersionFormat;
|
|
61
|
-
const getAppId = (environment, iosAppId) => {
|
|
62
|
-
if (environment === 'android') {
|
|
63
|
-
return atob(constants_1.ANDROID_APP_ID);
|
|
64
|
-
}
|
|
65
|
-
if (environment === 'ios' && iosAppId && typeof iosAppId === 'string') {
|
|
66
|
-
return iosAppId;
|
|
67
|
-
}
|
|
68
|
-
return null;
|
|
69
|
-
};
|
|
70
|
-
exports.getAppId = getAppId;
|
|
File without changes
|
|
File without changes
|