@alfalab/bridge-to-native 0.0.7-beta-11d7ff7 → 0.0.7-beta-b5c9d02
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/bridge-to-native.d.ts +62 -0
- package/bridge-to-native.js +142 -0
- package/constants.d.ts +1 -0
- package/constants.js +2 -1
- package/index.d.ts +2 -64
- package/index.js +2 -139
- package/native-fallbacks.d.ts +1 -1
- package/native-navigation-and-title.d.ts +13 -5
- package/native-navigation-and-title.js +28 -6
- package/package.json +6 -4
- package/types.d.ts +3 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { NativeFallbacks } from './native-fallbacks';
|
|
2
|
+
import { NativeNavigationAndTitle } from './native-navigation-and-title';
|
|
3
|
+
import type { Environment, HandleRedirect, NativeFeatureKey, NativeParams, Theme } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Этот класс — абстракция для связи веб приложения с нативом и предназначен ТОЛЬКО
|
|
6
|
+
* для использования в вебвью окружении.
|
|
7
|
+
*/
|
|
8
|
+
export declare class BridgeToNative {
|
|
9
|
+
readonly AndroidBridge: {
|
|
10
|
+
setPageSettings: (params: string) => void;
|
|
11
|
+
} | undefined;
|
|
12
|
+
readonly environment: Environment;
|
|
13
|
+
readonly nativeFallbacks: NativeFallbacks;
|
|
14
|
+
private nextPageId;
|
|
15
|
+
private _nativeNavigationAndTitle;
|
|
16
|
+
private _originalWebviewParams;
|
|
17
|
+
private _appVersion;
|
|
18
|
+
private _iosAppId?;
|
|
19
|
+
private _theme;
|
|
20
|
+
private readonly _blankPagePath;
|
|
21
|
+
private readonly _handleRedirect;
|
|
22
|
+
constructor(handleRedirect: HandleRedirect, blankPagePath: string, nativeParams?: NativeParams);
|
|
23
|
+
get theme(): Theme;
|
|
24
|
+
get appVersion(): string;
|
|
25
|
+
get iosAppId(): string | undefined;
|
|
26
|
+
get nativeNavigationAndTitle(): NativeNavigationAndTitle;
|
|
27
|
+
get originalWebviewParams(): string;
|
|
28
|
+
/**
|
|
29
|
+
* Метод, проверяющий, можно ли использовать нативную функциональность в текущей версии приложения.
|
|
30
|
+
*
|
|
31
|
+
* @param feature Название функциональности, которую нужно проверить.
|
|
32
|
+
*/
|
|
33
|
+
canUseNativeFeature(feature: NativeFeatureKey): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Метод, отправляющий сигнал нативу, что нужно закрыть текущее вебвью.
|
|
36
|
+
*/
|
|
37
|
+
closeWebview(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Сравнивает текущую версию приложения с переданной.
|
|
40
|
+
*
|
|
41
|
+
* @param versionToCompare Версия, с которой нужно сравнить текущую.
|
|
42
|
+
* @returns `true` – текущая версия больше или равняется переданной,
|
|
43
|
+
* `false` – текущая версия ниже.
|
|
44
|
+
*/
|
|
45
|
+
isCurrentVersionHigherOrEqual(versionToCompare: string): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Сохраняет текущее состояние BridgeToNative в sessionStorage.
|
|
48
|
+
* Так же сохраняет текущее состояние nativeNavigationAndTitle.
|
|
49
|
+
*/
|
|
50
|
+
private saveCurrentState;
|
|
51
|
+
/**
|
|
52
|
+
* Возвращает схему приложения в iOS окружении, на основе версии.
|
|
53
|
+
*
|
|
54
|
+
* @param knownIosAppId Тип iOS приложения, если он известен.
|
|
55
|
+
* @returns Тип приложения, `undefined` для Android окружения.
|
|
56
|
+
*/
|
|
57
|
+
private getIosAppId;
|
|
58
|
+
/**
|
|
59
|
+
* Восстанавливает свое предыдущее состояние из sessionStorage
|
|
60
|
+
*/
|
|
61
|
+
private restorePreviousState;
|
|
62
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable no-underscore-dangle */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.BridgeToNative = void 0;
|
|
5
|
+
const constants_1 = require("./constants");
|
|
6
|
+
const native_fallbacks_1 = require("./native-fallbacks");
|
|
7
|
+
const native_navigation_and_title_1 = require("./native-navigation-and-title");
|
|
8
|
+
const utils_1 = require("./utils");
|
|
9
|
+
/**
|
|
10
|
+
* Этот класс — абстракция для связи веб приложения с нативом и предназначен ТОЛЬКО
|
|
11
|
+
* для использования в вебвью окружении.
|
|
12
|
+
*/
|
|
13
|
+
class BridgeToNative {
|
|
14
|
+
constructor(handleRedirect, blankPagePath, nativeParams) {
|
|
15
|
+
// Webview, запущенное в Android окружении имеет объект `Android` в window.
|
|
16
|
+
this.AndroidBridge = window.Android;
|
|
17
|
+
this.environment = this.AndroidBridge ? 'android' : 'ios';
|
|
18
|
+
const previousState = !!sessionStorage.getItem(constants_1.PREVIOUS_B2N_STATE_STORAGE_KEY);
|
|
19
|
+
if (previousState) {
|
|
20
|
+
this.restorePreviousState();
|
|
21
|
+
this.nativeFallbacks = new native_fallbacks_1.NativeFallbacks(this);
|
|
22
|
+
this._blankPagePath = blankPagePath;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
this._appVersion =
|
|
26
|
+
nativeParams && (0, utils_1.isValidVersionFormat)(nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.appVersion)
|
|
27
|
+
? nativeParams.appVersion
|
|
28
|
+
: '0.0.0';
|
|
29
|
+
this._iosAppId = this.getIosAppId(nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.iosAppId);
|
|
30
|
+
this._theme = (nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.theme) === 'dark' ? 'dark' : 'light';
|
|
31
|
+
this._originalWebviewParams = (nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.originalWebviewParams) || '';
|
|
32
|
+
this._nativeNavigationAndTitle = new native_navigation_and_title_1.NativeNavigationAndTitle(this, nativeParams ? nativeParams.nextPageId : null, nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.title, handleRedirect);
|
|
33
|
+
this._handleRedirect = handleRedirect;
|
|
34
|
+
this.nextPageId = nativeParams ? nativeParams.nextPageId : null;
|
|
35
|
+
this.nativeFallbacks = new native_fallbacks_1.NativeFallbacks(this);
|
|
36
|
+
this._blankPagePath = blankPagePath;
|
|
37
|
+
}
|
|
38
|
+
get theme() {
|
|
39
|
+
return this._theme;
|
|
40
|
+
}
|
|
41
|
+
get appVersion() {
|
|
42
|
+
return this._appVersion;
|
|
43
|
+
}
|
|
44
|
+
get iosAppId() {
|
|
45
|
+
return this._iosAppId;
|
|
46
|
+
}
|
|
47
|
+
get nativeNavigationAndTitle() {
|
|
48
|
+
return this._nativeNavigationAndTitle;
|
|
49
|
+
}
|
|
50
|
+
get originalWebviewParams() {
|
|
51
|
+
return this._originalWebviewParams;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Метод, проверяющий, можно ли использовать нативную функциональность в текущей версии приложения.
|
|
55
|
+
*
|
|
56
|
+
* @param feature Название функциональности, которую нужно проверить.
|
|
57
|
+
*/
|
|
58
|
+
canUseNativeFeature(feature) {
|
|
59
|
+
const { fromVersion } = constants_1.nativeFeaturesFromVersion[this.environment][feature];
|
|
60
|
+
return this.isCurrentVersionHigherOrEqual(fromVersion);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Метод, отправляющий сигнал нативу, что нужно закрыть текущее вебвью.
|
|
64
|
+
*/
|
|
65
|
+
// eslint-disable-next-line class-methods-use-this
|
|
66
|
+
closeWebview() {
|
|
67
|
+
const originalPageUrl = new URL(window.location.href);
|
|
68
|
+
originalPageUrl.searchParams.set(constants_1.CLOSE_WEBVIEW_SEARCH_KEY, constants_1.CLOSE_WEBVIEW_SEARCH_VALUE);
|
|
69
|
+
window.location.href = originalPageUrl.toString();
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Сравнивает текущую версию приложения с переданной.
|
|
73
|
+
*
|
|
74
|
+
* @param versionToCompare Версия, с которой нужно сравнить текущую.
|
|
75
|
+
* @returns `true` – текущая версия больше или равняется переданной,
|
|
76
|
+
* `false` – текущая версия ниже.
|
|
77
|
+
*/
|
|
78
|
+
isCurrentVersionHigherOrEqual(versionToCompare) {
|
|
79
|
+
if (!(0, utils_1.isValidVersionFormat)(versionToCompare)) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
const matchPattern = /(\d+)\.(\d+)\.(\d+)/;
|
|
83
|
+
const [, ...appVersionComponents] = this._appVersion.match(matchPattern); // Формат версии проверен в конструкторе, можно смело убирать `null` из типа.
|
|
84
|
+
const [, ...versionToCompareComponents] = versionToCompare.match(matchPattern);
|
|
85
|
+
for (let i = 0; i < appVersionComponents.length; i++) {
|
|
86
|
+
if (appVersionComponents[i] !== versionToCompareComponents[i]) {
|
|
87
|
+
return appVersionComponents[i] >= versionToCompareComponents[i];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Сохраняет текущее состояние BridgeToNative в sessionStorage.
|
|
94
|
+
* Так же сохраняет текущее состояние nativeNavigationAndTitle.
|
|
95
|
+
*/
|
|
96
|
+
saveCurrentState() {
|
|
97
|
+
// В nativeNavigationAndTitle этот метод отмечен модификатором доступа private дабы не торчал наружу, но тут его нужно вызвать
|
|
98
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
99
|
+
// @ts-ignore
|
|
100
|
+
this._nativeNavigationAndTitle.saveCurrentState();
|
|
101
|
+
const currentState = {
|
|
102
|
+
appVersion: this._appVersion,
|
|
103
|
+
theme: this._theme,
|
|
104
|
+
nextPageId: this.nextPageId,
|
|
105
|
+
originalWebviewParams: this._originalWebviewParams || '',
|
|
106
|
+
iosAppId: this._iosAppId,
|
|
107
|
+
};
|
|
108
|
+
sessionStorage.setItem(constants_1.PREVIOUS_B2N_STATE_STORAGE_KEY, JSON.stringify(currentState));
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Возвращает схему приложения в iOS окружении, на основе версии.
|
|
112
|
+
*
|
|
113
|
+
* @param knownIosAppId Тип iOS приложения, если он известен.
|
|
114
|
+
* @returns Тип приложения, `undefined` для Android окружения.
|
|
115
|
+
*/
|
|
116
|
+
getIosAppId(knownIosAppId) {
|
|
117
|
+
if (this.environment !== 'ios') {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
if (knownIosAppId) {
|
|
121
|
+
return knownIosAppId;
|
|
122
|
+
}
|
|
123
|
+
const keys = Object.keys(constants_1.versionToIosAppId);
|
|
124
|
+
const rightKey = [...keys].reverse().find((version) => this.isCurrentVersionHigherOrEqual(version)) ||
|
|
125
|
+
keys[0];
|
|
126
|
+
return atob(constants_1.versionToIosAppId[rightKey]);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Восстанавливает свое предыдущее состояние из sessionStorage
|
|
130
|
+
*/
|
|
131
|
+
restorePreviousState() {
|
|
132
|
+
const previousState = JSON.parse(sessionStorage.getItem(constants_1.PREVIOUS_B2N_STATE_STORAGE_KEY) || '');
|
|
133
|
+
this._appVersion = previousState.appVersion;
|
|
134
|
+
this._iosAppId = previousState.iosAppId;
|
|
135
|
+
this._theme = previousState.theme;
|
|
136
|
+
this._originalWebviewParams = previousState.originalWebviewParams;
|
|
137
|
+
this.nextPageId = previousState.nextPageId;
|
|
138
|
+
this._nativeNavigationAndTitle = new native_navigation_and_title_1.NativeNavigationAndTitle(this, previousState.nextPageId, '', this._handleRedirect);
|
|
139
|
+
sessionStorage.removeItem(constants_1.PREVIOUS_B2N_STATE_STORAGE_KEY);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
exports.BridgeToNative = BridgeToNative;
|
package/constants.d.ts
CHANGED
package/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.nativeFeaturesFromVersion = exports.versionToIosAppId = exports.PREVIOUS_NATIVE_NAVIGATION_AND_TITLE_STATE_STORAGE_KEY = exports.PREVIOUS_B2N_STATE_STORAGE_KEY = exports.CLOSE_WEBVIEW_SEARCH_VALUE = exports.CLOSE_WEBVIEW_SEARCH_KEY = void 0;
|
|
3
|
+
exports.DEEP_LINK_PATTERN = exports.nativeFeaturesFromVersion = exports.versionToIosAppId = exports.PREVIOUS_NATIVE_NAVIGATION_AND_TITLE_STATE_STORAGE_KEY = exports.PREVIOUS_B2N_STATE_STORAGE_KEY = exports.CLOSE_WEBVIEW_SEARCH_VALUE = exports.CLOSE_WEBVIEW_SEARCH_KEY = void 0;
|
|
4
4
|
exports.CLOSE_WEBVIEW_SEARCH_KEY = 'closeWebView';
|
|
5
5
|
exports.CLOSE_WEBVIEW_SEARCH_VALUE = 'true';
|
|
6
6
|
exports.PREVIOUS_B2N_STATE_STORAGE_KEY = 'previousBridgeToNativeState';
|
|
@@ -25,3 +25,4 @@ exports.nativeFeaturesFromVersion = {
|
|
|
25
25
|
geolocation: { fromVersion: '0.0.0' },
|
|
26
26
|
},
|
|
27
27
|
};
|
|
28
|
+
exports.DEEP_LINK_PATTERN = /^(\/|\x61\x6c\x66\x61\x62\x61\x6e\x6b:\/{3}dashboard\/|\x61\x6c\x66\x61\x62\x61\x6e\x6b:\/{3}|\x61\x6c\x66\x61\x62\x61\x6e\x6b:\/{2}|https:\/{2}\x6f\x6e\x6c\x69\x6e\x65\x2e\x61\x6c\x66\x61\x62\x61\x6e\x6b\x2e\x72\x75\/)/;
|
package/index.d.ts
CHANGED
|
@@ -1,64 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import type { Environment, NativeFeatureKey, NativeParams } from './types';
|
|
4
|
-
declare type Theme = 'light' | 'dark';
|
|
5
|
-
/**
|
|
6
|
-
* Этот класс — абстракция для связи веб приложения с нативом и предназначен ТОЛЬКО
|
|
7
|
-
* для использования в вебвью окружении.
|
|
8
|
-
*/
|
|
9
|
-
export declare class BridgeToNative {
|
|
10
|
-
readonly AndroidBridge: {
|
|
11
|
-
setPageSettings: (params: string) => void;
|
|
12
|
-
} | undefined;
|
|
13
|
-
readonly environment: Environment;
|
|
14
|
-
readonly nativeFallbacks: NativeFallbacks;
|
|
15
|
-
private nextPageId;
|
|
16
|
-
private _nativeNavigationAndTitle;
|
|
17
|
-
private _originalWebviewParams;
|
|
18
|
-
private _appVersion;
|
|
19
|
-
private _iosAppId?;
|
|
20
|
-
private _theme;
|
|
21
|
-
private readonly _blankPagePath;
|
|
22
|
-
private readonly _handleRedirect;
|
|
23
|
-
constructor(handleRedirect: HandleRedirect, blankPagePath: string, nativeParams?: NativeParams);
|
|
24
|
-
get theme(): Theme;
|
|
25
|
-
get appVersion(): string;
|
|
26
|
-
get iosAppId(): string | undefined;
|
|
27
|
-
get nativeNavigationAndTitle(): NativeNavigationAndTitle;
|
|
28
|
-
get originalWebviewParams(): string;
|
|
29
|
-
/**
|
|
30
|
-
* Метод, проверяющий, можно ли использовать нативную функциональность в текущей версии приложения.
|
|
31
|
-
*
|
|
32
|
-
* @param feature Название функциональности, которую нужно проверить.
|
|
33
|
-
*/
|
|
34
|
-
canUseNativeFeature(feature: NativeFeatureKey): boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Метод, отправляющий сигнал нативу, что нужно закрыть текущее вебвью.
|
|
37
|
-
*/
|
|
38
|
-
closeWebview(): void;
|
|
39
|
-
/**
|
|
40
|
-
* Сравнивает текущую версию приложения с переданной.
|
|
41
|
-
*
|
|
42
|
-
* @param versionToCompare Версия, с которой нужно сравнить текущую.
|
|
43
|
-
* @returns `true` – текущая версия больше или равняется переданной,
|
|
44
|
-
* `false` – текущая версия ниже.
|
|
45
|
-
*/
|
|
46
|
-
isCurrentVersionHigherOrEqual(versionToCompare: string): boolean;
|
|
47
|
-
/**
|
|
48
|
-
* Сохраняет текущее состояние BridgeToNative в sessionStorage.
|
|
49
|
-
* Так же сохраняет текущее состояние nativeNavigationAndTitle.
|
|
50
|
-
*/
|
|
51
|
-
private saveCurrentState;
|
|
52
|
-
/**
|
|
53
|
-
* Возвращает схему приложения в iOS окружении, на основе версии.
|
|
54
|
-
*
|
|
55
|
-
* @param knownIosAppId Тип iOS приложения, если он известен.
|
|
56
|
-
* @returns Тип приложения, `undefined` для Android окружения.
|
|
57
|
-
*/
|
|
58
|
-
private getIosAppId;
|
|
59
|
-
/**
|
|
60
|
-
* Восстанавливает свое предыдущее состояние из sessionStorage
|
|
61
|
-
*/
|
|
62
|
-
private restorePreviousState;
|
|
63
|
-
}
|
|
64
|
-
export {};
|
|
1
|
+
export { BridgeToNative } from './bridge-to-native';
|
|
2
|
+
export { NativeParams, Theme, Environment, NativeFeatureKey, PdfType } from './types';
|
package/index.js
CHANGED
|
@@ -1,142 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint-disable no-underscore-dangle */
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.BridgeToNative = void 0;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const native_navigation_and_title_1 = require("./native-navigation-and-title");
|
|
8
|
-
const utils_1 = require("./utils");
|
|
9
|
-
/**
|
|
10
|
-
* Этот класс — абстракция для связи веб приложения с нативом и предназначен ТОЛЬКО
|
|
11
|
-
* для использования в вебвью окружении.
|
|
12
|
-
*/
|
|
13
|
-
class BridgeToNative {
|
|
14
|
-
constructor(handleRedirect, blankPagePath, nativeParams) {
|
|
15
|
-
// Webview, запущенное в Android окружении имеет объект `Android` в window.
|
|
16
|
-
this.AndroidBridge = window.Android;
|
|
17
|
-
this.environment = this.AndroidBridge ? 'android' : 'ios';
|
|
18
|
-
const previousState = !!sessionStorage.getItem(constants_1.PREVIOUS_B2N_STATE_STORAGE_KEY);
|
|
19
|
-
if (previousState) {
|
|
20
|
-
this.restorePreviousState();
|
|
21
|
-
this.nativeFallbacks = new native_fallbacks_1.NativeFallbacks(this);
|
|
22
|
-
this._blankPagePath = blankPagePath;
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
this._appVersion =
|
|
26
|
-
nativeParams && (0, utils_1.isValidVersionFormat)(nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.appVersion)
|
|
27
|
-
? nativeParams.appVersion
|
|
28
|
-
: '0.0.0';
|
|
29
|
-
this._iosAppId = this.getIosAppId(nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.iosAppId);
|
|
30
|
-
this._theme = (nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.theme) === 'dark' ? 'dark' : 'light';
|
|
31
|
-
this._originalWebviewParams = (nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.originalWebviewParams) || '';
|
|
32
|
-
this._nativeNavigationAndTitle = new native_navigation_and_title_1.NativeNavigationAndTitle(this, nativeParams ? nativeParams.nextPageId : null, nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.title, handleRedirect);
|
|
33
|
-
this._handleRedirect = handleRedirect;
|
|
34
|
-
this.nextPageId = nativeParams ? nativeParams.nextPageId : null;
|
|
35
|
-
this.nativeFallbacks = new native_fallbacks_1.NativeFallbacks(this);
|
|
36
|
-
this._blankPagePath = blankPagePath;
|
|
37
|
-
}
|
|
38
|
-
get theme() {
|
|
39
|
-
return this._theme;
|
|
40
|
-
}
|
|
41
|
-
get appVersion() {
|
|
42
|
-
return this._appVersion;
|
|
43
|
-
}
|
|
44
|
-
get iosAppId() {
|
|
45
|
-
return this._iosAppId;
|
|
46
|
-
}
|
|
47
|
-
get nativeNavigationAndTitle() {
|
|
48
|
-
return this._nativeNavigationAndTitle;
|
|
49
|
-
}
|
|
50
|
-
get originalWebviewParams() {
|
|
51
|
-
return this._originalWebviewParams;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Метод, проверяющий, можно ли использовать нативную функциональность в текущей версии приложения.
|
|
55
|
-
*
|
|
56
|
-
* @param feature Название функциональности, которую нужно проверить.
|
|
57
|
-
*/
|
|
58
|
-
canUseNativeFeature(feature) {
|
|
59
|
-
const { fromVersion } = constants_1.nativeFeaturesFromVersion[this.environment][feature];
|
|
60
|
-
return this.isCurrentVersionHigherOrEqual(fromVersion);
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Метод, отправляющий сигнал нативу, что нужно закрыть текущее вебвью.
|
|
64
|
-
*/
|
|
65
|
-
// eslint-disable-next-line class-methods-use-this
|
|
66
|
-
closeWebview() {
|
|
67
|
-
const originalPageUrl = new URL(window.location.href);
|
|
68
|
-
originalPageUrl.searchParams.set(constants_1.CLOSE_WEBVIEW_SEARCH_KEY, constants_1.CLOSE_WEBVIEW_SEARCH_VALUE);
|
|
69
|
-
window.location.href = originalPageUrl.toString();
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Сравнивает текущую версию приложения с переданной.
|
|
73
|
-
*
|
|
74
|
-
* @param versionToCompare Версия, с которой нужно сравнить текущую.
|
|
75
|
-
* @returns `true` – текущая версия больше или равняется переданной,
|
|
76
|
-
* `false` – текущая версия ниже.
|
|
77
|
-
*/
|
|
78
|
-
isCurrentVersionHigherOrEqual(versionToCompare) {
|
|
79
|
-
if (!(0, utils_1.isValidVersionFormat)(versionToCompare)) {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
const matchPattern = /(\d+)\.(\d+)\.(\d+)/;
|
|
83
|
-
const [, ...appVersionComponents] = this._appVersion.match(matchPattern); // Формат версии проверен в конструкторе, можно смело убирать `null` из типа.
|
|
84
|
-
const [, ...versionToCompareComponents] = versionToCompare.match(matchPattern);
|
|
85
|
-
for (let i = 0; i < appVersionComponents.length; i++) {
|
|
86
|
-
if (appVersionComponents[i] !== versionToCompareComponents[i]) {
|
|
87
|
-
return appVersionComponents[i] >= versionToCompareComponents[i];
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Сохраняет текущее состояние BridgeToNative в sessionStorage.
|
|
94
|
-
* Так же сохраняет текущее состояние nativeNavigationAndTitle.
|
|
95
|
-
*/
|
|
96
|
-
saveCurrentState() {
|
|
97
|
-
// В nativeNavigationAndTitle этот метод отмечен модификатором доступа private дабы не торчал наружу, но тут его нужно вызвать
|
|
98
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
99
|
-
// @ts-ignore
|
|
100
|
-
this._nativeNavigationAndTitle.saveCurrentState();
|
|
101
|
-
const currentState = {
|
|
102
|
-
appVersion: this._appVersion,
|
|
103
|
-
theme: this._theme,
|
|
104
|
-
nextPageId: this.nextPageId,
|
|
105
|
-
originalWebviewParams: this._originalWebviewParams || '',
|
|
106
|
-
iosAppId: this._iosAppId,
|
|
107
|
-
};
|
|
108
|
-
sessionStorage.setItem(constants_1.PREVIOUS_B2N_STATE_STORAGE_KEY, JSON.stringify(currentState));
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Возвращает схему приложения в iOS окружении, на основе версии.
|
|
112
|
-
*
|
|
113
|
-
* @param knownIosAppId Тип iOS приложения, если он известен.
|
|
114
|
-
* @returns Тип приложения, `undefined` для Android окружения.
|
|
115
|
-
*/
|
|
116
|
-
getIosAppId(knownIosAppId) {
|
|
117
|
-
if (this.environment !== 'ios') {
|
|
118
|
-
return undefined;
|
|
119
|
-
}
|
|
120
|
-
if (knownIosAppId) {
|
|
121
|
-
return knownIosAppId;
|
|
122
|
-
}
|
|
123
|
-
const keys = Object.keys(constants_1.versionToIosAppId);
|
|
124
|
-
const rightKey = [...keys].reverse().find((version) => this.isCurrentVersionHigherOrEqual(version)) ||
|
|
125
|
-
keys[0];
|
|
126
|
-
return atob(constants_1.versionToIosAppId[rightKey]);
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Восстанавливает свое предыдущее состояние из sessionStorage
|
|
130
|
-
*/
|
|
131
|
-
restorePreviousState() {
|
|
132
|
-
const previousState = JSON.parse(sessionStorage.getItem(constants_1.PREVIOUS_B2N_STATE_STORAGE_KEY) || '');
|
|
133
|
-
this._appVersion = previousState.appVersion;
|
|
134
|
-
this._iosAppId = previousState.iosAppId;
|
|
135
|
-
this._theme = previousState.theme;
|
|
136
|
-
this._originalWebviewParams = previousState.originalWebviewParams;
|
|
137
|
-
this.nextPageId = previousState.nextPageId;
|
|
138
|
-
this._nativeNavigationAndTitle = new native_navigation_and_title_1.NativeNavigationAndTitle(this, previousState.nextPageId, '', this._handleRedirect);
|
|
139
|
-
sessionStorage.removeItem(constants_1.PREVIOUS_B2N_STATE_STORAGE_KEY);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
exports.BridgeToNative = BridgeToNative;
|
|
4
|
+
var bridge_to_native_1 = require("./bridge-to-native");
|
|
5
|
+
Object.defineProperty(exports, "BridgeToNative", { enumerable: true, get: function () { return bridge_to_native_1.BridgeToNative; } });
|
package/native-fallbacks.d.ts
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { HandleRedirect } from './types';
|
|
2
|
+
import { BridgeToNative } from './bridge-to-native';
|
|
3
3
|
/**
|
|
4
|
-
* Класс, отвечающий за взаимодействие с нативными элементами в приложении – заголовком
|
|
5
|
-
* и нативной кнопкой назад.
|
|
4
|
+
* Класс, отвечающий за взаимодействие с нативными элементами в приложении – заголовком и нативной кнопкой назад.
|
|
6
5
|
*/
|
|
7
6
|
export declare class NativeNavigationAndTitle {
|
|
8
7
|
private b2n;
|
|
9
8
|
private nativeHistoryStack;
|
|
10
9
|
private numOfBackSteps;
|
|
11
10
|
private lastSetPageSettingsParams;
|
|
12
|
-
private readonly
|
|
11
|
+
private readonly _handleWindowRedirect;
|
|
13
12
|
constructor(b2n: BridgeToNative, pageId: number | null, initialNativeTitle: string | undefined, handleWindowRedirect: HandleRedirect);
|
|
14
13
|
/**
|
|
15
14
|
* Метод, вызывающий `history.back()` или закрывающий вебвью, если нет записей
|
|
@@ -67,6 +66,15 @@ export declare class NativeNavigationAndTitle {
|
|
|
67
66
|
* Безопасный способ для перезагрузки страницы.
|
|
68
67
|
*/
|
|
69
68
|
pseudoReloadPage(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Вызывает обработчик deeplinks в нативе (АМ) и передает туда переданный deeplink.
|
|
71
|
+
* На Android текущее webview будет закрыто из-за технических особенностей.
|
|
72
|
+
* На IOS нативная фича открывается в следующем по стеку экране и при выходе из нее пользователь вернется обратно в webview.
|
|
73
|
+
* На IOS есть возможность закрыть webview перед открытием нативной фичи, передав второй параметр closeIOSWebviewBeforeCallNativeDeeplinkHandler = true
|
|
74
|
+
* @param deeplink диплинк на нативную АМ фичу в AM
|
|
75
|
+
* @param [closeIOSWebviewBeforeCallNativeDeeplinkHandler = false] закрыть текущее webview после открытия нативной фичи (применимо только для IOS на Android по техническим причинам webview всегда будет закрываться)
|
|
76
|
+
*/
|
|
77
|
+
handleNativeDeeplink(deeplink: string, closeIOSWebviewBeforeCallNativeDeeplinkHandler?: boolean): void;
|
|
70
78
|
/**
|
|
71
79
|
* Метод для сохранения текущего состояния NativeNavigationAndTitle в sessionStorage.
|
|
72
80
|
*/
|
|
@@ -4,8 +4,7 @@ exports.NativeNavigationAndTitle = void 0;
|
|
|
4
4
|
const constants_1 = require("./constants");
|
|
5
5
|
const utils_1 = require("./utils");
|
|
6
6
|
/**
|
|
7
|
-
* Класс, отвечающий за взаимодействие с нативными элементами в приложении – заголовком
|
|
8
|
-
* и нативной кнопкой назад.
|
|
7
|
+
* Класс, отвечающий за взаимодействие с нативными элементами в приложении – заголовком и нативной кнопкой назад.
|
|
9
8
|
*/
|
|
10
9
|
class NativeNavigationAndTitle {
|
|
11
10
|
constructor(b2n, pageId, initialNativeTitle = '', handleWindowRedirect) {
|
|
@@ -16,7 +15,7 @@ class NativeNavigationAndTitle {
|
|
|
16
15
|
// Просто, чтобы не слать одинаковые сигналы в приложение.
|
|
17
16
|
this.lastSetPageSettingsParams = '';
|
|
18
17
|
this.handleBack = this.handleBack.bind(this);
|
|
19
|
-
this.
|
|
18
|
+
this._handleWindowRedirect = handleWindowRedirect;
|
|
20
19
|
const previousState = !!sessionStorage.getItem(constants_1.PREVIOUS_NATIVE_NAVIGATION_AND_TITLE_STATE_STORAGE_KEY);
|
|
21
20
|
if (pageId) {
|
|
22
21
|
this.supportSharedSession(pageId, initialNativeTitle);
|
|
@@ -70,11 +69,11 @@ class NativeNavigationAndTitle {
|
|
|
70
69
|
*/
|
|
71
70
|
handleRedirect(pageTitleOrPath, appName, path, params) {
|
|
72
71
|
if (appName) {
|
|
73
|
-
this.
|
|
72
|
+
this._handleWindowRedirect(appName, path, params);
|
|
74
73
|
}
|
|
75
74
|
else {
|
|
76
75
|
const { appName: extractedAppName, path: extractedPath, query: extractedQuery, } = (0, utils_1.extractAppNameRouteAndQuery)(pageTitleOrPath);
|
|
77
|
-
this.
|
|
76
|
+
this._handleWindowRedirect(extractedAppName, extractedPath, extractedQuery);
|
|
78
77
|
}
|
|
79
78
|
const title = appName ? pageTitleOrPath : '';
|
|
80
79
|
this.nativeHistoryStack.push(title);
|
|
@@ -111,7 +110,8 @@ class NativeNavigationAndTitle {
|
|
|
111
110
|
*/
|
|
112
111
|
navigateInsideASharedSession(url) {
|
|
113
112
|
if (this.b2n.environment === 'ios') {
|
|
114
|
-
|
|
113
|
+
const nativeDeeplink = `/webFeature?type=recommendation&url=${encodeURIComponent(url)}`;
|
|
114
|
+
this.handleNativeDeeplink(nativeDeeplink);
|
|
115
115
|
return;
|
|
116
116
|
}
|
|
117
117
|
// В b2n этот метод отмечен модификатором доступа private, но тут его нужно вызвать
|
|
@@ -130,6 +130,28 @@ class NativeNavigationAndTitle {
|
|
|
130
130
|
this.handleRedirect(this.b2n._blankPagePath);
|
|
131
131
|
this.goBack();
|
|
132
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* Вызывает обработчик deeplinks в нативе (АМ) и передает туда переданный deeplink.
|
|
135
|
+
* На Android текущее webview будет закрыто из-за технических особенностей.
|
|
136
|
+
* На IOS нативная фича открывается в следующем по стеку экране и при выходе из нее пользователь вернется обратно в webview.
|
|
137
|
+
* На IOS есть возможность закрыть webview перед открытием нативной фичи, передав второй параметр closeIOSWebviewBeforeCallNativeDeeplinkHandler = true
|
|
138
|
+
* @param deeplink диплинк на нативную АМ фичу в AM
|
|
139
|
+
* @param [closeIOSWebviewBeforeCallNativeDeeplinkHandler = false] закрыть текущее webview после открытия нативной фичи (применимо только для IOS на Android по техническим причинам webview всегда будет закрываться)
|
|
140
|
+
*/
|
|
141
|
+
handleNativeDeeplink(deeplink, closeIOSWebviewBeforeCallNativeDeeplinkHandler = false) {
|
|
142
|
+
const clearedDeeplinkPath = deeplink.replace(constants_1.DEEP_LINK_PATTERN, '');
|
|
143
|
+
if (this.b2n.environment === 'ios') {
|
|
144
|
+
if (closeIOSWebviewBeforeCallNativeDeeplinkHandler) {
|
|
145
|
+
this.b2n.closeWebview();
|
|
146
|
+
setTimeout(() => window.location.replace(`${this.b2n.iosAppId}://${clearedDeeplinkPath}`), 0);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
window.location.replace(`${this.b2n.iosAppId}://${clearedDeeplinkPath}`);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
window.location.replace(`alfabank://${clearedDeeplinkPath}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
133
155
|
/**
|
|
134
156
|
* Метод для сохранения текущего состояния NativeNavigationAndTitle в sessionStorage.
|
|
135
157
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"license": "UNLICENSED",
|
|
3
3
|
"name": "@alfalab/bridge-to-native",
|
|
4
|
-
"version": "0.0.7-beta-
|
|
4
|
+
"version": "0.0.7-beta-b5c9d02",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/core-ds/bridge-to-native.git"
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"changelog": "bash bin/fill-changelog-file-and-notify-github.sh",
|
|
16
16
|
"compile": "yarn compile:clean && yarn compile:ts && yarn compile:copy-resources",
|
|
17
17
|
"compile:copy-package-json": "shx cp package.json .publish/package.json",
|
|
18
|
-
"compile:copy-resources": "yarn copyfiles -e \"**/*.{[jt]s*(x),snap}\" -e \"**/*.json\" -
|
|
18
|
+
"compile:copy-resources": "yarn copyfiles -e \"**/*.{[jt]s*(x),snap}\" -e \"**/*.json\" -u 1 \"src/**/*\" .publish",
|
|
19
19
|
"compile:clean": "shx rm -rf .publish",
|
|
20
20
|
"compile:ts": "tsc --project tsconfig.build.json",
|
|
21
21
|
"lint:scripts": "eslint \"**/*.{js,jsx,ts,tsx}\" --ext .js,.jsx,.ts,.tsx",
|
|
@@ -67,13 +67,15 @@
|
|
|
67
67
|
],
|
|
68
68
|
"coveragePathIgnorePatterns": [
|
|
69
69
|
"/node_modules/",
|
|
70
|
-
"/test/"
|
|
70
|
+
"/test/",
|
|
71
|
+
"/src/index.ts"
|
|
71
72
|
],
|
|
72
73
|
"transformIgnorePatterns": [
|
|
73
74
|
"node_modules/(?!(uuid)/)"
|
|
74
75
|
],
|
|
75
76
|
"testPathIgnorePatterns": [
|
|
76
|
-
"/node_modules/"
|
|
77
|
+
"/node_modules/",
|
|
78
|
+
"/test/mock"
|
|
77
79
|
],
|
|
78
80
|
"reporters": [
|
|
79
81
|
"jest-junit",
|
package/types.d.ts
CHANGED
|
@@ -29,4 +29,7 @@ export declare type PreviousNativeNavigationAndTitleState = {
|
|
|
29
29
|
nativeHistoryStack: string[];
|
|
30
30
|
title: string;
|
|
31
31
|
};
|
|
32
|
+
export declare type SyncPurpose = 'initialization' | 'navigation' | 'title-replacing';
|
|
33
|
+
export declare type HandleRedirect = (appName: string, path?: string, params?: Record<string, string>) => void;
|
|
34
|
+
export declare type Theme = 'light' | 'dark';
|
|
32
35
|
export {};
|