@jetbrains/ring-ui-built 7.0.95 → 7.0.97
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/components/auth/auth-core.d.ts +13 -1
- package/components/auth/auth-core.js +79 -42
- package/components/auth/auth.js +1 -1
- package/components/avatar/avatar.js +1 -1
- package/components/list/list-item.js +1 -1
- package/components/list/list.d.ts +1 -2
- package/components/list/list.js +17 -10
- package/components/old-browsers-message/white-list.js +2 -2
- package/components/style.css +1 -1
- package/components/tabs/collapsible-tabs.js +2 -2
- package/package.json +6 -1
|
@@ -8,6 +8,7 @@ import TokenValidator, { type TokenValidationError, type TokenValidatorConfig }
|
|
|
8
8
|
import type AuthDialogService from '../auth-dialog-service/auth-dialog-service';
|
|
9
9
|
export declare const DEFAULT_EXPIRES_TIMEOUT: number;
|
|
10
10
|
export declare const DEFAULT_BACKGROUND_TIMEOUT: number;
|
|
11
|
+
export declare const TOKEN_REFRESH_RETRY_DELAYS: number[];
|
|
11
12
|
export declare const USER_CHANGED_EVENT = "userChange";
|
|
12
13
|
export declare const DOMAIN_USER_CHANGED_EVENT = "domainUser";
|
|
13
14
|
export declare const LOGOUT_EVENT = "logout";
|
|
@@ -80,6 +81,7 @@ export interface AuthConfig extends TokenValidatorConfig {
|
|
|
80
81
|
translations?: AuthTranslations | null | undefined;
|
|
81
82
|
userParams?: RequestParams | undefined;
|
|
82
83
|
waitForRedirectTimeout: number;
|
|
84
|
+
tokenRefreshRetryDelays: readonly number[];
|
|
83
85
|
rpInitiatedLogout: boolean;
|
|
84
86
|
}
|
|
85
87
|
type AuthPayloadMap = {
|
|
@@ -139,6 +141,7 @@ declare class Auth implements HTTPAuth {
|
|
|
139
141
|
_tokenValidator: TokenValidator | null;
|
|
140
142
|
private _postponed;
|
|
141
143
|
private _backendCheckPromise;
|
|
144
|
+
private _forceTokenUpdatePromise;
|
|
142
145
|
private _authDialogService;
|
|
143
146
|
_domainStorage: AuthStorage<UserChange>;
|
|
144
147
|
user: AuthUser | null;
|
|
@@ -168,9 +171,18 @@ declare class Auth implements HTTPAuth {
|
|
|
168
171
|
requestToken(): Promise<string | null>;
|
|
169
172
|
/**
|
|
170
173
|
* Get new token in the background or redirect to the login page.
|
|
171
|
-
*
|
|
174
|
+
*
|
|
175
|
+
* Retries background token refresh with delays from {@link AuthConfig.tokenRefreshRetryDelays}
|
|
176
|
+
* with increasing delays before showing the auth dialog.
|
|
177
|
+
* This handles transient failures that commonly occur after network
|
|
178
|
+
* recovery (e.g. waking from sleep, switching networks) where the first
|
|
179
|
+
* iframe-based auth attempt fails but a subsequent one succeeds once
|
|
180
|
+
* the Hub session is re-established.
|
|
181
|
+
*
|
|
182
|
+
* @return {Promise.<string | null>}
|
|
172
183
|
*/
|
|
173
184
|
forceTokenUpdate(): Promise<string | null>;
|
|
185
|
+
private _doForceTokenUpdate;
|
|
174
186
|
loadCurrentService(): Promise<void>;
|
|
175
187
|
getAPIPath(): string;
|
|
176
188
|
/**
|
|
@@ -47,6 +47,7 @@ const DEFAULT_BACKGROUND_TIMEOUT = 10 * 1000;
|
|
|
47
47
|
const DEFAULT_BACKEND_CHECK_TIMEOUT = 10 * 1000;
|
|
48
48
|
const BACKGROUND_REDIRECT_TIMEOUT = 20 * 1000;
|
|
49
49
|
const DEFAULT_WAIT_FOR_REDIRECT_TIMEOUT = 5 * 1000;
|
|
50
|
+
const TOKEN_REFRESH_RETRY_DELAYS = [0, 2000, 5000];
|
|
50
51
|
const USER_CHANGED_EVENT = 'userChange';
|
|
51
52
|
const DOMAIN_USER_CHANGED_EVENT = 'domainUser';
|
|
52
53
|
const LOGOUT_EVENT = 'logout';
|
|
@@ -75,6 +76,7 @@ const DEFAULT_CONFIG = {
|
|
|
75
76
|
onBackendDown: () => () => {},
|
|
76
77
|
defaultExpiresIn: DEFAULT_EXPIRES_TIMEOUT,
|
|
77
78
|
waitForRedirectTimeout: DEFAULT_WAIT_FOR_REDIRECT_TIMEOUT,
|
|
79
|
+
tokenRefreshRetryDelays: TOKEN_REFRESH_RETRY_DELAYS,
|
|
78
80
|
rpInitiatedLogout: true,
|
|
79
81
|
translations: null
|
|
80
82
|
};
|
|
@@ -100,6 +102,7 @@ class Auth {
|
|
|
100
102
|
_tokenValidator = null;
|
|
101
103
|
_postponed = false;
|
|
102
104
|
_backendCheckPromise = null;
|
|
105
|
+
_forceTokenUpdatePromise = null;
|
|
103
106
|
_authDialogService = undefined;
|
|
104
107
|
_domainStorage;
|
|
105
108
|
user = null;
|
|
@@ -254,6 +257,8 @@ class Auth {
|
|
|
254
257
|
throw error;
|
|
255
258
|
}
|
|
256
259
|
if (this._canShowDialogs()) {
|
|
260
|
+
// eslint-disable-next-line no-console
|
|
261
|
+
console.error('RingUI Auth: Init failure', error);
|
|
257
262
|
this._showAuthDialog({
|
|
258
263
|
nonInteractive: true,
|
|
259
264
|
error
|
|
@@ -273,7 +278,7 @@ class Auth {
|
|
|
273
278
|
if (this.user && userID === this.user.id) {
|
|
274
279
|
return;
|
|
275
280
|
}
|
|
276
|
-
this.forceTokenUpdate();
|
|
281
|
+
this.forceTokenUpdate().catch(noop);
|
|
277
282
|
});
|
|
278
283
|
let state;
|
|
279
284
|
try {
|
|
@@ -297,7 +302,7 @@ class Auth {
|
|
|
297
302
|
serviceID
|
|
298
303
|
} = message;
|
|
299
304
|
if (serviceID !== this.config.clientId && (!userID || this.user?.id !== userID)) {
|
|
300
|
-
this.forceTokenUpdate();
|
|
305
|
+
this.forceTokenUpdate().catch(noop);
|
|
301
306
|
}
|
|
302
307
|
}
|
|
303
308
|
// Access token appears to be valid.
|
|
@@ -392,56 +397,80 @@ class Auth {
|
|
|
392
397
|
}
|
|
393
398
|
/**
|
|
394
399
|
* Get new token in the background or redirect to the login page.
|
|
395
|
-
*
|
|
400
|
+
*
|
|
401
|
+
* Retries background token refresh with delays from {@link AuthConfig.tokenRefreshRetryDelays}
|
|
402
|
+
* with increasing delays before showing the auth dialog.
|
|
403
|
+
* This handles transient failures that commonly occur after network
|
|
404
|
+
* recovery (e.g. waking from sleep, switching networks) where the first
|
|
405
|
+
* iframe-based auth attempt fails but a subsequent one succeeds once
|
|
406
|
+
* the Hub session is re-established.
|
|
407
|
+
*
|
|
408
|
+
* @return {Promise.<string | null>}
|
|
396
409
|
*/
|
|
397
|
-
|
|
410
|
+
forceTokenUpdate() {
|
|
411
|
+
if (this._forceTokenUpdatePromise) {
|
|
412
|
+
return this._forceTokenUpdatePromise;
|
|
413
|
+
}
|
|
414
|
+
this._forceTokenUpdatePromise = this._doForceTokenUpdate().finally(() => {
|
|
415
|
+
this._forceTokenUpdatePromise = null;
|
|
416
|
+
});
|
|
417
|
+
return this._forceTokenUpdatePromise;
|
|
418
|
+
}
|
|
419
|
+
async _doForceTokenUpdate() {
|
|
420
|
+
var _lastError$message;
|
|
398
421
|
try {
|
|
399
422
|
if (!this._backendCheckPromise) {
|
|
400
423
|
this._backendCheckPromise = this._checkBackendsStatusesIfEnabled();
|
|
401
424
|
}
|
|
402
425
|
await this._backendCheckPromise;
|
|
403
426
|
} catch (e) {
|
|
404
|
-
throw new Error('Cannot refresh token: backend is not available. Postponed by user.'
|
|
427
|
+
throw new Error('Cannot refresh token: backend is not available. Postponed by user.', {
|
|
428
|
+
cause: e
|
|
429
|
+
});
|
|
405
430
|
} finally {
|
|
406
431
|
this._backendCheckPromise = null;
|
|
407
432
|
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
if (!(error instanceof Error)) {
|
|
413
|
-
return null;
|
|
433
|
+
let lastError = null;
|
|
434
|
+
for (const delay of this.config.tokenRefreshRetryDelays) {
|
|
435
|
+
if (delay > 0) {
|
|
436
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
414
437
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
438
|
+
try {
|
|
439
|
+
var _await$this$_backgrou;
|
|
440
|
+
return (_await$this$_backgrou = await this._backgroundFlow?.authorize()) !== null && _await$this$_backgrou !== void 0 ? _await$this$_backgrou : null;
|
|
441
|
+
} catch (error) {
|
|
442
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
if (this._canShowDialogs()) {
|
|
446
|
+
return new Promise(resolve => {
|
|
447
|
+
const onTryAgain = async () => {
|
|
448
|
+
try {
|
|
449
|
+
const result = await this._backgroundFlow?.authorize();
|
|
450
|
+
resolve(result !== null && result !== void 0 ? result : null);
|
|
451
|
+
} catch (retryError) {
|
|
452
|
+
if (retryError instanceof Error) {
|
|
453
|
+
this._showAuthDialog({
|
|
454
|
+
nonInteractive: true,
|
|
455
|
+
error: retryError,
|
|
456
|
+
onTryAgain
|
|
457
|
+
});
|
|
430
458
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
459
|
+
throw retryError;
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
this._showAuthDialog({
|
|
463
|
+
nonInteractive: true,
|
|
464
|
+
error: lastError,
|
|
465
|
+
onTryAgain
|
|
437
466
|
});
|
|
438
|
-
}
|
|
439
|
-
const authRequest = await this._requestBuilder?.prepareAuthRequest();
|
|
440
|
-
if (authRequest) {
|
|
441
|
-
this._redirectCurrentPage(authRequest.url);
|
|
442
|
-
}
|
|
443
|
-
throw new TokenValidator.TokenValidationError(error.message);
|
|
467
|
+
});
|
|
444
468
|
}
|
|
469
|
+
const authRequest = await this._requestBuilder?.prepareAuthRequest();
|
|
470
|
+
if (authRequest) {
|
|
471
|
+
this._redirectCurrentPage(authRequest.url);
|
|
472
|
+
}
|
|
473
|
+
throw new TokenValidator.TokenValidationError((_lastError$message = lastError?.message) !== null && _lastError$message !== void 0 ? _lastError$message : 'Failed to refresh token');
|
|
445
474
|
}
|
|
446
475
|
async loadCurrentService() {
|
|
447
476
|
if (this._service.serviceName) {
|
|
@@ -526,7 +555,13 @@ class Auth {
|
|
|
526
555
|
}
|
|
527
556
|
_beforeLogout(params) {
|
|
528
557
|
if (this._canShowDialogs()) {
|
|
529
|
-
|
|
558
|
+
const onTryAgain = async () => {
|
|
559
|
+
await this.forceTokenUpdate();
|
|
560
|
+
};
|
|
561
|
+
this._showAuthDialog({
|
|
562
|
+
onTryAgain,
|
|
563
|
+
...params
|
|
564
|
+
});
|
|
530
565
|
return;
|
|
531
566
|
}
|
|
532
567
|
this.logout();
|
|
@@ -571,7 +606,7 @@ class Auth {
|
|
|
571
606
|
return;
|
|
572
607
|
}
|
|
573
608
|
if (this.user?.guest && nonInteractive) {
|
|
574
|
-
this.forceTokenUpdate();
|
|
609
|
+
this.forceTokenUpdate().catch(noop);
|
|
575
610
|
} else {
|
|
576
611
|
this._initDeferred?.resolve?.();
|
|
577
612
|
}
|
|
@@ -748,6 +783,8 @@ class Auth {
|
|
|
748
783
|
this.listeners.trigger(USER_CHANGED_EVENT, user);
|
|
749
784
|
}
|
|
750
785
|
} catch (e) {
|
|
786
|
+
// eslint-disable-next-line no-console
|
|
787
|
+
console.error('RingUI Auth: login failure', e);
|
|
751
788
|
this._beforeLogout();
|
|
752
789
|
}
|
|
753
790
|
}
|
|
@@ -767,7 +804,7 @@ class Auth {
|
|
|
767
804
|
const {
|
|
768
805
|
scope: defaultScope
|
|
769
806
|
} = this.config;
|
|
770
|
-
let urlFromState
|
|
807
|
+
let urlFromState;
|
|
771
808
|
try {
|
|
772
809
|
urlFromState = new URL(state); // checking if state contains valid URL on same origin, see HUB-11514
|
|
773
810
|
} catch {
|
|
@@ -921,4 +958,4 @@ class Auth {
|
|
|
921
958
|
}
|
|
922
959
|
}
|
|
923
960
|
|
|
924
|
-
export { Auth, DEFAULT_BACKGROUND_TIMEOUT, DEFAULT_EXPIRES_TIMEOUT, DOMAIN_USER_CHANGED_EVENT, LOGOUT_EVENT, LOGOUT_POSTPONED_EVENT, USER_CHANGED_EVENT, USER_CHANGE_POSTPONED_EVENT, Auth as default };
|
|
961
|
+
export { Auth, DEFAULT_BACKGROUND_TIMEOUT, DEFAULT_EXPIRES_TIMEOUT, DOMAIN_USER_CHANGED_EVENT, LOGOUT_EVENT, LOGOUT_POSTPONED_EVENT, TOKEN_REFRESH_RETRY_DELAYS, USER_CHANGED_EVENT, USER_CHANGE_POSTPONED_EVENT, Auth as default };
|
package/components/auth/auth.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import WindowFlow from './window-flow.js';
|
|
2
2
|
import onBackendDown from './down-notification.js';
|
|
3
3
|
import { Auth } from './auth-core.js';
|
|
4
|
-
export { DEFAULT_BACKGROUND_TIMEOUT, DEFAULT_EXPIRES_TIMEOUT, DOMAIN_USER_CHANGED_EVENT, LOGOUT_EVENT, LOGOUT_POSTPONED_EVENT, USER_CHANGED_EVENT, USER_CHANGE_POSTPONED_EVENT } from './auth-core.js';
|
|
4
|
+
export { DEFAULT_BACKGROUND_TIMEOUT, DEFAULT_EXPIRES_TIMEOUT, DOMAIN_USER_CHANGED_EVENT, LOGOUT_EVENT, LOGOUT_POSTPONED_EVENT, TOKEN_REFRESH_RETRY_DELAYS, USER_CHANGED_EVENT, USER_CHANGE_POSTPONED_EVENT } from './auth-core.js';
|
|
5
5
|
import './response-parser.js';
|
|
6
6
|
import '../global/url.js';
|
|
7
7
|
import 'react-compiler-runtime';
|
|
@@ -93,7 +93,7 @@ class Avatar extends PureComponent {
|
|
|
93
93
|
};
|
|
94
94
|
src = encodeURL(urlStart, queryParams);
|
|
95
95
|
}
|
|
96
|
-
let subavatarSrc
|
|
96
|
+
let subavatarSrc;
|
|
97
97
|
if (subavatar && !isDataURI(subavatar)) {
|
|
98
98
|
const [urlStart, query] = subavatar.split('?');
|
|
99
99
|
const queryParams = {
|
|
@@ -89,7 +89,7 @@ class ListItem extends PureComponent {
|
|
|
89
89
|
const style = {
|
|
90
90
|
paddingLeft: `${(Number(level) || 0) * RING_UNIT + DEFAULT_PADDING + (showCheckbox ? CHECKBOX_WIDTH : 0)}px`
|
|
91
91
|
};
|
|
92
|
-
let computedTitle
|
|
92
|
+
let computedTitle;
|
|
93
93
|
if (this._isString(title)) {
|
|
94
94
|
// if title is specified and is a string then use it
|
|
95
95
|
computedTitle = title;
|
|
@@ -68,7 +68,6 @@ export interface ListState<T = unknown> {
|
|
|
68
68
|
prevActiveIndex: number | null;
|
|
69
69
|
prevData: ListDataItem<T>[];
|
|
70
70
|
activeItem: ListDataItem<T> | null;
|
|
71
|
-
needScrollToActive: boolean;
|
|
72
71
|
scrolling: boolean;
|
|
73
72
|
hasOverflow: boolean;
|
|
74
73
|
scrolledToBottom: boolean;
|
|
@@ -109,7 +108,7 @@ export default class List<T = unknown> extends Component<ListProps<T>, ListState
|
|
|
109
108
|
};
|
|
110
109
|
componentDidMount(): void;
|
|
111
110
|
shouldComponentUpdate(nextProps: ListProps<T>, nextState: ListState<T>): boolean;
|
|
112
|
-
componentDidUpdate(prevProps: ListProps<T>): void;
|
|
111
|
+
componentDidUpdate(prevProps: ListProps<T>, prevState: ListState<T>): void;
|
|
113
112
|
componentWillUnmount(): void;
|
|
114
113
|
scheduleScrollListener: (cb: () => void) => void;
|
|
115
114
|
static isItemType: typeof isItemType;
|
package/components/list/list.js
CHANGED
|
@@ -98,7 +98,6 @@ class List extends Component {
|
|
|
98
98
|
prevActiveIndex: null,
|
|
99
99
|
prevData: [],
|
|
100
100
|
activeItem: null,
|
|
101
|
-
needScrollToActive: false,
|
|
102
101
|
scrolling: false,
|
|
103
102
|
hasOverflow: false,
|
|
104
103
|
scrolledToBottom: false
|
|
@@ -132,8 +131,7 @@ class List extends Component {
|
|
|
132
131
|
if (activeIndex !== null && activeIndex !== undefined && activeIndex !== prevActiveIndex && data[activeIndex]) {
|
|
133
132
|
Object.assign(nextState, {
|
|
134
133
|
activeIndex,
|
|
135
|
-
activeItem: data[activeIndex]
|
|
136
|
-
needScrollToActive: true
|
|
134
|
+
activeItem: data[activeIndex]
|
|
137
135
|
});
|
|
138
136
|
} else if (data !== prevData && restoreActiveIndex && activeItem && activeItem.key) {
|
|
139
137
|
// Restore active index if there is an item with the same "key" property
|
|
@@ -155,14 +153,26 @@ class List extends Component {
|
|
|
155
153
|
shouldComponentUpdate(nextProps, nextState) {
|
|
156
154
|
return Object.keys(nextProps).some(key => !Object.is(nextProps[key], this.props[key])) || Object.keys(nextState).some(key => nextState[key] !== this.state[key]);
|
|
157
155
|
}
|
|
158
|
-
componentDidUpdate(prevProps) {
|
|
156
|
+
componentDidUpdate(prevProps, prevState) {
|
|
159
157
|
if (this.virtualizedList && prevProps.data !== this.props.data) {
|
|
160
158
|
this.virtualizedList.recomputeRowHeights();
|
|
161
159
|
}
|
|
162
160
|
const {
|
|
163
161
|
activeIndex
|
|
164
162
|
} = this.state;
|
|
165
|
-
|
|
163
|
+
if (!this.props.disableScrollToActive && activeIndex != null && activeIndex !== prevState.activeIndex) {
|
|
164
|
+
if (this.virtualizedList) {
|
|
165
|
+
this.virtualizedList.scrollToRow(activeIndex + 1);
|
|
166
|
+
} else {
|
|
167
|
+
const itemId = this.getId(this.props.data[activeIndex]);
|
|
168
|
+
if (itemId) {
|
|
169
|
+
document.getElementById(itemId)?.scrollIntoView?.({
|
|
170
|
+
block: 'center'
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const isActiveItemRetainedPosition = activeIndex != null ? prevProps.data[activeIndex]?.key === this.props.data[activeIndex]?.key : false;
|
|
166
176
|
if ((this.props.activeIndex === null || this.props.activeIndex === undefined) && getDataHash(this.props.data) !== getDataHash(prevProps.data) && shouldActivateFirstItem(this.props) && !isActiveItemRetainedPosition) {
|
|
167
177
|
this.activateFirst();
|
|
168
178
|
}
|
|
@@ -221,8 +231,7 @@ class List extends Component {
|
|
|
221
231
|
if (firstActivatableIndex >= 0) {
|
|
222
232
|
this.setState({
|
|
223
233
|
activeIndex: firstActivatableIndex,
|
|
224
|
-
activeItem: this.props.data[firstActivatableIndex]
|
|
225
|
-
needScrollToActive: true
|
|
234
|
+
activeItem: this.props.data[firstActivatableIndex]
|
|
226
235
|
});
|
|
227
236
|
}
|
|
228
237
|
};
|
|
@@ -298,8 +307,7 @@ class List extends Component {
|
|
|
298
307
|
const item = this.props.data[correctedIndex];
|
|
299
308
|
this.setState({
|
|
300
309
|
activeIndex: correctedIndex,
|
|
301
|
-
activeItem: item
|
|
302
|
-
needScrollToActive: true
|
|
310
|
+
activeItem: item
|
|
303
311
|
}, function onSet() {
|
|
304
312
|
if (!isActivatable(item)) {
|
|
305
313
|
retryCallback(e);
|
|
@@ -569,7 +577,6 @@ class List extends Component {
|
|
|
569
577
|
// ensure rerendering
|
|
570
578
|
,
|
|
571
579
|
noop: () => {},
|
|
572
|
-
scrollToIndex: !this.props.disableScrollToActive && this.state.needScrollToActive && this.state.activeIndex !== null && this.state.activeIndex !== undefined ? this.state.activeIndex + 1 : undefined,
|
|
573
580
|
scrollToAlignment: "center",
|
|
574
581
|
deferredMeasurementCache: this._cache,
|
|
575
582
|
onRowsRendered: this.checkOverflow,
|
|
@@ -5,11 +5,11 @@ const MAJOR_VERSION_INDEX = 0;
|
|
|
5
5
|
/**
|
|
6
6
|
* SUPPORTED_BROWSERS are defined by Babel plugin, see babel config
|
|
7
7
|
*/
|
|
8
|
-
if (!["and_chr
|
|
8
|
+
if (!["and_chr 145", "and_ff 147", "and_qq 14.9", "and_uc 15.5", "android 145", "chrome 145", "chrome 144", "chrome 143", "chrome 142", "chrome 141", "chrome 140", "chrome 139", "chrome 138", "chrome 137", "chrome 136", "chrome 135", "chrome 134", "chrome 133", "chrome 132", "chrome 131", "chrome 130", "chrome 129", "chrome 128", "chrome 127", "chrome 126", "chrome 125", "chrome 124", "chrome 123", "chrome 122", "chrome 121", "chrome 120", "chrome 119", "chrome 118", "chrome 117", "chrome 116", "chrome 115", "chrome 112", "chrome 109", "edge 145", "edge 144", "edge 143", "edge 142", "edge 141", "edge 140", "edge 139", "edge 138", "edge 137", "edge 136", "edge 135", "edge 134", "edge 133", "edge 132", "edge 131", "edge 130", "edge 129", "edge 128", "edge 127", "edge 126", "edge 125", "edge 124", "edge 123", "edge 122", "edge 121", "edge 120", "edge 119", "edge 118", "edge 117", "edge 116", "edge 115", "firefox 148", "firefox 147", "firefox 146", "firefox 145", "firefox 144", "firefox 143", "firefox 142", "firefox 141", "firefox 140", "firefox 139", "firefox 138", "firefox 137", "firefox 136", "firefox 135", "firefox 134", "firefox 133", "firefox 132", "firefox 131", "firefox 130", "firefox 129", "firefox 128", "firefox 127", "firefox 126", "firefox 125", "firefox 124", "firefox 123", "firefox 122", "firefox 121", "firefox 120", "firefox 119", "firefox 118", "firefox 117", "firefox 116", "ios_saf 26.3", "ios_saf 26.2", "ios_saf 26.1", "ios_saf 26.0", "ios_saf 18.5-18.7", "ios_saf 18.4", "ios_saf 18.3", "ios_saf 18.2", "ios_saf 18.1", "ios_saf 18.0", "ios_saf 17.6-17.7", "ios_saf 17.5", "ios_saf 17.4", "ios_saf 17.3", "ios_saf 17.2", "ios_saf 17.1", "ios_saf 17.0", "ios_saf 16.6-16.7", "ios_saf 16.5", "ios_saf 16.4", "kaios 3.0-3.1", "kaios 2.5", "op_mini all", "op_mob 80", "opera 125", "opera 124", "safari 26.3", "safari 26.2", "safari 26.1", "safari 26.0", "safari 18.5-18.6", "safari 18.4", "safari 18.3", "safari 18.2", "safari 18.1", "safari 18.0", "safari 17.6", "safari 17.5", "safari 17.4", "safari 17.3", "safari 17.2", "safari 17.1", "safari 17.0", "safari 16.6", "safari 16.5", "safari 16.4", "samsung 29", "samsung 28"]) {
|
|
9
9
|
// eslint-disable-next-line no-console
|
|
10
10
|
console.warn('Ring UI: no SUPPORTED_BROWSERS passed. Please check babel config.');
|
|
11
11
|
}
|
|
12
|
-
const SUPPORTED = ["and_chr
|
|
12
|
+
const SUPPORTED = ["and_chr 145", "and_ff 147", "and_qq 14.9", "and_uc 15.5", "android 145", "chrome 145", "chrome 144", "chrome 143", "chrome 142", "chrome 141", "chrome 140", "chrome 139", "chrome 138", "chrome 137", "chrome 136", "chrome 135", "chrome 134", "chrome 133", "chrome 132", "chrome 131", "chrome 130", "chrome 129", "chrome 128", "chrome 127", "chrome 126", "chrome 125", "chrome 124", "chrome 123", "chrome 122", "chrome 121", "chrome 120", "chrome 119", "chrome 118", "chrome 117", "chrome 116", "chrome 115", "chrome 112", "chrome 109", "edge 145", "edge 144", "edge 143", "edge 142", "edge 141", "edge 140", "edge 139", "edge 138", "edge 137", "edge 136", "edge 135", "edge 134", "edge 133", "edge 132", "edge 131", "edge 130", "edge 129", "edge 128", "edge 127", "edge 126", "edge 125", "edge 124", "edge 123", "edge 122", "edge 121", "edge 120", "edge 119", "edge 118", "edge 117", "edge 116", "edge 115", "firefox 148", "firefox 147", "firefox 146", "firefox 145", "firefox 144", "firefox 143", "firefox 142", "firefox 141", "firefox 140", "firefox 139", "firefox 138", "firefox 137", "firefox 136", "firefox 135", "firefox 134", "firefox 133", "firefox 132", "firefox 131", "firefox 130", "firefox 129", "firefox 128", "firefox 127", "firefox 126", "firefox 125", "firefox 124", "firefox 123", "firefox 122", "firefox 121", "firefox 120", "firefox 119", "firefox 118", "firefox 117", "firefox 116", "ios_saf 26.3", "ios_saf 26.2", "ios_saf 26.1", "ios_saf 26.0", "ios_saf 18.5-18.7", "ios_saf 18.4", "ios_saf 18.3", "ios_saf 18.2", "ios_saf 18.1", "ios_saf 18.0", "ios_saf 17.6-17.7", "ios_saf 17.5", "ios_saf 17.4", "ios_saf 17.3", "ios_saf 17.2", "ios_saf 17.1", "ios_saf 17.0", "ios_saf 16.6-16.7", "ios_saf 16.5", "ios_saf 16.4", "kaios 3.0-3.1", "kaios 2.5", "op_mini all", "op_mob 80", "opera 125", "opera 124", "safari 26.3", "safari 26.2", "safari 26.1", "safari 26.0", "safari 18.5-18.6", "safari 18.4", "safari 18.3", "safari 18.2", "safari 18.1", "safari 18.0", "safari 17.6", "safari 17.5", "safari 17.4", "safari 17.3", "safari 17.2", "safari 17.1", "safari 17.0", "safari 16.6", "safari 16.5", "safari 16.4", "samsung 29", "samsung 28"] || [];
|
|
13
13
|
const WHITE_LISTED_BROWSERS = ['chrome', 'firefox', 'safari', 'edge'];
|
|
14
14
|
const WHITE_LIST = SUPPORTED.reduce((acc, item) => {
|
|
15
15
|
var _item$match;
|