@lvce-editor/extension-detail-view 5.14.0 → 6.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/dist/extensionDetailViewWorkerMain.js +921 -870
- package/package.json +2 -2
|
@@ -100,7 +100,7 @@ const changelog = () => {
|
|
|
100
100
|
const details = () => {
|
|
101
101
|
return i18nString(Details$1);
|
|
102
102
|
};
|
|
103
|
-
const disable = () => {
|
|
103
|
+
const disable$1 = () => {
|
|
104
104
|
return i18nString(Disable$1);
|
|
105
105
|
};
|
|
106
106
|
const features$1 = () => {
|
|
@@ -133,7 +133,7 @@ const status = () => {
|
|
|
133
133
|
const setColorTheme$2 = () => {
|
|
134
134
|
return i18nString(SetColorTheme$1);
|
|
135
135
|
};
|
|
136
|
-
const enable = () => {
|
|
136
|
+
const enable$1 = () => {
|
|
137
137
|
return i18nString(Enable$1);
|
|
138
138
|
};
|
|
139
139
|
const theme = () => {
|
|
@@ -343,6 +343,7 @@ const ExtensionHostWorker = 44;
|
|
|
343
343
|
const FileSystemWorker$1 = 209;
|
|
344
344
|
const MarkdownWorker$1 = 300;
|
|
345
345
|
const RendererWorker = 1;
|
|
346
|
+
const ExtensionManagementWorker = 9006;
|
|
346
347
|
|
|
347
348
|
const mergeClassNames = (...classNames) => {
|
|
348
349
|
return classNames.filter(Boolean).join(' ');
|
|
@@ -1031,7 +1032,7 @@ const getFeatureVirtualDomHandler = featureName => {
|
|
|
1031
1032
|
};
|
|
1032
1033
|
|
|
1033
1034
|
const rpcs = Object.create(null);
|
|
1034
|
-
const set$
|
|
1035
|
+
const set$b = (id, rpc) => {
|
|
1035
1036
|
rpcs[id] = rpc;
|
|
1036
1037
|
};
|
|
1037
1038
|
const get$3 = id => {
|
|
@@ -1040,6 +1041,10 @@ const get$3 = id => {
|
|
|
1040
1041
|
|
|
1041
1042
|
const create$7 = rpcId => {
|
|
1042
1043
|
return {
|
|
1044
|
+
async dispose() {
|
|
1045
|
+
const rpc = get$3(rpcId);
|
|
1046
|
+
await rpc.dispose();
|
|
1047
|
+
},
|
|
1043
1048
|
// @ts-ignore
|
|
1044
1049
|
invoke(method, ...params) {
|
|
1045
1050
|
const rpc = get$3(rpcId);
|
|
@@ -1053,11 +1058,7 @@ const create$7 = rpcId => {
|
|
|
1053
1058
|
return rpc.invokeAndTransfer(method, ...params);
|
|
1054
1059
|
},
|
|
1055
1060
|
set(rpc) {
|
|
1056
|
-
set$
|
|
1057
|
-
},
|
|
1058
|
-
async dispose() {
|
|
1059
|
-
const rpc = get$3(rpcId);
|
|
1060
|
-
await rpc.dispose();
|
|
1061
|
+
set$b(rpcId, rpc);
|
|
1061
1062
|
}
|
|
1062
1063
|
};
|
|
1063
1064
|
};
|
|
@@ -1585,7 +1586,7 @@ const create$4 = (method, params) => {
|
|
|
1585
1586
|
};
|
|
1586
1587
|
};
|
|
1587
1588
|
const callbacks = Object.create(null);
|
|
1588
|
-
const set$
|
|
1589
|
+
const set$a = (id, fn) => {
|
|
1589
1590
|
callbacks[id] = fn;
|
|
1590
1591
|
};
|
|
1591
1592
|
const get$2 = id => {
|
|
@@ -1604,7 +1605,7 @@ const registerPromise = () => {
|
|
|
1604
1605
|
resolve,
|
|
1605
1606
|
promise
|
|
1606
1607
|
} = Promise.withResolvers();
|
|
1607
|
-
set$
|
|
1608
|
+
set$a(id, resolve);
|
|
1608
1609
|
return {
|
|
1609
1610
|
id,
|
|
1610
1611
|
promise
|
|
@@ -1949,7 +1950,7 @@ const send = (transport, method, ...params) => {
|
|
|
1949
1950
|
const message = create$4(method, params);
|
|
1950
1951
|
transport.send(message);
|
|
1951
1952
|
};
|
|
1952
|
-
const invoke$
|
|
1953
|
+
const invoke$6 = (ipc, method, ...params) => {
|
|
1953
1954
|
return invokeHelper(ipc, method, params, false);
|
|
1954
1955
|
};
|
|
1955
1956
|
const invokeAndTransfer$4 = (ipc, method, ...params) => {
|
|
@@ -1988,7 +1989,7 @@ const createRpc = ipc => {
|
|
|
1988
1989
|
send(ipc, method, ...params);
|
|
1989
1990
|
},
|
|
1990
1991
|
invoke(method, ...params) {
|
|
1991
|
-
return invoke$
|
|
1992
|
+
return invoke$6(ipc, method, ...params);
|
|
1992
1993
|
},
|
|
1993
1994
|
invokeAndTransfer(method, ...params) {
|
|
1994
1995
|
return invokeAndTransfer$4(ipc, method, ...params);
|
|
@@ -2098,28 +2099,28 @@ const createMockRpc = ({
|
|
|
2098
2099
|
};
|
|
2099
2100
|
|
|
2100
2101
|
const {
|
|
2101
|
-
|
|
2102
|
+
dispose: dispose$4,
|
|
2103
|
+
invoke: invoke$5,
|
|
2102
2104
|
invokeAndTransfer: invokeAndTransfer$3,
|
|
2103
|
-
set: set$
|
|
2104
|
-
dispose: dispose$4
|
|
2105
|
+
set: set$9
|
|
2105
2106
|
} = create$7(ExtensionHostWorker);
|
|
2106
2107
|
const executeReferenceProvider = async (id, offset) => {
|
|
2107
2108
|
// @ts-ignore
|
|
2108
|
-
return invoke$
|
|
2109
|
+
return invoke$5('ExtensionHostReference.executeReferenceProvider', id, offset);
|
|
2109
2110
|
};
|
|
2110
2111
|
const executeFileReferenceProvider = async id => {
|
|
2111
2112
|
// @ts-ignore
|
|
2112
|
-
return invoke$
|
|
2113
|
+
return invoke$5('ExtensionHostReference.executeFileReferenceProvider', id);
|
|
2113
2114
|
};
|
|
2114
2115
|
const getRuntimeStatus$2 = async extensionId => {
|
|
2115
2116
|
// @ts-ignore
|
|
2116
|
-
return invoke$
|
|
2117
|
+
return invoke$5('ExtensionHost.getRuntimeStatus', extensionId);
|
|
2117
2118
|
};
|
|
2118
2119
|
const registerMockRpc$2 = commandMap => {
|
|
2119
2120
|
const mockRpc = createMockRpc({
|
|
2120
2121
|
commandMap
|
|
2121
2122
|
});
|
|
2122
|
-
set$
|
|
2123
|
+
set$9(mockRpc);
|
|
2123
2124
|
return mockRpc;
|
|
2124
2125
|
};
|
|
2125
2126
|
|
|
@@ -2129,17 +2130,28 @@ const ExtensionHost = {
|
|
|
2129
2130
|
executeFileReferenceProvider,
|
|
2130
2131
|
executeReferenceProvider,
|
|
2131
2132
|
getRuntimeStatus: getRuntimeStatus$2,
|
|
2132
|
-
invoke: invoke$
|
|
2133
|
+
invoke: invoke$5,
|
|
2133
2134
|
invokeAndTransfer: invokeAndTransfer$3,
|
|
2134
2135
|
registerMockRpc: registerMockRpc$2,
|
|
2136
|
+
set: set$9
|
|
2137
|
+
};
|
|
2138
|
+
|
|
2139
|
+
const {
|
|
2140
|
+
invoke: invoke$4,
|
|
2135
2141
|
set: set$8
|
|
2142
|
+
} = create$7(ExtensionManagementWorker);
|
|
2143
|
+
const enable = id => {
|
|
2144
|
+
return invoke$4(`Extensions.enable`, id);
|
|
2145
|
+
};
|
|
2146
|
+
const disable = id => {
|
|
2147
|
+
return invoke$4(`Extensions.disable`, id);
|
|
2136
2148
|
};
|
|
2137
2149
|
|
|
2138
2150
|
const {
|
|
2151
|
+
dispose: dispose$3,
|
|
2139
2152
|
invoke: invoke$3,
|
|
2140
2153
|
invokeAndTransfer: invokeAndTransfer$2,
|
|
2141
|
-
set: set$7
|
|
2142
|
-
dispose: dispose$3
|
|
2154
|
+
set: set$7
|
|
2143
2155
|
} = create$7(FileSystemWorker$1);
|
|
2144
2156
|
const remove = async dirent => {
|
|
2145
2157
|
return invoke$3('FileSystem.remove', dirent);
|
|
@@ -2224,10 +2236,10 @@ const FileSystemWorker = {
|
|
|
2224
2236
|
};
|
|
2225
2237
|
|
|
2226
2238
|
const {
|
|
2239
|
+
dispose: dispose$2,
|
|
2227
2240
|
invoke: invoke$2,
|
|
2228
2241
|
invokeAndTransfer: invokeAndTransfer$1,
|
|
2229
|
-
set: set$6
|
|
2230
|
-
dispose: dispose$2
|
|
2242
|
+
set: set$6
|
|
2231
2243
|
} = create$7(MarkdownWorker$1);
|
|
2232
2244
|
const getVirtualDom$1 = async html => {
|
|
2233
2245
|
// @ts-ignore
|
|
@@ -2259,7 +2271,8 @@ const MarkdownWorker = {
|
|
|
2259
2271
|
const {
|
|
2260
2272
|
invoke: invoke$1,
|
|
2261
2273
|
invokeAndTransfer,
|
|
2262
|
-
set: set$5
|
|
2274
|
+
set: set$5
|
|
2275
|
+
} = create$7(RendererWorker);
|
|
2263
2276
|
const showContextMenu2 = async (uid, menuId, x, y, args) => {
|
|
2264
2277
|
number(uid);
|
|
2265
2278
|
number(menuId);
|
|
@@ -2282,14 +2295,6 @@ const sendMessagePortToFileSystemWorker$1 = async (port, rpcId) => {
|
|
|
2282
2295
|
// @ts-ignore
|
|
2283
2296
|
await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToFileSystemWorker', port, command, rpcId);
|
|
2284
2297
|
};
|
|
2285
|
-
const disableExtension$1 = async id => {
|
|
2286
|
-
// @ts-ignore
|
|
2287
|
-
return invoke$1('ExtensionManagement.disable', id);
|
|
2288
|
-
};
|
|
2289
|
-
const enableExtension$1 = async id => {
|
|
2290
|
-
// @ts-ignore
|
|
2291
|
-
return invoke$1('ExtensionManagement.enable', id);
|
|
2292
|
-
};
|
|
2293
2298
|
const sendMessagePortToExtensionHostWorker$1 = async (port, rpcId = 0) => {
|
|
2294
2299
|
const command = 'HandleMessagePort.handleMessagePort2';
|
|
2295
2300
|
await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionHostWorker', port, command, rpcId);
|
|
@@ -2306,6 +2311,10 @@ const writeClipBoardImage = async blob => {
|
|
|
2306
2311
|
// @ts-ignore
|
|
2307
2312
|
await invoke$1('ClipBoard.writeImage', /* text */blob);
|
|
2308
2313
|
};
|
|
2314
|
+
const sendMessagePortToExtensionManagementWorker = async (port, rpcId) => {
|
|
2315
|
+
const command = 'Extensions.handleMessagePort';
|
|
2316
|
+
await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionManagementWorker', port, command, rpcId);
|
|
2317
|
+
};
|
|
2309
2318
|
const getAllExtensions$1 = async () => {
|
|
2310
2319
|
return invoke$1('ExtensionManagement.getAllExtensions');
|
|
2311
2320
|
};
|
|
@@ -3379,7 +3388,7 @@ const handleClickCategory = async (state, categoryId) => {
|
|
|
3379
3388
|
};
|
|
3380
3389
|
|
|
3381
3390
|
const disableExtension = id => {
|
|
3382
|
-
return
|
|
3391
|
+
return disable(id);
|
|
3383
3392
|
};
|
|
3384
3393
|
|
|
3385
3394
|
const Web = 1;
|
|
@@ -3405,6 +3414,12 @@ const getExtension$1 = async (id, platform) => {
|
|
|
3405
3414
|
};
|
|
3406
3415
|
|
|
3407
3416
|
const getExtensionNew = async id => {
|
|
3417
|
+
try {
|
|
3418
|
+
const rpc = get$3(ExtensionManagementWorker);
|
|
3419
|
+
return await rpc.invoke('Extensions.getExtension', id);
|
|
3420
|
+
} catch {
|
|
3421
|
+
// ignore
|
|
3422
|
+
}
|
|
3408
3423
|
return getExtension$2(id);
|
|
3409
3424
|
};
|
|
3410
3425
|
const getExtension = async (id, platform) => {
|
|
@@ -3423,12 +3438,12 @@ const getExtensionDetailButtons = (hasColorTheme, isBuiltin, isDisabled) => {
|
|
|
3423
3438
|
onClick: HandleClickSetColorTheme
|
|
3424
3439
|
}, {
|
|
3425
3440
|
enabled: isDisabled,
|
|
3426
|
-
label: enable(),
|
|
3441
|
+
label: enable$1(),
|
|
3427
3442
|
name: Enable,
|
|
3428
3443
|
onClick: HandleClickEnable
|
|
3429
3444
|
}, {
|
|
3430
3445
|
enabled: !isDisabled,
|
|
3431
|
-
label: disable(),
|
|
3446
|
+
label: disable$1(),
|
|
3432
3447
|
name: Disable,
|
|
3433
3448
|
onClick: HandleClickDisable
|
|
3434
3449
|
}, {
|
|
@@ -3466,7 +3481,7 @@ const handleClickDisable = async state => {
|
|
|
3466
3481
|
};
|
|
3467
3482
|
|
|
3468
3483
|
const enableExtension = id => {
|
|
3469
|
-
return
|
|
3484
|
+
return enable(id);
|
|
3470
3485
|
};
|
|
3471
3486
|
|
|
3472
3487
|
const handleClickEnable = async state => {
|
|
@@ -3569,155 +3584,253 @@ const handleClickUninstall = async state => {
|
|
|
3569
3584
|
return state;
|
|
3570
3585
|
};
|
|
3571
3586
|
|
|
3572
|
-
const
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
}
|
|
3587
|
+
const existsFile = async uri => {
|
|
3588
|
+
try {
|
|
3589
|
+
return await exists(uri);
|
|
3590
|
+
} catch {
|
|
3591
|
+
return false;
|
|
3592
|
+
}
|
|
3578
3593
|
};
|
|
3579
3594
|
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
};
|
|
3583
|
-
|
|
3584
|
-
|
|
3595
|
+
class ExtensionNotFoundError extends Error {
|
|
3596
|
+
constructor(extensionId) {
|
|
3597
|
+
super(`extension not found: ${extensionId}`);
|
|
3598
|
+
this.name = 'ExtensionNotFoundError';
|
|
3599
|
+
}
|
|
3600
|
+
}
|
|
3601
|
+
|
|
3602
|
+
const getRemoteSrc = uri => {
|
|
3603
|
+
const src = `/remote${uri}`;
|
|
3604
|
+
return src;
|
|
3585
3605
|
};
|
|
3586
|
-
|
|
3587
|
-
|
|
3606
|
+
|
|
3607
|
+
const getBaseUrl = (extensionPath, platform) => {
|
|
3608
|
+
switch (platform) {
|
|
3609
|
+
case Electron:
|
|
3610
|
+
case Remote:
|
|
3611
|
+
return getRemoteSrc(extensionPath + '/');
|
|
3612
|
+
default:
|
|
3613
|
+
return extensionPath;
|
|
3614
|
+
}
|
|
3588
3615
|
};
|
|
3589
3616
|
|
|
3590
|
-
const
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
}
|
|
3595
|
-
|
|
3596
|
-
return state;
|
|
3617
|
+
const getCommit = async () => {
|
|
3618
|
+
try {
|
|
3619
|
+
const commit = await invoke$1('Layout.getCommit');
|
|
3620
|
+
return commit;
|
|
3621
|
+
} catch {
|
|
3622
|
+
return '';
|
|
3597
3623
|
}
|
|
3598
|
-
return {
|
|
3599
|
-
...state,
|
|
3600
|
-
iconSrc: extensionDefaultIcon(assetDir)
|
|
3601
|
-
};
|
|
3602
3624
|
};
|
|
3603
3625
|
|
|
3604
|
-
const
|
|
3626
|
+
const getExtensionIdFromUri = uri => {
|
|
3627
|
+
const id = uri.slice('extension-detail://'.length);
|
|
3628
|
+
return id;
|
|
3629
|
+
};
|
|
3605
3630
|
|
|
3606
|
-
const
|
|
3607
|
-
const
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
menuId: ExtensionDetailIconContextMenu
|
|
3612
|
-
});
|
|
3613
|
-
return state;
|
|
3631
|
+
const interpolate = (value, inMin, inMax, outMin, outMax) => {
|
|
3632
|
+
const clamped = Math.min(Math.max(value, inMin), inMax);
|
|
3633
|
+
const ratio = (clamped - inMin) / (inMax - inMin);
|
|
3634
|
+
const mapped = outMin + ratio * (outMax - outMin);
|
|
3635
|
+
return Math.round(mapped);
|
|
3614
3636
|
};
|
|
3615
3637
|
|
|
3616
|
-
const
|
|
3617
|
-
|
|
3638
|
+
const getPadding = width => {
|
|
3639
|
+
if (width < 600) {
|
|
3640
|
+
return 10;
|
|
3641
|
+
}
|
|
3642
|
+
if (width < 800) {
|
|
3643
|
+
return 10;
|
|
3644
|
+
}
|
|
3645
|
+
if (width < 1200) {
|
|
3646
|
+
return interpolate(width, 800, 1200, 10, 30);
|
|
3647
|
+
}
|
|
3648
|
+
return 30;
|
|
3618
3649
|
};
|
|
3619
|
-
const
|
|
3620
|
-
if (
|
|
3621
|
-
return
|
|
3650
|
+
const getSideBarWidth = width => {
|
|
3651
|
+
if (width < 490) {
|
|
3652
|
+
return 0;
|
|
3622
3653
|
}
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3654
|
+
if (width < 650) {
|
|
3655
|
+
return Math.max(175 + Math.round(20 * (width / 100)), Math.round(width / 4));
|
|
3656
|
+
}
|
|
3657
|
+
if (width < 800) {
|
|
3658
|
+
return Math.max(175 + Math.round(20 * (width / 100)), Math.round(width / 4));
|
|
3659
|
+
}
|
|
3660
|
+
return Math.max(175 + Math.round(20 * (width / 100)), Math.round(width / 4));
|
|
3628
3661
|
};
|
|
3629
3662
|
|
|
3630
|
-
const
|
|
3631
|
-
const {
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3663
|
+
const getTabs = (selectedTab, hasReadme, hasFeatures, hasChangelog) => {
|
|
3664
|
+
const tabs = [{
|
|
3665
|
+
enabled: hasReadme,
|
|
3666
|
+
label: details(),
|
|
3667
|
+
name: Details,
|
|
3668
|
+
selected: selectedTab === Details
|
|
3669
|
+
}, {
|
|
3670
|
+
enabled: hasFeatures,
|
|
3671
|
+
label: features$1(),
|
|
3672
|
+
name: Features,
|
|
3673
|
+
selected: selectedTab === Features
|
|
3674
|
+
}, {
|
|
3675
|
+
enabled: hasChangelog,
|
|
3676
|
+
label: changelog(),
|
|
3677
|
+
name: Changelog,
|
|
3678
|
+
selected: selectedTab === Changelog
|
|
3679
|
+
}];
|
|
3680
|
+
return tabs;
|
|
3642
3681
|
};
|
|
3643
3682
|
|
|
3644
|
-
const
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
...state,
|
|
3648
|
-
readmeScrollTop: newScrollTop,
|
|
3649
|
-
scrollSource
|
|
3650
|
-
};
|
|
3651
|
-
};
|
|
3683
|
+
const Small = 1;
|
|
3684
|
+
const Normal = 2;
|
|
3685
|
+
const Large = 3;
|
|
3652
3686
|
|
|
3653
|
-
const
|
|
3654
|
-
|
|
3655
|
-
|
|
3687
|
+
const getViewletSize = width => {
|
|
3688
|
+
if (width < 180) {
|
|
3689
|
+
return Small;
|
|
3690
|
+
}
|
|
3691
|
+
if (width < 768) {
|
|
3692
|
+
return Normal;
|
|
3693
|
+
}
|
|
3694
|
+
return Large;
|
|
3656
3695
|
};
|
|
3657
3696
|
|
|
3658
|
-
const
|
|
3659
|
-
return
|
|
3697
|
+
const extensionDefaultIcon = assetDir => {
|
|
3698
|
+
return `${assetDir}/icons/extensionDefaultIcon.png`;
|
|
3699
|
+
};
|
|
3700
|
+
const extensionLanguageBasics = assetDir => {
|
|
3701
|
+
return `${assetDir}/icons/language-icon.svg`;
|
|
3702
|
+
};
|
|
3703
|
+
const extensionTheme = assetDir => {
|
|
3704
|
+
return `${assetDir}/icons/theme-icon.png`;
|
|
3660
3705
|
};
|
|
3661
3706
|
|
|
3662
|
-
const
|
|
3707
|
+
const isLanguageBasicsExtension = extension => {
|
|
3708
|
+
return extension.name && extension.name.startsWith('Language Basics');
|
|
3709
|
+
};
|
|
3663
3710
|
|
|
3664
|
-
const
|
|
3665
|
-
return
|
|
3711
|
+
const isThemeExtension = extension => {
|
|
3712
|
+
return extension.name && extension.name.endsWith(' Theme');
|
|
3666
3713
|
};
|
|
3667
3714
|
|
|
3668
|
-
const
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3715
|
+
const getIcon = (extension, platform, assetDir) => {
|
|
3716
|
+
if (!extension) {
|
|
3717
|
+
return extensionDefaultIcon(assetDir);
|
|
3718
|
+
}
|
|
3719
|
+
if (!extension.path || !extension.icon) {
|
|
3720
|
+
if (isLanguageBasicsExtension(extension)) {
|
|
3721
|
+
return extensionLanguageBasics(assetDir);
|
|
3722
|
+
}
|
|
3723
|
+
if (isThemeExtension(extension)) {
|
|
3724
|
+
return extensionTheme(assetDir);
|
|
3725
|
+
}
|
|
3726
|
+
return extensionDefaultIcon(assetDir);
|
|
3727
|
+
}
|
|
3728
|
+
if (platform === Remote || platform === Electron) {
|
|
3729
|
+
if (extension.builtin) {
|
|
3730
|
+
return `${assetDir}/extensions/${extension.id}/${extension.icon}`;
|
|
3731
|
+
}
|
|
3732
|
+
return `/remote/${extension.path}/${extension.icon}`; // TODO support windows paths
|
|
3733
|
+
}
|
|
3734
|
+
return '';
|
|
3672
3735
|
};
|
|
3673
3736
|
|
|
3674
|
-
const
|
|
3675
|
-
|
|
3737
|
+
const getDescription = extension => {
|
|
3738
|
+
if (!extension || !extension.description) {
|
|
3739
|
+
return 'n/a';
|
|
3740
|
+
}
|
|
3741
|
+
return extension.description;
|
|
3676
3742
|
};
|
|
3677
3743
|
|
|
3678
|
-
const
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
if (isEnoentError(error$1)) {
|
|
3685
|
-
return '';
|
|
3686
|
-
}
|
|
3687
|
-
await error(new VError(error$1, 'Failed to load Changelog content'));
|
|
3688
|
-
return `${error$1}`;
|
|
3744
|
+
const getName = extension => {
|
|
3745
|
+
if (extension && extension.name) {
|
|
3746
|
+
return extension.name;
|
|
3747
|
+
}
|
|
3748
|
+
if (extension && extension.id) {
|
|
3749
|
+
return extension.id;
|
|
3689
3750
|
}
|
|
3751
|
+
return 'n/a';
|
|
3690
3752
|
};
|
|
3691
3753
|
|
|
3692
|
-
const
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3754
|
+
const getDownloadCount = extension => {
|
|
3755
|
+
if (!extension) {
|
|
3756
|
+
return 'n/a';
|
|
3757
|
+
}
|
|
3758
|
+
|
|
3759
|
+
// Check for download count in various possible locations
|
|
3760
|
+
const downloadCount = extension.downloadCount || extension.downloads || extension.marketplace?.downloadCount || extension.marketplace?.downloads || extension.packageJSON?.downloadCount || extension.packageJSON?.downloads;
|
|
3761
|
+
if (!downloadCount) {
|
|
3762
|
+
return 'n/a';
|
|
3763
|
+
}
|
|
3764
|
+
|
|
3765
|
+
// Format the number with commas for better readability
|
|
3766
|
+
return downloadCount.toLocaleString();
|
|
3767
|
+
};
|
|
3768
|
+
|
|
3769
|
+
const getRating = extension => {
|
|
3770
|
+
if (!extension) {
|
|
3771
|
+
return 'n/a';
|
|
3772
|
+
}
|
|
3773
|
+
|
|
3774
|
+
// Check for rating in various possible locations
|
|
3775
|
+
const rating = extension.rating || extension.averageRating || extension.marketplace?.rating || extension.marketplace?.averageRating || extension.packageJSON?.rating || extension.packageJSON?.averageRating;
|
|
3776
|
+
if (!rating) {
|
|
3777
|
+
return 'n/a';
|
|
3778
|
+
}
|
|
3779
|
+
|
|
3780
|
+
// Format rating to one decimal place
|
|
3781
|
+
return rating.toFixed(1);
|
|
3782
|
+
};
|
|
3783
|
+
|
|
3784
|
+
const getBadge = (builtin, badgeEnabled) => {
|
|
3785
|
+
if (builtin && badgeEnabled) {
|
|
3786
|
+
return 'builtin';
|
|
3787
|
+
}
|
|
3788
|
+
return '';
|
|
3789
|
+
};
|
|
3790
|
+
|
|
3791
|
+
const hasColorThemes = extension => {
|
|
3792
|
+
return Boolean(extension && extension.colorThemes && extension.colorThemes.length > 0);
|
|
3793
|
+
};
|
|
3794
|
+
|
|
3795
|
+
const loadHeaderContent = (state, platform, extension) => {
|
|
3796
|
+
const {
|
|
3797
|
+
assetDir,
|
|
3798
|
+
builtinExtensionsBadgeEnabled
|
|
3698
3799
|
} = state;
|
|
3699
|
-
const
|
|
3700
|
-
const
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
const
|
|
3705
|
-
const
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
});
|
|
3800
|
+
const iconSrc = getIcon(extension, platform, assetDir);
|
|
3801
|
+
const description = getDescription(extension);
|
|
3802
|
+
const name = getName(extension);
|
|
3803
|
+
const extensionUri = extension.uri || extension.path;
|
|
3804
|
+
const extensionId = extension?.id || 'n/a';
|
|
3805
|
+
const extensionVersion = extension?.version || 'n/a';
|
|
3806
|
+
const hasColorTheme = hasColorThemes(extension);
|
|
3807
|
+
const isBuiltin = extension?.builtin;
|
|
3808
|
+
const badge = getBadge(isBuiltin, builtinExtensionsBadgeEnabled);
|
|
3809
|
+
const downloadCount = getDownloadCount(extension);
|
|
3810
|
+
const rating = getRating(extension);
|
|
3711
3811
|
return {
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3812
|
+
badge,
|
|
3813
|
+
description,
|
|
3814
|
+
downloadCount,
|
|
3815
|
+
extension,
|
|
3816
|
+
extensionId,
|
|
3817
|
+
extensionUri,
|
|
3818
|
+
extensionVersion,
|
|
3819
|
+
hasColorTheme,
|
|
3820
|
+
iconSrc,
|
|
3821
|
+
name,
|
|
3822
|
+
rating
|
|
3716
3823
|
};
|
|
3717
3824
|
};
|
|
3718
3825
|
|
|
3719
|
-
const
|
|
3720
|
-
return
|
|
3826
|
+
const readFile = async uri => {
|
|
3827
|
+
return readFile$1(uri);
|
|
3828
|
+
};
|
|
3829
|
+
|
|
3830
|
+
const ENOENT = 'ENOENT';
|
|
3831
|
+
|
|
3832
|
+
const isEnoentError = error => {
|
|
3833
|
+
return error && error.code === ENOENT;
|
|
3721
3834
|
};
|
|
3722
3835
|
|
|
3723
3836
|
const loadReadmeContent = async readmeUrl => {
|
|
@@ -3735,432 +3848,366 @@ const loadReadmeContent = async readmeUrl => {
|
|
|
3735
3848
|
}
|
|
3736
3849
|
};
|
|
3737
3850
|
|
|
3738
|
-
const
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
locationProtocol,
|
|
3742
|
-
readmeUrl,
|
|
3743
|
-
tabs
|
|
3744
|
-
} = state;
|
|
3745
|
-
const readmeContent = await loadReadmeContent(readmeUrl);
|
|
3746
|
-
const readmeHtml = await renderMarkdown(readmeContent, {
|
|
3747
|
-
baseUrl,
|
|
3748
|
-
linksExternal: true,
|
|
3749
|
-
locationProtocol
|
|
3750
|
-
});
|
|
3751
|
-
const detailsDom = await getMarkdownVirtualDom(readmeHtml);
|
|
3752
|
-
const newTabs = tabs.map(tab => {
|
|
3753
|
-
return {
|
|
3754
|
-
...tab,
|
|
3755
|
-
selected: tab.name === Details
|
|
3756
|
-
};
|
|
3757
|
-
});
|
|
3758
|
-
return {
|
|
3759
|
-
...state,
|
|
3760
|
-
detailsVirtualDom: detailsDom,
|
|
3761
|
-
selectedTab: Details,
|
|
3762
|
-
tabs: newTabs
|
|
3763
|
-
};
|
|
3764
|
-
};
|
|
3765
|
-
|
|
3766
|
-
const selectTabFeatures = async state => {
|
|
3767
|
-
const {
|
|
3768
|
-
baseUrl,
|
|
3769
|
-
extension,
|
|
3770
|
-
features,
|
|
3771
|
-
locationProtocol,
|
|
3772
|
-
selectedFeature,
|
|
3773
|
-
tabs
|
|
3774
|
-
} = state;
|
|
3775
|
-
if (features.length === 0) {
|
|
3776
|
-
return state;
|
|
3851
|
+
const stringifyCategory = category => {
|
|
3852
|
+
if (typeof category === 'string') {
|
|
3853
|
+
return category;
|
|
3777
3854
|
}
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
const newTabs = tabs.map(tab => {
|
|
3782
|
-
return {
|
|
3783
|
-
...tab,
|
|
3784
|
-
selected: tab.name === Features
|
|
3785
|
-
};
|
|
3786
|
-
});
|
|
3787
|
-
const newFeatures = features.map(feature => {
|
|
3788
|
-
if (feature.id === actualSelectedFeature) {
|
|
3789
|
-
return {
|
|
3790
|
-
...feature,
|
|
3791
|
-
selected: true
|
|
3792
|
-
};
|
|
3793
|
-
}
|
|
3794
|
-
return {
|
|
3795
|
-
...feature,
|
|
3796
|
-
selected: false
|
|
3797
|
-
};
|
|
3798
|
-
});
|
|
3855
|
+
return JSON.stringify(category);
|
|
3856
|
+
};
|
|
3857
|
+
const toCategory = categoryString => {
|
|
3799
3858
|
return {
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
features: newFeatures,
|
|
3803
|
-
selectedFeature: features[0].id || '',
|
|
3804
|
-
selectedTab: Features,
|
|
3805
|
-
tabs: newTabs
|
|
3859
|
+
id: categoryString.toLowerCase(),
|
|
3860
|
+
label: categoryString
|
|
3806
3861
|
};
|
|
3807
3862
|
};
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
case Changelog:
|
|
3812
|
-
return selectTabChangelog;
|
|
3813
|
-
case Details:
|
|
3814
|
-
return selectTabDetails;
|
|
3815
|
-
case Features:
|
|
3816
|
-
return selectTabFeatures;
|
|
3817
|
-
default:
|
|
3818
|
-
return selectTabDefault;
|
|
3863
|
+
const getCategories = extension => {
|
|
3864
|
+
if (!hasProperty(extension, 'categories') || !Array.isArray(extension.categories)) {
|
|
3865
|
+
return [];
|
|
3819
3866
|
}
|
|
3867
|
+
const categoryStrings = extension.categories.map(stringifyCategory);
|
|
3868
|
+
const categories = categoryStrings.map(toCategory);
|
|
3869
|
+
return categories;
|
|
3820
3870
|
};
|
|
3821
3871
|
|
|
3822
|
-
const
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3872
|
+
const BYTE_UNITS = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
3873
|
+
const BIBYTE_UNITS = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
|
|
3874
|
+
const BIT_UNITS = ['b', 'kbit', 'Mbit', 'Gbit', 'Tbit', 'Pbit', 'Ebit', 'Zbit', 'Ybit'];
|
|
3875
|
+
const BIBIT_UNITS = ['b', 'kibit', 'Mibit', 'Gibit', 'Tibit', 'Pibit', 'Eibit', 'Zibit', 'Yibit'];
|
|
3826
3876
|
|
|
3827
|
-
|
|
3828
|
-
|
|
3877
|
+
/*
|
|
3878
|
+
Formats the given number using `Number#toLocaleString`.
|
|
3879
|
+
- If locale is a string, the value is expected to be a locale-key (for example: `de`).
|
|
3880
|
+
- If locale is true, the system default locale is used for translation.
|
|
3881
|
+
- If no value for locale is specified, the number is returned unmodified.
|
|
3882
|
+
*/
|
|
3883
|
+
const toLocaleString = (number, locale, options) => {
|
|
3884
|
+
let result = number;
|
|
3885
|
+
if (typeof locale === 'string' || Array.isArray(locale)) {
|
|
3886
|
+
result = number.toLocaleString(locale, options);
|
|
3887
|
+
} else if (locale === true || options !== undefined) {
|
|
3888
|
+
result = number.toLocaleString(undefined, options);
|
|
3889
|
+
}
|
|
3890
|
+
return result;
|
|
3829
3891
|
};
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
return [];
|
|
3892
|
+
const log10 = numberOrBigInt => {
|
|
3893
|
+
if (typeof numberOrBigInt === 'number') {
|
|
3894
|
+
return Math.log10(numberOrBigInt);
|
|
3834
3895
|
}
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
onClick: HandleClickSize,
|
|
3838
|
-
title: extensionUri,
|
|
3839
|
-
value: displaySize
|
|
3840
|
-
}];
|
|
3896
|
+
const string = numberOrBigInt.toString(10);
|
|
3897
|
+
return string.length + Math.log10(`0.${string.slice(0, 15)}`);
|
|
3841
3898
|
};
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
odd: true,
|
|
3848
|
-
value: extensionId
|
|
3849
|
-
}, {
|
|
3850
|
-
code: true,
|
|
3851
|
-
key: version(),
|
|
3852
|
-
value: extensionVersion
|
|
3853
|
-
}, {
|
|
3854
|
-
key: lastUpdated(),
|
|
3855
|
-
odd: true,
|
|
3856
|
-
value: 'n/a' // TODO get this from somewhere
|
|
3857
|
-
}, ...getSizeEntries(showSizeLink, displaySize, extensionUri)];
|
|
3858
|
-
return entries;
|
|
3899
|
+
const log = numberOrBigInt => {
|
|
3900
|
+
if (typeof numberOrBigInt === 'number') {
|
|
3901
|
+
return Math.log(numberOrBigInt);
|
|
3902
|
+
}
|
|
3903
|
+
return log10(numberOrBigInt) * Math.log(10);
|
|
3859
3904
|
};
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
displaySize,
|
|
3864
|
-
extensionId,
|
|
3865
|
-
extensionUri,
|
|
3866
|
-
extensionVersion
|
|
3867
|
-
} = state;
|
|
3868
|
-
const newShowSizeLink = false;
|
|
3869
|
-
const installationEntries = getInstallationEntries(displaySize, extensionId, extensionVersion, extensionUri, newShowSizeLink);
|
|
3870
|
-
return {
|
|
3871
|
-
...state,
|
|
3872
|
-
installationEntries,
|
|
3873
|
-
showSizeLink: newShowSizeLink
|
|
3874
|
-
};
|
|
3875
|
-
};
|
|
3876
|
-
|
|
3877
|
-
const sendMessagePortToExtensionHostWorker = async port => {
|
|
3878
|
-
await sendMessagePortToExtensionHostWorker$1(port, 0);
|
|
3879
|
-
};
|
|
3880
|
-
|
|
3881
|
-
const createExtensionHostWorkerRpc = async () => {
|
|
3882
|
-
try {
|
|
3883
|
-
const rpc = await TransferMessagePortRpcParent.create({
|
|
3884
|
-
commandMap: {},
|
|
3885
|
-
send: sendMessagePortToExtensionHostWorker
|
|
3886
|
-
});
|
|
3887
|
-
return rpc;
|
|
3888
|
-
} catch (error) {
|
|
3889
|
-
throw new VError(error, `Failed to create extension host rpc`);
|
|
3905
|
+
const divide = (numberOrBigInt, divisor) => {
|
|
3906
|
+
if (typeof numberOrBigInt === 'number') {
|
|
3907
|
+
return numberOrBigInt / divisor;
|
|
3890
3908
|
}
|
|
3909
|
+
const integerPart = numberOrBigInt / BigInt(divisor);
|
|
3910
|
+
const remainder = numberOrBigInt % BigInt(divisor);
|
|
3911
|
+
return Number(integerPart) + Number(remainder) / divisor;
|
|
3891
3912
|
};
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3913
|
+
const applyFixedWidth = (result, fixedWidth) => {
|
|
3914
|
+
if (fixedWidth === undefined) {
|
|
3915
|
+
return result;
|
|
3916
|
+
}
|
|
3917
|
+
if (typeof fixedWidth !== 'number' || !Number.isSafeInteger(fixedWidth) || fixedWidth < 0) {
|
|
3918
|
+
throw new TypeError(`Expected fixedWidth to be a non-negative integer, got ${typeof fixedWidth}: ${fixedWidth}`);
|
|
3919
|
+
}
|
|
3920
|
+
if (fixedWidth === 0) {
|
|
3921
|
+
return result;
|
|
3922
|
+
}
|
|
3923
|
+
return result.length < fixedWidth ? result.padStart(fixedWidth, ' ') : result;
|
|
3896
3924
|
};
|
|
3897
|
-
|
|
3898
|
-
const
|
|
3899
|
-
|
|
3925
|
+
const buildLocaleOptions = options => {
|
|
3926
|
+
const {
|
|
3927
|
+
minimumFractionDigits,
|
|
3928
|
+
maximumFractionDigits
|
|
3929
|
+
} = options;
|
|
3930
|
+
if (minimumFractionDigits === undefined && maximumFractionDigits === undefined) {
|
|
3931
|
+
return undefined;
|
|
3932
|
+
}
|
|
3933
|
+
return {
|
|
3934
|
+
...(minimumFractionDigits !== undefined && {
|
|
3935
|
+
minimumFractionDigits
|
|
3936
|
+
}),
|
|
3937
|
+
...(maximumFractionDigits !== undefined && {
|
|
3938
|
+
maximumFractionDigits
|
|
3939
|
+
}),
|
|
3940
|
+
roundingMode: 'trunc'
|
|
3941
|
+
};
|
|
3900
3942
|
};
|
|
3943
|
+
function prettyBytes(number, options) {
|
|
3944
|
+
if (typeof number !== 'bigint' && !Number.isFinite(number)) {
|
|
3945
|
+
throw new TypeError(`Expected a finite number, got ${typeof number}: ${number}`);
|
|
3946
|
+
}
|
|
3947
|
+
options = {
|
|
3948
|
+
bits: false,
|
|
3949
|
+
binary: false,
|
|
3950
|
+
space: true,
|
|
3951
|
+
nonBreakingSpace: false,
|
|
3952
|
+
...options
|
|
3953
|
+
};
|
|
3954
|
+
const UNITS = options.bits ? options.binary ? BIBIT_UNITS : BIT_UNITS : options.binary ? BIBYTE_UNITS : BYTE_UNITS;
|
|
3955
|
+
const separator = options.space ? options.nonBreakingSpace ? '\u00A0' : ' ' : '';
|
|
3901
3956
|
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
});
|
|
3908
|
-
return rpc;
|
|
3909
|
-
} catch (error) {
|
|
3910
|
-
throw new VError(error, `Failed to create file system worker rpc`);
|
|
3957
|
+
// Handle signed zero case
|
|
3958
|
+
const isZero = typeof number === 'number' ? number === 0 : number === 0n;
|
|
3959
|
+
if (options.signed && isZero) {
|
|
3960
|
+
const result = ` 0${separator}${UNITS[0]}`;
|
|
3961
|
+
return applyFixedWidth(result, options.fixedWidth);
|
|
3911
3962
|
}
|
|
3912
|
-
|
|
3963
|
+
const isNegative = number < 0;
|
|
3964
|
+
const prefix = isNegative ? '-' : options.signed ? '+' : '';
|
|
3965
|
+
if (isNegative) {
|
|
3966
|
+
number = -number;
|
|
3967
|
+
}
|
|
3968
|
+
const localeOptions = buildLocaleOptions(options);
|
|
3969
|
+
let result;
|
|
3970
|
+
if (number < 1) {
|
|
3971
|
+
const numberString = toLocaleString(number, options.locale, localeOptions);
|
|
3972
|
+
result = prefix + numberString + separator + UNITS[0];
|
|
3973
|
+
} else {
|
|
3974
|
+
const exponent = Math.min(Math.floor(options.binary ? log(number) / Math.log(1024) : log10(number) / 3), UNITS.length - 1);
|
|
3975
|
+
number = divide(number, (options.binary ? 1024 : 1000) ** exponent);
|
|
3976
|
+
if (!localeOptions) {
|
|
3977
|
+
const minPrecision = Math.max(3, Math.floor(number).toString().length);
|
|
3978
|
+
number = number.toPrecision(minPrecision);
|
|
3979
|
+
}
|
|
3980
|
+
const numberString = toLocaleString(Number(number), options.locale, localeOptions);
|
|
3981
|
+
const unit = UNITS[exponent];
|
|
3982
|
+
result = prefix + numberString + separator + unit;
|
|
3983
|
+
}
|
|
3984
|
+
return applyFixedWidth(result, options.fixedWidth);
|
|
3985
|
+
}
|
|
3913
3986
|
|
|
3914
|
-
const
|
|
3915
|
-
|
|
3916
|
-
|
|
3987
|
+
const getDisplaySize = size => {
|
|
3988
|
+
return prettyBytes(size, {
|
|
3989
|
+
maximumFractionDigits: 1
|
|
3990
|
+
});
|
|
3917
3991
|
};
|
|
3918
3992
|
|
|
3919
|
-
const
|
|
3920
|
-
|
|
3993
|
+
const supportsFileSize = uri => {
|
|
3994
|
+
if (uri.startsWith('http:') || uri.startsWith('https://')) {
|
|
3995
|
+
return false;
|
|
3996
|
+
}
|
|
3997
|
+
return true;
|
|
3921
3998
|
};
|
|
3922
|
-
|
|
3923
|
-
|
|
3999
|
+
const getFolderSize = async uri => {
|
|
4000
|
+
if (!uri) {
|
|
4001
|
+
throw new VError(`uri is required`);
|
|
4002
|
+
}
|
|
4003
|
+
if (!supportsFileSize(uri)) {
|
|
4004
|
+
return 0;
|
|
4005
|
+
}
|
|
3924
4006
|
try {
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
return rpc;
|
|
3930
|
-
} catch (error) {
|
|
3931
|
-
throw new VError(error, `Failed to create markdown worker rpc`);
|
|
4007
|
+
// @ts-ignore
|
|
4008
|
+
return await invoke('FileSystem.getFolderSize', uri);
|
|
4009
|
+
} catch {
|
|
4010
|
+
return 0;
|
|
3932
4011
|
}
|
|
3933
4012
|
};
|
|
3934
4013
|
|
|
3935
|
-
const
|
|
3936
|
-
|
|
3937
|
-
|
|
4014
|
+
const getSizeEntries = (showSizeLink, displaySize, extensionUri) => {
|
|
4015
|
+
if (!showSizeLink) {
|
|
4016
|
+
return [];
|
|
4017
|
+
}
|
|
4018
|
+
return [{
|
|
4019
|
+
key: size(),
|
|
4020
|
+
onClick: HandleClickSize,
|
|
4021
|
+
title: extensionUri,
|
|
4022
|
+
value: displaySize
|
|
4023
|
+
}];
|
|
3938
4024
|
};
|
|
3939
4025
|
|
|
3940
|
-
const
|
|
3941
|
-
|
|
3942
|
-
|
|
4026
|
+
const getInstallationEntries = (displaySize, extensionId, extensionVersion, extensionUri, showSizeLink) => {
|
|
4027
|
+
const entries = [{
|
|
4028
|
+
code: true,
|
|
4029
|
+
key: identifier(),
|
|
4030
|
+
odd: true,
|
|
4031
|
+
value: extensionId
|
|
4032
|
+
}, {
|
|
4033
|
+
code: true,
|
|
4034
|
+
key: version(),
|
|
4035
|
+
value: extensionVersion
|
|
4036
|
+
}, {
|
|
4037
|
+
key: lastUpdated(),
|
|
4038
|
+
odd: true,
|
|
4039
|
+
value: 'n/a' // TODO get this from somewhere
|
|
4040
|
+
}, ...getSizeEntries(showSizeLink, displaySize, extensionUri)];
|
|
4041
|
+
return entries;
|
|
3943
4042
|
};
|
|
3944
4043
|
|
|
3945
|
-
const
|
|
3946
|
-
|
|
3947
|
-
return
|
|
3948
|
-
} catch {
|
|
3949
|
-
return false;
|
|
4044
|
+
const getMarketplaceEntries = isBuiltin => {
|
|
4045
|
+
if (isBuiltin) {
|
|
4046
|
+
return [];
|
|
3950
4047
|
}
|
|
4048
|
+
return [{
|
|
4049
|
+
key: published(),
|
|
4050
|
+
odd: true,
|
|
4051
|
+
value: 'n/a'
|
|
4052
|
+
}, {
|
|
4053
|
+
key: lastReleased(),
|
|
4054
|
+
value: 'n/a'
|
|
4055
|
+
}];
|
|
3951
4056
|
};
|
|
3952
4057
|
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
this.name = 'ExtensionNotFoundError';
|
|
3957
|
-
}
|
|
3958
|
-
}
|
|
3959
|
-
|
|
3960
|
-
const getRemoteSrc = uri => {
|
|
3961
|
-
const src = `/remote${uri}`;
|
|
3962
|
-
return src;
|
|
4058
|
+
const getLicenseLink = extension => {
|
|
4059
|
+
// TODO
|
|
4060
|
+
return '#';
|
|
3963
4061
|
};
|
|
3964
4062
|
|
|
3965
|
-
const
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
case Remote:
|
|
3969
|
-
return getRemoteSrc(extensionPath + '/');
|
|
3970
|
-
default:
|
|
3971
|
-
return extensionPath;
|
|
4063
|
+
const ensureValidLink = link => {
|
|
4064
|
+
if (!link) {
|
|
4065
|
+
return '';
|
|
3972
4066
|
}
|
|
3973
|
-
};
|
|
3974
|
-
|
|
3975
|
-
const getCommit = async () => {
|
|
3976
4067
|
try {
|
|
3977
|
-
const
|
|
3978
|
-
|
|
4068
|
+
const parsed = new URL(link);
|
|
4069
|
+
if (parsed.protocol !== 'https:') {
|
|
4070
|
+
return '';
|
|
4071
|
+
}
|
|
4072
|
+
return link;
|
|
3979
4073
|
} catch {
|
|
3980
4074
|
return '';
|
|
3981
4075
|
}
|
|
3982
4076
|
};
|
|
3983
4077
|
|
|
3984
|
-
const
|
|
3985
|
-
|
|
3986
|
-
|
|
4078
|
+
const getRepositoryLinkRaw = extension => {
|
|
4079
|
+
if (extension && hasProperty(extension, 'repository') && typeof extension.repository === 'string') {
|
|
4080
|
+
return extension.repository; // TODO watch out for javascript: or other invalid links or path traversal
|
|
4081
|
+
}
|
|
4082
|
+
return '';
|
|
3987
4083
|
};
|
|
3988
|
-
|
|
3989
|
-
const
|
|
3990
|
-
const
|
|
3991
|
-
|
|
3992
|
-
const mapped = outMin + ratio * (outMax - outMin);
|
|
3993
|
-
return Math.round(mapped);
|
|
4084
|
+
const getRepositoryLink = extension => {
|
|
4085
|
+
const raw = getRepositoryLinkRaw(extension);
|
|
4086
|
+
const validLink = ensureValidLink(raw);
|
|
4087
|
+
return validLink;
|
|
3994
4088
|
};
|
|
3995
|
-
|
|
3996
|
-
const
|
|
3997
|
-
if (
|
|
3998
|
-
return
|
|
4089
|
+
const getIssuesLink = extension => {
|
|
4090
|
+
const repositoryLink = getRepositoryLink(extension);
|
|
4091
|
+
if (!repositoryLink) {
|
|
4092
|
+
return '';
|
|
3999
4093
|
}
|
|
4000
|
-
if (
|
|
4001
|
-
return
|
|
4094
|
+
if (repositoryLink && repositoryLink.startsWith('https://github.com')) {
|
|
4095
|
+
return `${repositoryLink}/issues`;
|
|
4002
4096
|
}
|
|
4003
|
-
|
|
4004
|
-
return interpolate(width, 800, 1200, 10, 30);
|
|
4005
|
-
}
|
|
4006
|
-
return 30;
|
|
4007
|
-
};
|
|
4008
|
-
const getSideBarWidth = width => {
|
|
4009
|
-
if (width < 490) {
|
|
4010
|
-
return 0;
|
|
4011
|
-
}
|
|
4012
|
-
if (width < 650) {
|
|
4013
|
-
return Math.max(175 + Math.round(20 * (width / 100)), Math.round(width / 4));
|
|
4014
|
-
}
|
|
4015
|
-
if (width < 800) {
|
|
4016
|
-
return Math.max(175 + Math.round(20 * (width / 100)), Math.round(width / 4));
|
|
4017
|
-
}
|
|
4018
|
-
return Math.max(175 + Math.round(20 * (width / 100)), Math.round(width / 4));
|
|
4097
|
+
return '';
|
|
4019
4098
|
};
|
|
4020
4099
|
|
|
4021
|
-
const
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4100
|
+
const getResources = (isBuiltin, extension) => {
|
|
4101
|
+
if (isBuiltin) {
|
|
4102
|
+
return [];
|
|
4103
|
+
}
|
|
4104
|
+
const repositoryLink = getRepositoryLink(extension);
|
|
4105
|
+
const issueLink = getIssuesLink(extension);
|
|
4106
|
+
const licenseLink = getLicenseLink();
|
|
4107
|
+
// TODO
|
|
4108
|
+
return [{
|
|
4109
|
+
icon: 'LinkExternal',
|
|
4110
|
+
label: marketplace(),
|
|
4111
|
+
url: '#'
|
|
4027
4112
|
}, {
|
|
4028
|
-
|
|
4029
|
-
label:
|
|
4030
|
-
|
|
4031
|
-
selected: selectedTab === Features
|
|
4113
|
+
icon: 'LinkExternal',
|
|
4114
|
+
label: issues(),
|
|
4115
|
+
url: issueLink
|
|
4032
4116
|
}, {
|
|
4033
|
-
|
|
4034
|
-
label:
|
|
4035
|
-
|
|
4036
|
-
|
|
4117
|
+
icon: 'Repo',
|
|
4118
|
+
label: repository(),
|
|
4119
|
+
url: repositoryLink
|
|
4120
|
+
}, {
|
|
4121
|
+
icon: 'LinkExternal',
|
|
4122
|
+
label: license(),
|
|
4123
|
+
url: licenseLink
|
|
4037
4124
|
}];
|
|
4038
|
-
return tabs;
|
|
4039
|
-
};
|
|
4040
|
-
|
|
4041
|
-
const Small = 1;
|
|
4042
|
-
const Normal = 2;
|
|
4043
|
-
const Large = 3;
|
|
4044
|
-
|
|
4045
|
-
const getViewletSize = width => {
|
|
4046
|
-
if (width < 180) {
|
|
4047
|
-
return Small;
|
|
4048
|
-
}
|
|
4049
|
-
if (width < 768) {
|
|
4050
|
-
return Normal;
|
|
4051
|
-
}
|
|
4052
|
-
return Large;
|
|
4053
|
-
};
|
|
4054
|
-
|
|
4055
|
-
const isLanguageBasicsExtension = extension => {
|
|
4056
|
-
return extension.name && extension.name.startsWith('Language Basics');
|
|
4057
4125
|
};
|
|
4058
4126
|
|
|
4059
|
-
const
|
|
4060
|
-
|
|
4127
|
+
const loadSideBarContent = async (extensionId, extensionVersion, extensionUri, isBuiltin, extension, showSizeLink) => {
|
|
4128
|
+
const folderSize = await getFolderSize(extensionUri);
|
|
4129
|
+
const displaySize = getDisplaySize(folderSize);
|
|
4130
|
+
const installationEntries = getInstallationEntries(displaySize, extensionId, extensionVersion, extensionUri, showSizeLink);
|
|
4131
|
+
const marketplaceEntries = getMarketplaceEntries(isBuiltin);
|
|
4132
|
+
const categories = getCategories(extension);
|
|
4133
|
+
const resources = getResources(isBuiltin, extension);
|
|
4134
|
+
return {
|
|
4135
|
+
categories,
|
|
4136
|
+
displaySize,
|
|
4137
|
+
folderSize,
|
|
4138
|
+
installationEntries,
|
|
4139
|
+
marketplaceEntries,
|
|
4140
|
+
resources
|
|
4141
|
+
};
|
|
4061
4142
|
};
|
|
4062
4143
|
|
|
4063
|
-
const
|
|
4064
|
-
|
|
4065
|
-
return extensionDefaultIcon(assetDir);
|
|
4066
|
-
}
|
|
4067
|
-
if (!extension.path || !extension.icon) {
|
|
4068
|
-
if (isLanguageBasicsExtension(extension)) {
|
|
4069
|
-
return extensionLanguageBasics(assetDir);
|
|
4070
|
-
}
|
|
4071
|
-
if (isThemeExtension(extension)) {
|
|
4072
|
-
return extensionTheme(assetDir);
|
|
4073
|
-
}
|
|
4074
|
-
return extensionDefaultIcon(assetDir);
|
|
4075
|
-
}
|
|
4076
|
-
if (platform === Remote || platform === Electron) {
|
|
4077
|
-
if (extension.builtin) {
|
|
4078
|
-
return `${assetDir}/extensions/${extension.id}/${extension.icon}`;
|
|
4079
|
-
}
|
|
4080
|
-
return `/remote/${extension.path}/${extension.icon}`; // TODO support windows paths
|
|
4081
|
-
}
|
|
4082
|
-
return '';
|
|
4144
|
+
const join = (...parts) => {
|
|
4145
|
+
return parts.join('/');
|
|
4083
4146
|
};
|
|
4084
4147
|
|
|
4085
|
-
const
|
|
4086
|
-
if (
|
|
4087
|
-
return
|
|
4148
|
+
const getSavedChangelogScrollTop = savedState => {
|
|
4149
|
+
if (savedState && typeof savedState === 'object' && 'changelogScrollTop' in savedState && typeof savedState.changelogScrollTop === 'number') {
|
|
4150
|
+
return savedState.changelogScrollTop;
|
|
4088
4151
|
}
|
|
4089
|
-
return
|
|
4152
|
+
return 0;
|
|
4090
4153
|
};
|
|
4091
4154
|
|
|
4092
|
-
const
|
|
4093
|
-
if (
|
|
4094
|
-
return
|
|
4095
|
-
}
|
|
4096
|
-
if (extension && extension.id) {
|
|
4097
|
-
return extension.id;
|
|
4155
|
+
const getSavedReadmeScrollTop = savedState => {
|
|
4156
|
+
if (savedState && typeof savedState === 'object' && 'readmeScrollTop' in savedState && typeof savedState.readmeScrollTop === 'number') {
|
|
4157
|
+
return savedState.readmeScrollTop;
|
|
4098
4158
|
}
|
|
4099
|
-
return
|
|
4159
|
+
return 0;
|
|
4100
4160
|
};
|
|
4101
4161
|
|
|
4102
|
-
const
|
|
4103
|
-
if (
|
|
4104
|
-
return
|
|
4105
|
-
}
|
|
4106
|
-
|
|
4107
|
-
// Check for download count in various possible locations
|
|
4108
|
-
const downloadCount = extension.downloadCount || extension.downloads || extension.marketplace?.downloadCount || extension.marketplace?.downloads || extension.packageJSON?.downloadCount || extension.packageJSON?.downloads;
|
|
4109
|
-
if (!downloadCount) {
|
|
4110
|
-
return 'n/a';
|
|
4162
|
+
const getSavedSelectedFeature = savedState => {
|
|
4163
|
+
if (savedState && typeof savedState === 'object' && 'selectedFeature' in savedState && typeof savedState.selectedFeature === 'string') {
|
|
4164
|
+
return savedState.selectedFeature;
|
|
4111
4165
|
}
|
|
4112
|
-
|
|
4113
|
-
// Format the number with commas for better readability
|
|
4114
|
-
return downloadCount.toLocaleString();
|
|
4166
|
+
return Details;
|
|
4115
4167
|
};
|
|
4116
4168
|
|
|
4117
|
-
const
|
|
4118
|
-
if (
|
|
4119
|
-
return
|
|
4120
|
-
}
|
|
4121
|
-
|
|
4122
|
-
// Check for rating in various possible locations
|
|
4123
|
-
const rating = extension.rating || extension.averageRating || extension.marketplace?.rating || extension.marketplace?.averageRating || extension.packageJSON?.rating || extension.packageJSON?.averageRating;
|
|
4124
|
-
if (!rating) {
|
|
4125
|
-
return 'n/a';
|
|
4169
|
+
const getSavedSelectedTab = savedState => {
|
|
4170
|
+
if (savedState && typeof savedState === 'object' && 'selectedTab' in savedState && typeof savedState.selectedTab === 'string') {
|
|
4171
|
+
return savedState.selectedTab;
|
|
4126
4172
|
}
|
|
4127
|
-
|
|
4128
|
-
// Format rating to one decimal place
|
|
4129
|
-
return rating.toFixed(1);
|
|
4173
|
+
return Details;
|
|
4130
4174
|
};
|
|
4131
4175
|
|
|
4132
|
-
const
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4176
|
+
const restoreState = savedState => {
|
|
4177
|
+
const selectedTab = getSavedSelectedTab(savedState);
|
|
4178
|
+
const selectedFeature = getSavedSelectedFeature(savedState);
|
|
4179
|
+
const readmeScrollTop = getSavedReadmeScrollTop(savedState);
|
|
4180
|
+
const changelogScrollTop = getSavedChangelogScrollTop(savedState);
|
|
4181
|
+
return {
|
|
4182
|
+
changelogScrollTop,
|
|
4183
|
+
readmeScrollTop,
|
|
4184
|
+
selectedFeature,
|
|
4185
|
+
selectedTab
|
|
4186
|
+
};
|
|
4137
4187
|
};
|
|
4138
4188
|
|
|
4139
|
-
const
|
|
4140
|
-
return
|
|
4189
|
+
const isEnabled = tab => {
|
|
4190
|
+
return tab.enabled;
|
|
4141
4191
|
};
|
|
4142
|
-
|
|
4143
|
-
|
|
4192
|
+
const loadContent = async (state, platform, savedState, isTest = false) => {
|
|
4193
|
+
if (isTest) {
|
|
4194
|
+
savedState = undefined;
|
|
4195
|
+
}
|
|
4144
4196
|
const {
|
|
4145
|
-
|
|
4146
|
-
|
|
4197
|
+
uri,
|
|
4198
|
+
width
|
|
4147
4199
|
} = state;
|
|
4148
|
-
const
|
|
4149
|
-
const
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
const
|
|
4154
|
-
const
|
|
4155
|
-
const
|
|
4156
|
-
const badge = getBadge(isBuiltin, builtinExtensionsBadgeEnabled);
|
|
4157
|
-
const downloadCount = getDownloadCount(extension);
|
|
4158
|
-
const rating = getRating(extension);
|
|
4159
|
-
return {
|
|
4200
|
+
const id = getExtensionIdFromUri(uri);
|
|
4201
|
+
const extension = await getExtension(id, platform);
|
|
4202
|
+
if (!extension) {
|
|
4203
|
+
throw new ExtensionNotFoundError(id);
|
|
4204
|
+
}
|
|
4205
|
+
const commit = await getCommit();
|
|
4206
|
+
const headerData = loadHeaderContent(state, platform, extension);
|
|
4207
|
+
const {
|
|
4160
4208
|
badge,
|
|
4161
4209
|
description,
|
|
4162
4210
|
downloadCount,
|
|
4163
|
-
extension,
|
|
4164
4211
|
extensionId,
|
|
4165
4212
|
extensionUri,
|
|
4166
4213
|
extensionVersion,
|
|
@@ -4168,429 +4215,428 @@ const loadHeaderContent = (state, platform, extension) => {
|
|
|
4168
4215
|
iconSrc,
|
|
4169
4216
|
name,
|
|
4170
4217
|
rating
|
|
4171
|
-
};
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
const
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
};
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
const
|
|
4191
|
-
const
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
const
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4218
|
+
} = headerData;
|
|
4219
|
+
const readmeUrl = join(extensionUri, 'README.md');
|
|
4220
|
+
const changelogUrl = join(extensionUri, 'CHANGELOG.md');
|
|
4221
|
+
const [hasReadme, hasChangelog] = await Promise.all([existsFile(readmeUrl), existsFile(changelogUrl)]);
|
|
4222
|
+
const readmeContent = hasReadme ? await loadReadmeContent(readmeUrl) : noReadmeFound();
|
|
4223
|
+
const baseUrl = getBaseUrl(extension.path, platform);
|
|
4224
|
+
const locationProtocol = location.protocol;
|
|
4225
|
+
const locationHost = location.host;
|
|
4226
|
+
const readmeHtml = await renderMarkdown(readmeContent, {
|
|
4227
|
+
baseUrl,
|
|
4228
|
+
commit,
|
|
4229
|
+
linksExternal: true,
|
|
4230
|
+
locationProtocol
|
|
4231
|
+
});
|
|
4232
|
+
const detailsVirtualDom = await getMarkdownVirtualDom(readmeHtml, {
|
|
4233
|
+
scrollToTopEnabled: true
|
|
4234
|
+
});
|
|
4235
|
+
const isBuiltin = extension?.isBuiltin;
|
|
4236
|
+
const disabled = extension?.disabled;
|
|
4237
|
+
const buttons = getExtensionDetailButtons(hasColorTheme, isBuiltin, disabled);
|
|
4238
|
+
const size = getViewletSize(width);
|
|
4239
|
+
const {
|
|
4240
|
+
changelogScrollTop,
|
|
4241
|
+
readmeScrollTop,
|
|
4242
|
+
selectedFeature,
|
|
4243
|
+
selectedTab
|
|
4244
|
+
} = restoreState(savedState);
|
|
4245
|
+
const features = getFeatures(selectedFeature || Theme, extension);
|
|
4246
|
+
const hasFeatures = features.length > 0;
|
|
4247
|
+
const tabs = getTabs(selectedTab, hasReadme, hasFeatures, hasChangelog);
|
|
4248
|
+
const enabledTabs = tabs.filter(isEnabled);
|
|
4249
|
+
const sizeValue = getViewletSize(width || 0);
|
|
4250
|
+
const showSizeLink = platform !== Web$1;
|
|
4251
|
+
const {
|
|
4252
|
+
categories,
|
|
4253
|
+
displaySize,
|
|
4254
|
+
folderSize,
|
|
4255
|
+
installationEntries,
|
|
4256
|
+
marketplaceEntries,
|
|
4257
|
+
resources
|
|
4258
|
+
} = await loadSideBarContent(extensionId, extensionVersion, extensionUri, isBuiltin, extension, showSizeLink);
|
|
4259
|
+
const padding = getPadding(width);
|
|
4260
|
+
const sideBarWidth = getSideBarWidth(width);
|
|
4261
|
+
const showSideBar = sideBarWidth > 0;
|
|
4262
|
+
return {
|
|
4263
|
+
...state,
|
|
4264
|
+
badge,
|
|
4265
|
+
baseUrl,
|
|
4266
|
+
buttons,
|
|
4267
|
+
categories,
|
|
4268
|
+
changelogScrollTop,
|
|
4269
|
+
commit,
|
|
4270
|
+
description,
|
|
4271
|
+
detailsVirtualDom,
|
|
4272
|
+
disabled,
|
|
4273
|
+
displaySize,
|
|
4274
|
+
downloadCount,
|
|
4275
|
+
extension,
|
|
4276
|
+
extensionId,
|
|
4277
|
+
extensionUri,
|
|
4278
|
+
extensionVersion,
|
|
4279
|
+
features,
|
|
4280
|
+
folderSize,
|
|
4281
|
+
hasColorTheme,
|
|
4282
|
+
hasReadme,
|
|
4283
|
+
iconSrc,
|
|
4284
|
+
installationEntries,
|
|
4285
|
+
locationHost,
|
|
4286
|
+
locationProtocol,
|
|
4287
|
+
marketplaceEntries,
|
|
4288
|
+
name,
|
|
4289
|
+
paddingLeft: padding,
|
|
4290
|
+
paddingRight: padding,
|
|
4291
|
+
rating,
|
|
4292
|
+
readmeScrollTop,
|
|
4293
|
+
readmeUrl,
|
|
4294
|
+
resources,
|
|
4295
|
+
scrollSource: Script,
|
|
4296
|
+
scrollToTopButtonEnabled: true,
|
|
4297
|
+
selectedTab,
|
|
4298
|
+
showSideBar,
|
|
4299
|
+
showSizeLink,
|
|
4300
|
+
sideBarWidth,
|
|
4301
|
+
sizeOnDisk: size,
|
|
4302
|
+
sizeValue,
|
|
4303
|
+
tabs: enabledTabs
|
|
4304
|
+
};
|
|
4214
4305
|
};
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
return
|
|
4306
|
+
|
|
4307
|
+
const handleExtensionsChanged = async state => {
|
|
4308
|
+
const {
|
|
4309
|
+
platform
|
|
4310
|
+
} = state;
|
|
4311
|
+
return loadContent(state, platform, {});
|
|
4221
4312
|
};
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4313
|
+
|
|
4314
|
+
const handleExtensionsStatusUpdate = async state => {
|
|
4315
|
+
const {
|
|
4316
|
+
extension
|
|
4317
|
+
} = state;
|
|
4318
|
+
const details = await getRuntimeStatusDetails(extension);
|
|
4319
|
+
return {
|
|
4320
|
+
...state,
|
|
4321
|
+
...details
|
|
4322
|
+
};
|
|
4227
4323
|
};
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4324
|
+
|
|
4325
|
+
const handleIconError = state => {
|
|
4326
|
+
const {
|
|
4327
|
+
assetDir,
|
|
4328
|
+
iconSrc
|
|
4329
|
+
} = state;
|
|
4330
|
+
if (iconSrc === extensionDefaultIcon(assetDir)) {
|
|
4331
|
+
return state;
|
|
4231
4332
|
}
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4333
|
+
return {
|
|
4334
|
+
...state,
|
|
4335
|
+
iconSrc: extensionDefaultIcon(assetDir)
|
|
4336
|
+
};
|
|
4235
4337
|
};
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
}
|
|
4243
|
-
|
|
4244
|
-
|
|
4338
|
+
|
|
4339
|
+
const ExtensionDetailIconContextMenu = 4091;
|
|
4340
|
+
|
|
4341
|
+
const handleImageContextMenu = async (state, eventX, eventY) => {
|
|
4342
|
+
const {
|
|
4343
|
+
uid
|
|
4344
|
+
} = state;
|
|
4345
|
+
await show2(uid, ExtensionDetailIconContextMenu, eventX, eventY, {
|
|
4346
|
+
menuId: ExtensionDetailIconContextMenu
|
|
4347
|
+
});
|
|
4348
|
+
return state;
|
|
4349
|
+
};
|
|
4350
|
+
|
|
4351
|
+
const isExternalLink = href => {
|
|
4352
|
+
return href.startsWith('http://') || href.startsWith('https://');
|
|
4353
|
+
};
|
|
4354
|
+
const handleReadmeClick = async (state, nodeName, href) => {
|
|
4355
|
+
if (!href || !isExternalLink(href)) {
|
|
4356
|
+
return state;
|
|
4245
4357
|
}
|
|
4246
|
-
|
|
4358
|
+
// TODO what to do about relative links? open them in editor?
|
|
4359
|
+
// TODO what to do about mail links?
|
|
4360
|
+
await openUrl$1(href);
|
|
4361
|
+
// TODO check node name and href
|
|
4362
|
+
return state;
|
|
4247
4363
|
};
|
|
4248
|
-
|
|
4364
|
+
|
|
4365
|
+
const handleReadmeContextMenu = async (state, x, y, nodeName, href) => {
|
|
4249
4366
|
const {
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4367
|
+
uid
|
|
4368
|
+
} = state;
|
|
4369
|
+
// TODO maybe also pass other args
|
|
4370
|
+
await show2(uid, ExtensionDetailReadme, x, y, {
|
|
4371
|
+
href,
|
|
4372
|
+
menuId: ExtensionDetailReadme,
|
|
4373
|
+
nodeName
|
|
4374
|
+
});
|
|
4375
|
+
// TODO
|
|
4376
|
+
return state;
|
|
4377
|
+
};
|
|
4378
|
+
|
|
4379
|
+
const handleScroll = (state, scrollTop, scrollSource = Script) => {
|
|
4380
|
+
const newScrollTop = Math.max(0, scrollTop);
|
|
4256
4381
|
return {
|
|
4257
|
-
...
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
...(maximumFractionDigits !== undefined && {
|
|
4261
|
-
maximumFractionDigits
|
|
4262
|
-
}),
|
|
4263
|
-
roundingMode: 'trunc'
|
|
4382
|
+
...state,
|
|
4383
|
+
readmeScrollTop: newScrollTop,
|
|
4384
|
+
scrollSource
|
|
4264
4385
|
};
|
|
4265
4386
|
};
|
|
4266
|
-
function prettyBytes(number, options) {
|
|
4267
|
-
if (typeof number !== 'bigint' && !Number.isFinite(number)) {
|
|
4268
|
-
throw new TypeError(`Expected a finite number, got ${typeof number}: ${number}`);
|
|
4269
|
-
}
|
|
4270
|
-
options = {
|
|
4271
|
-
bits: false,
|
|
4272
|
-
binary: false,
|
|
4273
|
-
space: true,
|
|
4274
|
-
nonBreakingSpace: false,
|
|
4275
|
-
...options
|
|
4276
|
-
};
|
|
4277
|
-
const UNITS = options.bits ? options.binary ? BIBIT_UNITS : BIT_UNITS : options.binary ? BIBYTE_UNITS : BYTE_UNITS;
|
|
4278
|
-
const separator = options.space ? options.nonBreakingSpace ? '\u00A0' : ' ' : '';
|
|
4279
4387
|
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
const
|
|
4295
|
-
|
|
4296
|
-
}
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
if (!localeOptions) {
|
|
4300
|
-
const minPrecision = Math.max(3, Math.floor(number).toString().length);
|
|
4301
|
-
number = number.toPrecision(minPrecision);
|
|
4388
|
+
const handleSelectionChange = async (state, selection) => {
|
|
4389
|
+
// console.log('selection change')
|
|
4390
|
+
return state;
|
|
4391
|
+
};
|
|
4392
|
+
|
|
4393
|
+
const error = async error => {
|
|
4394
|
+
// TODO send message to error worker or log worker
|
|
4395
|
+
// @ts-ignore
|
|
4396
|
+
console.error(error);
|
|
4397
|
+
};
|
|
4398
|
+
|
|
4399
|
+
const loadChangelogContent = async path => {
|
|
4400
|
+
try {
|
|
4401
|
+
const changelogUrl = join(path, 'CHANGELOG.md');
|
|
4402
|
+
const changelogContent = await readFile(changelogUrl);
|
|
4403
|
+
return changelogContent;
|
|
4404
|
+
} catch (error$1) {
|
|
4405
|
+
if (isEnoentError(error$1)) {
|
|
4406
|
+
return '';
|
|
4302
4407
|
}
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
result = prefix + numberString + separator + unit;
|
|
4408
|
+
await error(new VError(error$1, 'Failed to load Changelog content'));
|
|
4409
|
+
return `${error$1}`;
|
|
4306
4410
|
}
|
|
4307
|
-
|
|
4308
|
-
}
|
|
4411
|
+
};
|
|
4309
4412
|
|
|
4310
|
-
const
|
|
4311
|
-
|
|
4312
|
-
|
|
4413
|
+
const selectTabChangelog = async state => {
|
|
4414
|
+
const {
|
|
4415
|
+
baseUrl,
|
|
4416
|
+
extension,
|
|
4417
|
+
locationProtocol,
|
|
4418
|
+
tabs
|
|
4419
|
+
} = state;
|
|
4420
|
+
const changelogContent = await loadChangelogContent(extension.path); // TODO use uri
|
|
4421
|
+
const changelogMarkdownHtml = await renderMarkdown(changelogContent, {
|
|
4422
|
+
baseUrl,
|
|
4423
|
+
locationProtocol
|
|
4313
4424
|
});
|
|
4425
|
+
const changelogDom = await getMarkdownVirtualDom(changelogMarkdownHtml);
|
|
4426
|
+
const newTabs = tabs.map(tab => {
|
|
4427
|
+
return {
|
|
4428
|
+
...tab,
|
|
4429
|
+
selected: tab.name === Changelog
|
|
4430
|
+
};
|
|
4431
|
+
});
|
|
4432
|
+
return {
|
|
4433
|
+
...state,
|
|
4434
|
+
changelogVirtualDom: changelogDom,
|
|
4435
|
+
selectedTab: Changelog,
|
|
4436
|
+
tabs: newTabs
|
|
4437
|
+
};
|
|
4314
4438
|
};
|
|
4315
4439
|
|
|
4316
|
-
const
|
|
4317
|
-
|
|
4318
|
-
return false;
|
|
4319
|
-
}
|
|
4320
|
-
return true;
|
|
4440
|
+
const selectTabDefault = async state => {
|
|
4441
|
+
return state;
|
|
4321
4442
|
};
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4443
|
+
|
|
4444
|
+
const selectTabDetails = async state => {
|
|
4445
|
+
const {
|
|
4446
|
+
baseUrl,
|
|
4447
|
+
locationProtocol,
|
|
4448
|
+
readmeUrl,
|
|
4449
|
+
tabs
|
|
4450
|
+
} = state;
|
|
4451
|
+
const readmeContent = await loadReadmeContent(readmeUrl);
|
|
4452
|
+
const readmeHtml = await renderMarkdown(readmeContent, {
|
|
4453
|
+
baseUrl,
|
|
4454
|
+
linksExternal: true,
|
|
4455
|
+
locationProtocol
|
|
4456
|
+
});
|
|
4457
|
+
const detailsDom = await getMarkdownVirtualDom(readmeHtml);
|
|
4458
|
+
const newTabs = tabs.map(tab => {
|
|
4459
|
+
return {
|
|
4460
|
+
...tab,
|
|
4461
|
+
selected: tab.name === Details
|
|
4462
|
+
};
|
|
4463
|
+
});
|
|
4464
|
+
return {
|
|
4465
|
+
...state,
|
|
4466
|
+
detailsVirtualDom: detailsDom,
|
|
4467
|
+
selectedTab: Details,
|
|
4468
|
+
tabs: newTabs
|
|
4469
|
+
};
|
|
4470
|
+
};
|
|
4471
|
+
|
|
4472
|
+
const selectTabFeatures = async state => {
|
|
4473
|
+
const {
|
|
4474
|
+
baseUrl,
|
|
4475
|
+
extension,
|
|
4476
|
+
features,
|
|
4477
|
+
locationProtocol,
|
|
4478
|
+
selectedFeature,
|
|
4479
|
+
tabs
|
|
4480
|
+
} = state;
|
|
4481
|
+
if (features.length === 0) {
|
|
4482
|
+
return state;
|
|
4334
4483
|
}
|
|
4484
|
+
const actualSelectedFeature = selectedFeature || Theme;
|
|
4485
|
+
const fn = getFeatureDetailsHandler(actualSelectedFeature);
|
|
4486
|
+
const partialNewState = await fn(extension, baseUrl, locationProtocol);
|
|
4487
|
+
const newTabs = tabs.map(tab => {
|
|
4488
|
+
return {
|
|
4489
|
+
...tab,
|
|
4490
|
+
selected: tab.name === Features
|
|
4491
|
+
};
|
|
4492
|
+
});
|
|
4493
|
+
const newFeatures = features.map(feature => {
|
|
4494
|
+
if (feature.id === actualSelectedFeature) {
|
|
4495
|
+
return {
|
|
4496
|
+
...feature,
|
|
4497
|
+
selected: true
|
|
4498
|
+
};
|
|
4499
|
+
}
|
|
4500
|
+
return {
|
|
4501
|
+
...feature,
|
|
4502
|
+
selected: false
|
|
4503
|
+
};
|
|
4504
|
+
});
|
|
4505
|
+
return {
|
|
4506
|
+
...state,
|
|
4507
|
+
...partialNewState,
|
|
4508
|
+
features: newFeatures,
|
|
4509
|
+
selectedFeature: features[0].id || '',
|
|
4510
|
+
selectedTab: Features,
|
|
4511
|
+
tabs: newTabs
|
|
4512
|
+
};
|
|
4335
4513
|
};
|
|
4336
4514
|
|
|
4337
|
-
const
|
|
4338
|
-
|
|
4339
|
-
|
|
4515
|
+
const getSelectTabHandler = name => {
|
|
4516
|
+
switch (name) {
|
|
4517
|
+
case Changelog:
|
|
4518
|
+
return selectTabChangelog;
|
|
4519
|
+
case Details:
|
|
4520
|
+
return selectTabDetails;
|
|
4521
|
+
case Features:
|
|
4522
|
+
return selectTabFeatures;
|
|
4523
|
+
default:
|
|
4524
|
+
return selectTabDefault;
|
|
4340
4525
|
}
|
|
4341
|
-
return [{
|
|
4342
|
-
key: published(),
|
|
4343
|
-
odd: true,
|
|
4344
|
-
value: 'n/a'
|
|
4345
|
-
}, {
|
|
4346
|
-
key: lastReleased(),
|
|
4347
|
-
value: 'n/a'
|
|
4348
|
-
}];
|
|
4349
4526
|
};
|
|
4350
4527
|
|
|
4351
|
-
const
|
|
4352
|
-
|
|
4353
|
-
return
|
|
4528
|
+
const selectTab = (state, name) => {
|
|
4529
|
+
const fn = getSelectTabHandler(name);
|
|
4530
|
+
return fn(state);
|
|
4354
4531
|
};
|
|
4355
4532
|
|
|
4356
|
-
const
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
}
|
|
4367
|
-
|
|
4368
|
-
|
|
4533
|
+
const handleTabsClick = (state, name) => {
|
|
4534
|
+
return selectTab(state, name);
|
|
4535
|
+
};
|
|
4536
|
+
|
|
4537
|
+
const hideSizeLink = state => {
|
|
4538
|
+
const {
|
|
4539
|
+
displaySize,
|
|
4540
|
+
extensionId,
|
|
4541
|
+
extensionUri,
|
|
4542
|
+
extensionVersion
|
|
4543
|
+
} = state;
|
|
4544
|
+
const newShowSizeLink = false;
|
|
4545
|
+
const installationEntries = getInstallationEntries(displaySize, extensionId, extensionVersion, extensionUri, newShowSizeLink);
|
|
4546
|
+
return {
|
|
4547
|
+
...state,
|
|
4548
|
+
installationEntries,
|
|
4549
|
+
showSizeLink: newShowSizeLink
|
|
4550
|
+
};
|
|
4551
|
+
};
|
|
4552
|
+
|
|
4553
|
+
const sendMessagePortToExtensionHostWorker = async port => {
|
|
4554
|
+
await sendMessagePortToExtensionHostWorker$1(port, 0);
|
|
4369
4555
|
};
|
|
4370
4556
|
|
|
4371
|
-
const
|
|
4372
|
-
|
|
4373
|
-
|
|
4557
|
+
const createExtensionHostWorkerRpc = async () => {
|
|
4558
|
+
try {
|
|
4559
|
+
const rpc = await TransferMessagePortRpcParent.create({
|
|
4560
|
+
commandMap: {},
|
|
4561
|
+
send: sendMessagePortToExtensionHostWorker
|
|
4562
|
+
});
|
|
4563
|
+
return rpc;
|
|
4564
|
+
} catch (error) {
|
|
4565
|
+
throw new VError(error, `Failed to create extension host rpc`);
|
|
4374
4566
|
}
|
|
4375
|
-
return '';
|
|
4376
4567
|
};
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
const
|
|
4380
|
-
|
|
4568
|
+
|
|
4569
|
+
const initializeExtensionHostWorker = async () => {
|
|
4570
|
+
const rpc = await createExtensionHostWorkerRpc();
|
|
4571
|
+
set$4(rpc);
|
|
4381
4572
|
};
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4573
|
+
|
|
4574
|
+
const createExtensionManagementWorkerRpc = async () => {
|
|
4575
|
+
try {
|
|
4576
|
+
const rpc = await TransferMessagePortRpcParent.create({
|
|
4577
|
+
commandMap: {},
|
|
4578
|
+
send: port => sendMessagePortToExtensionManagementWorker(port, 0)
|
|
4579
|
+
});
|
|
4580
|
+
return rpc;
|
|
4581
|
+
} catch (error) {
|
|
4582
|
+
throw new VError(error, `Failed to create extension management rpc`);
|
|
4389
4583
|
}
|
|
4390
|
-
return '';
|
|
4391
4584
|
};
|
|
4392
4585
|
|
|
4393
|
-
const
|
|
4394
|
-
|
|
4395
|
-
|
|
4586
|
+
const initializeExtensionManagementWorker = async () => {
|
|
4587
|
+
try {
|
|
4588
|
+
const rpc = await createExtensionManagementWorkerRpc();
|
|
4589
|
+
set$8(rpc);
|
|
4590
|
+
} catch {
|
|
4591
|
+
// ignore
|
|
4396
4592
|
}
|
|
4397
|
-
const repositoryLink = getRepositoryLink(extension);
|
|
4398
|
-
const issueLink = getIssuesLink(extension);
|
|
4399
|
-
const licenseLink = getLicenseLink();
|
|
4400
|
-
// TODO
|
|
4401
|
-
return [{
|
|
4402
|
-
icon: 'LinkExternal',
|
|
4403
|
-
label: marketplace(),
|
|
4404
|
-
url: '#'
|
|
4405
|
-
}, {
|
|
4406
|
-
icon: 'LinkExternal',
|
|
4407
|
-
label: issues(),
|
|
4408
|
-
url: issueLink
|
|
4409
|
-
}, {
|
|
4410
|
-
icon: 'Repo',
|
|
4411
|
-
label: repository(),
|
|
4412
|
-
url: repositoryLink
|
|
4413
|
-
}, {
|
|
4414
|
-
icon: 'LinkExternal',
|
|
4415
|
-
label: license(),
|
|
4416
|
-
url: licenseLink
|
|
4417
|
-
}];
|
|
4418
4593
|
};
|
|
4419
4594
|
|
|
4420
|
-
const
|
|
4421
|
-
|
|
4422
|
-
const displaySize = getDisplaySize(folderSize);
|
|
4423
|
-
const installationEntries = getInstallationEntries(displaySize, extensionId, extensionVersion, extensionUri, showSizeLink);
|
|
4424
|
-
const marketplaceEntries = getMarketplaceEntries(isBuiltin);
|
|
4425
|
-
const categories = getCategories(extension);
|
|
4426
|
-
const resources = getResources(isBuiltin, extension);
|
|
4427
|
-
return {
|
|
4428
|
-
categories,
|
|
4429
|
-
displaySize,
|
|
4430
|
-
folderSize,
|
|
4431
|
-
installationEntries,
|
|
4432
|
-
marketplaceEntries,
|
|
4433
|
-
resources
|
|
4434
|
-
};
|
|
4595
|
+
const sendMessagePortToFileSystemWorker = async port => {
|
|
4596
|
+
await sendMessagePortToFileSystemWorker$1(port, 0);
|
|
4435
4597
|
};
|
|
4436
4598
|
|
|
4437
|
-
const
|
|
4438
|
-
|
|
4439
|
-
|
|
4599
|
+
const createFileSystemWorkerRpc = async () => {
|
|
4600
|
+
try {
|
|
4601
|
+
const rpc = await TransferMessagePortRpcParent.create({
|
|
4602
|
+
commandMap: {},
|
|
4603
|
+
send: sendMessagePortToFileSystemWorker
|
|
4604
|
+
});
|
|
4605
|
+
return rpc;
|
|
4606
|
+
} catch (error) {
|
|
4607
|
+
throw new VError(error, `Failed to create file system worker rpc`);
|
|
4440
4608
|
}
|
|
4441
|
-
return 0;
|
|
4442
4609
|
};
|
|
4443
4610
|
|
|
4444
|
-
const
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
}
|
|
4448
|
-
return 0;
|
|
4611
|
+
const initializeFileSystemWorker = async () => {
|
|
4612
|
+
const rpc = await createFileSystemWorkerRpc();
|
|
4613
|
+
set$1(rpc);
|
|
4449
4614
|
};
|
|
4450
4615
|
|
|
4451
|
-
const
|
|
4452
|
-
|
|
4453
|
-
return savedState.selectedFeature;
|
|
4454
|
-
}
|
|
4455
|
-
return Details;
|
|
4616
|
+
const sendMessagePortToMarkdownWorker = async port => {
|
|
4617
|
+
await sendMessagePortToMarkdownWorker$1(port, 0);
|
|
4456
4618
|
};
|
|
4457
4619
|
|
|
4458
|
-
const
|
|
4459
|
-
|
|
4460
|
-
|
|
4620
|
+
const createMarkdownWorkerRpc = async () => {
|
|
4621
|
+
try {
|
|
4622
|
+
const rpc = await TransferMessagePortRpcParent.create({
|
|
4623
|
+
commandMap: {},
|
|
4624
|
+
send: sendMessagePortToMarkdownWorker
|
|
4625
|
+
});
|
|
4626
|
+
return rpc;
|
|
4627
|
+
} catch (error) {
|
|
4628
|
+
throw new VError(error, `Failed to create markdown worker rpc`);
|
|
4461
4629
|
}
|
|
4462
|
-
return Details;
|
|
4463
4630
|
};
|
|
4464
4631
|
|
|
4465
|
-
const
|
|
4466
|
-
const
|
|
4467
|
-
|
|
4468
|
-
const readmeScrollTop = getSavedReadmeScrollTop(savedState);
|
|
4469
|
-
const changelogScrollTop = getSavedChangelogScrollTop(savedState);
|
|
4470
|
-
return {
|
|
4471
|
-
changelogScrollTop,
|
|
4472
|
-
readmeScrollTop,
|
|
4473
|
-
selectedFeature,
|
|
4474
|
-
selectedTab
|
|
4475
|
-
};
|
|
4632
|
+
const initializeMarkdownWorker = async () => {
|
|
4633
|
+
const rpc = await createMarkdownWorkerRpc();
|
|
4634
|
+
set$3(rpc);
|
|
4476
4635
|
};
|
|
4477
4636
|
|
|
4478
|
-
const
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
const loadContent = async (state, platform, savedState, isTest = false) => {
|
|
4482
|
-
if (isTest) {
|
|
4483
|
-
savedState = undefined;
|
|
4484
|
-
}
|
|
4485
|
-
const {
|
|
4486
|
-
uri,
|
|
4487
|
-
width
|
|
4488
|
-
} = state;
|
|
4489
|
-
const id = getExtensionIdFromUri(uri);
|
|
4490
|
-
const extension = await getExtension(id, platform);
|
|
4491
|
-
if (!extension) {
|
|
4492
|
-
throw new ExtensionNotFoundError(id);
|
|
4493
|
-
}
|
|
4494
|
-
const commit = await getCommit();
|
|
4495
|
-
const headerData = loadHeaderContent(state, platform, extension);
|
|
4496
|
-
const {
|
|
4497
|
-
badge,
|
|
4498
|
-
description,
|
|
4499
|
-
downloadCount,
|
|
4500
|
-
extensionId,
|
|
4501
|
-
extensionUri,
|
|
4502
|
-
extensionVersion,
|
|
4503
|
-
hasColorTheme,
|
|
4504
|
-
iconSrc,
|
|
4505
|
-
name,
|
|
4506
|
-
rating
|
|
4507
|
-
} = headerData;
|
|
4508
|
-
const readmeUrl = join(extensionUri, 'README.md');
|
|
4509
|
-
const changelogUrl = join(extensionUri, 'CHANGELOG.md');
|
|
4510
|
-
const [hasReadme, hasChangelog] = await Promise.all([existsFile(readmeUrl), existsFile(changelogUrl)]);
|
|
4511
|
-
const readmeContent = hasReadme ? await loadReadmeContent(readmeUrl) : noReadmeFound();
|
|
4512
|
-
const baseUrl = getBaseUrl(extension.path, platform);
|
|
4513
|
-
const locationProtocol = location.protocol;
|
|
4514
|
-
const locationHost = location.host;
|
|
4515
|
-
const readmeHtml = await renderMarkdown(readmeContent, {
|
|
4516
|
-
baseUrl,
|
|
4517
|
-
commit,
|
|
4518
|
-
linksExternal: true,
|
|
4519
|
-
locationProtocol
|
|
4520
|
-
});
|
|
4521
|
-
const detailsVirtualDom = await getMarkdownVirtualDom(readmeHtml, {
|
|
4522
|
-
scrollToTopEnabled: true
|
|
4523
|
-
});
|
|
4524
|
-
const isBuiltin = extension?.isBuiltin;
|
|
4525
|
-
const disabled = extension?.disabled;
|
|
4526
|
-
const buttons = getExtensionDetailButtons(hasColorTheme, isBuiltin, disabled);
|
|
4527
|
-
const size = getViewletSize(width);
|
|
4528
|
-
const {
|
|
4529
|
-
changelogScrollTop,
|
|
4530
|
-
readmeScrollTop,
|
|
4531
|
-
selectedFeature,
|
|
4532
|
-
selectedTab
|
|
4533
|
-
} = restoreState(savedState);
|
|
4534
|
-
const features = getFeatures(selectedFeature || Theme, extension);
|
|
4535
|
-
const hasFeatures = features.length > 0;
|
|
4536
|
-
const tabs = getTabs(selectedTab, hasReadme, hasFeatures, hasChangelog);
|
|
4537
|
-
const enabledTabs = tabs.filter(isEnabled);
|
|
4538
|
-
const sizeValue = getViewletSize(width || 0);
|
|
4539
|
-
const showSizeLink = platform !== Web$1;
|
|
4540
|
-
const {
|
|
4541
|
-
categories,
|
|
4542
|
-
displaySize,
|
|
4543
|
-
folderSize,
|
|
4544
|
-
installationEntries,
|
|
4545
|
-
marketplaceEntries,
|
|
4546
|
-
resources
|
|
4547
|
-
} = await loadSideBarContent(extensionId, extensionVersion, extensionUri, isBuiltin, extension, showSizeLink);
|
|
4548
|
-
const padding = getPadding(width);
|
|
4549
|
-
const sideBarWidth = getSideBarWidth(width);
|
|
4550
|
-
const showSideBar = sideBarWidth > 0;
|
|
4551
|
-
return {
|
|
4552
|
-
...state,
|
|
4553
|
-
badge,
|
|
4554
|
-
baseUrl,
|
|
4555
|
-
buttons,
|
|
4556
|
-
categories,
|
|
4557
|
-
changelogScrollTop,
|
|
4558
|
-
commit,
|
|
4559
|
-
description,
|
|
4560
|
-
detailsVirtualDom,
|
|
4561
|
-
disabled,
|
|
4562
|
-
displaySize,
|
|
4563
|
-
downloadCount,
|
|
4564
|
-
extension,
|
|
4565
|
-
extensionId,
|
|
4566
|
-
extensionUri,
|
|
4567
|
-
extensionVersion,
|
|
4568
|
-
features,
|
|
4569
|
-
folderSize,
|
|
4570
|
-
hasColorTheme,
|
|
4571
|
-
hasReadme,
|
|
4572
|
-
iconSrc,
|
|
4573
|
-
installationEntries,
|
|
4574
|
-
locationHost,
|
|
4575
|
-
locationProtocol,
|
|
4576
|
-
marketplaceEntries,
|
|
4577
|
-
name,
|
|
4578
|
-
paddingLeft: padding,
|
|
4579
|
-
paddingRight: padding,
|
|
4580
|
-
rating,
|
|
4581
|
-
readmeScrollTop,
|
|
4582
|
-
readmeUrl,
|
|
4583
|
-
resources,
|
|
4584
|
-
scrollSource: Script,
|
|
4585
|
-
scrollToTopButtonEnabled: true,
|
|
4586
|
-
selectedTab,
|
|
4587
|
-
showSideBar,
|
|
4588
|
-
showSizeLink,
|
|
4589
|
-
sideBarWidth,
|
|
4590
|
-
sizeOnDisk: size,
|
|
4591
|
-
sizeValue,
|
|
4592
|
-
tabs: enabledTabs
|
|
4593
|
-
};
|
|
4637
|
+
const initialize = async () => {
|
|
4638
|
+
// TODO load markdown worker only when needed
|
|
4639
|
+
await Promise.all([initializeMarkdownWorker(), initializeFileSystemWorker(), initializeExtensionHostWorker(), initializeExtensionManagementWorker()]);
|
|
4594
4640
|
};
|
|
4595
4641
|
|
|
4596
4642
|
const loadContent2 = async (state, savedState, isTest = false) => {
|
|
@@ -4947,10 +4993,11 @@ const getExtensionDetailDescriptionVirtualDom = description => {
|
|
|
4947
4993
|
}, text(description)];
|
|
4948
4994
|
};
|
|
4949
4995
|
|
|
4996
|
+
const className = mergeClassNames(Button, ButtonPrimary);
|
|
4950
4997
|
const getButtonVirtualDom = (message, onClick, name) => {
|
|
4951
4998
|
return [{
|
|
4952
4999
|
childCount: 1,
|
|
4953
|
-
className
|
|
5000
|
+
className,
|
|
4954
5001
|
name,
|
|
4955
5002
|
onClick,
|
|
4956
5003
|
type: Button$1
|
|
@@ -5218,6 +5265,9 @@ const renderEventListeners = () => {
|
|
|
5218
5265
|
}, {
|
|
5219
5266
|
name: HandleClickDisable,
|
|
5220
5267
|
params: ['handleClickDisable']
|
|
5268
|
+
}, {
|
|
5269
|
+
name: HandleClickEnable,
|
|
5270
|
+
params: ['handleClickEnable']
|
|
5221
5271
|
}, {
|
|
5222
5272
|
name: HandleClickScrollToTop,
|
|
5223
5273
|
params: ['handleClickScrollToTop'],
|
|
@@ -5292,6 +5342,7 @@ const commandMap = {
|
|
|
5292
5342
|
'ExtensionDetail.handleClickSettings': wrapCommand(handleClickSettings),
|
|
5293
5343
|
'ExtensionDetail.handleClickSize': wrapCommand(handleClickSize),
|
|
5294
5344
|
'ExtensionDetail.handleClickUninstall': wrapCommand(handleClickUninstall),
|
|
5345
|
+
'ExtensionDetail.handleExtensionsChanged': wrapCommand(handleExtensionsChanged),
|
|
5295
5346
|
'ExtensionDetail.handleExtensionsStatusUpdate': wrapCommand(handleExtensionsStatusUpdate),
|
|
5296
5347
|
'ExtensionDetail.handleFeaturesClick': wrapCommand(handleClickFeatures),
|
|
5297
5348
|
'ExtensionDetail.handleIconError': wrapCommand(handleIconError),
|