@todesktop/shared 7.184.18 → 7.184.19
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/.eslintrc.js +33 -0
- package/.github/workflows/main.yml +19 -19
- package/.github/workflows/test.yml +14 -0
- package/.prettierignore +3 -0
- package/.prettierrc +5 -0
- package/lib/base.d.ts +23 -23
- package/lib/desktopify.d.ts +16 -16
- package/lib/desktopify.js +8 -8
- package/lib/desktopify2.d.ts +21 -21
- package/lib/desktopify2.js +61 -61
- package/lib/getSiteInfo.d.ts +1 -1
- package/lib/index.d.ts +6 -6
- package/lib/plans.d.ts +11 -11
- package/lib/plans.js +42 -42
- package/lib/plugin.d.ts +3 -3
- package/lib/toDesktop.d.ts +8 -8
- package/lib/translation.d.ts +2 -2
- package/lib/validations.d.ts +2 -2
- package/lib/validations.js +26 -26
- package/package.json +10 -6
- package/src/base.ts +25 -25
- package/src/desktopify.ts +53 -52
- package/src/desktopify2.ts +99 -99
- package/src/getSiteInfo.ts +1 -1
- package/src/index.ts +7 -7
- package/src/json.d.ts +2 -2
- package/src/plans.ts +61 -61
- package/src/plugin.ts +3 -3
- package/src/toDesktop.ts +12 -12
- package/src/translation.ts +3 -3
- package/src/validations.ts +36 -39
package/src/plans.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
function pick<T, K extends keyof T>(objectInput: T, ...keys: K[]): Pick<T, K> {
|
|
2
|
-
const objectOutput
|
|
2
|
+
const objectOutput = {} as Pick<T, K>;
|
|
3
3
|
keys.forEach((key) => {
|
|
4
4
|
objectOutput[key] = objectInput[key];
|
|
5
5
|
});
|
|
@@ -7,109 +7,109 @@ function pick<T, K extends keyof T>(objectInput: T, ...keys: K[]): Pick<T, K> {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export const devPlanIds = {
|
|
10
|
-
startup:
|
|
11
|
-
business:
|
|
12
|
-
essential:
|
|
13
|
-
growth:
|
|
14
|
-
essential_new:
|
|
15
|
-
professional:
|
|
16
|
-
professional_annual:
|
|
17
|
-
cli_founder:
|
|
18
|
-
cli_founder_30:
|
|
19
|
-
cli_founder_50:
|
|
20
|
-
cli_performance:
|
|
21
|
-
cli_scale:
|
|
22
|
-
builder_essential:
|
|
23
|
-
builder_professional:
|
|
24
|
-
enterprise:
|
|
10
|
+
startup: 'plan_Fe8BzLp7k71eGD',
|
|
11
|
+
business: 'plan_Fe8CUkZfXasFtB',
|
|
12
|
+
essential: 'plan_FpljxNuZtNFFbm',
|
|
13
|
+
growth: 'plan_FplOshrr1w3Mvu',
|
|
14
|
+
essential_new: 'plan_GYXmTA3EdfCv4q',
|
|
15
|
+
professional: 'plan_GYXoIkvwVKyfF2',
|
|
16
|
+
professional_annual: 'price_1KHU70IewCKA2h0IR87yXOQ2',
|
|
17
|
+
cli_founder: 'plan_Gq0FzdmoTJshQL',
|
|
18
|
+
cli_founder_30: 'plan_GsL7NZskOY0TC9',
|
|
19
|
+
cli_founder_50: 'plan_GsL6VYAshfh7c4',
|
|
20
|
+
cli_performance: 'price_1L821UIewCKA2h0IUwRhicyo',
|
|
21
|
+
cli_scale: 'price_1L821wIewCKA2h0IMLUmjulL',
|
|
22
|
+
builder_essential: 'price_1M4o9XIewCKA2h0IVfGrid8E',
|
|
23
|
+
builder_professional: 'price_1M4o9vIewCKA2h0IHREokdD8',
|
|
24
|
+
enterprise: 'price_1H2v6JIewCKA2h0IgUwsuctb',
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
export const prodPlanIds = {
|
|
28
|
-
startup:
|
|
29
|
-
business:
|
|
30
|
-
essential:
|
|
31
|
-
growth:
|
|
32
|
-
essential_new:
|
|
33
|
-
professional:
|
|
34
|
-
professional_annual:
|
|
35
|
-
professional_annual_full_price:
|
|
36
|
-
cli_founder:
|
|
37
|
-
cli_founder_30:
|
|
38
|
-
cli_founder_50:
|
|
39
|
-
cli_performance:
|
|
40
|
-
cli_scale:
|
|
41
|
-
builder_essential:
|
|
42
|
-
builder_professional:
|
|
43
|
-
enterprise:
|
|
28
|
+
startup: 'plan_FdmDAUN7JGD8pR',
|
|
29
|
+
business: 'plan_FdmE8akq9ukxiY',
|
|
30
|
+
essential: 'plan_FohJzCujA6vvt4',
|
|
31
|
+
growth: 'plan_FohKGuWis5ocsi',
|
|
32
|
+
essential_new: 'plan_GYXn2cnPl5dy7j',
|
|
33
|
+
professional: 'plan_GYXoKsa2j0yURg',
|
|
34
|
+
professional_annual: 'price_1KHTgaIewCKA2h0I81TVg85r',
|
|
35
|
+
professional_annual_full_price: 'price_1KLT32IewCKA2h0IFeJOAgG5',
|
|
36
|
+
cli_founder: 'plan_GpzWZLfsOzjrvI',
|
|
37
|
+
cli_founder_30: 'plan_GsL1IRUwpj5CIF',
|
|
38
|
+
cli_founder_50: 'plan_GsL1IRUwpj5CIF',
|
|
39
|
+
cli_performance: 'price_1L822LIewCKA2h0I5JYyOG1p',
|
|
40
|
+
cli_scale: 'price_1L822RIewCKA2h0IPt9f2nZM',
|
|
41
|
+
builder_essential: 'price_1M4oA4IewCKA2h0IWgfbSJBe',
|
|
42
|
+
builder_professional: 'price_1MIDxtIewCKA2h0IvWi5weJL',
|
|
43
|
+
enterprise: 'plan_GuGICX6nRtDthN',
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
export type PlanIds = typeof prodPlanIds;
|
|
47
47
|
|
|
48
|
-
export const getPlanEnvironment = (stage:
|
|
49
|
-
stage ===
|
|
48
|
+
export const getPlanEnvironment = (stage: 'dev' | 'prod') =>
|
|
49
|
+
stage === 'prod' ? prodPlanIds : devPlanIds;
|
|
50
50
|
|
|
51
51
|
/* ToDesktop CLI Plans */
|
|
52
|
-
export const getCLIPlanIds = (stage:
|
|
52
|
+
export const getCLIPlanIds = (stage: 'dev' | 'prod') => {
|
|
53
53
|
const planIds = getPlanEnvironment(stage);
|
|
54
54
|
return pick(
|
|
55
55
|
planIds,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
'cli_founder',
|
|
57
|
+
'cli_founder_30',
|
|
58
|
+
'cli_founder_50',
|
|
59
|
+
'cli_performance',
|
|
60
|
+
'cli_scale'
|
|
61
61
|
);
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
export const getCLIFounderPlanIds = (stage:
|
|
64
|
+
export const getCLIFounderPlanIds = (stage: 'dev' | 'prod') => {
|
|
65
65
|
const planIds = getPlanEnvironment(stage);
|
|
66
|
-
return pick(planIds,
|
|
66
|
+
return pick(planIds, 'cli_founder', 'cli_founder_30', 'cli_founder_50');
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
-
export const getCLIPerformancePlanIds = (stage:
|
|
69
|
+
export const getCLIPerformancePlanIds = (stage: 'dev' | 'prod') => {
|
|
70
70
|
const planIds = getPlanEnvironment(stage);
|
|
71
|
-
return pick(planIds,
|
|
71
|
+
return pick(planIds, 'cli_performance');
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
-
export const getCLIScalePlanIds = (stage:
|
|
74
|
+
export const getCLIScalePlanIds = (stage: 'dev' | 'prod') => {
|
|
75
75
|
const planIds = getPlanEnvironment(stage);
|
|
76
|
-
return pick(planIds,
|
|
76
|
+
return pick(planIds, 'cli_scale');
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
/* ToDesktop Builder Plans */
|
|
80
|
-
export const getBuilderPlanIds = (stage:
|
|
80
|
+
export const getBuilderPlanIds = (stage: 'dev' | 'prod') => {
|
|
81
81
|
const planIds = getPlanEnvironment(stage);
|
|
82
|
-
return pick(planIds,
|
|
82
|
+
return pick(planIds, 'builder_essential', 'builder_professional');
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
-
export const getBuilderEssentialPlanIds = (stage:
|
|
85
|
+
export const getBuilderEssentialPlanIds = (stage: 'dev' | 'prod') => {
|
|
86
86
|
const planIds = getPlanEnvironment(stage);
|
|
87
|
-
return pick(planIds,
|
|
87
|
+
return pick(planIds, 'builder_essential');
|
|
88
88
|
};
|
|
89
89
|
|
|
90
|
-
export const getBuilderProfessionalPlanIds = (stage:
|
|
90
|
+
export const getBuilderProfessionalPlanIds = (stage: 'dev' | 'prod') => {
|
|
91
91
|
const planIds = getPlanEnvironment(stage);
|
|
92
|
-
return pick(planIds,
|
|
92
|
+
return pick(planIds, 'builder_professional');
|
|
93
93
|
};
|
|
94
94
|
|
|
95
95
|
/* ToDesktop Web Plans */
|
|
96
|
-
export const getEssentialPlanIds = (stage:
|
|
96
|
+
export const getEssentialPlanIds = (stage: 'dev' | 'prod') => {
|
|
97
97
|
const planIds = getPlanEnvironment(stage);
|
|
98
|
-
return pick(planIds,
|
|
98
|
+
return pick(planIds, 'startup', 'essential', 'essential_new');
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
-
export const getProfessionalPlanIds = (stage:
|
|
101
|
+
export const getProfessionalPlanIds = (stage: 'dev' | 'prod') => {
|
|
102
102
|
const planIds = getPlanEnvironment(stage);
|
|
103
103
|
return pick(
|
|
104
104
|
planIds,
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
105
|
+
'business',
|
|
106
|
+
'growth',
|
|
107
|
+
'professional',
|
|
108
|
+
'professional_annual'
|
|
109
109
|
);
|
|
110
110
|
};
|
|
111
111
|
|
|
112
|
-
export const getEnterprisePlanIds = (stage:
|
|
112
|
+
export const getEnterprisePlanIds = (stage: 'dev' | 'prod') => {
|
|
113
113
|
const planIds = getPlanEnvironment(stage);
|
|
114
|
-
return pick(planIds,
|
|
114
|
+
return pick(planIds, 'enterprise');
|
|
115
115
|
};
|
package/src/plugin.ts
CHANGED
|
@@ -28,7 +28,7 @@ export type PluginPreferences = {
|
|
|
28
28
|
export type PluginPreference = NumberSpec | TextSpec | CheckboxSpec;
|
|
29
29
|
|
|
30
30
|
export type TextSpec = PreferenceSpec<
|
|
31
|
-
|
|
31
|
+
'text',
|
|
32
32
|
{
|
|
33
33
|
validator?: AjvJSONSchemaType;
|
|
34
34
|
value?: string;
|
|
@@ -37,7 +37,7 @@ export type TextSpec = PreferenceSpec<
|
|
|
37
37
|
>;
|
|
38
38
|
|
|
39
39
|
export type NumberSpec = PreferenceSpec<
|
|
40
|
-
|
|
40
|
+
'number',
|
|
41
41
|
{
|
|
42
42
|
validator?: AjvJSONSchemaType;
|
|
43
43
|
value?: number;
|
|
@@ -46,7 +46,7 @@ export type NumberSpec = PreferenceSpec<
|
|
|
46
46
|
>;
|
|
47
47
|
|
|
48
48
|
export type CheckboxSpec = PreferenceSpec<
|
|
49
|
-
|
|
49
|
+
'checkbox',
|
|
50
50
|
{
|
|
51
51
|
validator?: AjvJSONSchemaType;
|
|
52
52
|
value?: boolean;
|
package/src/toDesktop.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { BaseApp, Schemable } from
|
|
2
|
-
import { IAppBuilderLib
|
|
1
|
+
import { BaseApp, Schemable } from './base';
|
|
2
|
+
import { IAppBuilderLib } from './desktopify';
|
|
3
3
|
|
|
4
4
|
export type IUploadFileStatus =
|
|
5
|
-
|
|
|
6
|
-
|
|
|
7
|
-
|
|
|
8
|
-
|
|
|
9
|
-
|
|
|
5
|
+
| 'error'
|
|
6
|
+
| 'success'
|
|
7
|
+
| 'done'
|
|
8
|
+
| 'uploading'
|
|
9
|
+
| 'removed';
|
|
10
10
|
|
|
11
11
|
export interface IUploadFile {
|
|
12
12
|
uid: string;
|
|
@@ -105,7 +105,7 @@ export interface IApp extends BaseApp {
|
|
|
105
105
|
appPkgName?: string;
|
|
106
106
|
appProtocol?: ISwitchableValue<string>;
|
|
107
107
|
appType?: string;
|
|
108
|
-
appxConfig?: Partial<IAppBuilderLib[
|
|
108
|
+
appxConfig?: Partial<IAppBuilderLib['config']['appx']>;
|
|
109
109
|
cssToInject?: string;
|
|
110
110
|
customDomain?: string;
|
|
111
111
|
customUserAgent?: ISwitchableValue<string>;
|
|
@@ -131,14 +131,14 @@ export interface IApp extends BaseApp {
|
|
|
131
131
|
jsToInject?: string;
|
|
132
132
|
menubarIcon?: string;
|
|
133
133
|
name: string;
|
|
134
|
-
nsisConfig?: Partial<IAppBuilderLib[
|
|
134
|
+
nsisConfig?: Partial<IAppBuilderLib['config']['nsis']>;
|
|
135
135
|
runtimeEnvs?: string;
|
|
136
136
|
secret?: string; // support old schema versions
|
|
137
137
|
shouldLaunchAtStartupByDefault?: boolean;
|
|
138
138
|
shouldOnlySendAbsolutelyNecessaryRequests?: boolean;
|
|
139
139
|
shouldReuseRendererProcess?: boolean;
|
|
140
|
-
themeSource?:
|
|
141
|
-
themeSourceMac?:
|
|
140
|
+
themeSource?: 'system' | 'light' | 'dark';
|
|
141
|
+
themeSourceMac?: 'system' | 'light' | 'dark';
|
|
142
142
|
toggleVisibilityKeyboardShortcut?: ISwitchableValue<string>;
|
|
143
143
|
trayIcon?: string;
|
|
144
144
|
url: string;
|
|
@@ -149,7 +149,7 @@ export interface IApp extends BaseApp {
|
|
|
149
149
|
|
|
150
150
|
export interface IUser extends Schemable {
|
|
151
151
|
id: string;
|
|
152
|
-
authInfo?:
|
|
152
|
+
authInfo?: object;
|
|
153
153
|
avatar?: string;
|
|
154
154
|
currentApplication?: string;
|
|
155
155
|
customerId?: string;
|
package/src/translation.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type ValidTranslationKeys =
|
|
2
|
-
|
|
|
3
|
-
|
|
|
4
|
-
export type ValidTranslationLanguages =
|
|
2
|
+
| 'updateNotification.title'
|
|
3
|
+
| 'updateNotification.body';
|
|
4
|
+
export type ValidTranslationLanguages = 'default';
|
|
5
5
|
/* TODO - Support more languages here */
|
|
6
6
|
// | "en"
|
|
7
7
|
// | "es"
|
package/src/validations.ts
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import * as yup from
|
|
2
|
-
import * as semver from
|
|
3
|
-
import * as isRegex from
|
|
4
|
-
import { DesktopifyApp2
|
|
1
|
+
import * as yup from 'yup';
|
|
2
|
+
import * as semver from 'semver';
|
|
3
|
+
import * as isRegex from 'is-regex';
|
|
4
|
+
import { DesktopifyApp2 } from '.';
|
|
5
5
|
export const appTitleValidation = yup
|
|
6
6
|
.string()
|
|
7
|
-
.label(
|
|
7
|
+
.label('App title')
|
|
8
8
|
.max(26)
|
|
9
9
|
.matches(
|
|
10
10
|
/^[\w\-\s]+$/,
|
|
11
|
-
|
|
11
|
+
'App title may contain letters, numbers, spaces and dashes only'
|
|
12
12
|
)
|
|
13
|
-
.matches(/^[^\s]+(\s+[^\s]+)*$/,
|
|
13
|
+
.matches(/^[^\s]+(\s+[^\s]+)*$/, 'App title may not begin or end with space')
|
|
14
14
|
.required();
|
|
15
15
|
|
|
16
16
|
function isNumeric(str: string) {
|
|
17
|
-
if (typeof str !=
|
|
18
|
-
return !isNaN(str
|
|
17
|
+
if (typeof str != 'string') return false;
|
|
18
|
+
return !isNaN(Number(str)) && !isNaN(parseFloat(str));
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
function isNumericSemver(value: string) {
|
|
@@ -23,19 +23,19 @@ function isNumericSemver(value: string) {
|
|
|
23
23
|
if (!semver.valid(value)) return false;
|
|
24
24
|
|
|
25
25
|
// ensure that all values are numbers
|
|
26
|
-
if (!value.split(
|
|
26
|
+
if (!value.split('.').every((num) => isNumeric(num))) return false;
|
|
27
27
|
|
|
28
28
|
return true;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export const forceVersionValidation = yup
|
|
32
32
|
.string()
|
|
33
|
-
.label(
|
|
33
|
+
.label('App version')
|
|
34
34
|
.required()
|
|
35
|
-
.when(
|
|
35
|
+
.when('$currentVersion', (currentVersion, schema) =>
|
|
36
36
|
schema.test(
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
'semantic-version',
|
|
38
|
+
'App version must follow a numeric SemVer versioning scheme (e.g. 1.0.0) and be greater than prior version.',
|
|
39
39
|
(forceVersion: string) => {
|
|
40
40
|
return (
|
|
41
41
|
isNumericSemver(forceVersion) &&
|
|
@@ -47,9 +47,9 @@ export const forceVersionValidation = yup
|
|
|
47
47
|
|
|
48
48
|
export const iconValidation = yup
|
|
49
49
|
.string()
|
|
50
|
-
.label(
|
|
50
|
+
.label('Icon')
|
|
51
51
|
.url()
|
|
52
|
-
.required(
|
|
52
|
+
.required('You must upload an icon for your app');
|
|
53
53
|
|
|
54
54
|
export const urlValidation = yup
|
|
55
55
|
.string()
|
|
@@ -61,7 +61,7 @@ export const urlValidation = yup
|
|
|
61
61
|
excludeEmptyString: true,
|
|
62
62
|
}
|
|
63
63
|
)
|
|
64
|
-
.label(
|
|
64
|
+
.label('Website URL')
|
|
65
65
|
.required();
|
|
66
66
|
|
|
67
67
|
export const urlValidationForm = yup.object().shape({
|
|
@@ -70,14 +70,14 @@ export const urlValidationForm = yup.object().shape({
|
|
|
70
70
|
|
|
71
71
|
export const heightValidation = yup
|
|
72
72
|
.number()
|
|
73
|
-
.label(
|
|
73
|
+
.label('Height')
|
|
74
74
|
.moreThan(1)
|
|
75
75
|
.lessThan(2000)
|
|
76
76
|
.required();
|
|
77
77
|
|
|
78
78
|
export const widthValidation = yup
|
|
79
79
|
.number()
|
|
80
|
-
.label(
|
|
80
|
+
.label('Width')
|
|
81
81
|
.moreThan(1)
|
|
82
82
|
.lessThan(3000)
|
|
83
83
|
.required();
|
|
@@ -85,17 +85,17 @@ export const widthValidation = yup
|
|
|
85
85
|
export const internalAppRegexValidation = yup
|
|
86
86
|
.string()
|
|
87
87
|
.required()
|
|
88
|
-
.label(
|
|
88
|
+
.label('Internal URLs')
|
|
89
89
|
.test(
|
|
90
|
-
|
|
90
|
+
'escape-forward-slash',
|
|
91
91
|
"a forward-slash ('/') must be escaped with a back-slash ('\\')",
|
|
92
92
|
(value: string) => {
|
|
93
|
-
if (value.includes(
|
|
94
|
-
|
|
95
|
-
.split(
|
|
96
|
-
.map((char) => char ===
|
|
93
|
+
if (value.includes('/')) {
|
|
94
|
+
const forwardSlashCount = value
|
|
95
|
+
.split('')
|
|
96
|
+
.map((char) => char === '/')
|
|
97
97
|
.filter((isTrue) => isTrue).length;
|
|
98
|
-
|
|
98
|
+
const backSlashEscapeCount = ((value || '').match(/(?=\\\/)/g) || [])
|
|
99
99
|
.length;
|
|
100
100
|
return forwardSlashCount === backSlashEscapeCount;
|
|
101
101
|
}
|
|
@@ -103,29 +103,26 @@ export const internalAppRegexValidation = yup
|
|
|
103
103
|
}
|
|
104
104
|
)
|
|
105
105
|
.test(
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
'is-regex',
|
|
107
|
+
'${path} must be valid regular expression',
|
|
108
108
|
(value: string) => isRegex(RegExp(value))
|
|
109
109
|
);
|
|
110
110
|
|
|
111
111
|
export const appProtocolValidation = yup
|
|
112
112
|
.string()
|
|
113
113
|
.required()
|
|
114
|
-
.label(
|
|
114
|
+
.label('App Protocol')
|
|
115
115
|
.test(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
(value: string) => value.endsWith(
|
|
116
|
+
'ends-with-protocol',
|
|
117
|
+
'Protocols must end with `://`',
|
|
118
|
+
(value: string) => value.endsWith('://')
|
|
119
119
|
)
|
|
120
120
|
.test(
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
'is-lowercase',
|
|
122
|
+
'Protocols must be lowercase',
|
|
123
123
|
(value) => value === value.toLowerCase()
|
|
124
124
|
)
|
|
125
|
-
.matches(
|
|
126
|
-
/^[a-zA-Z\-]+\:\/\/$/,
|
|
127
|
-
"Protocols contain letters and dashes (-) only"
|
|
128
|
-
)
|
|
125
|
+
.matches(/^[a-zA-Z-]+:\/\/$/, 'Protocols contain letters and dashes (-) only')
|
|
129
126
|
.min(5);
|
|
130
127
|
|
|
131
128
|
export const appConfigValidation = yup.object({
|
|
@@ -180,6 +177,6 @@ export const appConfigValidation = yup.object({
|
|
|
180
177
|
export const shouldMinimizeToTrayIsActive = (desktopApp: DesktopifyApp2) => {
|
|
181
178
|
return desktopApp.trays.some(
|
|
182
179
|
(t) =>
|
|
183
|
-
t.leftClick.role ===
|
|
180
|
+
t.leftClick.role === 'toggleMenu' || t.rightClick.role === 'toggleMenu'
|
|
184
181
|
);
|
|
185
182
|
};
|