@lvce-editor/extension-search-view 7.13.1 → 7.13.3
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/extensionSearchViewWorkerMain.js +485 -389
- package/package.json +1 -1
|
@@ -1014,6 +1014,34 @@ const listen$1 = async (module, options) => {
|
|
|
1014
1014
|
return ipc;
|
|
1015
1015
|
};
|
|
1016
1016
|
|
|
1017
|
+
const createSharedLazyRpc = factory => {
|
|
1018
|
+
let rpcPromise;
|
|
1019
|
+
const getOrCreate = () => {
|
|
1020
|
+
if (!rpcPromise) {
|
|
1021
|
+
rpcPromise = factory();
|
|
1022
|
+
}
|
|
1023
|
+
return rpcPromise;
|
|
1024
|
+
};
|
|
1025
|
+
return {
|
|
1026
|
+
async dispose() {
|
|
1027
|
+
const rpc = await getOrCreate();
|
|
1028
|
+
await rpc.dispose();
|
|
1029
|
+
},
|
|
1030
|
+
async invoke(method, ...params) {
|
|
1031
|
+
const rpc = await getOrCreate();
|
|
1032
|
+
return rpc.invoke(method, ...params);
|
|
1033
|
+
},
|
|
1034
|
+
async invokeAndTransfer(method, ...params) {
|
|
1035
|
+
const rpc = await getOrCreate();
|
|
1036
|
+
return rpc.invokeAndTransfer(method, ...params);
|
|
1037
|
+
},
|
|
1038
|
+
async send(method, ...params) {
|
|
1039
|
+
const rpc = await getOrCreate();
|
|
1040
|
+
rpc.send(method, ...params);
|
|
1041
|
+
}
|
|
1042
|
+
};
|
|
1043
|
+
};
|
|
1044
|
+
|
|
1017
1045
|
const create$7 = async ({
|
|
1018
1046
|
commandMap,
|
|
1019
1047
|
isMessagePortOpen = true,
|
|
@@ -1049,34 +1077,6 @@ const create$6 = async ({
|
|
|
1049
1077
|
});
|
|
1050
1078
|
};
|
|
1051
1079
|
|
|
1052
|
-
const createSharedLazyRpc = factory => {
|
|
1053
|
-
let rpcPromise;
|
|
1054
|
-
const getOrCreate = () => {
|
|
1055
|
-
if (!rpcPromise) {
|
|
1056
|
-
rpcPromise = factory();
|
|
1057
|
-
}
|
|
1058
|
-
return rpcPromise;
|
|
1059
|
-
};
|
|
1060
|
-
return {
|
|
1061
|
-
async dispose() {
|
|
1062
|
-
const rpc = await getOrCreate();
|
|
1063
|
-
await rpc.dispose();
|
|
1064
|
-
},
|
|
1065
|
-
async invoke(method, ...params) {
|
|
1066
|
-
const rpc = await getOrCreate();
|
|
1067
|
-
return rpc.invoke(method, ...params);
|
|
1068
|
-
},
|
|
1069
|
-
async invokeAndTransfer(method, ...params) {
|
|
1070
|
-
const rpc = await getOrCreate();
|
|
1071
|
-
return rpc.invokeAndTransfer(method, ...params);
|
|
1072
|
-
},
|
|
1073
|
-
async send(method, ...params) {
|
|
1074
|
-
const rpc = await getOrCreate();
|
|
1075
|
-
rpc.send(method, ...params);
|
|
1076
|
-
}
|
|
1077
|
-
};
|
|
1078
|
-
};
|
|
1079
|
-
|
|
1080
1080
|
const create$5 = async ({
|
|
1081
1081
|
commandMap,
|
|
1082
1082
|
isMessagePortOpen,
|
|
@@ -1375,6 +1375,9 @@ const {
|
|
|
1375
1375
|
invoke: invoke$1,
|
|
1376
1376
|
set: set$2
|
|
1377
1377
|
} = create$3(ExtensionManagementWorker);
|
|
1378
|
+
const disableWorkspace$2 = id => {
|
|
1379
|
+
return invoke$1('Extensions.disableWorkspace', id);
|
|
1380
|
+
};
|
|
1378
1381
|
|
|
1379
1382
|
const {
|
|
1380
1383
|
invoke,
|
|
@@ -1406,7 +1409,11 @@ const sendMessagePortToExtensionManagementWorker = async (port, rpcId) => {
|
|
|
1406
1409
|
await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionManagementWorker', port, command, rpcId);
|
|
1407
1410
|
};
|
|
1408
1411
|
const openUri$1 = async (uri, focus, options) => {
|
|
1409
|
-
await invoke('Main.openUri',
|
|
1412
|
+
await invoke('Main.openUri', {
|
|
1413
|
+
...options,
|
|
1414
|
+
focus,
|
|
1415
|
+
uri
|
|
1416
|
+
});
|
|
1410
1417
|
};
|
|
1411
1418
|
const showErrorDialog = async errorInfo => {
|
|
1412
1419
|
await invoke('ErrorHandling.showErrorDialog', errorInfo);
|
|
@@ -1668,8 +1675,9 @@ const None$2 = 0;
|
|
|
1668
1675
|
const Input = 1;
|
|
1669
1676
|
const List$2 = 2;
|
|
1670
1677
|
|
|
1678
|
+
const RE_WHITESPACE$1 = /\s/;
|
|
1671
1679
|
const isWhiteSpace = character => {
|
|
1672
|
-
return
|
|
1680
|
+
return RE_WHITESPACE$1.test(character);
|
|
1673
1681
|
};
|
|
1674
1682
|
const getCompletionRange = (value, cursorOffset) => {
|
|
1675
1683
|
const offset = Math.min(Math.max(cursorOffset, 0), value.length);
|
|
@@ -2016,6 +2024,7 @@ const Recommended = '@recommended';
|
|
|
2016
2024
|
const WorkspaceUnsupported = '@workspaceunsupported';
|
|
2017
2025
|
const Deprecated = '@deprecated';
|
|
2018
2026
|
|
|
2027
|
+
const RE_LEADING_COLON = /^:/;
|
|
2019
2028
|
const RE_PARAM = /@[\w-]+(?::\w+)?/g;
|
|
2020
2029
|
const deserializeCategory = value => {
|
|
2021
2030
|
if (value.startsWith(':"') && value.endsWith('"')) {
|
|
@@ -2064,7 +2073,7 @@ const parseValue = value => {
|
|
|
2064
2073
|
sort = 'installs';
|
|
2065
2074
|
} else {
|
|
2066
2075
|
// Handle cases like @sort:installs or @sortsize (without colon)
|
|
2067
|
-
sort = sortValue.replace(
|
|
2076
|
+
sort = sortValue.replace(RE_LEADING_COLON, '');
|
|
2068
2077
|
}
|
|
2069
2078
|
}
|
|
2070
2079
|
if (match.startsWith(Id)) {
|
|
@@ -2294,8 +2303,9 @@ const handleChange = async (state, update) => {
|
|
|
2294
2303
|
const User = 1;
|
|
2295
2304
|
const Script = 2;
|
|
2296
2305
|
|
|
2306
|
+
const RE_WHITESPACE = /\s/;
|
|
2297
2307
|
const getCompletionText = (searchValue, completion, rangeEnd) => {
|
|
2298
|
-
const hasTrailingWhitespace =
|
|
2308
|
+
const hasTrailingWhitespace = RE_WHITESPACE.test(searchValue[rangeEnd] || '');
|
|
2299
2309
|
return completion.endsWith(':') || hasTrailingWhitespace ? completion : `${completion} `;
|
|
2300
2310
|
};
|
|
2301
2311
|
const acceptCompletionWithContext = async (context, label) => {
|
|
@@ -2535,14 +2545,55 @@ const diff2 = uid => {
|
|
|
2535
2545
|
return diff(uid, modules, numbers);
|
|
2536
2546
|
};
|
|
2537
2547
|
|
|
2538
|
-
const
|
|
2539
|
-
|
|
2540
|
-
|
|
2548
|
+
const Disabled$1 = 'disabled';
|
|
2549
|
+
const Enabled = 'enabled';
|
|
2550
|
+
const Installing = 'installing';
|
|
2551
|
+
const NotInstalled = 'not-installed';
|
|
2552
|
+
const Uninstalling = 'uninstalling';
|
|
2553
|
+
const statuses = [Disabled$1, Enabled, Installing, NotInstalled, Uninstalling];
|
|
2554
|
+
const isExtensionStatus = status => {
|
|
2555
|
+
return statuses.includes(status);
|
|
2541
2556
|
};
|
|
2542
2557
|
|
|
2543
|
-
const
|
|
2544
|
-
|
|
2545
|
-
|
|
2558
|
+
const updateStatus = (extension, id, status, builtin) => {
|
|
2559
|
+
if (extension.id !== id) {
|
|
2560
|
+
return extension;
|
|
2561
|
+
}
|
|
2562
|
+
return {
|
|
2563
|
+
...extension,
|
|
2564
|
+
builtin: builtin ?? extension.builtin,
|
|
2565
|
+
disabled: status === Disabled$1,
|
|
2566
|
+
status
|
|
2567
|
+
};
|
|
2568
|
+
};
|
|
2569
|
+
const setExtensionStatus = (state, id, status, builtin) => {
|
|
2570
|
+
if (!isExtensionStatus(status)) {
|
|
2571
|
+
throw new TypeError(`Invalid extension status: ${status}`);
|
|
2572
|
+
}
|
|
2573
|
+
return {
|
|
2574
|
+
...state,
|
|
2575
|
+
allExtensions: state.allExtensions.map(extension => updateStatus(extension, id, status, builtin)),
|
|
2576
|
+
items: state.items.map(extension => updateStatus(extension, id, status, builtin))
|
|
2577
|
+
};
|
|
2578
|
+
};
|
|
2579
|
+
|
|
2580
|
+
const handleDisable = async (state, id) => {
|
|
2581
|
+
const error = await disableExtension(id);
|
|
2582
|
+
return error ? state : setExtensionStatus(state, id, Disabled$1);
|
|
2583
|
+
};
|
|
2584
|
+
|
|
2585
|
+
const disable$1 = async state => {
|
|
2586
|
+
const item = getFocusedItem(state);
|
|
2587
|
+
return item ? handleDisable(state, item.id) : state;
|
|
2588
|
+
};
|
|
2589
|
+
|
|
2590
|
+
const disableWorkspace = async state => {
|
|
2591
|
+
const item = getFocusedItem(state);
|
|
2592
|
+
if (!item) {
|
|
2593
|
+
return state;
|
|
2594
|
+
}
|
|
2595
|
+
await disableWorkspace$2(item.id);
|
|
2596
|
+
return setExtensionStatus(state, item.id, Disabled$1);
|
|
2546
2597
|
};
|
|
2547
2598
|
|
|
2548
2599
|
const dispose = uid => {
|
|
@@ -2550,14 +2601,23 @@ const dispose = uid => {
|
|
|
2550
2601
|
dispose$1(uid);
|
|
2551
2602
|
};
|
|
2552
2603
|
|
|
2553
|
-
const
|
|
2554
|
-
|
|
2555
|
-
return state;
|
|
2604
|
+
const handleEnable = async (state, id) => {
|
|
2605
|
+
const error = await enableExtension(id);
|
|
2606
|
+
return error ? state : setExtensionStatus(state, id, Enabled);
|
|
2556
2607
|
};
|
|
2557
2608
|
|
|
2558
|
-
const
|
|
2559
|
-
|
|
2560
|
-
return state;
|
|
2609
|
+
const enable$1 = async state => {
|
|
2610
|
+
const item = getFocusedItem(state);
|
|
2611
|
+
return item ? handleEnable(state, item.id) : state;
|
|
2612
|
+
};
|
|
2613
|
+
|
|
2614
|
+
const enableWorkspace = async state => {
|
|
2615
|
+
const item = getFocusedItem(state);
|
|
2616
|
+
if (!item) {
|
|
2617
|
+
return state;
|
|
2618
|
+
}
|
|
2619
|
+
await invoke$1('Extensions.enableWorkspace', item.id);
|
|
2620
|
+
return setExtensionStatus(state, item.id, Enabled);
|
|
2561
2621
|
};
|
|
2562
2622
|
|
|
2563
2623
|
const CategorySuggestions = ['@category:"ai"', '@category:"azure"', '@category:"chat"', '@category:"data science"', '@category:"debuggers"', '@category:"education"', '@category:"extension packs"', '@category:"formatters"', '@category:"keymaps"', '@category:"language packs"', '@category:"linters"', '@category:"machine learning"', '@category:"notebooks"', '@category:"other"', '@category:"programming languages"', '@category:"scm providers"', '@category:"snippets"', '@category:"testing"', '@category:"themes"', '@category:"visualization"'];
|
|
@@ -2621,20 +2681,26 @@ const handleInputWithContext = async (context, value, inputSource = User, cursor
|
|
|
2621
2681
|
});
|
|
2622
2682
|
};
|
|
2623
2683
|
|
|
2684
|
+
const RE_WHITESPACE_SEQUENCE = /\s+/;
|
|
2624
2685
|
const addFilter = (searchValue, filter) => {
|
|
2625
|
-
const values = searchValue.trim().split(
|
|
2686
|
+
const values = searchValue.trim().split(RE_WHITESPACE_SEQUENCE);
|
|
2626
2687
|
if (values.includes(filter)) {
|
|
2627
2688
|
return searchValue;
|
|
2628
2689
|
}
|
|
2629
2690
|
return `${searchValue.trim()} ${filter}`.trim();
|
|
2630
2691
|
};
|
|
2631
|
-
const
|
|
2692
|
+
const filterByValueWithContext = async (context, filter) => {
|
|
2632
2693
|
const {
|
|
2633
2694
|
searchValue
|
|
2634
2695
|
} = context.getState();
|
|
2635
|
-
const value = addFilter(searchValue,
|
|
2696
|
+
const value = addFilter(searchValue, filter);
|
|
2636
2697
|
await handleInputWithContext(context, value, Script);
|
|
2637
2698
|
};
|
|
2699
|
+
const createFilterCommand = filter => {
|
|
2700
|
+
return context => filterByValueWithContext(context, filter);
|
|
2701
|
+
};
|
|
2702
|
+
|
|
2703
|
+
const filterByMostPopularWithContext = createFilterCommand(MostPopular);
|
|
2638
2704
|
|
|
2639
2705
|
// TODO optimize this function to return the minimum number
|
|
2640
2706
|
// of visible items needed, e.g. when not scrolled 5 items with
|
|
@@ -2899,16 +2965,6 @@ const getKeyBindings = () => {
|
|
|
2899
2965
|
}];
|
|
2900
2966
|
};
|
|
2901
2967
|
|
|
2902
|
-
const Disabled$1 = 'disabled';
|
|
2903
|
-
const Enabled = 'enabled';
|
|
2904
|
-
const Installing = 'installing';
|
|
2905
|
-
const NotInstalled = 'not-installed';
|
|
2906
|
-
const Uninstalling = 'uninstalling';
|
|
2907
|
-
const statuses = [Disabled$1, Enabled, Installing, NotInstalled, Uninstalling];
|
|
2908
|
-
const isExtensionStatus = status => {
|
|
2909
|
-
return statuses.includes(status);
|
|
2910
|
-
};
|
|
2911
|
-
|
|
2912
2968
|
const Separator = 1;
|
|
2913
2969
|
const None$1 = 0;
|
|
2914
2970
|
const SubMenu = 4;
|
|
@@ -2931,12 +2987,12 @@ const getEnablementFlags = (disabled, status) => {
|
|
|
2931
2987
|
const getMenuEntriesList = (builtin, disabled = false, status) => {
|
|
2932
2988
|
const enablementFlags = getEnablementFlags(disabled, status);
|
|
2933
2989
|
return [{
|
|
2934
|
-
command: '
|
|
2990
|
+
command: 'Extensions.enable',
|
|
2935
2991
|
flags: enablementFlags.enable,
|
|
2936
2992
|
id: 'enable',
|
|
2937
2993
|
label: enable$2()
|
|
2938
2994
|
}, {
|
|
2939
|
-
command: '
|
|
2995
|
+
command: 'Extensions.enableWorkspace',
|
|
2940
2996
|
flags: enablementFlags.enable,
|
|
2941
2997
|
id: 'enableWorkspace',
|
|
2942
2998
|
label: enableWorkspace$1()
|
|
@@ -2946,12 +3002,12 @@ const getMenuEntriesList = (builtin, disabled = false, status) => {
|
|
|
2946
3002
|
id: 'separator1',
|
|
2947
3003
|
label: ''
|
|
2948
3004
|
}, {
|
|
2949
|
-
command: '
|
|
3005
|
+
command: 'Extensions.disable',
|
|
2950
3006
|
flags: enablementFlags.disable,
|
|
2951
3007
|
id: 'disable',
|
|
2952
3008
|
label: disable$2()
|
|
2953
3009
|
}, {
|
|
2954
|
-
command: '
|
|
3010
|
+
command: 'Extensions.disableWorkspace',
|
|
2955
3011
|
flags: enablementFlags.disable,
|
|
2956
3012
|
id: 'disableWorkspace',
|
|
2957
3013
|
label: disableWorkspace$1()
|
|
@@ -2961,8 +3017,8 @@ const getMenuEntriesList = (builtin, disabled = false, status) => {
|
|
|
2961
3017
|
id: 'separator2',
|
|
2962
3018
|
label: ''
|
|
2963
3019
|
}, {
|
|
2964
|
-
command: '
|
|
2965
|
-
flags:
|
|
3020
|
+
command: 'Extensions.installAnotherVersion',
|
|
3021
|
+
flags: Disabled,
|
|
2966
3022
|
id: 'installAnotherVersion',
|
|
2967
3023
|
label: installAnotherVersion$1()
|
|
2968
3024
|
}, {
|
|
@@ -2980,12 +3036,12 @@ const getMenuEntriesList = (builtin, disabled = false, status) => {
|
|
|
2980
3036
|
|
|
2981
3037
|
const getMenuEntriesFilter = () => {
|
|
2982
3038
|
return [{
|
|
2983
|
-
command: '
|
|
3039
|
+
command: 'Extensions.filterByFeatured',
|
|
2984
3040
|
flags: None$1,
|
|
2985
3041
|
id: 'filterByFeatured',
|
|
2986
3042
|
label: featured()
|
|
2987
3043
|
}, {
|
|
2988
|
-
command: '
|
|
3044
|
+
command: 'Extensions.filterByMcpServers',
|
|
2989
3045
|
flags: None$1,
|
|
2990
3046
|
id: 'filterByMcpServers',
|
|
2991
3047
|
label: mcpServers()
|
|
@@ -2995,12 +3051,12 @@ const getMenuEntriesFilter = () => {
|
|
|
2995
3051
|
id: 'filterByMostPopular',
|
|
2996
3052
|
label: mostPopular()
|
|
2997
3053
|
}, {
|
|
2998
|
-
command: '
|
|
3054
|
+
command: 'Extensions.filterByRecentlyPublished',
|
|
2999
3055
|
flags: None$1,
|
|
3000
3056
|
id: 'filterByRecentlyPublished',
|
|
3001
3057
|
label: recentlyPublished()
|
|
3002
3058
|
}, {
|
|
3003
|
-
command: '
|
|
3059
|
+
command: 'Extensions.filterByRecommended',
|
|
3004
3060
|
flags: None$1,
|
|
3005
3061
|
id: 'filterByRecommended',
|
|
3006
3062
|
label: recommended()
|
|
@@ -3015,32 +3071,32 @@ const getMenuEntriesFilter = () => {
|
|
|
3015
3071
|
id: 'filterByCategory',
|
|
3016
3072
|
label: category()
|
|
3017
3073
|
}, {
|
|
3018
|
-
command: '
|
|
3074
|
+
command: 'Extensions.filterByInstalled',
|
|
3019
3075
|
flags: None$1,
|
|
3020
3076
|
id: 'filterByInstalled',
|
|
3021
3077
|
label: installed()
|
|
3022
3078
|
}, {
|
|
3023
|
-
command: '
|
|
3079
|
+
command: 'Extensions.filterByUpdates',
|
|
3024
3080
|
flags: None$1,
|
|
3025
3081
|
id: 'filterByUpdates',
|
|
3026
3082
|
label: updates()
|
|
3027
3083
|
}, {
|
|
3028
|
-
command: '
|
|
3084
|
+
command: 'Extensions.filterByBuiltin',
|
|
3029
3085
|
flags: None$1,
|
|
3030
3086
|
id: 'filterByBuiltin',
|
|
3031
3087
|
label: builtIn()
|
|
3032
3088
|
}, {
|
|
3033
|
-
command: '
|
|
3089
|
+
command: 'Extensions.filterByEnabled',
|
|
3034
3090
|
flags: None$1,
|
|
3035
3091
|
id: 'filterByEnabled',
|
|
3036
3092
|
label: enabled()
|
|
3037
3093
|
}, {
|
|
3038
|
-
command: '
|
|
3094
|
+
command: 'Extensions.filterByDisabled',
|
|
3039
3095
|
flags: None$1,
|
|
3040
3096
|
id: 'filterByDisabled',
|
|
3041
3097
|
label: disabled()
|
|
3042
3098
|
}, {
|
|
3043
|
-
command: '
|
|
3099
|
+
command: 'Extensions.filterByWorkspaceUnsupported',
|
|
3044
3100
|
flags: None$1,
|
|
3045
3101
|
id: 'filterByWorkspaceUnsupported',
|
|
3046
3102
|
label: workspaceUnsupported()
|
|
@@ -3212,14 +3268,11 @@ const compareNodes = (oldNode, newNode) => {
|
|
|
3212
3268
|
}
|
|
3213
3269
|
const patches = [];
|
|
3214
3270
|
// Handle reference nodes - special handling for uid changes
|
|
3215
|
-
if (oldNode.type === Reference) {
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
});
|
|
3221
|
-
}
|
|
3222
|
-
return patches;
|
|
3271
|
+
if (oldNode.type === Reference && oldNode.uid !== newNode.uid) {
|
|
3272
|
+
patches.push({
|
|
3273
|
+
type: SetReferenceNodeUid,
|
|
3274
|
+
uid: newNode.uid
|
|
3275
|
+
});
|
|
3223
3276
|
}
|
|
3224
3277
|
// Handle text nodes
|
|
3225
3278
|
if (oldNode.type === Text && newNode.type === Text) {
|
|
@@ -3232,8 +3285,8 @@ const compareNodes = (oldNode, newNode) => {
|
|
|
3232
3285
|
return patches;
|
|
3233
3286
|
}
|
|
3234
3287
|
// Compare attributes
|
|
3235
|
-
const oldKeys = getKeys(oldNode);
|
|
3236
|
-
const newKeys = getKeys(newNode);
|
|
3288
|
+
const oldKeys = getKeys(oldNode).filter(key => oldNode.type !== Reference || key !== 'uid');
|
|
3289
|
+
const newKeys = getKeys(newNode).filter(key => newNode.type !== Reference || key !== 'uid');
|
|
3237
3290
|
// Check for attribute changes
|
|
3238
3291
|
for (const key of newKeys) {
|
|
3239
3292
|
if (oldNode[key] !== newNode[key]) {
|
|
@@ -3257,9 +3310,14 @@ const compareNodes = (oldNode, newNode) => {
|
|
|
3257
3310
|
};
|
|
3258
3311
|
|
|
3259
3312
|
const treeToArray = node => {
|
|
3260
|
-
const result = [
|
|
3261
|
-
|
|
3262
|
-
|
|
3313
|
+
const result = [];
|
|
3314
|
+
const stack = [node];
|
|
3315
|
+
while (stack.length > 0) {
|
|
3316
|
+
const current = stack.pop();
|
|
3317
|
+
result.push(current.node);
|
|
3318
|
+
for (let i = current.children.length - 1; i >= 0; i--) {
|
|
3319
|
+
stack.push(current.children[i]);
|
|
3320
|
+
}
|
|
3263
3321
|
}
|
|
3264
3322
|
return result;
|
|
3265
3323
|
};
|
|
@@ -3469,136 +3527,334 @@ const handleContextMenu = async (state, button, eventX, eventY) => {
|
|
|
3469
3527
|
headerHeight,
|
|
3470
3528
|
itemHeight,
|
|
3471
3529
|
items,
|
|
3530
|
+
minLineY,
|
|
3472
3531
|
uid,
|
|
3473
3532
|
x,
|
|
3474
3533
|
y
|
|
3475
3534
|
} = state;
|
|
3476
|
-
const
|
|
3477
|
-
|
|
3535
|
+
const visibleIndex = getListIndex(eventX, eventY, x, y, deltaY, itemHeight, headerHeight);
|
|
3536
|
+
const index = visibleIndex + minLineY;
|
|
3537
|
+
if (index < 0 || index >= items.length) {
|
|
3478
3538
|
return state;
|
|
3479
3539
|
}
|
|
3540
|
+
const item = items[index];
|
|
3480
3541
|
await show2(uid, ManageExtension, eventX, eventY, {
|
|
3481
|
-
builtin:
|
|
3482
|
-
disabled:
|
|
3542
|
+
builtin: item.builtin === true,
|
|
3543
|
+
disabled: item.disabled === true,
|
|
3483
3544
|
menuId: ManageExtension,
|
|
3484
|
-
status:
|
|
3545
|
+
status: item.status
|
|
3485
3546
|
});
|
|
3486
|
-
return state;
|
|
3487
|
-
};
|
|
3488
|
-
|
|
3489
|
-
const updateStatus = (extension, id, status, builtin) => {
|
|
3490
|
-
if (extension.id !== id) {
|
|
3491
|
-
return extension;
|
|
3492
|
-
}
|
|
3493
|
-
return {
|
|
3494
|
-
...extension,
|
|
3495
|
-
builtin: builtin ?? extension.builtin,
|
|
3496
|
-
disabled: status === Disabled$1,
|
|
3497
|
-
status
|
|
3498
|
-
};
|
|
3499
|
-
};
|
|
3500
|
-
const setExtensionStatus = (state, id, status, builtin) => {
|
|
3501
|
-
if (!isExtensionStatus(status)) {
|
|
3502
|
-
throw new TypeError(`Invalid extension status: ${status}`);
|
|
3503
|
-
}
|
|
3504
3547
|
return {
|
|
3505
3548
|
...state,
|
|
3506
|
-
|
|
3507
|
-
items: state.items.map(extension => updateStatus(extension, id, status, builtin))
|
|
3549
|
+
focusedIndex: index
|
|
3508
3550
|
};
|
|
3509
3551
|
};
|
|
3510
3552
|
|
|
3511
|
-
const handleDisable = async (state, id) => {
|
|
3512
|
-
const error = await disableExtension(id);
|
|
3513
|
-
return error ? state : setExtensionStatus(state, id, Disabled$1);
|
|
3514
|
-
};
|
|
3515
|
-
|
|
3516
3553
|
const handleDisableWorkspace = (state, id) => {
|
|
3517
3554
|
return state;
|
|
3518
3555
|
};
|
|
3519
3556
|
|
|
3520
|
-
const handleEnable = async (state, id) => {
|
|
3521
|
-
const error = await enableExtension(id);
|
|
3522
|
-
return error ? state : setExtensionStatus(state, id, Enabled);
|
|
3523
|
-
};
|
|
3524
|
-
|
|
3525
3557
|
const handleEnableWorkspace = (state, id) => {
|
|
3526
3558
|
return state;
|
|
3527
3559
|
};
|
|
3528
3560
|
|
|
3529
|
-
const
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
focus: List$2
|
|
3533
|
-
};
|
|
3534
|
-
};
|
|
3561
|
+
const Web = 1;
|
|
3562
|
+
const Electron = 2;
|
|
3563
|
+
const Remote = 3;
|
|
3535
3564
|
|
|
3536
|
-
const
|
|
3537
|
-
|
|
3565
|
+
const getAllExtensions$1 = async (assetDir, platform) => {
|
|
3566
|
+
try {
|
|
3567
|
+
return await invoke$1('Extensions.getAllExtensions', assetDir, platform);
|
|
3568
|
+
} catch (error) {
|
|
3569
|
+
if (platform === Web) {
|
|
3570
|
+
return [];
|
|
3571
|
+
}
|
|
3572
|
+
throw error;
|
|
3573
|
+
}
|
|
3538
3574
|
};
|
|
3539
3575
|
|
|
3540
|
-
const
|
|
3541
|
-
return
|
|
3542
|
-
...state,
|
|
3543
|
-
focus: Input
|
|
3544
|
-
};
|
|
3576
|
+
const getAllExtensions = (assetDir, platform) => {
|
|
3577
|
+
return getAllExtensions$1(assetDir, platform);
|
|
3545
3578
|
};
|
|
3546
3579
|
|
|
3547
|
-
const
|
|
3548
|
-
|
|
3549
|
-
return setExtensionStatus(state, id, Enabled);
|
|
3580
|
+
const getBuiltin = extension => {
|
|
3581
|
+
return extension !== null && typeof extension === 'object' && 'builtin' in extension && extension.builtin === true;
|
|
3550
3582
|
};
|
|
3551
3583
|
|
|
3552
|
-
const
|
|
3553
|
-
return
|
|
3554
|
-
...state,
|
|
3555
|
-
scrollBarActive: false
|
|
3556
|
-
};
|
|
3584
|
+
const isString = item => {
|
|
3585
|
+
return typeof item === 'string';
|
|
3557
3586
|
};
|
|
3558
3587
|
|
|
3559
|
-
const
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
// clicked at top
|
|
3563
|
-
return {
|
|
3564
|
-
handleOffset: relativeY,
|
|
3565
|
-
percent: 0
|
|
3566
|
-
};
|
|
3588
|
+
const getCategories = extension => {
|
|
3589
|
+
if (extension === null || typeof extension !== 'object' || !('categories' in extension) || !Array.isArray(extension.categories)) {
|
|
3590
|
+
return [];
|
|
3567
3591
|
}
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3592
|
+
return extension.categories.filter(isString);
|
|
3593
|
+
};
|
|
3594
|
+
|
|
3595
|
+
const getDescription = extension => {
|
|
3596
|
+
if (extension === null || typeof extension !== 'object' || !('description' in extension) || typeof extension.description !== 'string' || !extension.description) {
|
|
3597
|
+
return 'n/a';
|
|
3574
3598
|
}
|
|
3575
|
-
|
|
3576
|
-
return {
|
|
3577
|
-
handleOffset: scrollBarHeight - height + relativeY,
|
|
3578
|
-
percent: 1
|
|
3579
|
-
};
|
|
3599
|
+
return extension.description;
|
|
3580
3600
|
};
|
|
3581
3601
|
|
|
3582
|
-
const
|
|
3583
|
-
|
|
3584
|
-
number(min);
|
|
3585
|
-
number(max);
|
|
3586
|
-
return Math.min(Math.max(num, min), max);
|
|
3602
|
+
const getDisabled = extension => {
|
|
3603
|
+
return extension !== null && typeof extension === 'object' && 'disabled' in extension && extension.disabled === true;
|
|
3587
3604
|
};
|
|
3588
3605
|
|
|
3589
|
-
const
|
|
3590
|
-
object
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3606
|
+
const getDownloadCountValue = extension => {
|
|
3607
|
+
if (extension === null || typeof extension !== 'object') {
|
|
3608
|
+
return undefined;
|
|
3609
|
+
}
|
|
3610
|
+
const marketplace = 'marketplace' in extension && extension.marketplace !== null && typeof extension.marketplace === 'object' ? extension.marketplace : {};
|
|
3611
|
+
const packageJson = 'packageJSON' in extension && extension.packageJSON !== null && typeof extension.packageJSON === 'object' ? extension.packageJSON : {};
|
|
3612
|
+
return ('downloadCount' in extension ? extension.downloadCount : undefined) ?? ('downloads' in extension ? extension.downloads : undefined) ?? ('downloadCount' in marketplace ? marketplace.downloadCount : undefined) ?? ('downloads' in marketplace ? marketplace.downloads : undefined) ?? ('downloadCount' in packageJson ? packageJson.downloadCount : undefined) ?? ('downloads' in packageJson ? packageJson.downloads : undefined);
|
|
3613
|
+
};
|
|
3614
|
+
const getDownloadCount = extension => {
|
|
3615
|
+
const downloadCount = getDownloadCountValue(extension);
|
|
3616
|
+
if (typeof downloadCount !== 'number') {
|
|
3617
|
+
return 'n/a';
|
|
3618
|
+
}
|
|
3619
|
+
return downloadCount.toLocaleString();
|
|
3620
|
+
};
|
|
3621
|
+
|
|
3622
|
+
const getRemoteUrl = (extension, platform, assetDir) => {
|
|
3623
|
+
if (extension === null || typeof extension !== 'object') {
|
|
3624
|
+
return '';
|
|
3625
|
+
}
|
|
3626
|
+
const builtin = 'builtin' in extension && extension.builtin === true;
|
|
3627
|
+
const icon = 'icon' in extension && typeof extension.icon === 'string' ? extension.icon : '';
|
|
3628
|
+
const id = 'id' in extension && typeof extension.id === 'string' ? extension.id : '';
|
|
3629
|
+
const path = 'path' in extension && typeof extension.path === 'string' ? extension.path : '';
|
|
3630
|
+
if (platform === Remote || platform === Electron) {
|
|
3631
|
+
if (builtin) {
|
|
3632
|
+
return `${assetDir}/extensions/${id}/${icon}`;
|
|
3633
|
+
}
|
|
3634
|
+
return `/remote/${path}/${icon}`; // TODO support windows paths
|
|
3635
|
+
}
|
|
3636
|
+
if (platform === Web) {
|
|
3637
|
+
return `${path}/${icon}`;
|
|
3638
|
+
}
|
|
3639
|
+
return '';
|
|
3640
|
+
};
|
|
3641
|
+
|
|
3642
|
+
const getExtensionDefaultIcon = assetDir => {
|
|
3643
|
+
return `${assetDir}/icons/extensionDefaultIcon.png`;
|
|
3644
|
+
};
|
|
3645
|
+
const getExtensionLanguageBasicsIcon = assetDir => {
|
|
3646
|
+
return `${assetDir}/icons/language-icon.svg`;
|
|
3647
|
+
};
|
|
3648
|
+
const getExtensionThemeIcon = assetDir => {
|
|
3649
|
+
return `${assetDir}/icons/theme-icon.png`;
|
|
3650
|
+
};
|
|
3651
|
+
|
|
3652
|
+
const isLanguageBasicsExtension = extension => {
|
|
3653
|
+
return 'name' in extension && typeof extension.name === 'string' && extension.name.startsWith('Language Basics');
|
|
3654
|
+
};
|
|
3655
|
+
const isThemeExtension = extension => {
|
|
3656
|
+
return 'name' in extension && typeof extension.name === 'string' && extension.name.endsWith(' Theme');
|
|
3657
|
+
};
|
|
3658
|
+
const getExtensionIcon = (extension, platform, assetDir) => {
|
|
3659
|
+
if (extension === null || typeof extension !== 'object') {
|
|
3660
|
+
return getExtensionDefaultIcon(assetDir);
|
|
3661
|
+
}
|
|
3662
|
+
const hasIcon = 'icon' in extension && typeof extension.icon === 'string' && extension.icon;
|
|
3663
|
+
const hasPath = 'path' in extension && typeof extension.path === 'string' && extension.path;
|
|
3664
|
+
if (!hasPath || !hasIcon) {
|
|
3665
|
+
if (isLanguageBasicsExtension(extension)) {
|
|
3666
|
+
return getExtensionLanguageBasicsIcon(assetDir);
|
|
3667
|
+
}
|
|
3668
|
+
if (isThemeExtension(extension)) {
|
|
3669
|
+
return getExtensionThemeIcon(assetDir);
|
|
3670
|
+
}
|
|
3671
|
+
return getExtensionDefaultIcon(assetDir);
|
|
3672
|
+
}
|
|
3673
|
+
return getRemoteUrl(extension, platform, assetDir);
|
|
3674
|
+
};
|
|
3675
|
+
|
|
3676
|
+
const getIcon = (extension, platform, assetDir) => {
|
|
3677
|
+
return getExtensionIcon(extension, platform, assetDir);
|
|
3678
|
+
};
|
|
3679
|
+
|
|
3680
|
+
const getId = extension => {
|
|
3681
|
+
if (extension === null || typeof extension !== 'object' || !('id' in extension) || typeof extension.id !== 'string' || !extension.id) {
|
|
3682
|
+
return 'n/a';
|
|
3683
|
+
}
|
|
3684
|
+
return extension.id;
|
|
3685
|
+
};
|
|
3686
|
+
|
|
3687
|
+
const getName = extension => {
|
|
3688
|
+
if (extension === null || typeof extension !== 'object') {
|
|
3689
|
+
return 'n/a';
|
|
3690
|
+
}
|
|
3691
|
+
if ('name' in extension && typeof extension.name === 'string' && extension.name) {
|
|
3692
|
+
return extension.name;
|
|
3693
|
+
}
|
|
3694
|
+
if ('id' in extension && typeof extension.id === 'string' && extension.id) {
|
|
3695
|
+
return extension.id;
|
|
3696
|
+
}
|
|
3697
|
+
return 'n/a';
|
|
3698
|
+
};
|
|
3699
|
+
|
|
3700
|
+
const RE_PUBLISHER = /^[a-z\d-]+/;
|
|
3701
|
+
const getPublisher = extension => {
|
|
3702
|
+
if (extension === null || typeof extension !== 'object' || !('id' in extension) || typeof extension.id !== 'string') {
|
|
3703
|
+
return 'n/a';
|
|
3704
|
+
}
|
|
3705
|
+
const match = extension.id.match(RE_PUBLISHER);
|
|
3706
|
+
if (!match) {
|
|
3707
|
+
return 'n/a';
|
|
3708
|
+
}
|
|
3709
|
+
return match[0];
|
|
3710
|
+
};
|
|
3711
|
+
|
|
3712
|
+
const getRatingValue = extension => {
|
|
3713
|
+
if (extension === null || typeof extension !== 'object') {
|
|
3714
|
+
return undefined;
|
|
3715
|
+
}
|
|
3716
|
+
const marketplace = 'marketplace' in extension && extension.marketplace !== null && typeof extension.marketplace === 'object' ? extension.marketplace : {};
|
|
3717
|
+
const packageJson = 'packageJSON' in extension && extension.packageJSON !== null && typeof extension.packageJSON === 'object' ? extension.packageJSON : {};
|
|
3718
|
+
return ('rating' in extension ? extension.rating : undefined) ?? ('averageRating' in extension ? extension.averageRating : undefined) ?? ('rating' in marketplace ? marketplace.rating : undefined) ?? ('averageRating' in marketplace ? marketplace.averageRating : undefined) ?? ('rating' in packageJson ? packageJson.rating : undefined) ?? ('averageRating' in packageJson ? packageJson.averageRating : undefined);
|
|
3719
|
+
};
|
|
3720
|
+
const getRating = extension => {
|
|
3721
|
+
const rating = getRatingValue(extension);
|
|
3722
|
+
if (typeof rating !== 'number') {
|
|
3723
|
+
return 'n/a';
|
|
3724
|
+
}
|
|
3725
|
+
return rating.toFixed(1);
|
|
3726
|
+
};
|
|
3727
|
+
|
|
3728
|
+
const getSize = extension => {
|
|
3729
|
+
if (extension === null || typeof extension !== 'object' || !('size' in extension) || extension.size === 0 || typeof extension.size !== 'number') {
|
|
3730
|
+
return 0;
|
|
3731
|
+
}
|
|
3732
|
+
return extension.size;
|
|
3733
|
+
};
|
|
3734
|
+
|
|
3735
|
+
const getStatus = extension => {
|
|
3736
|
+
if (extension === null || typeof extension !== 'object' || !('status' in extension)) {
|
|
3737
|
+
return undefined;
|
|
3738
|
+
}
|
|
3739
|
+
return typeof extension.status === 'string' ? extension.status : undefined;
|
|
3740
|
+
};
|
|
3741
|
+
|
|
3742
|
+
const getUpdatedDate = extension => {
|
|
3743
|
+
if (extension === null || typeof extension !== 'object' || !('updatedDate' in extension) || !extension.updatedDate || typeof extension.updatedDate !== 'number') {
|
|
3744
|
+
return 0;
|
|
3745
|
+
}
|
|
3746
|
+
return extension.updatedDate;
|
|
3747
|
+
};
|
|
3748
|
+
|
|
3749
|
+
const normalizeExtension = (extension, platform, assetDir) => {
|
|
3750
|
+
return {
|
|
3751
|
+
builtin: getBuiltin(extension),
|
|
3752
|
+
categories: getCategories(extension),
|
|
3753
|
+
description: getDescription(extension),
|
|
3754
|
+
disabled: getDisabled(extension),
|
|
3755
|
+
downloadCount: getDownloadCount(extension),
|
|
3756
|
+
icon: getIcon(extension, platform, assetDir),
|
|
3757
|
+
id: getId(extension),
|
|
3758
|
+
name: getName(extension),
|
|
3759
|
+
publisher: getPublisher(extension),
|
|
3760
|
+
rating: getRating(extension),
|
|
3761
|
+
size: getSize(extension),
|
|
3762
|
+
status: getStatus(extension),
|
|
3763
|
+
updatedDate: getUpdatedDate(extension),
|
|
3764
|
+
uri: ''
|
|
3765
|
+
};
|
|
3766
|
+
};
|
|
3767
|
+
|
|
3768
|
+
const normalizeExtensions = (extensions, platform, assetDir) => {
|
|
3769
|
+
return Array.from(extensions, extension => normalizeExtension(extension, platform, assetDir));
|
|
3770
|
+
};
|
|
3771
|
+
|
|
3772
|
+
const handleExtensionsChanged = async state => {
|
|
3773
|
+
const {
|
|
3774
|
+
assetDir,
|
|
3775
|
+
platform
|
|
3776
|
+
} = state;
|
|
3777
|
+
const allExtensions = await getAllExtensions(assetDir, platform);
|
|
3778
|
+
const normalized = normalizeExtensions(allExtensions, platform, assetDir);
|
|
3779
|
+
return handleChange({
|
|
3780
|
+
...state,
|
|
3781
|
+
allExtensions: normalized
|
|
3782
|
+
}, {});
|
|
3783
|
+
};
|
|
3784
|
+
|
|
3785
|
+
const handleFocus = async state => {
|
|
3786
|
+
return {
|
|
3787
|
+
...state,
|
|
3788
|
+
focus: List$2
|
|
3789
|
+
};
|
|
3790
|
+
};
|
|
3791
|
+
|
|
3792
|
+
const handleHeaderContextMenu = async state => {
|
|
3793
|
+
return state;
|
|
3794
|
+
};
|
|
3795
|
+
|
|
3796
|
+
const handleInputFocus = state => {
|
|
3797
|
+
return {
|
|
3798
|
+
...state,
|
|
3799
|
+
focus: Input
|
|
3800
|
+
};
|
|
3801
|
+
};
|
|
3802
|
+
|
|
3803
|
+
const handleInstall = async (state, id) => {
|
|
3804
|
+
await installExtension(id);
|
|
3805
|
+
return setExtensionStatus(state, id, Enabled);
|
|
3806
|
+
};
|
|
3807
|
+
|
|
3808
|
+
const handleScrollBarCaptureLost = state => {
|
|
3809
|
+
return {
|
|
3810
|
+
...state,
|
|
3811
|
+
scrollBarActive: false
|
|
3812
|
+
};
|
|
3813
|
+
};
|
|
3814
|
+
|
|
3815
|
+
const getNewDeltaPercent = (height, scrollBarHeight, relativeY) => {
|
|
3816
|
+
const halfScrollBarHeight = scrollBarHeight / 2;
|
|
3817
|
+
if (relativeY <= halfScrollBarHeight) {
|
|
3818
|
+
// clicked at top
|
|
3819
|
+
return {
|
|
3820
|
+
handleOffset: relativeY,
|
|
3821
|
+
percent: 0
|
|
3822
|
+
};
|
|
3823
|
+
}
|
|
3824
|
+
if (relativeY <= height - halfScrollBarHeight) {
|
|
3825
|
+
// clicked in middle
|
|
3826
|
+
return {
|
|
3827
|
+
handleOffset: halfScrollBarHeight,
|
|
3828
|
+
percent: (relativeY - halfScrollBarHeight) / (height - scrollBarHeight)
|
|
3829
|
+
};
|
|
3830
|
+
}
|
|
3831
|
+
// clicked at bottom
|
|
3832
|
+
return {
|
|
3833
|
+
handleOffset: scrollBarHeight - height + relativeY,
|
|
3834
|
+
percent: 1
|
|
3835
|
+
};
|
|
3836
|
+
};
|
|
3837
|
+
|
|
3838
|
+
const clamp = (num, min, max) => {
|
|
3839
|
+
number(num);
|
|
3840
|
+
number(min);
|
|
3841
|
+
number(max);
|
|
3842
|
+
return Math.min(Math.max(num, min), max);
|
|
3843
|
+
};
|
|
3844
|
+
|
|
3845
|
+
const setDeltaY = (state, value) => {
|
|
3846
|
+
object(state);
|
|
3847
|
+
number(value);
|
|
3848
|
+
const {
|
|
3849
|
+
deltaY,
|
|
3850
|
+
finalDeltaY,
|
|
3851
|
+
headerHeight,
|
|
3852
|
+
height,
|
|
3853
|
+
itemHeight,
|
|
3854
|
+
items,
|
|
3855
|
+
minimumSliderSize
|
|
3856
|
+
} = state;
|
|
3857
|
+
const listHeight = height - headerHeight;
|
|
3602
3858
|
const newDeltaY = clamp(value, 0, finalDeltaY);
|
|
3603
3859
|
if (deltaY === newDeltaY) {
|
|
3604
3860
|
return state;
|
|
@@ -3756,25 +4012,6 @@ const installAnotherVersion = async state => {
|
|
|
3756
4012
|
return state;
|
|
3757
4013
|
};
|
|
3758
4014
|
|
|
3759
|
-
const Web = 1;
|
|
3760
|
-
const Electron = 2;
|
|
3761
|
-
const Remote = 3;
|
|
3762
|
-
|
|
3763
|
-
const getAllExtensions$1 = async (assetDir, platform) => {
|
|
3764
|
-
try {
|
|
3765
|
-
return await invoke$1('Extensions.getAllExtensions', assetDir, platform);
|
|
3766
|
-
} catch (error) {
|
|
3767
|
-
if (platform === Web) {
|
|
3768
|
-
return [];
|
|
3769
|
-
}
|
|
3770
|
-
throw error;
|
|
3771
|
-
}
|
|
3772
|
-
};
|
|
3773
|
-
|
|
3774
|
-
const getAllExtensions = (assetDir, platform) => {
|
|
3775
|
-
return getAllExtensions$1(assetDir, platform);
|
|
3776
|
-
};
|
|
3777
|
-
|
|
3778
4015
|
const Small = 1;
|
|
3779
4016
|
const Normal = 2;
|
|
3780
4017
|
const Large = 3;
|
|
@@ -3794,166 +4031,6 @@ const getIsFirefox = () => {
|
|
|
3794
4031
|
return globalWithNavigator.navigator?.userAgent.toLowerCase().includes('firefox') ?? false;
|
|
3795
4032
|
};
|
|
3796
4033
|
|
|
3797
|
-
const getRemoteUrl = (extension, platform, assetDir) => {
|
|
3798
|
-
if (platform === Remote || platform === Electron) {
|
|
3799
|
-
if (extension.builtin) {
|
|
3800
|
-
return `${assetDir}/extensions/${extension.id}/${extension.icon}`;
|
|
3801
|
-
}
|
|
3802
|
-
return `/remote/${extension.path}/${extension.icon}`; // TODO support windows paths
|
|
3803
|
-
}
|
|
3804
|
-
if (platform === Web) {
|
|
3805
|
-
return `${extension.path}/${extension.icon}`;
|
|
3806
|
-
}
|
|
3807
|
-
return '';
|
|
3808
|
-
};
|
|
3809
|
-
|
|
3810
|
-
const getExtensionDefaultIcon = assetDir => {
|
|
3811
|
-
return `${assetDir}/icons/extensionDefaultIcon.png`;
|
|
3812
|
-
};
|
|
3813
|
-
const getExtensionLanguageBasicsIcon = assetDir => {
|
|
3814
|
-
return `${assetDir}/icons/language-icon.svg`;
|
|
3815
|
-
};
|
|
3816
|
-
const getExtensionThemeIcon = assetDir => {
|
|
3817
|
-
return `${assetDir}/icons/theme-icon.png`;
|
|
3818
|
-
};
|
|
3819
|
-
|
|
3820
|
-
const isLanguageBasicsExtension = extension => {
|
|
3821
|
-
return extension.name && extension.name.startsWith('Language Basics');
|
|
3822
|
-
};
|
|
3823
|
-
const isThemeExtension = extension => {
|
|
3824
|
-
return extension.name && extension.name.endsWith(' Theme');
|
|
3825
|
-
};
|
|
3826
|
-
const getExtensionIcon = (extension, platform, assetDir) => {
|
|
3827
|
-
if (!extension) {
|
|
3828
|
-
return getExtensionDefaultIcon(assetDir);
|
|
3829
|
-
}
|
|
3830
|
-
if (!extension.path || !extension.icon) {
|
|
3831
|
-
if (isLanguageBasicsExtension(extension)) {
|
|
3832
|
-
return getExtensionLanguageBasicsIcon(assetDir);
|
|
3833
|
-
}
|
|
3834
|
-
if (isThemeExtension(extension)) {
|
|
3835
|
-
return getExtensionThemeIcon(assetDir);
|
|
3836
|
-
}
|
|
3837
|
-
return getExtensionDefaultIcon(assetDir);
|
|
3838
|
-
}
|
|
3839
|
-
return getRemoteUrl(extension, platform, assetDir);
|
|
3840
|
-
};
|
|
3841
|
-
|
|
3842
|
-
const getDownloadCountValue = extension => {
|
|
3843
|
-
return extension?.downloadCount ?? extension?.downloads ?? extension?.marketplace?.downloadCount ?? extension?.marketplace?.downloads ?? extension?.packageJSON?.downloadCount ?? extension?.packageJSON?.downloads;
|
|
3844
|
-
};
|
|
3845
|
-
const getDownloadCount = extension => {
|
|
3846
|
-
const downloadCount = getDownloadCountValue(extension);
|
|
3847
|
-
if (typeof downloadCount !== 'number') {
|
|
3848
|
-
return 'n/a';
|
|
3849
|
-
}
|
|
3850
|
-
return downloadCount.toLocaleString();
|
|
3851
|
-
};
|
|
3852
|
-
|
|
3853
|
-
const getRatingValue = extension => {
|
|
3854
|
-
return extension?.rating ?? extension?.averageRating ?? extension?.marketplace?.rating ?? extension?.marketplace?.averageRating ?? extension?.packageJSON?.rating ?? extension?.packageJSON?.averageRating;
|
|
3855
|
-
};
|
|
3856
|
-
const getRating = extension => {
|
|
3857
|
-
const rating = getRatingValue(extension);
|
|
3858
|
-
if (typeof rating !== 'number') {
|
|
3859
|
-
return 'n/a';
|
|
3860
|
-
}
|
|
3861
|
-
return rating.toFixed(1);
|
|
3862
|
-
};
|
|
3863
|
-
|
|
3864
|
-
const getBuiltin = extension => {
|
|
3865
|
-
return extension?.builtin === true;
|
|
3866
|
-
};
|
|
3867
|
-
const getDisabled = extension => {
|
|
3868
|
-
return extension?.disabled === true;
|
|
3869
|
-
};
|
|
3870
|
-
const getStatus = extension => {
|
|
3871
|
-
return typeof extension?.status === 'string' ? extension.status : undefined;
|
|
3872
|
-
};
|
|
3873
|
-
const getIcon = (extension, platform, assetDir) => {
|
|
3874
|
-
return getExtensionIcon(extension, platform, assetDir);
|
|
3875
|
-
};
|
|
3876
|
-
const getName = extension => {
|
|
3877
|
-
if (extension && extension.name) {
|
|
3878
|
-
return extension.name;
|
|
3879
|
-
}
|
|
3880
|
-
if (extension && extension.id) {
|
|
3881
|
-
return extension.id;
|
|
3882
|
-
}
|
|
3883
|
-
return 'n/a';
|
|
3884
|
-
};
|
|
3885
|
-
const getDescription = extension => {
|
|
3886
|
-
if (!extension || !extension.description) {
|
|
3887
|
-
return 'n/a';
|
|
3888
|
-
}
|
|
3889
|
-
return extension.description;
|
|
3890
|
-
};
|
|
3891
|
-
const getId$1 = extension => {
|
|
3892
|
-
if (!extension || !extension.id) {
|
|
3893
|
-
return 'n/a';
|
|
3894
|
-
}
|
|
3895
|
-
return extension.id;
|
|
3896
|
-
};
|
|
3897
|
-
const getSize = extension => {
|
|
3898
|
-
if (!extension || extension.size === 0 || typeof extension.size !== 'number') {
|
|
3899
|
-
return 0;
|
|
3900
|
-
}
|
|
3901
|
-
return extension.size;
|
|
3902
|
-
};
|
|
3903
|
-
const getUpdatedDate = extension => {
|
|
3904
|
-
if (!extension || !extension.updatedDate || typeof extension.updatedDate !== 'number') {
|
|
3905
|
-
return 0;
|
|
3906
|
-
}
|
|
3907
|
-
return extension.updatedDate;
|
|
3908
|
-
};
|
|
3909
|
-
const isString = item => {
|
|
3910
|
-
return typeof item === 'string';
|
|
3911
|
-
};
|
|
3912
|
-
const getCategories = extension => {
|
|
3913
|
-
if (!extension || !extension.categories || !Array.isArray(extension.categories)) {
|
|
3914
|
-
return [];
|
|
3915
|
-
}
|
|
3916
|
-
return extension.categories.filter(isString);
|
|
3917
|
-
};
|
|
3918
|
-
|
|
3919
|
-
const RE_PUBLISHER = /^[a-z\d-]+/;
|
|
3920
|
-
|
|
3921
|
-
// TODO handle case when extension is of type number|array|null|string
|
|
3922
|
-
const getPublisher = extension => {
|
|
3923
|
-
if (!extension || !extension.id) {
|
|
3924
|
-
return 'n/a';
|
|
3925
|
-
}
|
|
3926
|
-
// TODO handle case when id is not of type string -> should not crash application
|
|
3927
|
-
const match = extension.id.match(RE_PUBLISHER);
|
|
3928
|
-
if (!match) {
|
|
3929
|
-
return 'n/a';
|
|
3930
|
-
}
|
|
3931
|
-
return match[0];
|
|
3932
|
-
};
|
|
3933
|
-
|
|
3934
|
-
const normalizeExtension = (extension, platform, assetDir) => {
|
|
3935
|
-
return {
|
|
3936
|
-
builtin: getBuiltin(extension),
|
|
3937
|
-
categories: getCategories(extension),
|
|
3938
|
-
description: getDescription(extension),
|
|
3939
|
-
disabled: getDisabled(extension),
|
|
3940
|
-
downloadCount: getDownloadCount(extension),
|
|
3941
|
-
icon: getIcon(extension, platform, assetDir),
|
|
3942
|
-
id: getId$1(extension),
|
|
3943
|
-
name: getName(extension),
|
|
3944
|
-
publisher: getPublisher(extension),
|
|
3945
|
-
rating: getRating(extension),
|
|
3946
|
-
size: getSize(extension),
|
|
3947
|
-
status: getStatus(extension),
|
|
3948
|
-
updatedDate: getUpdatedDate(extension),
|
|
3949
|
-
uri: ''
|
|
3950
|
-
};
|
|
3951
|
-
};
|
|
3952
|
-
|
|
3953
|
-
const normalizeExtensions = (extensions, platform, assetDir) => {
|
|
3954
|
-
return Array.from(extensions, extension => normalizeExtension(extension, platform, assetDir));
|
|
3955
|
-
};
|
|
3956
|
-
|
|
3957
4034
|
const getSavedValue = savedState => {
|
|
3958
4035
|
if (savedState && typeof savedState === 'object' && 'searchValue' in savedState && typeof savedState.searchValue === 'string') {
|
|
3959
4036
|
return savedState.searchValue;
|
|
@@ -4313,7 +4390,7 @@ const getCompletionWidgetVirtualDom = (items, focusedIndex) => {
|
|
|
4313
4390
|
const Focusable = 0;
|
|
4314
4391
|
|
|
4315
4392
|
const disabledClassName = mergeClassNames(SearchFieldButton, SearchFieldButtonDisabled);
|
|
4316
|
-
const getClassName
|
|
4393
|
+
const getClassName = enabled => {
|
|
4317
4394
|
if (enabled) {
|
|
4318
4395
|
return SearchFieldButton;
|
|
4319
4396
|
}
|
|
@@ -4328,7 +4405,7 @@ const getSearchFieldButtonVirtualDom = button => {
|
|
|
4328
4405
|
} = button;
|
|
4329
4406
|
return [{
|
|
4330
4407
|
childCount: 1,
|
|
4331
|
-
className: getClassName
|
|
4408
|
+
className: getClassName(enabled),
|
|
4332
4409
|
onClick,
|
|
4333
4410
|
tabIndex: Focusable,
|
|
4334
4411
|
title,
|
|
@@ -4462,7 +4539,7 @@ const getExtensionActions = (builtin, disabled, status) => {
|
|
|
4462
4539
|
};
|
|
4463
4540
|
|
|
4464
4541
|
const className = mergeClassNames(ExtensionListItemActionInstall, ExtensionActionButton);
|
|
4465
|
-
const
|
|
4542
|
+
const getExtensionActionVirtualDom = (action, id) => {
|
|
4466
4543
|
return [{
|
|
4467
4544
|
childCount: 1,
|
|
4468
4545
|
className,
|
|
@@ -4472,13 +4549,33 @@ const getActionVirtualDom$1 = (action, id) => {
|
|
|
4472
4549
|
type: Button$2
|
|
4473
4550
|
}, text(action.label)];
|
|
4474
4551
|
};
|
|
4552
|
+
|
|
4475
4553
|
const getExtensionActionsVirtualDom = (id, builtin, disabled, status) => {
|
|
4476
4554
|
const actions = getExtensionActions(builtin, disabled, status);
|
|
4477
4555
|
return [{
|
|
4478
4556
|
childCount: actions.length,
|
|
4479
4557
|
className: ExtensionActions,
|
|
4480
4558
|
type: Div
|
|
4481
|
-
}, ...actions.flatMap(action =>
|
|
4559
|
+
}, ...actions.flatMap(action => getExtensionActionVirtualDom(action, id))];
|
|
4560
|
+
};
|
|
4561
|
+
|
|
4562
|
+
const getExtensionListItemClassName = (focused, disabled) => {
|
|
4563
|
+
return mergeClassNames(ExtensionListItem, focused ? ExtensionActive : '', disabled ? ExtensionListItemDisabled : '');
|
|
4564
|
+
};
|
|
4565
|
+
|
|
4566
|
+
const getExtensionListItemFooter = hasStatistics => {
|
|
4567
|
+
return {
|
|
4568
|
+
childCount: hasStatistics ? 3 : 2,
|
|
4569
|
+
className: ExtensionListItemFooter,
|
|
4570
|
+
type: Div
|
|
4571
|
+
};
|
|
4572
|
+
};
|
|
4573
|
+
|
|
4574
|
+
const getExtensionListItemId = focused => {
|
|
4575
|
+
if (focused) {
|
|
4576
|
+
return `ExtensionActive`;
|
|
4577
|
+
}
|
|
4578
|
+
return undefined;
|
|
4482
4579
|
};
|
|
4483
4580
|
|
|
4484
4581
|
const extensionListItemMetadataNode = {
|
|
@@ -4500,6 +4597,13 @@ const getExtensionStatisticsVirtualDom = (downloadCount, rating$1) => {
|
|
|
4500
4597
|
return [extensionListItemMetadataNode, ...getStatisticVirtualDom(downloads(), downloadCount, ExtensionListItemDownloadCount), ...getStatisticVirtualDom(rating(), rating$1, ExtensionListItemRating)];
|
|
4501
4598
|
};
|
|
4502
4599
|
|
|
4600
|
+
const getExtensionListItemStatisticsVirtualDom = (hasStatistics, downloadCount, rating) => {
|
|
4601
|
+
if (!hasStatistics) {
|
|
4602
|
+
return [];
|
|
4603
|
+
}
|
|
4604
|
+
return getExtensionStatisticsVirtualDom(downloadCount, rating);
|
|
4605
|
+
};
|
|
4606
|
+
|
|
4503
4607
|
const listItemDetail = {
|
|
4504
4608
|
childCount: 3,
|
|
4505
4609
|
className: ExtensionListItemDetail,
|
|
@@ -4515,33 +4619,11 @@ const listItemDescription = {
|
|
|
4515
4619
|
className: ExtensionListItemDescription,
|
|
4516
4620
|
type: Div
|
|
4517
4621
|
};
|
|
4518
|
-
const getListItemFooter = hasStatistics => {
|
|
4519
|
-
return {
|
|
4520
|
-
childCount: hasStatistics ? 3 : 2,
|
|
4521
|
-
className: ExtensionListItemFooter,
|
|
4522
|
-
type: Div
|
|
4523
|
-
};
|
|
4524
|
-
};
|
|
4525
4622
|
const listItemAuthorName = {
|
|
4526
4623
|
childCount: 1,
|
|
4527
4624
|
className: ExtensionListItemAuthorName,
|
|
4528
4625
|
type: Div
|
|
4529
4626
|
};
|
|
4530
|
-
const getClassName = (focused, disabled) => {
|
|
4531
|
-
return mergeClassNames(ExtensionListItem, focused ? ExtensionActive : '', disabled ? ExtensionListItemDisabled : '');
|
|
4532
|
-
};
|
|
4533
|
-
const getId = focused => {
|
|
4534
|
-
if (focused) {
|
|
4535
|
-
return `ExtensionActive`;
|
|
4536
|
-
}
|
|
4537
|
-
return undefined;
|
|
4538
|
-
};
|
|
4539
|
-
const getStatisticsVirtualDom = (hasStatistics, downloadCount, rating) => {
|
|
4540
|
-
if (!hasStatistics) {
|
|
4541
|
-
return [];
|
|
4542
|
-
}
|
|
4543
|
-
return getExtensionStatisticsVirtualDom(downloadCount, rating);
|
|
4544
|
-
};
|
|
4545
4627
|
const getExtensionListItemVirtualDom = extension => {
|
|
4546
4628
|
const {
|
|
4547
4629
|
builtin = false,
|
|
@@ -4565,8 +4647,8 @@ const getExtensionListItemVirtualDom = extension => {
|
|
|
4565
4647
|
ariaRoleDescription: Extension,
|
|
4566
4648
|
ariaSetSize: setSize,
|
|
4567
4649
|
childCount: 2,
|
|
4568
|
-
className:
|
|
4569
|
-
id:
|
|
4650
|
+
className: getExtensionListItemClassName(focused, disabled),
|
|
4651
|
+
id: getExtensionListItemId(focused),
|
|
4570
4652
|
role: ListItem,
|
|
4571
4653
|
type: Div
|
|
4572
4654
|
}, {
|
|
@@ -4575,16 +4657,19 @@ const getExtensionListItemVirtualDom = extension => {
|
|
|
4575
4657
|
role: None,
|
|
4576
4658
|
src: icon,
|
|
4577
4659
|
type: Img
|
|
4578
|
-
}, listItemDetail, listItemName, text(name), listItemDescription, text(description),
|
|
4660
|
+
}, listItemDetail, listItemName, text(name), listItemDescription, text(description), getExtensionListItemFooter(hasStatistics), listItemAuthorName, text(publisher), ...getExtensionListItemStatisticsVirtualDom(hasStatistics, downloadCount, rating), ...actionsDom];
|
|
4579
4661
|
return dom;
|
|
4580
4662
|
};
|
|
4581
4663
|
|
|
4582
|
-
const
|
|
4664
|
+
const getListClassName = focusOutline => {
|
|
4583
4665
|
const className = focusOutline ? mergeClassNames(ListItems, FocusOutline) : ListItems;
|
|
4666
|
+
return className;
|
|
4667
|
+
};
|
|
4668
|
+
const getExtensionsListVirtualDom = (visibleExtensions, focusOutline) => {
|
|
4584
4669
|
const dom = [{
|
|
4585
4670
|
ariaLabel: extensions(),
|
|
4586
4671
|
childCount: visibleExtensions.length,
|
|
4587
|
-
className,
|
|
4672
|
+
className: getListClassName(focusOutline),
|
|
4588
4673
|
onBlur: HandleBlur,
|
|
4589
4674
|
onContextmenu: HandleContextMenu,
|
|
4590
4675
|
onContextMenu: HandleContextMenu,
|
|
@@ -5099,7 +5184,17 @@ const commandMap = {
|
|
|
5099
5184
|
'SearchExtensions.dispose': dispose,
|
|
5100
5185
|
'SearchExtensions.enable': wrapCommand(enable$1),
|
|
5101
5186
|
'SearchExtensions.enableWorkspace': wrapCommand(enableWorkspace),
|
|
5187
|
+
'SearchExtensions.filterByBuiltin': wrapAsyncCommand(createFilterCommand(Builtin)),
|
|
5188
|
+
'SearchExtensions.filterByDisabled': wrapAsyncCommand(createFilterCommand(Disabled$2)),
|
|
5189
|
+
'SearchExtensions.filterByEnabled': wrapAsyncCommand(createFilterCommand(Enabled$1)),
|
|
5190
|
+
'SearchExtensions.filterByFeatured': wrapAsyncCommand(createFilterCommand(Featured)),
|
|
5191
|
+
'SearchExtensions.filterByInstalled': wrapAsyncCommand(createFilterCommand(Installed)),
|
|
5192
|
+
'SearchExtensions.filterByMcpServers': wrapAsyncCommand(createFilterCommand(McpServers)),
|
|
5102
5193
|
'SearchExtensions.filterByMostPopular': wrapAsyncCommand(filterByMostPopularWithContext),
|
|
5194
|
+
'SearchExtensions.filterByRecentlyPublished': wrapAsyncCommand(createFilterCommand(RecentlyPublished)),
|
|
5195
|
+
'SearchExtensions.filterByRecommended': wrapAsyncCommand(createFilterCommand(Recommended)),
|
|
5196
|
+
'SearchExtensions.filterByUpdates': wrapAsyncCommand(createFilterCommand(Outdated)),
|
|
5197
|
+
'SearchExtensions.filterByWorkspaceUnsupported': wrapAsyncCommand(createFilterCommand(WorkspaceUnsupported)),
|
|
5103
5198
|
'SearchExtensions.focusFirst': wrapCommand(focusFirst),
|
|
5104
5199
|
'SearchExtensions.focusIndex': wrapCommand(focusIndex),
|
|
5105
5200
|
'SearchExtensions.focusLast': wrapCommand(focusLast),
|
|
@@ -5125,6 +5220,7 @@ const commandMap = {
|
|
|
5125
5220
|
'SearchExtensions.handleDisableWorkspace': wrapCommand(handleDisableWorkspace),
|
|
5126
5221
|
'SearchExtensions.handleEnable': wrapCommand(handleEnable),
|
|
5127
5222
|
'SearchExtensions.handleEnableWorkspace': wrapCommand(handleEnableWorkspace),
|
|
5223
|
+
'SearchExtensions.handleExtensionsChanged': wrapCommand(handleExtensionsChanged),
|
|
5128
5224
|
'SearchExtensions.handleFocus': wrapCommand(handleFocus),
|
|
5129
5225
|
'SearchExtensions.handleHeaderContextMenu': wrapCommand(handleHeaderContextMenu),
|
|
5130
5226
|
'SearchExtensions.handleInput': wrapAsyncCommand(handleInputWithContext),
|