@lvce-editor/extension-search-view 7.21.0 → 7.23.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/extensionSearchViewWorkerMain.js +1779 -1756
- package/package.json +1 -1
|
@@ -2908,2039 +2908,2060 @@ const getComponentState = uid => {
|
|
|
2908
2908
|
return get(uid).newState;
|
|
2909
2909
|
};
|
|
2910
2910
|
|
|
2911
|
-
const
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
const Space = 9;
|
|
2915
|
-
const PageUp = 10;
|
|
2916
|
-
const PageDown = 11;
|
|
2917
|
-
const End = 255;
|
|
2918
|
-
const Home = 12;
|
|
2919
|
-
const UpArrow = 14;
|
|
2920
|
-
const DownArrow = 16;
|
|
2911
|
+
const mergeClassNames = (...classNames) => {
|
|
2912
|
+
return classNames.filter(Boolean).join(' ');
|
|
2913
|
+
};
|
|
2921
2914
|
|
|
2922
|
-
const
|
|
2915
|
+
const text = data => {
|
|
2916
|
+
return {
|
|
2917
|
+
childCount: 0,
|
|
2918
|
+
text: data,
|
|
2919
|
+
type: Text
|
|
2920
|
+
};
|
|
2921
|
+
};
|
|
2923
2922
|
|
|
2924
|
-
|
|
2925
|
-
const FocusExtensionsInput = 7000;
|
|
2923
|
+
new Set(Object.values(VirtualDomElements));
|
|
2926
2924
|
|
|
2927
|
-
const
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
}, {
|
|
2941
|
-
command: 'Extensions.selectPreviousCompletion',
|
|
2942
|
-
key: UpArrow,
|
|
2943
|
-
when: FocusExtensionsInput
|
|
2944
|
-
}, {
|
|
2945
|
-
command: 'Extensions.selectNextCompletion',
|
|
2946
|
-
key: DownArrow,
|
|
2947
|
-
when: FocusExtensionsInput
|
|
2948
|
-
}, {
|
|
2949
|
-
command: 'Extensions.openSuggest',
|
|
2950
|
-
key: CtrlCmd | Space,
|
|
2951
|
-
when: FocusExtensionsInput
|
|
2952
|
-
}, {
|
|
2953
|
-
command: 'Extensions.focusFirst',
|
|
2954
|
-
key: Home,
|
|
2955
|
-
when: FocusExtensions
|
|
2956
|
-
}, {
|
|
2957
|
-
command: 'Extensions.focusLast',
|
|
2958
|
-
key: End,
|
|
2959
|
-
when: FocusExtensions
|
|
2960
|
-
}, {
|
|
2961
|
-
command: 'Extensions.focusPreviousPage',
|
|
2962
|
-
key: PageUp,
|
|
2963
|
-
when: FocusExtensions
|
|
2964
|
-
}, {
|
|
2965
|
-
command: 'Extensions.focusNextPage',
|
|
2966
|
-
key: PageDown,
|
|
2967
|
-
when: FocusExtensions
|
|
2968
|
-
}, {
|
|
2969
|
-
command: 'Extensions.focusPrevious',
|
|
2970
|
-
key: UpArrow,
|
|
2971
|
-
when: FocusExtensions
|
|
2972
|
-
}, {
|
|
2973
|
-
command: 'Extensions.focusNext',
|
|
2974
|
-
key: DownArrow,
|
|
2975
|
-
when: FocusExtensions
|
|
2976
|
-
}, {
|
|
2977
|
-
command: 'Extensions.handleClickCurrentButKeepFocus',
|
|
2978
|
-
key: Space,
|
|
2979
|
-
when: FocusExtensions
|
|
2980
|
-
}, {
|
|
2981
|
-
command: 'Extensions.handleClickCurrent',
|
|
2982
|
-
key: Enter,
|
|
2983
|
-
when: FocusExtensions
|
|
2984
|
-
}, {
|
|
2985
|
-
command: 'Extensions.toggleSuggest',
|
|
2986
|
-
key: CtrlCmd | Space,
|
|
2987
|
-
when: FocusExtensions
|
|
2988
|
-
}, {
|
|
2989
|
-
command: 'Extensions.scrollDown',
|
|
2990
|
-
key: CtrlCmd | DownArrow,
|
|
2991
|
-
when: FocusExtensions
|
|
2992
|
-
}];
|
|
2925
|
+
const SetText = 1;
|
|
2926
|
+
const Replace = 2;
|
|
2927
|
+
const SetAttribute = 3;
|
|
2928
|
+
const RemoveAttribute = 4;
|
|
2929
|
+
const Add = 6;
|
|
2930
|
+
const NavigateChild = 7;
|
|
2931
|
+
const NavigateParent = 8;
|
|
2932
|
+
const RemoveChild = 9;
|
|
2933
|
+
const NavigateSibling = 10;
|
|
2934
|
+
const SetReferenceNodeUid = 11;
|
|
2935
|
+
|
|
2936
|
+
const isKey = key => {
|
|
2937
|
+
return key !== 'type' && key !== 'childCount';
|
|
2993
2938
|
};
|
|
2994
2939
|
|
|
2995
|
-
const
|
|
2996
|
-
const
|
|
2997
|
-
|
|
2998
|
-
|
|
2940
|
+
const getKeys = node => {
|
|
2941
|
+
const keys = Object.keys(node).filter(isKey);
|
|
2942
|
+
return keys;
|
|
2943
|
+
};
|
|
2999
2944
|
|
|
3000
|
-
const
|
|
3001
|
-
const
|
|
3002
|
-
|
|
2945
|
+
const arrayToTree = nodes => {
|
|
2946
|
+
const result = [];
|
|
2947
|
+
let i = 0;
|
|
2948
|
+
while (i < nodes.length) {
|
|
2949
|
+
const node = nodes[i];
|
|
2950
|
+
const {
|
|
2951
|
+
children,
|
|
2952
|
+
nodesConsumed
|
|
2953
|
+
} = getChildrenWithCount(nodes, i + 1, node.childCount || 0);
|
|
2954
|
+
result.push({
|
|
2955
|
+
node,
|
|
2956
|
+
children
|
|
2957
|
+
});
|
|
2958
|
+
i += 1 + nodesConsumed;
|
|
2959
|
+
}
|
|
2960
|
+
return result;
|
|
2961
|
+
};
|
|
2962
|
+
const getChildrenWithCount = (nodes, startIndex, childCount) => {
|
|
2963
|
+
if (childCount === 0) {
|
|
3003
2964
|
return {
|
|
3004
|
-
|
|
3005
|
-
|
|
2965
|
+
children: [],
|
|
2966
|
+
nodesConsumed: 0
|
|
3006
2967
|
};
|
|
3007
2968
|
}
|
|
3008
|
-
const
|
|
2969
|
+
const children = [];
|
|
2970
|
+
let i = startIndex;
|
|
2971
|
+
let remaining = childCount;
|
|
2972
|
+
let totalConsumed = 0;
|
|
2973
|
+
while (remaining > 0 && i < nodes.length) {
|
|
2974
|
+
const node = nodes[i];
|
|
2975
|
+
const nodeChildCount = node.childCount || 0;
|
|
2976
|
+
const {
|
|
2977
|
+
children: nodeChildren,
|
|
2978
|
+
nodesConsumed
|
|
2979
|
+
} = getChildrenWithCount(nodes, i + 1, nodeChildCount);
|
|
2980
|
+
children.push({
|
|
2981
|
+
node,
|
|
2982
|
+
children: nodeChildren
|
|
2983
|
+
});
|
|
2984
|
+
const nodeSize = 1 + nodesConsumed;
|
|
2985
|
+
i += nodeSize;
|
|
2986
|
+
totalConsumed += nodeSize;
|
|
2987
|
+
remaining--;
|
|
2988
|
+
}
|
|
3009
2989
|
return {
|
|
3010
|
-
|
|
3011
|
-
|
|
2990
|
+
children,
|
|
2991
|
+
nodesConsumed: totalConsumed
|
|
3012
2992
|
};
|
|
3013
2993
|
};
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
return
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
}
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
2994
|
+
|
|
2995
|
+
const compareNodes = (oldNode, newNode) => {
|
|
2996
|
+
// Check if node type changed - return null to signal incompatible nodes
|
|
2997
|
+
// (caller should handle this with a Replace operation)
|
|
2998
|
+
if (oldNode.type !== newNode.type) {
|
|
2999
|
+
return null;
|
|
3000
|
+
}
|
|
3001
|
+
const patches = [];
|
|
3002
|
+
// Handle reference nodes - special handling for uid changes
|
|
3003
|
+
if (oldNode.type === Reference && oldNode.uid !== newNode.uid) {
|
|
3004
|
+
patches.push({
|
|
3005
|
+
type: SetReferenceNodeUid,
|
|
3006
|
+
uid: newNode.uid
|
|
3007
|
+
});
|
|
3008
|
+
}
|
|
3009
|
+
// Handle text nodes
|
|
3010
|
+
if (oldNode.type === Text && newNode.type === Text) {
|
|
3011
|
+
if (oldNode.text !== newNode.text) {
|
|
3012
|
+
patches.push({
|
|
3013
|
+
type: SetText,
|
|
3014
|
+
value: newNode.text
|
|
3015
|
+
});
|
|
3016
|
+
}
|
|
3017
|
+
return patches;
|
|
3018
|
+
}
|
|
3019
|
+
// Compare attributes
|
|
3020
|
+
const oldKeys = getKeys(oldNode).filter(key => oldNode.type !== Reference || key !== 'uid');
|
|
3021
|
+
const newKeys = getKeys(newNode).filter(key => newNode.type !== Reference || key !== 'uid');
|
|
3022
|
+
// Check for attribute changes
|
|
3023
|
+
for (const key of newKeys) {
|
|
3024
|
+
if (oldNode[key] !== newNode[key]) {
|
|
3025
|
+
patches.push({
|
|
3026
|
+
type: SetAttribute,
|
|
3027
|
+
key,
|
|
3028
|
+
value: newNode[key]
|
|
3029
|
+
});
|
|
3030
|
+
}
|
|
3031
|
+
}
|
|
3032
|
+
// Check for removed attributes
|
|
3033
|
+
for (const key of oldKeys) {
|
|
3034
|
+
if (!Object.hasOwn(newNode, key)) {
|
|
3035
|
+
patches.push({
|
|
3036
|
+
type: RemoveAttribute,
|
|
3037
|
+
key
|
|
3038
|
+
});
|
|
3039
|
+
}
|
|
3040
|
+
}
|
|
3041
|
+
return patches;
|
|
3062
3042
|
};
|
|
3063
3043
|
|
|
3064
|
-
const
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
}, {
|
|
3076
|
-
command: 'Extensions.filterByMostPopular',
|
|
3077
|
-
flags: None$1,
|
|
3078
|
-
id: 'filterByMostPopular',
|
|
3079
|
-
label: mostPopular()
|
|
3080
|
-
}, {
|
|
3081
|
-
command: 'Extensions.filterByRecentlyPublished',
|
|
3082
|
-
flags: None$1,
|
|
3083
|
-
id: 'filterByRecentlyPublished',
|
|
3084
|
-
label: recentlyPublished()
|
|
3085
|
-
}, {
|
|
3086
|
-
command: 'Extensions.filterByRecommended',
|
|
3087
|
-
flags: None$1,
|
|
3088
|
-
id: 'filterByRecommended',
|
|
3089
|
-
label: recommended()
|
|
3090
|
-
}, {
|
|
3091
|
-
command: '',
|
|
3092
|
-
flags: Separator,
|
|
3093
|
-
id: 'separator1',
|
|
3094
|
-
label: ''
|
|
3095
|
-
}, {
|
|
3096
|
-
command: 'SearchExtensions.filterByCategory',
|
|
3097
|
-
flags: SubMenu,
|
|
3098
|
-
id: 'filterByCategory',
|
|
3099
|
-
label: category()
|
|
3100
|
-
}, {
|
|
3101
|
-
command: 'Extensions.filterByInstalled',
|
|
3102
|
-
flags: None$1,
|
|
3103
|
-
id: 'filterByInstalled',
|
|
3104
|
-
label: installed()
|
|
3105
|
-
}, {
|
|
3106
|
-
command: 'Extensions.filterByUpdates',
|
|
3107
|
-
flags: None$1,
|
|
3108
|
-
id: 'filterByUpdates',
|
|
3109
|
-
label: updates()
|
|
3110
|
-
}, {
|
|
3111
|
-
command: 'Extensions.filterByBuiltin',
|
|
3112
|
-
flags: None$1,
|
|
3113
|
-
id: 'filterByBuiltin',
|
|
3114
|
-
label: builtIn()
|
|
3115
|
-
}, {
|
|
3116
|
-
command: 'Extensions.filterByLinked',
|
|
3117
|
-
flags: None$1,
|
|
3118
|
-
id: 'filterByLinked',
|
|
3119
|
-
label: linked()
|
|
3120
|
-
}, {
|
|
3121
|
-
command: 'Extensions.filterByEnabled',
|
|
3122
|
-
flags: None$1,
|
|
3123
|
-
id: 'filterByEnabled',
|
|
3124
|
-
label: enabled()
|
|
3125
|
-
}, {
|
|
3126
|
-
command: 'Extensions.filterByDisabled',
|
|
3127
|
-
flags: None$1,
|
|
3128
|
-
id: 'filterByDisabled',
|
|
3129
|
-
label: disabled()
|
|
3130
|
-
}, {
|
|
3131
|
-
command: 'Extensions.filterByWorkspaceUnsupported',
|
|
3132
|
-
flags: None$1,
|
|
3133
|
-
id: 'filterByWorkspaceUnsupported',
|
|
3134
|
-
label: workspaceUnsupported()
|
|
3135
|
-
}, {
|
|
3136
|
-
command: '',
|
|
3137
|
-
flags: Separator,
|
|
3138
|
-
id: 'separator2',
|
|
3139
|
-
label: ''
|
|
3140
|
-
}, {
|
|
3141
|
-
command: 'SearchExtensions.filterBySortBy',
|
|
3142
|
-
flags: SubMenu,
|
|
3143
|
-
id: 'filterBySortBy',
|
|
3144
|
-
label: sortBy()
|
|
3145
|
-
}];
|
|
3044
|
+
const treeToArray = node => {
|
|
3045
|
+
const result = [];
|
|
3046
|
+
const stack = [node];
|
|
3047
|
+
while (stack.length > 0) {
|
|
3048
|
+
const current = stack.pop();
|
|
3049
|
+
result.push(current.node);
|
|
3050
|
+
for (let i = current.children.length - 1; i >= 0; i--) {
|
|
3051
|
+
stack.push(current.children[i]);
|
|
3052
|
+
}
|
|
3053
|
+
}
|
|
3054
|
+
return result;
|
|
3146
3055
|
};
|
|
3147
3056
|
|
|
3148
|
-
const
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3057
|
+
const navigateToChild = (patches, currentChildIndex, index) => {
|
|
3058
|
+
if (currentChildIndex === -1) {
|
|
3059
|
+
patches.push({
|
|
3060
|
+
type: NavigateChild,
|
|
3061
|
+
index
|
|
3062
|
+
});
|
|
3063
|
+
return index;
|
|
3064
|
+
}
|
|
3065
|
+
if (currentChildIndex !== index) {
|
|
3066
|
+
patches.push({
|
|
3067
|
+
type: NavigateSibling,
|
|
3068
|
+
index
|
|
3069
|
+
});
|
|
3157
3070
|
}
|
|
3071
|
+
return index;
|
|
3158
3072
|
};
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3073
|
+
const navigateToParent = (patches, currentChildIndex) => {
|
|
3074
|
+
if (currentChildIndex >= 0) {
|
|
3075
|
+
patches.push({
|
|
3076
|
+
type: NavigateParent
|
|
3077
|
+
});
|
|
3078
|
+
}
|
|
3079
|
+
return -1;
|
|
3162
3080
|
};
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
suggestOpen: false
|
|
3169
|
-
};
|
|
3081
|
+
const addTree = (newNode, patches) => {
|
|
3082
|
+
patches.push({
|
|
3083
|
+
type: Add,
|
|
3084
|
+
nodes: treeToArray(newNode)
|
|
3085
|
+
});
|
|
3170
3086
|
};
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3087
|
+
const replaceTree = (newNode, patches) => {
|
|
3088
|
+
patches.push({
|
|
3089
|
+
type: Replace,
|
|
3090
|
+
nodes: treeToArray(newNode)
|
|
3091
|
+
});
|
|
3174
3092
|
};
|
|
3175
|
-
|
|
3176
|
-
const
|
|
3177
|
-
|
|
3093
|
+
const diffExistingChild = (oldNode, newNode, patches, currentChildIndex, index) => {
|
|
3094
|
+
const nodePatches = compareNodes(oldNode.node, newNode.node);
|
|
3095
|
+
if (nodePatches === null) {
|
|
3096
|
+
const nextChildIndex = navigateToChild(patches, currentChildIndex, index);
|
|
3097
|
+
replaceTree(newNode, patches);
|
|
3098
|
+
return nextChildIndex;
|
|
3099
|
+
}
|
|
3100
|
+
const hasChildrenToCompare = oldNode.children.length > 0 || newNode.children.length > 0;
|
|
3101
|
+
if (nodePatches.length === 0 && !hasChildrenToCompare) {
|
|
3102
|
+
return currentChildIndex;
|
|
3103
|
+
}
|
|
3104
|
+
const nextChildIndex = navigateToChild(patches, currentChildIndex, index);
|
|
3105
|
+
if (nodePatches.length > 0) {
|
|
3106
|
+
patches.push(...nodePatches);
|
|
3107
|
+
}
|
|
3108
|
+
if (hasChildrenToCompare) {
|
|
3109
|
+
diffChildren(oldNode.children, newNode.children, patches);
|
|
3110
|
+
}
|
|
3111
|
+
return nextChildIndex;
|
|
3178
3112
|
};
|
|
3179
|
-
|
|
3180
|
-
const
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
}
|
|
3113
|
+
const diffRootNode = (oldNode, newNode, patches) => {
|
|
3114
|
+
const nodePatches = compareNodes(oldNode.node, newNode.node);
|
|
3115
|
+
if (nodePatches === null) {
|
|
3116
|
+
replaceTree(newNode, patches);
|
|
3117
|
+
return;
|
|
3118
|
+
}
|
|
3119
|
+
if (nodePatches.length > 0) {
|
|
3120
|
+
patches.push(...nodePatches);
|
|
3121
|
+
}
|
|
3122
|
+
if (oldNode.children.length > 0 || newNode.children.length > 0) {
|
|
3123
|
+
diffChildren(oldNode.children, newNode.children, patches);
|
|
3124
|
+
}
|
|
3185
3125
|
};
|
|
3186
|
-
|
|
3187
|
-
const
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3126
|
+
const diffChildren = (oldChildren, newChildren, patches) => {
|
|
3127
|
+
const maxLength = Math.max(oldChildren.length, newChildren.length);
|
|
3128
|
+
let currentChildIndex = -1;
|
|
3129
|
+
const indicesToRemove = [];
|
|
3130
|
+
for (let i = 0; i < maxLength; i++) {
|
|
3131
|
+
const oldNode = oldChildren[i];
|
|
3132
|
+
const newNode = newChildren[i];
|
|
3133
|
+
if (!oldNode && !newNode) {
|
|
3134
|
+
continue;
|
|
3135
|
+
}
|
|
3136
|
+
if (!oldNode) {
|
|
3137
|
+
currentChildIndex = navigateToParent(patches, currentChildIndex);
|
|
3138
|
+
addTree(newNode, patches);
|
|
3139
|
+
continue;
|
|
3140
|
+
}
|
|
3141
|
+
if (!newNode) {
|
|
3142
|
+
indicesToRemove.push(i);
|
|
3143
|
+
continue;
|
|
3144
|
+
}
|
|
3145
|
+
currentChildIndex = diffExistingChild(oldNode, newNode, patches, currentChildIndex, i);
|
|
3146
|
+
}
|
|
3147
|
+
navigateToParent(patches, currentChildIndex);
|
|
3148
|
+
for (let j = indicesToRemove.length - 1; j >= 0; j--) {
|
|
3149
|
+
patches.push({
|
|
3150
|
+
type: RemoveChild,
|
|
3151
|
+
index: indicesToRemove[j]
|
|
3152
|
+
});
|
|
3199
3153
|
}
|
|
3200
|
-
const extension = items[actualIndex];
|
|
3201
|
-
const uri = getExtensionDetailUri(extension.id);
|
|
3202
|
-
await openUri(uri);
|
|
3203
|
-
const partialNewState = selectIndex(state, actualIndex);
|
|
3204
|
-
const newState = {
|
|
3205
|
-
...partialNewState,
|
|
3206
|
-
focus: List$2
|
|
3207
|
-
};
|
|
3208
|
-
return newState;
|
|
3209
3154
|
};
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3155
|
+
const diffTrees = (oldTree, newTree, patches, path) => {
|
|
3156
|
+
if (path.length === 0 && oldTree.length === 1 && newTree.length === 1) {
|
|
3157
|
+
diffRootNode(oldTree[0], newTree[0], patches);
|
|
3158
|
+
return;
|
|
3159
|
+
}
|
|
3160
|
+
diffChildren(oldTree, newTree, patches);
|
|
3213
3161
|
};
|
|
3214
3162
|
|
|
3215
|
-
const
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3163
|
+
const removeTrailingNavigationPatches = patches => {
|
|
3164
|
+
while (patches.length > 0) {
|
|
3165
|
+
const patch = patches.at(-1);
|
|
3166
|
+
if (patch.type !== NavigateChild && patch.type !== NavigateParent && patch.type !== NavigateSibling) {
|
|
3167
|
+
break;
|
|
3168
|
+
}
|
|
3169
|
+
patches.pop();
|
|
3170
|
+
}
|
|
3171
|
+
return patches;
|
|
3221
3172
|
};
|
|
3222
3173
|
|
|
3223
|
-
|
|
3174
|
+
const diffTree = (oldNodes, newNodes) => {
|
|
3175
|
+
// Step 1: Convert flat arrays to tree structures
|
|
3176
|
+
const oldTree = arrayToTree(oldNodes);
|
|
3177
|
+
const newTree = arrayToTree(newNodes);
|
|
3178
|
+
// Step 3: Compare the trees
|
|
3179
|
+
const patches = [];
|
|
3180
|
+
diffTrees(oldTree, newTree, patches, []);
|
|
3181
|
+
// Remove trailing navigation patches since they serve no purpose
|
|
3182
|
+
return removeTrailingNavigationPatches(patches);
|
|
3183
|
+
};
|
|
3224
3184
|
|
|
3225
|
-
const
|
|
3226
|
-
const
|
|
3227
|
-
const
|
|
3228
|
-
const
|
|
3229
|
-
const
|
|
3230
|
-
const
|
|
3231
|
-
const
|
|
3232
|
-
const
|
|
3233
|
-
const
|
|
3234
|
-
const
|
|
3235
|
-
|
|
3236
|
-
const
|
|
3237
|
-
|
|
3238
|
-
|
|
3185
|
+
const Actions = 'Actions';
|
|
3186
|
+
const ExtensionActions = 'ExtensionActions';
|
|
3187
|
+
const ExtensionActionButton = 'ExtensionActionButton';
|
|
3188
|
+
const ExtensionActive = 'ExtensionActive';
|
|
3189
|
+
const ExtensionHeader = 'ExtensionHeader';
|
|
3190
|
+
const ExtensionListItem = 'ExtensionListItem';
|
|
3191
|
+
const ExtensionListItemActionInstall = 'ExtensionListItemActionInstall';
|
|
3192
|
+
const ExtensionListItemAuthorName = 'ExtensionListItemAuthorName';
|
|
3193
|
+
const ExtensionListItemDescription = 'ExtensionListItemDescription';
|
|
3194
|
+
const ExtensionListItemDetail = 'ExtensionListItemDetail';
|
|
3195
|
+
const ExtensionListItemDisabled = 'ExtensionListItemDisabled';
|
|
3196
|
+
const ExtensionListItemDownloadCount = 'ExtensionListItemDownloadCount';
|
|
3197
|
+
const ExtensionListItemFooter = 'ExtensionListItemFooter';
|
|
3198
|
+
const ExtensionListItemIcon = 'ExtensionListItemIcon';
|
|
3199
|
+
const ExtensionListItemLinkedIcon = 'ExtensionListItemLinkedIcon';
|
|
3200
|
+
const ExtensionListItemMetadata = 'ExtensionListItemMetadata';
|
|
3201
|
+
const ExtensionListItemName = 'ExtensionListItemName';
|
|
3202
|
+
const ExtensionListItemRating = 'ExtensionListItemRating';
|
|
3203
|
+
const ExtensionListItemStatistic = 'ExtensionListItemStatistic';
|
|
3204
|
+
const ExtensionSearchCompletionHighlight = 'ExtensionSearchCompletionHighlight';
|
|
3205
|
+
const ExtensionSearchCompletionItem = 'ExtensionSearchCompletionItem';
|
|
3206
|
+
const ExtensionSearchCompletionItemFocused = 'ExtensionSearchCompletionItemFocused';
|
|
3207
|
+
const ExtensionSearchCompletionWidget = 'ExtensionSearchCompletionWidget';
|
|
3208
|
+
const Extensions$1 = 'Extensions';
|
|
3209
|
+
const FocusOutline = 'FocusOutline';
|
|
3210
|
+
const IconButton = 'IconButton';
|
|
3211
|
+
const List$1 = 'List';
|
|
3212
|
+
const ListItems = 'ListItems';
|
|
3213
|
+
const MaskIcon = 'MaskIcon';
|
|
3214
|
+
const MultilineInputBox = 'MultilineInputBox';
|
|
3215
|
+
const NoExtensionsFoundMessage = 'NoExtensionsFoundMessage';
|
|
3216
|
+
const ScrollBar = 'ScrollBar';
|
|
3217
|
+
const ScrollBarSmall = 'ScrollBarSmall';
|
|
3218
|
+
const ScrollBarThumb = 'ScrollBarThumb';
|
|
3219
|
+
const ScrollBarThumbActive = 'ScrollBarThumbActive';
|
|
3220
|
+
const SearchField = 'SearchField';
|
|
3221
|
+
const SearchFieldButton = 'SearchFieldButton';
|
|
3222
|
+
const SearchFieldButtonDisabled = 'SearchFieldButtonDisabled';
|
|
3223
|
+
const SearchFieldButtons = 'SearchFieldButtons';
|
|
3224
|
+
const SearchFieldContainer = 'SearchFieldContainer';
|
|
3225
|
+
const Viewlet = 'Viewlet';
|
|
3239
3226
|
|
|
3240
|
-
const
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3227
|
+
const ComboBox = 'combobox';
|
|
3228
|
+
const Image = 'img';
|
|
3229
|
+
const List = 'list';
|
|
3230
|
+
const ListBox = 'listbox';
|
|
3231
|
+
const ListItem = 'listitem';
|
|
3232
|
+
const None$1 = 'none';
|
|
3233
|
+
const Option = 'option';
|
|
3234
|
+
const ToolBar = 'toolbar';
|
|
3244
3235
|
|
|
3245
|
-
const
|
|
3246
|
-
const
|
|
3247
|
-
let
|
|
3248
|
-
|
|
3249
|
-
const
|
|
3250
|
-
const
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
}
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
};
|
|
3262
|
-
const getChildrenWithCount = (nodes, startIndex, childCount) => {
|
|
3263
|
-
if (childCount === 0) {
|
|
3264
|
-
return {
|
|
3265
|
-
children: [],
|
|
3266
|
-
nodesConsumed: 0
|
|
3267
|
-
};
|
|
3236
|
+
const getCompletionLabelVirtualDom = (label, highlights) => {
|
|
3237
|
+
const dom = [];
|
|
3238
|
+
let position = 0;
|
|
3239
|
+
for (let i = 0; i < highlights.length; i += 2) {
|
|
3240
|
+
const start = highlights[i];
|
|
3241
|
+
const end = highlights[i + 1];
|
|
3242
|
+
if (position < start) {
|
|
3243
|
+
dom.push(text(label.slice(position, start)));
|
|
3244
|
+
}
|
|
3245
|
+
dom.push({
|
|
3246
|
+
childCount: 1,
|
|
3247
|
+
className: ExtensionSearchCompletionHighlight,
|
|
3248
|
+
name: label,
|
|
3249
|
+
type: Span
|
|
3250
|
+
}, text(label.slice(start, end)));
|
|
3251
|
+
position = end;
|
|
3268
3252
|
}
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
let remaining = childCount;
|
|
3272
|
-
let totalConsumed = 0;
|
|
3273
|
-
while (remaining > 0 && i < nodes.length) {
|
|
3274
|
-
const node = nodes[i];
|
|
3275
|
-
const nodeChildCount = node.childCount || 0;
|
|
3276
|
-
const {
|
|
3277
|
-
children: nodeChildren,
|
|
3278
|
-
nodesConsumed
|
|
3279
|
-
} = getChildrenWithCount(nodes, i + 1, nodeChildCount);
|
|
3280
|
-
children.push({
|
|
3281
|
-
node,
|
|
3282
|
-
children: nodeChildren
|
|
3283
|
-
});
|
|
3284
|
-
const nodeSize = 1 + nodesConsumed;
|
|
3285
|
-
i += nodeSize;
|
|
3286
|
-
totalConsumed += nodeSize;
|
|
3287
|
-
remaining--;
|
|
3253
|
+
if (position < label.length) {
|
|
3254
|
+
dom.push(text(label.slice(position)));
|
|
3288
3255
|
}
|
|
3289
|
-
return
|
|
3290
|
-
children,
|
|
3291
|
-
nodesConsumed: totalConsumed
|
|
3292
|
-
};
|
|
3256
|
+
return dom;
|
|
3293
3257
|
};
|
|
3294
3258
|
|
|
3295
|
-
const
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
const patches = [];
|
|
3302
|
-
// Handle reference nodes - special handling for uid changes
|
|
3303
|
-
if (oldNode.type === Reference && oldNode.uid !== newNode.uid) {
|
|
3304
|
-
patches.push({
|
|
3305
|
-
type: SetReferenceNodeUid,
|
|
3306
|
-
uid: newNode.uid
|
|
3307
|
-
});
|
|
3308
|
-
}
|
|
3309
|
-
// Handle text nodes
|
|
3310
|
-
if (oldNode.type === Text && newNode.type === Text) {
|
|
3311
|
-
if (oldNode.text !== newNode.text) {
|
|
3312
|
-
patches.push({
|
|
3313
|
-
type: SetText,
|
|
3314
|
-
value: newNode.text
|
|
3315
|
-
});
|
|
3316
|
-
}
|
|
3317
|
-
return patches;
|
|
3318
|
-
}
|
|
3319
|
-
// Compare attributes
|
|
3320
|
-
const oldKeys = getKeys(oldNode).filter(key => oldNode.type !== Reference || key !== 'uid');
|
|
3321
|
-
const newKeys = getKeys(newNode).filter(key => newNode.type !== Reference || key !== 'uid');
|
|
3322
|
-
// Check for attribute changes
|
|
3323
|
-
for (const key of newKeys) {
|
|
3324
|
-
if (oldNode[key] !== newNode[key]) {
|
|
3325
|
-
patches.push({
|
|
3326
|
-
type: SetAttribute,
|
|
3327
|
-
key,
|
|
3328
|
-
value: newNode[key]
|
|
3329
|
-
});
|
|
3259
|
+
const getRootNodeCount = nodes => {
|
|
3260
|
+
let count = 0;
|
|
3261
|
+
const remainingChildCounts = [];
|
|
3262
|
+
for (const node of nodes) {
|
|
3263
|
+
while (remainingChildCounts.length > 0 && remainingChildCounts.at(-1) === 0) {
|
|
3264
|
+
remainingChildCounts.pop();
|
|
3330
3265
|
}
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
type: RemoveAttribute,
|
|
3337
|
-
key
|
|
3338
|
-
});
|
|
3266
|
+
if (remainingChildCounts.length === 0) {
|
|
3267
|
+
count++;
|
|
3268
|
+
} else {
|
|
3269
|
+
const lastIndex = remainingChildCounts.length - 1;
|
|
3270
|
+
remainingChildCounts[lastIndex]--;
|
|
3339
3271
|
}
|
|
3272
|
+
remainingChildCounts.push(node.childCount);
|
|
3340
3273
|
}
|
|
3341
|
-
return
|
|
3274
|
+
return count;
|
|
3342
3275
|
};
|
|
3343
|
-
|
|
3344
|
-
const
|
|
3345
|
-
const
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3276
|
+
const getCompletionItemVirtualDom = (item, index, focusedIndex) => {
|
|
3277
|
+
const labelDom = getCompletionLabelVirtualDom(item.label, item.highlights);
|
|
3278
|
+
const focused = index === focusedIndex;
|
|
3279
|
+
return [{
|
|
3280
|
+
ariaSelected: focused,
|
|
3281
|
+
childCount: getRootNodeCount(labelDom),
|
|
3282
|
+
className: focused ? mergeClassNames(ExtensionSearchCompletionItem, ExtensionSearchCompletionItemFocused) : ExtensionSearchCompletionItem,
|
|
3283
|
+
id: `ExtensionSearchCompletion-${index}`,
|
|
3284
|
+
name: item.label,
|
|
3285
|
+
onPointerDown: HandlePointerDown,
|
|
3286
|
+
role: Option,
|
|
3287
|
+
type: Button$2
|
|
3288
|
+
}, ...labelDom];
|
|
3355
3289
|
};
|
|
3356
3290
|
|
|
3357
|
-
const
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
patches.push({
|
|
3367
|
-
type: NavigateSibling,
|
|
3368
|
-
index
|
|
3369
|
-
});
|
|
3370
|
-
}
|
|
3371
|
-
return index;
|
|
3291
|
+
const getCompletionWidgetVirtualDom = (items, focusedIndex) => {
|
|
3292
|
+
return [{
|
|
3293
|
+
ariaLabel: 'Extension search completions',
|
|
3294
|
+
childCount: items.length,
|
|
3295
|
+
className: ExtensionSearchCompletionWidget,
|
|
3296
|
+
id: 'ExtensionSearchCompletions',
|
|
3297
|
+
role: ListBox,
|
|
3298
|
+
type: Div
|
|
3299
|
+
}, ...items.flatMap((item, index) => getCompletionItemVirtualDom(item, index, focusedIndex))];
|
|
3372
3300
|
};
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3301
|
+
|
|
3302
|
+
const Focusable = 0;
|
|
3303
|
+
|
|
3304
|
+
const disabledClassName = mergeClassNames(SearchFieldButton, SearchFieldButtonDisabled);
|
|
3305
|
+
const getClassName = enabled => {
|
|
3306
|
+
if (enabled) {
|
|
3307
|
+
return SearchFieldButton;
|
|
3378
3308
|
}
|
|
3379
|
-
return
|
|
3380
|
-
};
|
|
3381
|
-
const addTree = (newNode, patches) => {
|
|
3382
|
-
patches.push({
|
|
3383
|
-
type: Add,
|
|
3384
|
-
nodes: treeToArray(newNode)
|
|
3385
|
-
});
|
|
3386
|
-
};
|
|
3387
|
-
const replaceTree = (newNode, patches) => {
|
|
3388
|
-
patches.push({
|
|
3389
|
-
type: Replace,
|
|
3390
|
-
nodes: treeToArray(newNode)
|
|
3391
|
-
});
|
|
3309
|
+
return disabledClassName;
|
|
3392
3310
|
};
|
|
3393
|
-
const
|
|
3394
|
-
const
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
}
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
}
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3311
|
+
const getSearchFieldButtonVirtualDom = button => {
|
|
3312
|
+
const {
|
|
3313
|
+
enabled,
|
|
3314
|
+
icon,
|
|
3315
|
+
onClick,
|
|
3316
|
+
title
|
|
3317
|
+
} = button;
|
|
3318
|
+
return [{
|
|
3319
|
+
childCount: 1,
|
|
3320
|
+
className: getClassName(enabled),
|
|
3321
|
+
onClick,
|
|
3322
|
+
tabIndex: Focusable,
|
|
3323
|
+
title,
|
|
3324
|
+
type: Button$2
|
|
3325
|
+
}, {
|
|
3326
|
+
childCount: 0,
|
|
3327
|
+
className: mergeClassNames(MaskIcon, icon),
|
|
3328
|
+
type: Div
|
|
3329
|
+
}];
|
|
3412
3330
|
};
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
if (nodePatches.length > 0) {
|
|
3420
|
-
patches.push(...nodePatches);
|
|
3421
|
-
}
|
|
3422
|
-
if (oldNode.children.length > 0 || newNode.children.length > 0) {
|
|
3423
|
-
diffChildren(oldNode.children, newNode.children, patches);
|
|
3424
|
-
}
|
|
3331
|
+
|
|
3332
|
+
const searchFieldNode = {
|
|
3333
|
+
childCount: 2,
|
|
3334
|
+
className: SearchField,
|
|
3335
|
+
role: None$1,
|
|
3336
|
+
type: Div
|
|
3425
3337
|
};
|
|
3426
|
-
const
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3338
|
+
const getSearchFieldVirtualDom = (name, placeholder, onInput, insideButtons, outsideButtons, onFocus = '', onBlur = '', inputProperties = {}) => {
|
|
3339
|
+
// TODO avoid mutation
|
|
3340
|
+
const dom = [searchFieldNode, {
|
|
3341
|
+
autocapitalize: 'off',
|
|
3342
|
+
autocomplete: 'off',
|
|
3343
|
+
autocorrect: 'off',
|
|
3344
|
+
childCount: 0,
|
|
3345
|
+
className: MultilineInputBox,
|
|
3346
|
+
inputType: 'search',
|
|
3347
|
+
name,
|
|
3348
|
+
...(onBlur && {
|
|
3349
|
+
onBlur
|
|
3350
|
+
}),
|
|
3351
|
+
onFocus,
|
|
3352
|
+
onInput,
|
|
3353
|
+
placeholder,
|
|
3354
|
+
spellcheck: false,
|
|
3355
|
+
type: Input$1,
|
|
3356
|
+
...inputProperties
|
|
3357
|
+
}, {
|
|
3358
|
+
childCount: insideButtons.length,
|
|
3359
|
+
className: SearchFieldButtons,
|
|
3360
|
+
type: Div
|
|
3361
|
+
}, ...insideButtons.flatMap(getSearchFieldButtonVirtualDom)];
|
|
3362
|
+
if (outsideButtons.length > 0) {
|
|
3363
|
+
dom.unshift({
|
|
3364
|
+
childCount: 1 + outsideButtons.length,
|
|
3365
|
+
className: SearchFieldContainer,
|
|
3366
|
+
role: None$1,
|
|
3367
|
+
type: Div
|
|
3452
3368
|
});
|
|
3369
|
+
dom.push(...outsideButtons.flatMap(getSearchFieldButtonVirtualDom));
|
|
3453
3370
|
}
|
|
3454
|
-
|
|
3455
|
-
const diffTrees = (oldTree, newTree, patches, path) => {
|
|
3456
|
-
if (path.length === 0 && oldTree.length === 1 && newTree.length === 1) {
|
|
3457
|
-
diffRootNode(oldTree[0], newTree[0], patches);
|
|
3458
|
-
return;
|
|
3459
|
-
}
|
|
3460
|
-
diffChildren(oldTree, newTree, patches);
|
|
3371
|
+
return dom;
|
|
3461
3372
|
};
|
|
3462
3373
|
|
|
3463
|
-
const
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
}
|
|
3469
|
-
patches.pop();
|
|
3374
|
+
const Extensions = 'extensions';
|
|
3375
|
+
|
|
3376
|
+
const getCompletionVirtualDom = (completionItems, completionFocusedIndex, suggestOpen) => {
|
|
3377
|
+
if (!suggestOpen) {
|
|
3378
|
+
return [];
|
|
3470
3379
|
}
|
|
3471
|
-
return
|
|
3380
|
+
return getCompletionWidgetVirtualDom(completionItems, completionFocusedIndex);
|
|
3472
3381
|
};
|
|
3473
|
-
|
|
3474
|
-
const
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3382
|
+
const getExtensionHeaderVirtualDom = (placeholder, actions, completionItems = [], completionFocusedIndex = 0, suggestOpen = false) => {
|
|
3383
|
+
const inputProperties = suggestOpen ? {
|
|
3384
|
+
ariaActivedescendant: `ExtensionSearchCompletion-${completionFocusedIndex}`,
|
|
3385
|
+
ariaAutoComplete: 'list',
|
|
3386
|
+
ariaControls: 'ExtensionSearchCompletions',
|
|
3387
|
+
ariaExpanded: true,
|
|
3388
|
+
role: ComboBox
|
|
3389
|
+
} : {
|
|
3390
|
+
ariaAutoComplete: 'list',
|
|
3391
|
+
ariaExpanded: false,
|
|
3392
|
+
role: ComboBox
|
|
3393
|
+
};
|
|
3394
|
+
const completionDom = getCompletionVirtualDom(completionItems, completionFocusedIndex, suggestOpen);
|
|
3395
|
+
return [{
|
|
3396
|
+
childCount: suggestOpen ? 2 : 1,
|
|
3397
|
+
className: ExtensionHeader,
|
|
3398
|
+
onContextMenu: HandleHeaderContextMenu,
|
|
3399
|
+
type: Div
|
|
3400
|
+
}, ...getSearchFieldVirtualDom(Extensions, placeholder, HandleExtensionsInput, actions, [], HandleInputFocus, HandleInputBlur, inputProperties), ...completionDom];
|
|
3483
3401
|
};
|
|
3484
3402
|
|
|
3485
|
-
const
|
|
3486
|
-
const relativeDeltaY = deltaY % itemHeight;
|
|
3487
|
-
const relativeY = eventY - y - headerHeight + relativeDeltaY;
|
|
3488
|
-
const index = Math.floor(relativeY / itemHeight);
|
|
3489
|
-
return index;
|
|
3490
|
-
};
|
|
3403
|
+
const Extension = 'Extension';
|
|
3491
3404
|
|
|
3492
|
-
const
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
return acceptCompletion(state, label);
|
|
3405
|
+
const install = {
|
|
3406
|
+
disabled: false,
|
|
3407
|
+
label: install$1(),
|
|
3408
|
+
onClick: HandleInstall
|
|
3497
3409
|
};
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3410
|
+
const installing = {
|
|
3411
|
+
disabled: true,
|
|
3412
|
+
label: installing$1(),
|
|
3413
|
+
onClick: HandleInstall
|
|
3414
|
+
};
|
|
3415
|
+
const enable = {
|
|
3416
|
+
disabled: false,
|
|
3417
|
+
label: enable$2(),
|
|
3418
|
+
onClick: HandleEnable
|
|
3419
|
+
};
|
|
3420
|
+
const disable = {
|
|
3421
|
+
disabled: false,
|
|
3422
|
+
label: disable$2(),
|
|
3423
|
+
onClick: HandleDisable
|
|
3424
|
+
};
|
|
3425
|
+
const uninstall = {
|
|
3426
|
+
disabled: false,
|
|
3427
|
+
label: uninstall$1(),
|
|
3428
|
+
onClick: HandleUninstall
|
|
3429
|
+
};
|
|
3430
|
+
const uninstalling = {
|
|
3431
|
+
disabled: true,
|
|
3432
|
+
label: uninstalling$1(),
|
|
3433
|
+
onClick: HandleUninstall
|
|
3434
|
+
};
|
|
3435
|
+
const getExtensionActions = (builtin, disabled, status) => {
|
|
3436
|
+
if (status === NotInstalled) {
|
|
3437
|
+
return [install];
|
|
3502
3438
|
}
|
|
3503
|
-
if (
|
|
3504
|
-
return
|
|
3439
|
+
if (status === Installing) {
|
|
3440
|
+
return [installing];
|
|
3505
3441
|
}
|
|
3506
|
-
if (
|
|
3507
|
-
return
|
|
3442
|
+
if (status === Uninstalling) {
|
|
3443
|
+
return builtin ? [] : [uninstalling];
|
|
3508
3444
|
}
|
|
3509
|
-
const
|
|
3510
|
-
|
|
3511
|
-
headerHeight,
|
|
3512
|
-
itemHeight,
|
|
3513
|
-
x,
|
|
3514
|
-
y
|
|
3515
|
-
} = state;
|
|
3516
|
-
const index = getListIndex(eventX, eventY, x, y, deltaY, itemHeight, headerHeight);
|
|
3517
|
-
return handleClick(state, index);
|
|
3445
|
+
const enableOrDisable = isExtensionDisabled(disabled, status) ? enable : disable;
|
|
3446
|
+
return builtin ? [enableOrDisable] : [enableOrDisable, uninstall];
|
|
3518
3447
|
};
|
|
3519
3448
|
|
|
3520
|
-
const
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3449
|
+
const className = mergeClassNames(ExtensionListItemActionInstall, ExtensionActionButton);
|
|
3450
|
+
const getExtensionActionVirtualDom = (action, id) => {
|
|
3451
|
+
return [{
|
|
3452
|
+
childCount: 1,
|
|
3453
|
+
className,
|
|
3454
|
+
disabled: action.disabled,
|
|
3455
|
+
name: id,
|
|
3456
|
+
onClick: action.onClick,
|
|
3457
|
+
type: Button$2
|
|
3458
|
+
}, text(action.label)];
|
|
3525
3459
|
};
|
|
3526
3460
|
|
|
3527
|
-
const
|
|
3528
|
-
const
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3461
|
+
const getExtensionActionsVirtualDom = (id, builtin, disabled, status) => {
|
|
3462
|
+
const actions = getExtensionActions(builtin, disabled, status);
|
|
3463
|
+
return [{
|
|
3464
|
+
childCount: actions.length,
|
|
3465
|
+
className: ExtensionActions,
|
|
3466
|
+
type: Div
|
|
3467
|
+
}, ...actions.flatMap(action => getExtensionActionVirtualDom(action, id))];
|
|
3532
3468
|
};
|
|
3533
3469
|
|
|
3534
|
-
const
|
|
3535
|
-
|
|
3536
|
-
};
|
|
3537
|
-
|
|
3538
|
-
const handleClickFilter = async state => {
|
|
3539
|
-
const {
|
|
3540
|
-
headerHeight,
|
|
3541
|
-
uid,
|
|
3542
|
-
width,
|
|
3543
|
-
x,
|
|
3544
|
-
y
|
|
3545
|
-
} = state;
|
|
3546
|
-
const menuX = x + width + 60;
|
|
3547
|
-
const menuHeight = 370;
|
|
3548
|
-
const menuY = y + headerHeight + menuHeight;
|
|
3549
|
-
await show2(uid, ExtensionSearchFilter, menuX, menuY, {
|
|
3550
|
-
menuId: ExtensionSearchFilter
|
|
3551
|
-
});
|
|
3552
|
-
return state;
|
|
3470
|
+
const getExtensionListItemClassName = (focused, disabled) => {
|
|
3471
|
+
return mergeClassNames(ExtensionListItem, focused ? ExtensionActive : '', disabled ? ExtensionListItemDisabled : '');
|
|
3553
3472
|
};
|
|
3554
3473
|
|
|
3555
|
-
const
|
|
3556
|
-
// TODO use focused index when when context menu button is -1 (keyboard)
|
|
3557
|
-
const {
|
|
3558
|
-
deltaY,
|
|
3559
|
-
headerHeight,
|
|
3560
|
-
itemHeight,
|
|
3561
|
-
items,
|
|
3562
|
-
minLineY,
|
|
3563
|
-
uid,
|
|
3564
|
-
x,
|
|
3565
|
-
y
|
|
3566
|
-
} = state;
|
|
3567
|
-
const visibleIndex = getListIndex(eventX, eventY, x, y, deltaY, itemHeight, headerHeight);
|
|
3568
|
-
const index = visibleIndex + minLineY;
|
|
3569
|
-
if (index < 0 || index >= items.length) {
|
|
3570
|
-
return state;
|
|
3571
|
-
}
|
|
3572
|
-
const item = items[index];
|
|
3573
|
-
await show2(uid, ManageExtension, eventX, eventY, {
|
|
3574
|
-
builtin: item.builtin === true,
|
|
3575
|
-
disabled: item.disabled === true,
|
|
3576
|
-
menuId: ManageExtension,
|
|
3577
|
-
status: item.status
|
|
3578
|
-
});
|
|
3474
|
+
const getExtensionListItemFooter = hasStatistics => {
|
|
3579
3475
|
return {
|
|
3580
|
-
|
|
3581
|
-
|
|
3476
|
+
childCount: hasStatistics ? 3 : 2,
|
|
3477
|
+
className: ExtensionListItemFooter,
|
|
3478
|
+
type: Div
|
|
3582
3479
|
};
|
|
3583
3480
|
};
|
|
3584
3481
|
|
|
3585
|
-
const
|
|
3586
|
-
|
|
3482
|
+
const getExtensionListItemId = focused => {
|
|
3483
|
+
if (focused) {
|
|
3484
|
+
return `ExtensionActive`;
|
|
3485
|
+
}
|
|
3486
|
+
return undefined;
|
|
3587
3487
|
};
|
|
3588
3488
|
|
|
3589
|
-
const
|
|
3590
|
-
|
|
3489
|
+
const extensionListItemMetadataNode = {
|
|
3490
|
+
childCount: 2,
|
|
3491
|
+
className: ExtensionListItemMetadata,
|
|
3492
|
+
type: Div
|
|
3493
|
+
};
|
|
3494
|
+
const getStatisticVirtualDom = (label, value, className) => {
|
|
3495
|
+
const accessibleLabel = `${label}: ${value}`;
|
|
3496
|
+
return [{
|
|
3497
|
+
ariaLabel: accessibleLabel,
|
|
3498
|
+
childCount: 1,
|
|
3499
|
+
className: mergeClassNames(ExtensionListItemStatistic, className),
|
|
3500
|
+
title: accessibleLabel,
|
|
3501
|
+
type: Span
|
|
3502
|
+
}, text(value)];
|
|
3503
|
+
};
|
|
3504
|
+
const getExtensionStatisticsVirtualDom = (downloadCount, rating$1) => {
|
|
3505
|
+
return [extensionListItemMetadataNode, ...getStatisticVirtualDom(downloads(), downloadCount, ExtensionListItemDownloadCount), ...getStatisticVirtualDom(rating(), rating$1, ExtensionListItemRating)];
|
|
3591
3506
|
};
|
|
3592
3507
|
|
|
3593
|
-
const
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
const getAllExtensions$1 = async (assetDir, platform) => {
|
|
3598
|
-
try {
|
|
3599
|
-
return await invoke$3('Extensions.getAllExtensions', assetDir, platform);
|
|
3600
|
-
} catch (error) {
|
|
3601
|
-
if (platform === Web) {
|
|
3602
|
-
return [];
|
|
3603
|
-
}
|
|
3604
|
-
throw error;
|
|
3508
|
+
const getExtensionListItemStatisticsVirtualDom = (hasStatistics, downloadCount, rating) => {
|
|
3509
|
+
if (!hasStatistics) {
|
|
3510
|
+
return [];
|
|
3605
3511
|
}
|
|
3512
|
+
return getExtensionStatisticsVirtualDom(downloadCount, rating);
|
|
3606
3513
|
};
|
|
3607
3514
|
|
|
3608
|
-
const
|
|
3609
|
-
return
|
|
3515
|
+
const getListItemDetail = linked => {
|
|
3516
|
+
return {
|
|
3517
|
+
childCount: linked ? 4 : 3,
|
|
3518
|
+
className: ExtensionListItemDetail,
|
|
3519
|
+
type: Div
|
|
3520
|
+
};
|
|
3610
3521
|
};
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3522
|
+
const listItemName = {
|
|
3523
|
+
childCount: 1,
|
|
3524
|
+
className: ExtensionListItemName,
|
|
3525
|
+
type: Div
|
|
3526
|
+
};
|
|
3527
|
+
const listItemDescription = {
|
|
3528
|
+
childCount: 1,
|
|
3529
|
+
className: ExtensionListItemDescription,
|
|
3530
|
+
type: Div
|
|
3531
|
+
};
|
|
3532
|
+
const listItemAuthorName = {
|
|
3533
|
+
childCount: 1,
|
|
3534
|
+
className: ExtensionListItemAuthorName,
|
|
3535
|
+
type: Div
|
|
3536
|
+
};
|
|
3537
|
+
const getLinkedIconVirtualDom = linked$1 => {
|
|
3538
|
+
if (!linked$1) {
|
|
3539
|
+
return [];
|
|
3615
3540
|
}
|
|
3541
|
+
const label = linked();
|
|
3542
|
+
return [{
|
|
3543
|
+
ariaLabel: label,
|
|
3544
|
+
childCount: 0,
|
|
3545
|
+
className: mergeClassNames(MaskIcon, 'MaskIconLinkExternal', ExtensionListItemLinkedIcon),
|
|
3546
|
+
role: Image,
|
|
3547
|
+
title: 'Extension is linked',
|
|
3548
|
+
type: Div
|
|
3549
|
+
}];
|
|
3550
|
+
};
|
|
3551
|
+
const getExtensionListItemVirtualDom = extension => {
|
|
3616
3552
|
const {
|
|
3617
|
-
builtin,
|
|
3553
|
+
builtin = false,
|
|
3554
|
+
description,
|
|
3555
|
+
disabled = false,
|
|
3556
|
+
downloadCount = 'n/a',
|
|
3557
|
+
focused,
|
|
3558
|
+
icon,
|
|
3618
3559
|
id,
|
|
3619
|
-
|
|
3560
|
+
linked = false,
|
|
3561
|
+
name,
|
|
3562
|
+
posInSet,
|
|
3563
|
+
publisher,
|
|
3564
|
+
rating = 'n/a',
|
|
3565
|
+
setSize,
|
|
3566
|
+
status
|
|
3620
3567
|
} = extension;
|
|
3621
|
-
|
|
3568
|
+
const actionsDom = getExtensionActionsVirtualDom(id, builtin, disabled, status);
|
|
3569
|
+
const hasStatistics = !builtin;
|
|
3570
|
+
const dom = [{
|
|
3571
|
+
ariaPosInSet: posInSet,
|
|
3572
|
+
ariaRoleDescription: Extension,
|
|
3573
|
+
ariaSetSize: setSize,
|
|
3574
|
+
childCount: 2,
|
|
3575
|
+
className: getExtensionListItemClassName(focused, disabled),
|
|
3576
|
+
id: getExtensionListItemId(focused),
|
|
3577
|
+
role: ListItem,
|
|
3578
|
+
type: Div
|
|
3579
|
+
}, {
|
|
3580
|
+
childCount: 0,
|
|
3581
|
+
className: ExtensionListItemIcon,
|
|
3582
|
+
role: None$1,
|
|
3583
|
+
src: icon,
|
|
3584
|
+
type: Img
|
|
3585
|
+
}, getListItemDetail(linked), listItemName, text(name), listItemDescription, text(description), getExtensionListItemFooter(hasStatistics), listItemAuthorName, text(publisher), ...getExtensionListItemStatisticsVirtualDom(hasStatistics, downloadCount, rating), ...actionsDom, ...getLinkedIconVirtualDom(linked)];
|
|
3586
|
+
return dom;
|
|
3622
3587
|
};
|
|
3623
3588
|
|
|
3624
|
-
const
|
|
3625
|
-
|
|
3589
|
+
const getListClassName = focusOutline => {
|
|
3590
|
+
const className = focusOutline ? mergeClassNames(ListItems, FocusOutline) : ListItems;
|
|
3591
|
+
return className;
|
|
3626
3592
|
};
|
|
3627
|
-
|
|
3628
|
-
const
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3593
|
+
const getExtensionsListVirtualDom = (visibleExtensions, focusOutline) => {
|
|
3594
|
+
const dom = [{
|
|
3595
|
+
ariaLabel: extensions(),
|
|
3596
|
+
childCount: visibleExtensions.length,
|
|
3597
|
+
className: getListClassName(focusOutline),
|
|
3598
|
+
onBlur: HandleBlur,
|
|
3599
|
+
onContextmenu: HandleContextMenu,
|
|
3600
|
+
onContextMenu: HandleContextMenu,
|
|
3601
|
+
onFocus: HandleFocus,
|
|
3602
|
+
onPointerDown: HandlePointerDown,
|
|
3603
|
+
onTouchEnd: HandleTouchEnd,
|
|
3604
|
+
onTouchMove: HandleTouchMove,
|
|
3605
|
+
onTouchStart: HandleTouchStart,
|
|
3606
|
+
onWheel: HandleWheel,
|
|
3607
|
+
role: List,
|
|
3608
|
+
tabIndex: Focusable,
|
|
3609
|
+
type: Div
|
|
3610
|
+
}, ...visibleExtensions.flatMap(getExtensionListItemVirtualDom)];
|
|
3611
|
+
return dom;
|
|
3633
3612
|
};
|
|
3634
3613
|
|
|
3635
|
-
const
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
return extension.description;
|
|
3614
|
+
const getExtensionsVirtualDom = (visibleExtensions, focusOutline) => {
|
|
3615
|
+
const dom = getExtensionsListVirtualDom(visibleExtensions, focusOutline);
|
|
3616
|
+
// TODO
|
|
3617
|
+
return dom;
|
|
3640
3618
|
};
|
|
3641
3619
|
|
|
3642
|
-
const
|
|
3643
|
-
|
|
3620
|
+
const noExtensionsFoundNode = {
|
|
3621
|
+
childCount: 1,
|
|
3622
|
+
className: NoExtensionsFoundMessage,
|
|
3623
|
+
type: Div
|
|
3624
|
+
};
|
|
3625
|
+
const getNoExtensionsFoundVirtualDom = message => {
|
|
3626
|
+
return [noExtensionsFoundNode, text(message)];
|
|
3644
3627
|
};
|
|
3645
3628
|
|
|
3646
|
-
const
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
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);
|
|
3629
|
+
const scrollBarNode = {
|
|
3630
|
+
childCount: 1,
|
|
3631
|
+
className: mergeClassNames(ScrollBar, ScrollBarSmall),
|
|
3632
|
+
onPointerDown: HandleScrollBarPointerDown,
|
|
3633
|
+
// TODO support pointercapture event
|
|
3634
|
+
type: Div
|
|
3653
3635
|
};
|
|
3654
|
-
const
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3636
|
+
const scrollBarThumbNode = {
|
|
3637
|
+
childCount: 0,
|
|
3638
|
+
className: ScrollBarThumb,
|
|
3639
|
+
type: Div
|
|
3640
|
+
};
|
|
3641
|
+
const getScrollBarVirtualDom = (scrollBarHeight, scrollBarTop) => {
|
|
3642
|
+
const shouldShowScrollbar = scrollBarHeight > 0;
|
|
3643
|
+
if (!shouldShowScrollbar) {
|
|
3644
|
+
return [];
|
|
3658
3645
|
}
|
|
3659
|
-
return
|
|
3646
|
+
return [scrollBarNode, scrollBarThumbNode];
|
|
3660
3647
|
};
|
|
3661
3648
|
|
|
3662
|
-
const
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3649
|
+
const getVisibleItem = (item, setSize, itemHeight, minLineY, relative, i, focusedIndex) => {
|
|
3650
|
+
// TODO use normal parameters
|
|
3651
|
+
const {
|
|
3652
|
+
builtin,
|
|
3653
|
+
description,
|
|
3654
|
+
disabled,
|
|
3655
|
+
downloadCount,
|
|
3656
|
+
icon,
|
|
3657
|
+
id,
|
|
3658
|
+
linked,
|
|
3659
|
+
name,
|
|
3660
|
+
publisher,
|
|
3661
|
+
rating,
|
|
3662
|
+
status
|
|
3663
|
+
} = item;
|
|
3664
|
+
return {
|
|
3665
|
+
builtin,
|
|
3666
|
+
description,
|
|
3667
|
+
disabled,
|
|
3668
|
+
downloadCount,
|
|
3669
|
+
focused: i === focusedIndex,
|
|
3670
|
+
icon,
|
|
3671
|
+
id,
|
|
3672
|
+
index: i,
|
|
3673
|
+
linked,
|
|
3674
|
+
name,
|
|
3675
|
+
posInSet: i + 1,
|
|
3676
|
+
publisher,
|
|
3677
|
+
rating,
|
|
3678
|
+
setSize,
|
|
3679
|
+
status,
|
|
3680
|
+
top: (i - minLineY) * itemHeight - relative
|
|
3681
|
+
};
|
|
3680
3682
|
};
|
|
3681
3683
|
|
|
3682
|
-
const
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3684
|
+
const getVisible = state => {
|
|
3685
|
+
const {
|
|
3686
|
+
deltaY,
|
|
3687
|
+
focusedIndex,
|
|
3688
|
+
itemHeight,
|
|
3689
|
+
items,
|
|
3690
|
+
maxLineY,
|
|
3691
|
+
minLineY
|
|
3692
|
+
} = state;
|
|
3693
|
+
const setSize = items.length;
|
|
3694
|
+
const visible = [];
|
|
3695
|
+
const relative = deltaY % itemHeight;
|
|
3696
|
+
for (let i = minLineY; i < maxLineY; i++) {
|
|
3697
|
+
const item = items[i];
|
|
3698
|
+
visible.push(getVisibleItem(item, setSize, itemHeight, minLineY, relative, i, focusedIndex));
|
|
3699
|
+
}
|
|
3700
|
+
return visible;
|
|
3690
3701
|
};
|
|
3691
3702
|
|
|
3692
|
-
const
|
|
3693
|
-
|
|
3703
|
+
const contentNode = {
|
|
3704
|
+
childCount: 2,
|
|
3705
|
+
className: mergeClassNames(Viewlet, List$1),
|
|
3706
|
+
type: Div
|
|
3694
3707
|
};
|
|
3695
|
-
const
|
|
3696
|
-
|
|
3708
|
+
const extensionsNode = {
|
|
3709
|
+
ariaBusy: false,
|
|
3710
|
+
ariaLive: 'polite',
|
|
3711
|
+
childCount: 2,
|
|
3712
|
+
className: mergeClassNames(Viewlet, Extensions$1),
|
|
3713
|
+
role: None$3,
|
|
3714
|
+
type: Div
|
|
3697
3715
|
};
|
|
3698
|
-
const
|
|
3699
|
-
if (
|
|
3700
|
-
return
|
|
3701
|
-
}
|
|
3702
|
-
const hasIcon = 'icon' in extension && typeof extension.icon === 'string' && extension.icon;
|
|
3703
|
-
const hasPath = 'path' in extension && typeof extension.path === 'string' && extension.path;
|
|
3704
|
-
if (!hasPath || !hasIcon) {
|
|
3705
|
-
if (isLanguageBasicsExtension(extension)) {
|
|
3706
|
-
return getExtensionLanguageBasicsIcon(assetDir);
|
|
3707
|
-
}
|
|
3708
|
-
if (isThemeExtension(extension)) {
|
|
3709
|
-
return getExtensionThemeIcon(assetDir);
|
|
3710
|
-
}
|
|
3711
|
-
return getExtensionDefaultIcon(assetDir);
|
|
3716
|
+
const getContentVirtualDom = (visibleExtensions, message, scrollBarHeight, scrollBarY, focusOutline) => {
|
|
3717
|
+
if (message) {
|
|
3718
|
+
return getNoExtensionsFoundVirtualDom(message);
|
|
3712
3719
|
}
|
|
3713
|
-
return
|
|
3720
|
+
return [contentNode, ...getExtensionsVirtualDom(visibleExtensions, focusOutline), ...getScrollBarVirtualDom(scrollBarHeight)];
|
|
3714
3721
|
};
|
|
3715
|
-
|
|
3716
|
-
const
|
|
3717
|
-
|
|
3722
|
+
const getExtensionsViewVirtualDom = state => {
|
|
3723
|
+
const visibleExtensions = getVisible(state);
|
|
3724
|
+
const {
|
|
3725
|
+
completionFocusedIndex,
|
|
3726
|
+
completionItems,
|
|
3727
|
+
focus,
|
|
3728
|
+
focusedIndex,
|
|
3729
|
+
inputActions,
|
|
3730
|
+
message,
|
|
3731
|
+
placeholder,
|
|
3732
|
+
scrollBarHeight,
|
|
3733
|
+
scrollBarY,
|
|
3734
|
+
suggestOpen
|
|
3735
|
+
} = state;
|
|
3736
|
+
const focusOutline = focusedIndex === -1 && focus === List$2;
|
|
3737
|
+
return [extensionsNode, ...getExtensionHeaderVirtualDom(placeholder, inputActions, completionItems, completionFocusedIndex, suggestOpen), ...getContentVirtualDom(visibleExtensions, message, scrollBarHeight, scrollBarY, focusOutline)];
|
|
3718
3738
|
};
|
|
3719
3739
|
|
|
3720
|
-
const
|
|
3721
|
-
|
|
3722
|
-
|
|
3740
|
+
const renderItems2 = newState => {
|
|
3741
|
+
const {
|
|
3742
|
+
initial,
|
|
3743
|
+
uid
|
|
3744
|
+
} = newState;
|
|
3745
|
+
if (initial) {
|
|
3746
|
+
return [SetDom2, uid, []];
|
|
3723
3747
|
}
|
|
3724
|
-
|
|
3748
|
+
const dom = getExtensionsViewVirtualDom(newState);
|
|
3749
|
+
return [SetDom2, uid, dom];
|
|
3725
3750
|
};
|
|
3726
3751
|
|
|
3727
|
-
const
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
}
|
|
3731
|
-
if ('linked' in extension && extension.linked === true) {
|
|
3732
|
-
return true;
|
|
3733
|
-
}
|
|
3734
|
-
return 'symlink' in extension && typeof extension.symlink === 'string' && extension.symlink.length > 0;
|
|
3752
|
+
const getComponentDom = uid => {
|
|
3753
|
+
const state = getComponentState(uid);
|
|
3754
|
+
return renderItems2(state)[2];
|
|
3735
3755
|
};
|
|
3736
3756
|
|
|
3737
|
-
const
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
return 'n/a';
|
|
3748
|
-
};
|
|
3757
|
+
const Tab = 2;
|
|
3758
|
+
const Enter = 3;
|
|
3759
|
+
const Escape = 8;
|
|
3760
|
+
const Space = 9;
|
|
3761
|
+
const PageUp = 10;
|
|
3762
|
+
const PageDown = 11;
|
|
3763
|
+
const End = 255;
|
|
3764
|
+
const Home = 12;
|
|
3765
|
+
const UpArrow = 14;
|
|
3766
|
+
const DownArrow = 16;
|
|
3749
3767
|
|
|
3750
|
-
const
|
|
3751
|
-
const getPublisher = extension => {
|
|
3752
|
-
if (extension === null || typeof extension !== 'object' || !('id' in extension) || typeof extension.id !== 'string') {
|
|
3753
|
-
return 'n/a';
|
|
3754
|
-
}
|
|
3755
|
-
const match = extension.id.match(RE_PUBLISHER);
|
|
3756
|
-
if (!match) {
|
|
3757
|
-
return 'n/a';
|
|
3758
|
-
}
|
|
3759
|
-
return match[0];
|
|
3760
|
-
};
|
|
3768
|
+
const CtrlCmd = 1 << 11 >>> 0;
|
|
3761
3769
|
|
|
3762
|
-
const
|
|
3763
|
-
|
|
3764
|
-
return undefined;
|
|
3765
|
-
}
|
|
3766
|
-
const marketplace = 'marketplace' in extension && extension.marketplace !== null && typeof extension.marketplace === 'object' ? extension.marketplace : {};
|
|
3767
|
-
const packageJson = 'packageJSON' in extension && extension.packageJSON !== null && typeof extension.packageJSON === 'object' ? extension.packageJSON : {};
|
|
3768
|
-
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);
|
|
3769
|
-
};
|
|
3770
|
-
const getRating = extension => {
|
|
3771
|
-
const rating = getRatingValue(extension);
|
|
3772
|
-
if (typeof rating !== 'number') {
|
|
3773
|
-
return 'n/a';
|
|
3774
|
-
}
|
|
3775
|
-
return rating.toFixed(1);
|
|
3776
|
-
};
|
|
3770
|
+
const FocusExtensions = 15;
|
|
3771
|
+
const FocusExtensionsInput = 7000;
|
|
3777
3772
|
|
|
3778
|
-
const
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3773
|
+
const getKeyBindings = () => {
|
|
3774
|
+
return [{
|
|
3775
|
+
command: 'Extensions.closeSuggest',
|
|
3776
|
+
key: Escape,
|
|
3777
|
+
when: FocusExtensionsInput
|
|
3778
|
+
}, {
|
|
3779
|
+
command: 'Extensions.acceptCompletion',
|
|
3780
|
+
key: Enter,
|
|
3781
|
+
when: FocusExtensionsInput
|
|
3782
|
+
}, {
|
|
3783
|
+
command: 'Extensions.acceptCompletion',
|
|
3784
|
+
key: Tab,
|
|
3785
|
+
when: FocusExtensionsInput
|
|
3786
|
+
}, {
|
|
3787
|
+
command: 'Extensions.selectPreviousCompletion',
|
|
3788
|
+
key: UpArrow,
|
|
3789
|
+
when: FocusExtensionsInput
|
|
3790
|
+
}, {
|
|
3791
|
+
command: 'Extensions.selectNextCompletion',
|
|
3792
|
+
key: DownArrow,
|
|
3793
|
+
when: FocusExtensionsInput
|
|
3794
|
+
}, {
|
|
3795
|
+
command: 'Extensions.openSuggest',
|
|
3796
|
+
key: CtrlCmd | Space,
|
|
3797
|
+
when: FocusExtensionsInput
|
|
3798
|
+
}, {
|
|
3799
|
+
command: 'Extensions.focusFirst',
|
|
3800
|
+
key: Home,
|
|
3801
|
+
when: FocusExtensions
|
|
3802
|
+
}, {
|
|
3803
|
+
command: 'Extensions.focusLast',
|
|
3804
|
+
key: End,
|
|
3805
|
+
when: FocusExtensions
|
|
3806
|
+
}, {
|
|
3807
|
+
command: 'Extensions.focusPreviousPage',
|
|
3808
|
+
key: PageUp,
|
|
3809
|
+
when: FocusExtensions
|
|
3810
|
+
}, {
|
|
3811
|
+
command: 'Extensions.focusNextPage',
|
|
3812
|
+
key: PageDown,
|
|
3813
|
+
when: FocusExtensions
|
|
3814
|
+
}, {
|
|
3815
|
+
command: 'Extensions.focusPrevious',
|
|
3816
|
+
key: UpArrow,
|
|
3817
|
+
when: FocusExtensions
|
|
3818
|
+
}, {
|
|
3819
|
+
command: 'Extensions.focusNext',
|
|
3820
|
+
key: DownArrow,
|
|
3821
|
+
when: FocusExtensions
|
|
3822
|
+
}, {
|
|
3823
|
+
command: 'Extensions.handleClickCurrentButKeepFocus',
|
|
3824
|
+
key: Space,
|
|
3825
|
+
when: FocusExtensions
|
|
3826
|
+
}, {
|
|
3827
|
+
command: 'Extensions.handleClickCurrent',
|
|
3828
|
+
key: Enter,
|
|
3829
|
+
when: FocusExtensions
|
|
3830
|
+
}, {
|
|
3831
|
+
command: 'Extensions.toggleSuggest',
|
|
3832
|
+
key: CtrlCmd | Space,
|
|
3833
|
+
when: FocusExtensions
|
|
3834
|
+
}, {
|
|
3835
|
+
command: 'Extensions.scrollDown',
|
|
3836
|
+
key: CtrlCmd | DownArrow,
|
|
3837
|
+
when: FocusExtensions
|
|
3838
|
+
}];
|
|
3783
3839
|
};
|
|
3784
3840
|
|
|
3785
|
-
const
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
return typeof extension.status === 'string' ? extension.status : undefined;
|
|
3790
|
-
};
|
|
3791
|
-
|
|
3792
|
-
const getUpdatedDate = extension => {
|
|
3793
|
-
if (extension === null || typeof extension !== 'object' || !('updatedDate' in extension) || !extension.updatedDate || typeof extension.updatedDate !== 'number') {
|
|
3794
|
-
return 0;
|
|
3795
|
-
}
|
|
3796
|
-
return extension.updatedDate;
|
|
3797
|
-
};
|
|
3798
|
-
|
|
3799
|
-
const normalizeExtension = (extension, platform, assetDir) => {
|
|
3800
|
-
return {
|
|
3801
|
-
builtin: getBuiltin(extension),
|
|
3802
|
-
categories: getCategories(extension),
|
|
3803
|
-
description: getDescription(extension),
|
|
3804
|
-
disabled: getDisabled(extension),
|
|
3805
|
-
downloadCount: getDownloadCount(extension),
|
|
3806
|
-
icon: getIcon(extension, platform, assetDir),
|
|
3807
|
-
id: getId(extension),
|
|
3808
|
-
linked: getLinked(extension),
|
|
3809
|
-
name: getName(extension),
|
|
3810
|
-
publisher: getPublisher(extension),
|
|
3811
|
-
rating: getRating(extension),
|
|
3812
|
-
size: getSize(extension),
|
|
3813
|
-
status: getStatus(extension),
|
|
3814
|
-
updatedDate: getUpdatedDate(extension),
|
|
3815
|
-
uri: ''
|
|
3816
|
-
};
|
|
3817
|
-
};
|
|
3818
|
-
|
|
3819
|
-
const normalizeExtensions = (extensions, platform, assetDir) => {
|
|
3820
|
-
return Array.from(extensions, extension => normalizeExtension(extension, platform, assetDir));
|
|
3821
|
-
};
|
|
3822
|
-
|
|
3823
|
-
const handleExtensionsChanged = async state => {
|
|
3824
|
-
const {
|
|
3825
|
-
assetDir,
|
|
3826
|
-
platform
|
|
3827
|
-
} = state;
|
|
3828
|
-
const allExtensions = await getAllExtensions(assetDir, platform);
|
|
3829
|
-
const normalized = normalizeExtensions(allExtensions, platform, assetDir);
|
|
3830
|
-
return handleChange({
|
|
3831
|
-
...state,
|
|
3832
|
-
allExtensions: normalized
|
|
3833
|
-
}, {});
|
|
3834
|
-
};
|
|
3835
|
-
|
|
3836
|
-
const handleFocus = async state => {
|
|
3837
|
-
return {
|
|
3838
|
-
...state,
|
|
3839
|
-
focus: List$2
|
|
3840
|
-
};
|
|
3841
|
-
};
|
|
3842
|
-
|
|
3843
|
-
const handleHeaderContextMenu = async state => {
|
|
3844
|
-
return state;
|
|
3845
|
-
};
|
|
3846
|
-
|
|
3847
|
-
const handleInputFocus = state => {
|
|
3848
|
-
return {
|
|
3849
|
-
...state,
|
|
3850
|
-
focus: Input
|
|
3851
|
-
};
|
|
3852
|
-
};
|
|
3853
|
-
|
|
3854
|
-
const handleInstall = async (state, id) => {
|
|
3855
|
-
await installExtension(id);
|
|
3856
|
-
return setExtensionStatus(state, id, Enabled);
|
|
3857
|
-
};
|
|
3858
|
-
|
|
3859
|
-
const state = {
|
|
3860
|
-
connected: false
|
|
3861
|
-
};
|
|
3862
|
-
const isConnected = () => {
|
|
3863
|
-
const {
|
|
3864
|
-
connected
|
|
3865
|
-
} = state;
|
|
3866
|
-
return connected;
|
|
3867
|
-
};
|
|
3868
|
-
const invoke = (method, ...params) => {
|
|
3869
|
-
return invoke$2(method, ...params);
|
|
3870
|
-
};
|
|
3871
|
-
const set = rpc => {
|
|
3872
|
-
set$3(rpc);
|
|
3873
|
-
state.connected = true;
|
|
3874
|
-
};
|
|
3875
|
-
|
|
3876
|
-
const handleMessagePort = async (port, viewletCommandMap, setAsRendererProcess = true) => {
|
|
3877
|
-
const executeViewletCommand = async (uid, command, ...args) => {
|
|
3878
|
-
const fn = viewletCommandMap[`SearchExtensions.${command}`];
|
|
3879
|
-
if (typeof fn !== 'function') {
|
|
3880
|
-
throw new TypeError(`Viewlet command not found: ${command}`);
|
|
3881
|
-
}
|
|
3882
|
-
await fn(uid, ...args);
|
|
3883
|
-
await invoke$1('Viewlet.requestRender', uid);
|
|
3884
|
-
};
|
|
3885
|
-
const rpc = await create$7({
|
|
3886
|
-
commandMap: {
|
|
3887
|
-
'Viewlet.executeViewletCommand': executeViewletCommand
|
|
3888
|
-
},
|
|
3889
|
-
messagePort: port
|
|
3890
|
-
});
|
|
3891
|
-
if (setAsRendererProcess) {
|
|
3892
|
-
set(rpc);
|
|
3893
|
-
}
|
|
3894
|
-
};
|
|
3895
|
-
|
|
3896
|
-
const handleScrollBarCaptureLost = state => {
|
|
3897
|
-
return {
|
|
3898
|
-
...state,
|
|
3899
|
-
scrollBarActive: false
|
|
3900
|
-
};
|
|
3901
|
-
};
|
|
3841
|
+
const Separator = 1;
|
|
3842
|
+
const None = 0;
|
|
3843
|
+
const SubMenu = 4;
|
|
3844
|
+
const Disabled = 5;
|
|
3902
3845
|
|
|
3903
|
-
const
|
|
3904
|
-
|
|
3905
|
-
if (
|
|
3906
|
-
// clicked at top
|
|
3907
|
-
return {
|
|
3908
|
-
handleOffset: relativeY,
|
|
3909
|
-
percent: 0
|
|
3910
|
-
};
|
|
3911
|
-
}
|
|
3912
|
-
if (relativeY <= height - halfScrollBarHeight) {
|
|
3913
|
-
// clicked in middle
|
|
3846
|
+
const nonEnableableStatuses = [Installing, NotInstalled, Uninstalling];
|
|
3847
|
+
const getEnablementFlags = (disabled, status) => {
|
|
3848
|
+
if (status && nonEnableableStatuses.includes(status)) {
|
|
3914
3849
|
return {
|
|
3915
|
-
|
|
3916
|
-
|
|
3850
|
+
disable: Disabled,
|
|
3851
|
+
enable: Disabled
|
|
3917
3852
|
};
|
|
3918
3853
|
}
|
|
3919
|
-
|
|
3920
|
-
return {
|
|
3921
|
-
handleOffset: scrollBarHeight - height + relativeY,
|
|
3922
|
-
percent: 1
|
|
3923
|
-
};
|
|
3924
|
-
};
|
|
3925
|
-
|
|
3926
|
-
const clamp = (num, min, max) => {
|
|
3927
|
-
number(num);
|
|
3928
|
-
number(min);
|
|
3929
|
-
number(max);
|
|
3930
|
-
return Math.min(Math.max(num, min), max);
|
|
3931
|
-
};
|
|
3932
|
-
|
|
3933
|
-
const setDeltaY = (state, value) => {
|
|
3934
|
-
object(state);
|
|
3935
|
-
number(value);
|
|
3936
|
-
const {
|
|
3937
|
-
deltaY,
|
|
3938
|
-
finalDeltaY,
|
|
3939
|
-
headerHeight,
|
|
3940
|
-
height,
|
|
3941
|
-
itemHeight,
|
|
3942
|
-
items,
|
|
3943
|
-
minimumSliderSize
|
|
3944
|
-
} = state;
|
|
3945
|
-
const listHeight = height - headerHeight;
|
|
3946
|
-
const newDeltaY = clamp(value, 0, finalDeltaY);
|
|
3947
|
-
if (deltaY === newDeltaY) {
|
|
3948
|
-
return state;
|
|
3949
|
-
}
|
|
3950
|
-
// TODO when it only moves by one px, extensions don't need to be rerendered, only negative margin
|
|
3951
|
-
const minLineY = Math.floor(newDeltaY / itemHeight);
|
|
3952
|
-
const total = items.length;
|
|
3953
|
-
const maxLineY = Math.min(minLineY + getNumberOfVisibleItems$1(listHeight, itemHeight), total);
|
|
3954
|
-
const contentHeight = total * itemHeight;
|
|
3955
|
-
const scrollBarHeight = getScrollBarSize(listHeight, contentHeight, minimumSliderSize);
|
|
3956
|
-
const scrollBarY = getScrollBarY$1(newDeltaY, finalDeltaY, height - headerHeight, scrollBarHeight);
|
|
3854
|
+
const isDisabled = status === Disabled$1 || status === undefined && disabled;
|
|
3957
3855
|
return {
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
maxLineY,
|
|
3961
|
-
minLineY,
|
|
3962
|
-
scrollBarY
|
|
3856
|
+
disable: isDisabled ? Disabled : None,
|
|
3857
|
+
enable: isDisabled ? None : Disabled
|
|
3963
3858
|
};
|
|
3964
3859
|
};
|
|
3965
|
-
|
|
3966
|
-
const
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3860
|
+
const getMenuEntriesList = (builtin, disabled = false, status) => {
|
|
3861
|
+
const enablementFlags = getEnablementFlags(disabled, status);
|
|
3862
|
+
return [{
|
|
3863
|
+
command: 'Extensions.enable',
|
|
3864
|
+
flags: enablementFlags.enable,
|
|
3865
|
+
id: 'enable',
|
|
3866
|
+
label: enable$2()
|
|
3867
|
+
}, {
|
|
3868
|
+
command: 'Extensions.enableWorkspace',
|
|
3869
|
+
flags: enablementFlags.enable,
|
|
3870
|
+
id: 'enableWorkspace',
|
|
3871
|
+
label: enableWorkspace$1()
|
|
3872
|
+
}, {
|
|
3873
|
+
command: '',
|
|
3874
|
+
flags: Separator,
|
|
3875
|
+
id: 'separator1',
|
|
3876
|
+
label: ''
|
|
3877
|
+
}, {
|
|
3878
|
+
command: 'Extensions.disable',
|
|
3879
|
+
flags: enablementFlags.disable,
|
|
3880
|
+
id: 'disable',
|
|
3881
|
+
label: disable$2()
|
|
3882
|
+
}, {
|
|
3883
|
+
command: 'Extensions.disableWorkspace',
|
|
3884
|
+
flags: enablementFlags.disable,
|
|
3885
|
+
id: 'disableWorkspace',
|
|
3886
|
+
label: disableWorkspace$1()
|
|
3887
|
+
}, {
|
|
3888
|
+
command: '',
|
|
3889
|
+
flags: Separator,
|
|
3890
|
+
id: 'separator2',
|
|
3891
|
+
label: ''
|
|
3892
|
+
}, {
|
|
3893
|
+
command: 'Extensions.installAnotherVersion',
|
|
3894
|
+
flags: Disabled,
|
|
3895
|
+
id: 'installAnotherVersion',
|
|
3896
|
+
label: installAnotherVersion$1()
|
|
3897
|
+
}, {
|
|
3898
|
+
command: 'Extensions.copyExtensionInfo',
|
|
3899
|
+
flags: None,
|
|
3900
|
+
id: 'copy',
|
|
3901
|
+
label: copy()
|
|
3902
|
+
}, {
|
|
3903
|
+
command: 'Extensions.copyExtensionId',
|
|
3904
|
+
flags: None,
|
|
3905
|
+
id: 'copyExtensionId',
|
|
3906
|
+
label: copyExtensionId$1()
|
|
3907
|
+
}];
|
|
3997
3908
|
};
|
|
3998
3909
|
|
|
3999
|
-
const
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
const {
|
|
4009
|
-
finalDeltaY,
|
|
4010
|
-
handleOffset,
|
|
4011
|
-
headerHeight,
|
|
4012
|
-
height,
|
|
4013
|
-
scrollBarActive,
|
|
4014
|
-
scrollBarHeight,
|
|
4015
|
-
y
|
|
4016
|
-
} = state;
|
|
4017
|
-
if (!scrollBarActive) {
|
|
4018
|
-
return state;
|
|
4019
|
-
}
|
|
4020
|
-
const relativeY = eventY - y - headerHeight - handleOffset;
|
|
4021
|
-
const contentHeight = height - headerHeight;
|
|
4022
|
-
const newPercent = getNewPercent(contentHeight, scrollBarHeight, relativeY);
|
|
4023
|
-
const newDeltaY = newPercent * finalDeltaY;
|
|
4024
|
-
return setDeltaY(state, newDeltaY);
|
|
3910
|
+
const RE_WORD_START = /\b[a-z]/g;
|
|
3911
|
+
const getMenuEntriesCategory = () => {
|
|
3912
|
+
return CategorySuggestions.map(query => ({
|
|
3913
|
+
args: [query],
|
|
3914
|
+
command: 'Extensions.filterByCategory',
|
|
3915
|
+
flags: None,
|
|
3916
|
+
id: query,
|
|
3917
|
+
label: query.slice(11, -1).replaceAll(RE_WORD_START, character => character.toUpperCase()).replace('Ai', 'AI').replace('Scm', 'SCM')
|
|
3918
|
+
}));
|
|
4025
3919
|
};
|
|
4026
3920
|
|
|
4027
|
-
const
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
}
|
|
4054
|
-
|
|
3921
|
+
const getMenuEntriesFilter = () => {
|
|
3922
|
+
return [{
|
|
3923
|
+
command: 'Extensions.filterByFeatured',
|
|
3924
|
+
flags: None,
|
|
3925
|
+
id: 'filterByFeatured',
|
|
3926
|
+
label: featured()
|
|
3927
|
+
}, {
|
|
3928
|
+
command: 'Extensions.filterByMcpServers',
|
|
3929
|
+
flags: None,
|
|
3930
|
+
id: 'filterByMcpServers',
|
|
3931
|
+
label: mcpServers()
|
|
3932
|
+
}, {
|
|
3933
|
+
command: 'Extensions.filterByMostPopular',
|
|
3934
|
+
flags: None,
|
|
3935
|
+
id: 'filterByMostPopular',
|
|
3936
|
+
label: mostPopular()
|
|
3937
|
+
}, {
|
|
3938
|
+
command: 'Extensions.filterByRecentlyPublished',
|
|
3939
|
+
flags: None,
|
|
3940
|
+
id: 'filterByRecentlyPublished',
|
|
3941
|
+
label: recentlyPublished()
|
|
3942
|
+
}, {
|
|
3943
|
+
command: 'Extensions.filterByRecommended',
|
|
3944
|
+
flags: None,
|
|
3945
|
+
id: 'filterByRecommended',
|
|
3946
|
+
label: recommended()
|
|
3947
|
+
}, {
|
|
3948
|
+
command: '',
|
|
3949
|
+
flags: Separator,
|
|
3950
|
+
id: 'separator1',
|
|
3951
|
+
label: ''
|
|
3952
|
+
}, {
|
|
3953
|
+
args: [{
|
|
3954
|
+
menuId: ExtensionSearchFilter,
|
|
3955
|
+
subMenu: 'category'
|
|
3956
|
+
}],
|
|
3957
|
+
command: '',
|
|
3958
|
+
flags: SubMenu,
|
|
3959
|
+
id: ExtensionSearchFilter,
|
|
3960
|
+
label: category()
|
|
3961
|
+
}, {
|
|
3962
|
+
command: 'Extensions.filterByInstalled',
|
|
3963
|
+
flags: None,
|
|
3964
|
+
id: 'filterByInstalled',
|
|
3965
|
+
label: installed()
|
|
3966
|
+
}, {
|
|
3967
|
+
command: 'Extensions.filterByUpdates',
|
|
3968
|
+
flags: None,
|
|
3969
|
+
id: 'filterByUpdates',
|
|
3970
|
+
label: updates()
|
|
3971
|
+
}, {
|
|
3972
|
+
command: 'Extensions.filterByBuiltin',
|
|
3973
|
+
flags: None,
|
|
3974
|
+
id: 'filterByBuiltin',
|
|
3975
|
+
label: builtIn()
|
|
3976
|
+
}, {
|
|
3977
|
+
command: 'Extensions.filterByLinked',
|
|
3978
|
+
flags: None,
|
|
3979
|
+
id: 'filterByLinked',
|
|
3980
|
+
label: linked()
|
|
3981
|
+
}, {
|
|
3982
|
+
command: 'Extensions.filterByEnabled',
|
|
3983
|
+
flags: None,
|
|
3984
|
+
id: 'filterByEnabled',
|
|
3985
|
+
label: enabled()
|
|
3986
|
+
}, {
|
|
3987
|
+
command: 'Extensions.filterByDisabled',
|
|
3988
|
+
flags: None,
|
|
3989
|
+
id: 'filterByDisabled',
|
|
3990
|
+
label: disabled()
|
|
3991
|
+
}, {
|
|
3992
|
+
command: 'Extensions.filterByWorkspaceUnsupported',
|
|
3993
|
+
flags: None,
|
|
3994
|
+
id: 'filterByWorkspaceUnsupported',
|
|
3995
|
+
label: workspaceUnsupported()
|
|
3996
|
+
}, {
|
|
3997
|
+
command: '',
|
|
3998
|
+
flags: Separator,
|
|
3999
|
+
id: 'separator2',
|
|
4000
|
+
label: ''
|
|
4001
|
+
}, {
|
|
4002
|
+
command: 'SearchExtensions.filterBySortBy',
|
|
4003
|
+
flags: SubMenu,
|
|
4004
|
+
id: 'filterBySortBy',
|
|
4005
|
+
label: sortBy()
|
|
4006
|
+
}];
|
|
4055
4007
|
};
|
|
4056
4008
|
|
|
4057
|
-
const
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4009
|
+
const getMenuEntries2 = (state, props) => {
|
|
4010
|
+
const {
|
|
4011
|
+
menuId
|
|
4012
|
+
} = props;
|
|
4013
|
+
switch (menuId) {
|
|
4014
|
+
case ExtensionSearchFilter:
|
|
4015
|
+
return props.subMenu === 'category' ? getMenuEntriesCategory() : getMenuEntriesFilter();
|
|
4016
|
+
default:
|
|
4017
|
+
return getMenuEntriesList(props.builtin, props.disabled, props.status);
|
|
4064
4018
|
}
|
|
4065
4019
|
};
|
|
4066
4020
|
|
|
4067
|
-
const
|
|
4068
|
-
|
|
4069
|
-
number(deltaY);
|
|
4070
|
-
return setDeltaY(state, state.deltaY + deltaY * state.scrollSensitivity);
|
|
4021
|
+
const getMenuIds = () => {
|
|
4022
|
+
return [ManageExtension, ExtensionSearchFilter];
|
|
4071
4023
|
};
|
|
4072
4024
|
|
|
4073
|
-
const
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
return rpc;
|
|
4080
|
-
} catch (error) {
|
|
4081
|
-
throw new VError(error, `Failed to create extension management rpc`);
|
|
4082
|
-
}
|
|
4025
|
+
const handleBlur = state => {
|
|
4026
|
+
return {
|
|
4027
|
+
...state,
|
|
4028
|
+
focus: None$2,
|
|
4029
|
+
suggestOpen: false
|
|
4030
|
+
};
|
|
4083
4031
|
};
|
|
4084
4032
|
|
|
4085
|
-
const
|
|
4086
|
-
|
|
4087
|
-
const rpc = await createExtensionManagementWorkerRpc();
|
|
4088
|
-
set$4(rpc);
|
|
4089
|
-
} catch {
|
|
4090
|
-
// ignore
|
|
4091
|
-
}
|
|
4033
|
+
const getExtensionDetailUri = extensionId => {
|
|
4034
|
+
return `extension-detail://${extensionId}`;
|
|
4092
4035
|
};
|
|
4093
4036
|
|
|
4094
|
-
const
|
|
4095
|
-
|
|
4037
|
+
const openUri = async uri => {
|
|
4038
|
+
return openUri$1(uri);
|
|
4096
4039
|
};
|
|
4097
4040
|
|
|
4098
|
-
const
|
|
4099
|
-
|
|
4100
|
-
|
|
4041
|
+
const selectIndex = (state, index) => {
|
|
4042
|
+
return {
|
|
4043
|
+
...state,
|
|
4044
|
+
focusedIndex: index
|
|
4045
|
+
};
|
|
4101
4046
|
};
|
|
4102
4047
|
|
|
4103
|
-
const
|
|
4104
|
-
const
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4048
|
+
const handleClick = async (state, index) => {
|
|
4049
|
+
const {
|
|
4050
|
+
items,
|
|
4051
|
+
minLineY
|
|
4052
|
+
} = state;
|
|
4053
|
+
const actualIndex = index + minLineY;
|
|
4054
|
+
if (actualIndex < 0 || actualIndex >= items.length) {
|
|
4055
|
+
return {
|
|
4056
|
+
...state,
|
|
4057
|
+
focus: List$2,
|
|
4058
|
+
focusedIndex: -1
|
|
4059
|
+
};
|
|
4113
4060
|
}
|
|
4114
|
-
|
|
4061
|
+
const extension = items[actualIndex];
|
|
4062
|
+
const uri = getExtensionDetailUri(extension.id);
|
|
4063
|
+
await openUri(uri);
|
|
4064
|
+
const partialNewState = selectIndex(state, actualIndex);
|
|
4065
|
+
const newState = {
|
|
4066
|
+
...partialNewState,
|
|
4067
|
+
focus: List$2
|
|
4068
|
+
};
|
|
4069
|
+
return newState;
|
|
4115
4070
|
};
|
|
4116
4071
|
|
|
4117
|
-
const
|
|
4118
|
-
const
|
|
4119
|
-
|
|
4072
|
+
const getListIndex = (eventX, eventY, x, y, deltaY, itemHeight, headerHeight) => {
|
|
4073
|
+
const relativeDeltaY = deltaY % itemHeight;
|
|
4074
|
+
const relativeY = eventY - y - headerHeight + relativeDeltaY;
|
|
4075
|
+
const index = Math.floor(relativeY / itemHeight);
|
|
4076
|
+
return index;
|
|
4120
4077
|
};
|
|
4121
4078
|
|
|
4122
|
-
const
|
|
4123
|
-
if (
|
|
4124
|
-
return
|
|
4079
|
+
const handleCompletionPointerDown = (state, label) => {
|
|
4080
|
+
if (state.completionItems.every(item => item.label !== label)) {
|
|
4081
|
+
return Promise.resolve(state);
|
|
4125
4082
|
}
|
|
4126
|
-
return
|
|
4083
|
+
return acceptCompletion(state, label);
|
|
4127
4084
|
};
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4085
|
+
|
|
4086
|
+
const handleClickAt = async (state, button, eventX, eventY, name = '') => {
|
|
4087
|
+
if (name.startsWith('@')) {
|
|
4088
|
+
return handleCompletionPointerDown(state, name);
|
|
4131
4089
|
}
|
|
4132
|
-
|
|
4090
|
+
if (name) {
|
|
4091
|
+
return state;
|
|
4092
|
+
}
|
|
4093
|
+
if (button !== LeftClick) {
|
|
4094
|
+
return state;
|
|
4095
|
+
}
|
|
4096
|
+
const {
|
|
4097
|
+
deltaY,
|
|
4098
|
+
headerHeight,
|
|
4099
|
+
itemHeight,
|
|
4100
|
+
x,
|
|
4101
|
+
y
|
|
4102
|
+
} = state;
|
|
4103
|
+
const index = getListIndex(eventX, eventY, x, y, deltaY, itemHeight, headerHeight);
|
|
4104
|
+
return handleClick(state, index);
|
|
4133
4105
|
};
|
|
4134
4106
|
|
|
4135
|
-
const
|
|
4136
|
-
const
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
searchValue
|
|
4141
|
-
};
|
|
4107
|
+
const handleClickCurrent = state => {
|
|
4108
|
+
const {
|
|
4109
|
+
focusedIndex
|
|
4110
|
+
} = state;
|
|
4111
|
+
return handleClick(state, focusedIndex);
|
|
4142
4112
|
};
|
|
4143
4113
|
|
|
4144
|
-
const
|
|
4114
|
+
const handleClickCurrentButKeepFocus = state => {
|
|
4145
4115
|
const {
|
|
4146
|
-
|
|
4147
|
-
} =
|
|
4148
|
-
|
|
4149
|
-
try {
|
|
4150
|
-
const initialState = context.getState();
|
|
4151
|
-
const {
|
|
4152
|
-
assetDir,
|
|
4153
|
-
platform,
|
|
4154
|
-
width
|
|
4155
|
-
} = initialState;
|
|
4156
|
-
const {
|
|
4157
|
-
deltaY,
|
|
4158
|
-
searchValue: restoredSearchValue
|
|
4159
|
-
} = restoreState(savedState);
|
|
4160
|
-
const size = getViewletSize(width);
|
|
4161
|
-
const scrollSensitivity = getIsFirefox() ? 2.5 : 1;
|
|
4162
|
-
await context.updateState(state => {
|
|
4163
|
-
if (!state.initial) {
|
|
4164
|
-
return state;
|
|
4165
|
-
}
|
|
4166
|
-
return {
|
|
4167
|
-
...state,
|
|
4168
|
-
deltaY,
|
|
4169
|
-
initial: false,
|
|
4170
|
-
inputSource: Script,
|
|
4171
|
-
scrollSensitivity,
|
|
4172
|
-
searchValue: restoredSearchValue,
|
|
4173
|
-
size
|
|
4174
|
-
};
|
|
4175
|
-
});
|
|
4176
|
-
const allExtensions = await getAllExtensions(assetDir, platform);
|
|
4177
|
-
const normalized = normalizeExtensions(allExtensions, platform, assetDir);
|
|
4178
|
-
await context.updateState(state => ({
|
|
4179
|
-
...state,
|
|
4180
|
-
allExtensions: normalized
|
|
4181
|
-
}));
|
|
4182
|
-
await handleChangeWithContext(context, {}, false);
|
|
4183
|
-
} finally {
|
|
4184
|
-
finish(uid, loadToken);
|
|
4185
|
-
}
|
|
4116
|
+
focusedIndex
|
|
4117
|
+
} = state;
|
|
4118
|
+
return handleClick(state, focusedIndex);
|
|
4186
4119
|
};
|
|
4187
4120
|
|
|
4188
|
-
const
|
|
4189
|
-
|
|
4190
|
-
if (completionItems.length === 0) {
|
|
4191
|
-
return state;
|
|
4192
|
-
}
|
|
4193
|
-
return {
|
|
4194
|
-
...state,
|
|
4195
|
-
completionFocusedIndex: 0,
|
|
4196
|
-
completionItems,
|
|
4197
|
-
suggestOpen: true
|
|
4198
|
-
};
|
|
4121
|
+
const show2 = async (uid, menuId, x, y, args) => {
|
|
4122
|
+
await showContextMenu2(uid, menuId, x, y, args);
|
|
4199
4123
|
};
|
|
4200
4124
|
|
|
4201
|
-
const
|
|
4125
|
+
const handleClickFilter = async state => {
|
|
4126
|
+
const {
|
|
4127
|
+
headerHeight,
|
|
4128
|
+
uid,
|
|
4129
|
+
width,
|
|
4130
|
+
x,
|
|
4131
|
+
y
|
|
4132
|
+
} = state;
|
|
4133
|
+
const menuX = x + width + 60;
|
|
4134
|
+
const menuHeight = 370;
|
|
4135
|
+
const menuY = y + headerHeight + menuHeight;
|
|
4136
|
+
await show2(uid, ExtensionSearchFilter, menuX, menuY, {
|
|
4137
|
+
menuId: ExtensionSearchFilter,
|
|
4138
|
+
openSubMenuToLeft: true
|
|
4139
|
+
});
|
|
4140
|
+
return state;
|
|
4141
|
+
};
|
|
4142
|
+
|
|
4143
|
+
const handleContextMenu = async (state, button, eventX, eventY) => {
|
|
4144
|
+
// TODO use focused index when when context menu button is -1 (keyboard)
|
|
4202
4145
|
const {
|
|
4203
|
-
cursorOffset,
|
|
4204
4146
|
deltaY,
|
|
4205
4147
|
headerHeight,
|
|
4206
4148
|
itemHeight,
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4149
|
+
items,
|
|
4150
|
+
minLineY,
|
|
4151
|
+
uid,
|
|
4152
|
+
x,
|
|
4153
|
+
y
|
|
4210
4154
|
} = state;
|
|
4211
|
-
const
|
|
4212
|
-
const
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4155
|
+
const visibleIndex = getListIndex(eventX, eventY, x, y, deltaY, itemHeight, headerHeight);
|
|
4156
|
+
const index = visibleIndex + minLineY;
|
|
4157
|
+
if (index < 0 || index >= items.length) {
|
|
4158
|
+
return state;
|
|
4159
|
+
}
|
|
4160
|
+
const item = items[index];
|
|
4161
|
+
await show2(uid, ManageExtension, eventX, eventY, {
|
|
4162
|
+
builtin: item.builtin === true,
|
|
4163
|
+
disabled: item.disabled === true,
|
|
4164
|
+
menuId: ManageExtension,
|
|
4165
|
+
status: item.status
|
|
4166
|
+
});
|
|
4167
|
+
return {
|
|
4168
|
+
...state,
|
|
4169
|
+
focusedIndex: index
|
|
4170
|
+
};
|
|
4171
|
+
};
|
|
4226
4172
|
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
flex-shrink: 0;
|
|
4231
|
-
}
|
|
4173
|
+
const handleDisableWorkspace = (state, id) => {
|
|
4174
|
+
return state;
|
|
4175
|
+
};
|
|
4232
4176
|
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
right: 6px;
|
|
4237
|
-
width: 14px;
|
|
4238
|
-
height: 14px;
|
|
4239
|
-
color: var(--WorkbenchForeground, rgb(188, 190, 190));
|
|
4240
|
-
opacity: 0.8;
|
|
4241
|
-
}
|
|
4177
|
+
const handleEnableWorkspace = (state, id) => {
|
|
4178
|
+
return state;
|
|
4179
|
+
};
|
|
4242
4180
|
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
}
|
|
4181
|
+
const Web = 1;
|
|
4182
|
+
const Electron = 2;
|
|
4183
|
+
const Remote = 3;
|
|
4247
4184
|
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4185
|
+
const getAllExtensions$1 = async (assetDir, platform) => {
|
|
4186
|
+
try {
|
|
4187
|
+
return await invoke$3('Extensions.getAllExtensions', assetDir, platform);
|
|
4188
|
+
} catch (error) {
|
|
4189
|
+
if (platform === Web) {
|
|
4190
|
+
return [];
|
|
4191
|
+
}
|
|
4192
|
+
throw error;
|
|
4193
|
+
}
|
|
4194
|
+
};
|
|
4254
4195
|
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
z-index: 1;
|
|
4259
|
-
}
|
|
4196
|
+
const getAllExtensions = (assetDir, platform) => {
|
|
4197
|
+
return getAllExtensions$1(assetDir, platform);
|
|
4198
|
+
};
|
|
4260
4199
|
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
}
|
|
4200
|
+
const getBuiltin = extension => {
|
|
4201
|
+
if (extension === null || typeof extension !== 'object') {
|
|
4202
|
+
return false;
|
|
4203
|
+
}
|
|
4204
|
+
const {
|
|
4205
|
+
builtin,
|
|
4206
|
+
id,
|
|
4207
|
+
isBuiltin
|
|
4208
|
+
} = extension;
|
|
4209
|
+
return isBuiltin === true || builtin === true || typeof id === 'string' && id.startsWith('builtin.');
|
|
4210
|
+
};
|
|
4265
4211
|
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
}
|
|
4212
|
+
const isString = item => {
|
|
4213
|
+
return typeof item === 'string';
|
|
4214
|
+
};
|
|
4269
4215
|
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
}
|
|
4216
|
+
const getCategories = extension => {
|
|
4217
|
+
if (extension === null || typeof extension !== 'object' || !('categories' in extension) || !Array.isArray(extension.categories)) {
|
|
4218
|
+
return [];
|
|
4219
|
+
}
|
|
4220
|
+
return extension.categories.filter(isString);
|
|
4221
|
+
};
|
|
4274
4222
|
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4223
|
+
const getDescription = extension => {
|
|
4224
|
+
if (extension === null || typeof extension !== 'object' || !('description' in extension) || typeof extension.description !== 'string' || !extension.description) {
|
|
4225
|
+
return 'n/a';
|
|
4226
|
+
}
|
|
4227
|
+
return extension.description;
|
|
4228
|
+
};
|
|
4278
4229
|
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
top: ${completionTop}px;
|
|
4283
|
-
width: min(320px, calc(100% - ${completionLeft + 8}px));
|
|
4284
|
-
max-height: 240px;
|
|
4285
|
-
overflow-y: auto;
|
|
4286
|
-
z-index: 10;
|
|
4287
|
-
box-sizing: border-box;
|
|
4288
|
-
border: 1px solid var(--CompletionListBorder, #95a29d);
|
|
4289
|
-
background: var(--CompletionListBackground, #282e2f);
|
|
4290
|
-
color: var(--CompletionListForeground, white);
|
|
4291
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.36);
|
|
4292
|
-
font-size: 13px;
|
|
4293
|
-
line-height: 20px;
|
|
4294
|
-
user-select: none;
|
|
4295
|
-
}
|
|
4230
|
+
const getDisabled = extension => {
|
|
4231
|
+
return extension !== null && typeof extension === 'object' && 'disabled' in extension && extension.disabled === true;
|
|
4232
|
+
};
|
|
4296
4233
|
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
}
|
|
4234
|
+
const getDownloadCountValue = extension => {
|
|
4235
|
+
if (extension === null || typeof extension !== 'object') {
|
|
4236
|
+
return undefined;
|
|
4237
|
+
}
|
|
4238
|
+
const marketplace = 'marketplace' in extension && extension.marketplace !== null && typeof extension.marketplace === 'object' ? extension.marketplace : {};
|
|
4239
|
+
const packageJson = 'packageJSON' in extension && extension.packageJSON !== null && typeof extension.packageJSON === 'object' ? extension.packageJSON : {};
|
|
4240
|
+
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);
|
|
4241
|
+
};
|
|
4242
|
+
const getDownloadCount = extension => {
|
|
4243
|
+
const downloadCount = getDownloadCountValue(extension);
|
|
4244
|
+
if (typeof downloadCount !== 'number') {
|
|
4245
|
+
return 'n/a';
|
|
4246
|
+
}
|
|
4247
|
+
return downloadCount.toLocaleString();
|
|
4248
|
+
};
|
|
4313
4249
|
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4250
|
+
const getRemoteUrl = (extension, platform, assetDir) => {
|
|
4251
|
+
if (extension === null || typeof extension !== 'object') {
|
|
4252
|
+
return '';
|
|
4253
|
+
}
|
|
4254
|
+
const builtin = 'builtin' in extension && extension.builtin === true;
|
|
4255
|
+
const icon = 'icon' in extension && typeof extension.icon === 'string' ? extension.icon : '';
|
|
4256
|
+
const id = 'id' in extension && typeof extension.id === 'string' ? extension.id : '';
|
|
4257
|
+
const path = 'path' in extension && typeof extension.path === 'string' ? extension.path : '';
|
|
4258
|
+
if (platform === Remote || platform === Electron) {
|
|
4259
|
+
if (builtin) {
|
|
4260
|
+
return `${assetDir}/extensions/${id}/${icon}`;
|
|
4261
|
+
}
|
|
4262
|
+
return `/remote/${path}/${icon}`; // TODO support windows paths
|
|
4263
|
+
}
|
|
4264
|
+
if (platform === Web) {
|
|
4265
|
+
return `${path}/${icon}`;
|
|
4266
|
+
}
|
|
4267
|
+
return '';
|
|
4268
|
+
};
|
|
4317
4269
|
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4270
|
+
const getExtensionDefaultIcon = assetDir => {
|
|
4271
|
+
return `${assetDir}/icons/extensionDefaultIcon.png`;
|
|
4272
|
+
};
|
|
4273
|
+
const getExtensionLanguageBasicsIcon = assetDir => {
|
|
4274
|
+
return `${assetDir}/icons/language-icon.svg`;
|
|
4275
|
+
};
|
|
4276
|
+
const getExtensionThemeIcon = assetDir => {
|
|
4277
|
+
return `${assetDir}/icons/theme-icon.png`;
|
|
4278
|
+
};
|
|
4322
4279
|
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4280
|
+
const isLanguageBasicsExtension = extension => {
|
|
4281
|
+
return 'name' in extension && typeof extension.name === 'string' && extension.name.startsWith('Language Basics');
|
|
4282
|
+
};
|
|
4283
|
+
const isThemeExtension = extension => {
|
|
4284
|
+
return 'name' in extension && typeof extension.name === 'string' && extension.name.endsWith(' Theme');
|
|
4285
|
+
};
|
|
4286
|
+
const getExtensionIcon = (extension, platform, assetDir) => {
|
|
4287
|
+
if (extension === null || typeof extension !== 'object') {
|
|
4288
|
+
return getExtensionDefaultIcon(assetDir);
|
|
4289
|
+
}
|
|
4290
|
+
const hasIcon = 'icon' in extension && typeof extension.icon === 'string' && extension.icon;
|
|
4291
|
+
const hasPath = 'path' in extension && typeof extension.path === 'string' && extension.path;
|
|
4292
|
+
if (!hasPath || !hasIcon) {
|
|
4293
|
+
if (isLanguageBasicsExtension(extension)) {
|
|
4294
|
+
return getExtensionLanguageBasicsIcon(assetDir);
|
|
4295
|
+
}
|
|
4296
|
+
if (isThemeExtension(extension)) {
|
|
4297
|
+
return getExtensionThemeIcon(assetDir);
|
|
4298
|
+
}
|
|
4299
|
+
return getExtensionDefaultIcon(assetDir);
|
|
4300
|
+
}
|
|
4301
|
+
return getRemoteUrl(extension, platform, assetDir);
|
|
4328
4302
|
};
|
|
4329
4303
|
|
|
4330
|
-
const
|
|
4331
|
-
|
|
4332
|
-
uid
|
|
4333
|
-
} = newState;
|
|
4334
|
-
const css = getCss(newState);
|
|
4335
|
-
return [SetCss, uid, css];
|
|
4304
|
+
const getIcon = (extension, platform, assetDir) => {
|
|
4305
|
+
return getExtensionIcon(extension, platform, assetDir);
|
|
4336
4306
|
};
|
|
4337
4307
|
|
|
4338
|
-
const
|
|
4308
|
+
const getId = extension => {
|
|
4309
|
+
if (extension === null || typeof extension !== 'object' || !('id' in extension) || typeof extension.id !== 'string' || !extension.id) {
|
|
4310
|
+
return 'n/a';
|
|
4311
|
+
}
|
|
4312
|
+
return extension.id;
|
|
4313
|
+
};
|
|
4339
4314
|
|
|
4340
|
-
const
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
default:
|
|
4347
|
-
return '';
|
|
4315
|
+
const getLinked = extension => {
|
|
4316
|
+
if (extension === null || typeof extension !== 'object') {
|
|
4317
|
+
return false;
|
|
4318
|
+
}
|
|
4319
|
+
if ('linked' in extension && extension.linked === true) {
|
|
4320
|
+
return true;
|
|
4348
4321
|
}
|
|
4322
|
+
return 'symlink' in extension && typeof extension.symlink === 'string' && extension.symlink.length > 0;
|
|
4349
4323
|
};
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
}
|
|
4355
|
-
if (
|
|
4356
|
-
return
|
|
4324
|
+
|
|
4325
|
+
const getName = extension => {
|
|
4326
|
+
if (extension === null || typeof extension !== 'object') {
|
|
4327
|
+
return 'n/a';
|
|
4328
|
+
}
|
|
4329
|
+
if ('name' in extension && typeof extension.name === 'string' && extension.name) {
|
|
4330
|
+
return extension.name;
|
|
4357
4331
|
}
|
|
4358
|
-
|
|
4359
|
-
|
|
4332
|
+
if ('id' in extension && typeof extension.id === 'string' && extension.id) {
|
|
4333
|
+
return extension.id;
|
|
4334
|
+
}
|
|
4335
|
+
return 'n/a';
|
|
4360
4336
|
};
|
|
4361
4337
|
|
|
4362
|
-
const
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
if (newState.focus === Input) {
|
|
4367
|
-
return ['Viewlet.setFocusContext', uid, FocusExtensionsInput];
|
|
4338
|
+
const RE_PUBLISHER = /^[a-z\d-]+/;
|
|
4339
|
+
const getPublisher = extension => {
|
|
4340
|
+
if (extension === null || typeof extension !== 'object' || !('id' in extension) || typeof extension.id !== 'string') {
|
|
4341
|
+
return 'n/a';
|
|
4368
4342
|
}
|
|
4369
|
-
|
|
4370
|
-
|
|
4343
|
+
const match = extension.id.match(RE_PUBLISHER);
|
|
4344
|
+
if (!match) {
|
|
4345
|
+
return 'n/a';
|
|
4371
4346
|
}
|
|
4372
|
-
return [];
|
|
4347
|
+
return match[0];
|
|
4373
4348
|
};
|
|
4374
4349
|
|
|
4375
|
-
const
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
const ListBox = 'listbox';
|
|
4379
|
-
const ListItem = 'listitem';
|
|
4380
|
-
const None = 'none';
|
|
4381
|
-
const Option = 'option';
|
|
4382
|
-
const ToolBar = 'toolbar';
|
|
4383
|
-
|
|
4384
|
-
const Actions = 'Actions';
|
|
4385
|
-
const ExtensionActions = 'ExtensionActions';
|
|
4386
|
-
const ExtensionActionButton = 'ExtensionActionButton';
|
|
4387
|
-
const ExtensionActive = 'ExtensionActive';
|
|
4388
|
-
const ExtensionHeader = 'ExtensionHeader';
|
|
4389
|
-
const ExtensionListItem = 'ExtensionListItem';
|
|
4390
|
-
const ExtensionListItemActionInstall = 'ExtensionListItemActionInstall';
|
|
4391
|
-
const ExtensionListItemAuthorName = 'ExtensionListItemAuthorName';
|
|
4392
|
-
const ExtensionListItemDescription = 'ExtensionListItemDescription';
|
|
4393
|
-
const ExtensionListItemDetail = 'ExtensionListItemDetail';
|
|
4394
|
-
const ExtensionListItemDisabled = 'ExtensionListItemDisabled';
|
|
4395
|
-
const ExtensionListItemDownloadCount = 'ExtensionListItemDownloadCount';
|
|
4396
|
-
const ExtensionListItemFooter = 'ExtensionListItemFooter';
|
|
4397
|
-
const ExtensionListItemIcon = 'ExtensionListItemIcon';
|
|
4398
|
-
const ExtensionListItemLinkedIcon = 'ExtensionListItemLinkedIcon';
|
|
4399
|
-
const ExtensionListItemMetadata = 'ExtensionListItemMetadata';
|
|
4400
|
-
const ExtensionListItemName = 'ExtensionListItemName';
|
|
4401
|
-
const ExtensionListItemRating = 'ExtensionListItemRating';
|
|
4402
|
-
const ExtensionListItemStatistic = 'ExtensionListItemStatistic';
|
|
4403
|
-
const ExtensionSearchCompletionHighlight = 'ExtensionSearchCompletionHighlight';
|
|
4404
|
-
const ExtensionSearchCompletionItem = 'ExtensionSearchCompletionItem';
|
|
4405
|
-
const ExtensionSearchCompletionItemFocused = 'ExtensionSearchCompletionItemFocused';
|
|
4406
|
-
const ExtensionSearchCompletionWidget = 'ExtensionSearchCompletionWidget';
|
|
4407
|
-
const Extensions = 'Extensions';
|
|
4408
|
-
const FocusOutline = 'FocusOutline';
|
|
4409
|
-
const IconButton = 'IconButton';
|
|
4410
|
-
const List = 'List';
|
|
4411
|
-
const ListItems = 'ListItems';
|
|
4412
|
-
const MaskIcon = 'MaskIcon';
|
|
4413
|
-
const MultilineInputBox = 'MultilineInputBox';
|
|
4414
|
-
const NoExtensionsFoundMessage = 'NoExtensionsFoundMessage';
|
|
4415
|
-
const ScrollBar = 'ScrollBar';
|
|
4416
|
-
const ScrollBarSmall = 'ScrollBarSmall';
|
|
4417
|
-
const ScrollBarThumb = 'ScrollBarThumb';
|
|
4418
|
-
const ScrollBarThumbActive = 'ScrollBarThumbActive';
|
|
4419
|
-
const SearchField = 'SearchField';
|
|
4420
|
-
const SearchFieldButton = 'SearchFieldButton';
|
|
4421
|
-
const SearchFieldButtonDisabled = 'SearchFieldButtonDisabled';
|
|
4422
|
-
const SearchFieldButtons = 'SearchFieldButtons';
|
|
4423
|
-
const SearchFieldContainer = 'SearchFieldContainer';
|
|
4424
|
-
const Viewlet = 'Viewlet';
|
|
4425
|
-
|
|
4426
|
-
const getCompletionLabelVirtualDom = (label, highlights) => {
|
|
4427
|
-
const dom = [];
|
|
4428
|
-
let position = 0;
|
|
4429
|
-
for (let i = 0; i < highlights.length; i += 2) {
|
|
4430
|
-
const start = highlights[i];
|
|
4431
|
-
const end = highlights[i + 1];
|
|
4432
|
-
if (position < start) {
|
|
4433
|
-
dom.push(text(label.slice(position, start)));
|
|
4434
|
-
}
|
|
4435
|
-
dom.push({
|
|
4436
|
-
childCount: 1,
|
|
4437
|
-
className: ExtensionSearchCompletionHighlight,
|
|
4438
|
-
name: label,
|
|
4439
|
-
type: Span
|
|
4440
|
-
}, text(label.slice(start, end)));
|
|
4441
|
-
position = end;
|
|
4350
|
+
const getRatingValue = extension => {
|
|
4351
|
+
if (extension === null || typeof extension !== 'object') {
|
|
4352
|
+
return undefined;
|
|
4442
4353
|
}
|
|
4443
|
-
|
|
4444
|
-
|
|
4354
|
+
const marketplace = 'marketplace' in extension && extension.marketplace !== null && typeof extension.marketplace === 'object' ? extension.marketplace : {};
|
|
4355
|
+
const packageJson = 'packageJSON' in extension && extension.packageJSON !== null && typeof extension.packageJSON === 'object' ? extension.packageJSON : {};
|
|
4356
|
+
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);
|
|
4357
|
+
};
|
|
4358
|
+
const getRating = extension => {
|
|
4359
|
+
const rating = getRatingValue(extension);
|
|
4360
|
+
if (typeof rating !== 'number') {
|
|
4361
|
+
return 'n/a';
|
|
4445
4362
|
}
|
|
4446
|
-
return
|
|
4363
|
+
return rating.toFixed(1);
|
|
4447
4364
|
};
|
|
4448
4365
|
|
|
4449
|
-
const
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
for (const node of nodes) {
|
|
4453
|
-
while (remainingChildCounts.length > 0 && remainingChildCounts.at(-1) === 0) {
|
|
4454
|
-
remainingChildCounts.pop();
|
|
4455
|
-
}
|
|
4456
|
-
if (remainingChildCounts.length === 0) {
|
|
4457
|
-
count++;
|
|
4458
|
-
} else {
|
|
4459
|
-
const lastIndex = remainingChildCounts.length - 1;
|
|
4460
|
-
remainingChildCounts[lastIndex]--;
|
|
4461
|
-
}
|
|
4462
|
-
remainingChildCounts.push(node.childCount);
|
|
4366
|
+
const getSize = extension => {
|
|
4367
|
+
if (extension === null || typeof extension !== 'object' || !('size' in extension) || extension.size === 0 || typeof extension.size !== 'number') {
|
|
4368
|
+
return 0;
|
|
4463
4369
|
}
|
|
4464
|
-
return
|
|
4370
|
+
return extension.size;
|
|
4465
4371
|
};
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
className: focused ? mergeClassNames(ExtensionSearchCompletionItem, ExtensionSearchCompletionItemFocused) : ExtensionSearchCompletionItem,
|
|
4473
|
-
id: `ExtensionSearchCompletion-${index}`,
|
|
4474
|
-
name: item.label,
|
|
4475
|
-
onPointerDown: HandlePointerDown,
|
|
4476
|
-
role: Option,
|
|
4477
|
-
type: Button$2
|
|
4478
|
-
}, ...labelDom];
|
|
4372
|
+
|
|
4373
|
+
const getStatus = extension => {
|
|
4374
|
+
if (extension === null || typeof extension !== 'object' || !('status' in extension)) {
|
|
4375
|
+
return undefined;
|
|
4376
|
+
}
|
|
4377
|
+
return typeof extension.status === 'string' ? extension.status : undefined;
|
|
4479
4378
|
};
|
|
4480
4379
|
|
|
4481
|
-
const
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
id: 'ExtensionSearchCompletions',
|
|
4487
|
-
role: ListBox,
|
|
4488
|
-
type: Div
|
|
4489
|
-
}, ...items.flatMap((item, index) => getCompletionItemVirtualDom(item, index, focusedIndex))];
|
|
4380
|
+
const getUpdatedDate = extension => {
|
|
4381
|
+
if (extension === null || typeof extension !== 'object' || !('updatedDate' in extension) || !extension.updatedDate || typeof extension.updatedDate !== 'number') {
|
|
4382
|
+
return 0;
|
|
4383
|
+
}
|
|
4384
|
+
return extension.updatedDate;
|
|
4490
4385
|
};
|
|
4491
4386
|
|
|
4492
|
-
const
|
|
4387
|
+
const normalizeExtension = (extension, platform, assetDir) => {
|
|
4388
|
+
return {
|
|
4389
|
+
builtin: getBuiltin(extension),
|
|
4390
|
+
categories: getCategories(extension),
|
|
4391
|
+
description: getDescription(extension),
|
|
4392
|
+
disabled: getDisabled(extension),
|
|
4393
|
+
downloadCount: getDownloadCount(extension),
|
|
4394
|
+
icon: getIcon(extension, platform, assetDir),
|
|
4395
|
+
id: getId(extension),
|
|
4396
|
+
linked: getLinked(extension),
|
|
4397
|
+
name: getName(extension),
|
|
4398
|
+
publisher: getPublisher(extension),
|
|
4399
|
+
rating: getRating(extension),
|
|
4400
|
+
size: getSize(extension),
|
|
4401
|
+
status: getStatus(extension),
|
|
4402
|
+
updatedDate: getUpdatedDate(extension),
|
|
4403
|
+
uri: ''
|
|
4404
|
+
};
|
|
4405
|
+
};
|
|
4493
4406
|
|
|
4494
|
-
const
|
|
4495
|
-
|
|
4496
|
-
if (enabled) {
|
|
4497
|
-
return SearchFieldButton;
|
|
4498
|
-
}
|
|
4499
|
-
return disabledClassName;
|
|
4407
|
+
const normalizeExtensions = (extensions, platform, assetDir) => {
|
|
4408
|
+
return Array.from(extensions, extension => normalizeExtension(extension, platform, assetDir));
|
|
4500
4409
|
};
|
|
4501
|
-
|
|
4410
|
+
|
|
4411
|
+
const handleExtensionsChanged = async state => {
|
|
4502
4412
|
const {
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
return
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
tabIndex: Focusable,
|
|
4513
|
-
title,
|
|
4514
|
-
type: Button$2
|
|
4515
|
-
}, {
|
|
4516
|
-
childCount: 0,
|
|
4517
|
-
className: mergeClassNames(MaskIcon, icon),
|
|
4518
|
-
type: Div
|
|
4519
|
-
}];
|
|
4413
|
+
assetDir,
|
|
4414
|
+
platform
|
|
4415
|
+
} = state;
|
|
4416
|
+
const allExtensions = await getAllExtensions(assetDir, platform);
|
|
4417
|
+
const normalized = normalizeExtensions(allExtensions, platform, assetDir);
|
|
4418
|
+
return handleChange({
|
|
4419
|
+
...state,
|
|
4420
|
+
allExtensions: normalized
|
|
4421
|
+
}, {});
|
|
4520
4422
|
};
|
|
4521
4423
|
|
|
4522
|
-
const
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4424
|
+
const handleFocus = async state => {
|
|
4425
|
+
return {
|
|
4426
|
+
...state,
|
|
4427
|
+
focus: List$2
|
|
4428
|
+
};
|
|
4527
4429
|
};
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
autocapitalize: 'off',
|
|
4532
|
-
autocomplete: 'off',
|
|
4533
|
-
autocorrect: 'off',
|
|
4534
|
-
childCount: 0,
|
|
4535
|
-
className: MultilineInputBox,
|
|
4536
|
-
inputType: 'search',
|
|
4537
|
-
name,
|
|
4538
|
-
...(onBlur && {
|
|
4539
|
-
onBlur
|
|
4540
|
-
}),
|
|
4541
|
-
onFocus,
|
|
4542
|
-
onInput,
|
|
4543
|
-
placeholder,
|
|
4544
|
-
spellcheck: false,
|
|
4545
|
-
type: Input$1,
|
|
4546
|
-
...inputProperties
|
|
4547
|
-
}, {
|
|
4548
|
-
childCount: insideButtons.length,
|
|
4549
|
-
className: SearchFieldButtons,
|
|
4550
|
-
type: Div
|
|
4551
|
-
}, ...insideButtons.flatMap(getSearchFieldButtonVirtualDom)];
|
|
4552
|
-
if (outsideButtons.length > 0) {
|
|
4553
|
-
dom.unshift({
|
|
4554
|
-
childCount: 1 + outsideButtons.length,
|
|
4555
|
-
className: SearchFieldContainer,
|
|
4556
|
-
role: None,
|
|
4557
|
-
type: Div
|
|
4558
|
-
});
|
|
4559
|
-
dom.push(...outsideButtons.flatMap(getSearchFieldButtonVirtualDom));
|
|
4560
|
-
}
|
|
4561
|
-
return dom;
|
|
4430
|
+
|
|
4431
|
+
const handleHeaderContextMenu = async state => {
|
|
4432
|
+
return state;
|
|
4562
4433
|
};
|
|
4563
4434
|
|
|
4564
|
-
const
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
return getCompletionWidgetVirtualDom(completionItems, completionFocusedIndex);
|
|
4569
|
-
};
|
|
4570
|
-
const getExtensionHeaderVirtualDom = (placeholder, actions, completionItems = [], completionFocusedIndex = 0, suggestOpen = false) => {
|
|
4571
|
-
const inputProperties = suggestOpen ? {
|
|
4572
|
-
ariaActivedescendant: `ExtensionSearchCompletion-${completionFocusedIndex}`,
|
|
4573
|
-
ariaAutoComplete: 'list',
|
|
4574
|
-
ariaControls: 'ExtensionSearchCompletions',
|
|
4575
|
-
ariaExpanded: true,
|
|
4576
|
-
role: ComboBox
|
|
4577
|
-
} : {
|
|
4578
|
-
ariaAutoComplete: 'list',
|
|
4579
|
-
ariaExpanded: false,
|
|
4580
|
-
role: ComboBox
|
|
4435
|
+
const handleInputFocus = state => {
|
|
4436
|
+
return {
|
|
4437
|
+
...state,
|
|
4438
|
+
focus: Input
|
|
4581
4439
|
};
|
|
4582
|
-
const completionDom = getCompletionVirtualDom(completionItems, completionFocusedIndex, suggestOpen);
|
|
4583
|
-
return [{
|
|
4584
|
-
childCount: suggestOpen ? 2 : 1,
|
|
4585
|
-
className: ExtensionHeader,
|
|
4586
|
-
onContextMenu: HandleHeaderContextMenu,
|
|
4587
|
-
type: Div
|
|
4588
|
-
}, ...getSearchFieldVirtualDom(Extensions$1, placeholder, HandleExtensionsInput, actions, [], HandleInputFocus, HandleInputBlur, inputProperties), ...completionDom];
|
|
4589
4440
|
};
|
|
4590
4441
|
|
|
4591
|
-
const
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
return ['setHeaderDom', dom];
|
|
4442
|
+
const handleInstall = async (state, id) => {
|
|
4443
|
+
await installExtension(id);
|
|
4444
|
+
return setExtensionStatus(state, id, Enabled);
|
|
4595
4445
|
};
|
|
4596
4446
|
|
|
4597
|
-
const
|
|
4598
|
-
|
|
4599
|
-
const install = {
|
|
4600
|
-
disabled: false,
|
|
4601
|
-
label: install$1(),
|
|
4602
|
-
onClick: HandleInstall
|
|
4447
|
+
const state = {
|
|
4448
|
+
connected: false
|
|
4603
4449
|
};
|
|
4604
|
-
const
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4450
|
+
const isConnected = () => {
|
|
4451
|
+
const {
|
|
4452
|
+
connected
|
|
4453
|
+
} = state;
|
|
4454
|
+
return connected;
|
|
4608
4455
|
};
|
|
4609
|
-
const
|
|
4610
|
-
|
|
4611
|
-
label: enable$2(),
|
|
4612
|
-
onClick: HandleEnable
|
|
4456
|
+
const invoke = (method, ...params) => {
|
|
4457
|
+
return invoke$2(method, ...params);
|
|
4613
4458
|
};
|
|
4614
|
-
const
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
onClick: HandleDisable
|
|
4459
|
+
const set = rpc => {
|
|
4460
|
+
set$3(rpc);
|
|
4461
|
+
state.connected = true;
|
|
4618
4462
|
};
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4463
|
+
|
|
4464
|
+
const handleMessagePort = async (port, viewletCommandMap, setAsRendererProcess = true) => {
|
|
4465
|
+
const executeViewletCommand = async (uid, command, ...args) => {
|
|
4466
|
+
const fn = viewletCommandMap[`SearchExtensions.${command}`];
|
|
4467
|
+
if (typeof fn !== 'function') {
|
|
4468
|
+
throw new TypeError(`Viewlet command not found: ${command}`);
|
|
4469
|
+
}
|
|
4470
|
+
await fn(uid, ...args);
|
|
4471
|
+
await invoke$1('Viewlet.requestRender', uid);
|
|
4472
|
+
};
|
|
4473
|
+
const rpc = await create$7({
|
|
4474
|
+
commandMap: {
|
|
4475
|
+
'Viewlet.executeViewletCommand': executeViewletCommand
|
|
4476
|
+
},
|
|
4477
|
+
messagePort: port
|
|
4478
|
+
});
|
|
4479
|
+
if (setAsRendererProcess) {
|
|
4480
|
+
set(rpc);
|
|
4481
|
+
}
|
|
4623
4482
|
};
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4483
|
+
|
|
4484
|
+
const handleScrollBarCaptureLost = state => {
|
|
4485
|
+
return {
|
|
4486
|
+
...state,
|
|
4487
|
+
scrollBarActive: false
|
|
4488
|
+
};
|
|
4628
4489
|
};
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
return
|
|
4490
|
+
|
|
4491
|
+
const getNewDeltaPercent = (height, scrollBarHeight, relativeY) => {
|
|
4492
|
+
const halfScrollBarHeight = scrollBarHeight / 2;
|
|
4493
|
+
if (relativeY <= halfScrollBarHeight) {
|
|
4494
|
+
// clicked at top
|
|
4495
|
+
return {
|
|
4496
|
+
handleOffset: relativeY,
|
|
4497
|
+
percent: 0
|
|
4498
|
+
};
|
|
4635
4499
|
}
|
|
4636
|
-
if (
|
|
4637
|
-
|
|
4500
|
+
if (relativeY <= height - halfScrollBarHeight) {
|
|
4501
|
+
// clicked in middle
|
|
4502
|
+
return {
|
|
4503
|
+
handleOffset: halfScrollBarHeight,
|
|
4504
|
+
percent: (relativeY - halfScrollBarHeight) / (height - scrollBarHeight)
|
|
4505
|
+
};
|
|
4638
4506
|
}
|
|
4639
|
-
|
|
4640
|
-
return
|
|
4507
|
+
// clicked at bottom
|
|
4508
|
+
return {
|
|
4509
|
+
handleOffset: scrollBarHeight - height + relativeY,
|
|
4510
|
+
percent: 1
|
|
4511
|
+
};
|
|
4641
4512
|
};
|
|
4642
4513
|
|
|
4643
|
-
const
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
disabled: action.disabled,
|
|
4649
|
-
name: id,
|
|
4650
|
-
onClick: action.onClick,
|
|
4651
|
-
type: Button$2
|
|
4652
|
-
}, text(action.label)];
|
|
4514
|
+
const clamp = (num, min, max) => {
|
|
4515
|
+
number(num);
|
|
4516
|
+
number(min);
|
|
4517
|
+
number(max);
|
|
4518
|
+
return Math.min(Math.max(num, min), max);
|
|
4653
4519
|
};
|
|
4654
4520
|
|
|
4655
|
-
const
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4521
|
+
const setDeltaY = (state, value) => {
|
|
4522
|
+
object(state);
|
|
4523
|
+
number(value);
|
|
4524
|
+
const {
|
|
4525
|
+
deltaY,
|
|
4526
|
+
finalDeltaY,
|
|
4527
|
+
headerHeight,
|
|
4528
|
+
height,
|
|
4529
|
+
itemHeight,
|
|
4530
|
+
items,
|
|
4531
|
+
minimumSliderSize
|
|
4532
|
+
} = state;
|
|
4533
|
+
const listHeight = height - headerHeight;
|
|
4534
|
+
const newDeltaY = clamp(value, 0, finalDeltaY);
|
|
4535
|
+
if (deltaY === newDeltaY) {
|
|
4536
|
+
return state;
|
|
4537
|
+
}
|
|
4538
|
+
// TODO when it only moves by one px, extensions don't need to be rerendered, only negative margin
|
|
4539
|
+
const minLineY = Math.floor(newDeltaY / itemHeight);
|
|
4540
|
+
const total = items.length;
|
|
4541
|
+
const maxLineY = Math.min(minLineY + getNumberOfVisibleItems$1(listHeight, itemHeight), total);
|
|
4542
|
+
const contentHeight = total * itemHeight;
|
|
4543
|
+
const scrollBarHeight = getScrollBarSize(listHeight, contentHeight, minimumSliderSize);
|
|
4544
|
+
const scrollBarY = getScrollBarY$1(newDeltaY, finalDeltaY, height - headerHeight, scrollBarHeight);
|
|
4545
|
+
return {
|
|
4546
|
+
...state,
|
|
4547
|
+
deltaY: newDeltaY,
|
|
4548
|
+
maxLineY,
|
|
4549
|
+
minLineY,
|
|
4550
|
+
scrollBarY
|
|
4551
|
+
};
|
|
4662
4552
|
};
|
|
4663
4553
|
|
|
4664
|
-
const
|
|
4665
|
-
|
|
4554
|
+
const handleScrollBarClick = (state, eventY) => {
|
|
4555
|
+
// TODO move this to list
|
|
4556
|
+
const {
|
|
4557
|
+
deltaY,
|
|
4558
|
+
finalDeltaY,
|
|
4559
|
+
headerHeight,
|
|
4560
|
+
height,
|
|
4561
|
+
scrollBarHeight,
|
|
4562
|
+
y
|
|
4563
|
+
} = state;
|
|
4564
|
+
const contentHeight = height - headerHeight;
|
|
4565
|
+
const relativeY = eventY - y - headerHeight;
|
|
4566
|
+
const currentScrollBarY = getScrollBarY$1(deltaY, finalDeltaY, contentHeight, scrollBarHeight);
|
|
4567
|
+
const diff = relativeY - currentScrollBarY;
|
|
4568
|
+
if (diff >= 0 && diff < scrollBarHeight) {
|
|
4569
|
+
return {
|
|
4570
|
+
...state,
|
|
4571
|
+
handleOffset: diff,
|
|
4572
|
+
scrollBarActive: true
|
|
4573
|
+
};
|
|
4574
|
+
}
|
|
4575
|
+
const {
|
|
4576
|
+
handleOffset,
|
|
4577
|
+
percent
|
|
4578
|
+
} = getNewDeltaPercent(contentHeight, scrollBarHeight, relativeY);
|
|
4579
|
+
const newDeltaY = percent * finalDeltaY;
|
|
4580
|
+
return {
|
|
4581
|
+
...setDeltaY(state, newDeltaY),
|
|
4582
|
+
handleOffset,
|
|
4583
|
+
scrollBarActive: true
|
|
4584
|
+
};
|
|
4585
|
+
};
|
|
4586
|
+
|
|
4587
|
+
const getNewPercent = (contentHeight, scrollBarHeight, relativeY) => {
|
|
4588
|
+
if (relativeY <= contentHeight - scrollBarHeight / 2) {
|
|
4589
|
+
// clicked in middle
|
|
4590
|
+
return relativeY / (contentHeight - scrollBarHeight);
|
|
4591
|
+
}
|
|
4592
|
+
// clicked at bottom
|
|
4593
|
+
return 1;
|
|
4594
|
+
};
|
|
4595
|
+
const handleScrollBarMove = (state, eventY) => {
|
|
4596
|
+
const {
|
|
4597
|
+
finalDeltaY,
|
|
4598
|
+
handleOffset,
|
|
4599
|
+
headerHeight,
|
|
4600
|
+
height,
|
|
4601
|
+
scrollBarActive,
|
|
4602
|
+
scrollBarHeight,
|
|
4603
|
+
y
|
|
4604
|
+
} = state;
|
|
4605
|
+
if (!scrollBarActive) {
|
|
4606
|
+
return state;
|
|
4607
|
+
}
|
|
4608
|
+
const relativeY = eventY - y - headerHeight - handleOffset;
|
|
4609
|
+
const contentHeight = height - headerHeight;
|
|
4610
|
+
const newPercent = getNewPercent(contentHeight, scrollBarHeight, relativeY);
|
|
4611
|
+
const newDeltaY = newPercent * finalDeltaY;
|
|
4612
|
+
return setDeltaY(state, newDeltaY);
|
|
4666
4613
|
};
|
|
4667
4614
|
|
|
4668
|
-
const
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4615
|
+
const handleSettingsButtonClick = async (state, index) => {
|
|
4616
|
+
const {
|
|
4617
|
+
deltaY,
|
|
4618
|
+
headerHeight,
|
|
4619
|
+
itemHeight,
|
|
4620
|
+
items,
|
|
4621
|
+
uid,
|
|
4622
|
+
x,
|
|
4623
|
+
y
|
|
4624
|
+
} = state;
|
|
4625
|
+
const actualIndex = index;
|
|
4626
|
+
if (actualIndex < 0 || actualIndex >= items.length) {
|
|
4627
|
+
return state;
|
|
4628
|
+
}
|
|
4629
|
+
|
|
4630
|
+
// Calculate the position for the context menu
|
|
4631
|
+
// The settings button is at the bottom right of the extension list item
|
|
4632
|
+
const itemY = y + headerHeight + actualIndex * itemHeight - deltaY;
|
|
4633
|
+
const menuX = x + 200; // Position near the right side of the extension item
|
|
4634
|
+
const menuY = itemY + itemHeight - 10; // Position at the bottom of the extension item
|
|
4635
|
+
|
|
4636
|
+
await show2(uid, ManageExtension, menuX, menuY, {
|
|
4637
|
+
builtin: items[actualIndex].builtin === true,
|
|
4638
|
+
disabled: items[actualIndex].disabled === true,
|
|
4639
|
+
menuId: ManageExtension,
|
|
4640
|
+
status: items[actualIndex].status
|
|
4641
|
+
});
|
|
4642
|
+
return state;
|
|
4674
4643
|
};
|
|
4675
4644
|
|
|
4676
|
-
const
|
|
4677
|
-
|
|
4678
|
-
|
|
4645
|
+
const handleUninstall = async (state, id) => {
|
|
4646
|
+
try {
|
|
4647
|
+
await uninstall$2(id);
|
|
4648
|
+
return setExtensionStatus(state, id, NotInstalled);
|
|
4649
|
+
} catch (error) {
|
|
4650
|
+
await showErrorDialog(error);
|
|
4651
|
+
return state;
|
|
4679
4652
|
}
|
|
4680
|
-
return undefined;
|
|
4681
4653
|
};
|
|
4682
4654
|
|
|
4683
|
-
const
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
};
|
|
4688
|
-
const getStatisticVirtualDom = (label, value, className) => {
|
|
4689
|
-
const accessibleLabel = `${label}: ${value}`;
|
|
4690
|
-
return [{
|
|
4691
|
-
ariaLabel: accessibleLabel,
|
|
4692
|
-
childCount: 1,
|
|
4693
|
-
className: mergeClassNames(ExtensionListItemStatistic, className),
|
|
4694
|
-
title: accessibleLabel,
|
|
4695
|
-
type: Span
|
|
4696
|
-
}, text(value)];
|
|
4697
|
-
};
|
|
4698
|
-
const getExtensionStatisticsVirtualDom = (downloadCount, rating$1) => {
|
|
4699
|
-
return [extensionListItemMetadataNode, ...getStatisticVirtualDom(downloads(), downloadCount, ExtensionListItemDownloadCount), ...getStatisticVirtualDom(rating(), rating$1, ExtensionListItemRating)];
|
|
4655
|
+
const handleWheel = (state, deltaMode, deltaY) => {
|
|
4656
|
+
number(deltaMode);
|
|
4657
|
+
number(deltaY);
|
|
4658
|
+
return setDeltaY(state, state.deltaY + deltaY * state.scrollSensitivity);
|
|
4700
4659
|
};
|
|
4701
4660
|
|
|
4702
|
-
const
|
|
4703
|
-
|
|
4704
|
-
|
|
4661
|
+
const createExtensionManagementWorkerRpc = async () => {
|
|
4662
|
+
try {
|
|
4663
|
+
const rpc = await create$6({
|
|
4664
|
+
commandMap: {},
|
|
4665
|
+
send: port => sendMessagePortToExtensionManagementWorker(port, 0)
|
|
4666
|
+
});
|
|
4667
|
+
return rpc;
|
|
4668
|
+
} catch (error) {
|
|
4669
|
+
throw new VError(error, `Failed to create extension management rpc`);
|
|
4705
4670
|
}
|
|
4706
|
-
return getExtensionStatisticsVirtualDom(downloadCount, rating);
|
|
4707
4671
|
};
|
|
4708
4672
|
|
|
4709
|
-
const
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
};
|
|
4716
|
-
const listItemName = {
|
|
4717
|
-
childCount: 1,
|
|
4718
|
-
className: ExtensionListItemName,
|
|
4719
|
-
type: Div
|
|
4720
|
-
};
|
|
4721
|
-
const listItemDescription = {
|
|
4722
|
-
childCount: 1,
|
|
4723
|
-
className: ExtensionListItemDescription,
|
|
4724
|
-
type: Div
|
|
4725
|
-
};
|
|
4726
|
-
const listItemAuthorName = {
|
|
4727
|
-
childCount: 1,
|
|
4728
|
-
className: ExtensionListItemAuthorName,
|
|
4729
|
-
type: Div
|
|
4730
|
-
};
|
|
4731
|
-
const getLinkedIconVirtualDom = linked$1 => {
|
|
4732
|
-
if (!linked$1) {
|
|
4733
|
-
return [];
|
|
4673
|
+
const initializeExtensionManagementWorker = async () => {
|
|
4674
|
+
try {
|
|
4675
|
+
const rpc = await createExtensionManagementWorkerRpc();
|
|
4676
|
+
set$4(rpc);
|
|
4677
|
+
} catch {
|
|
4678
|
+
// ignore
|
|
4734
4679
|
}
|
|
4735
|
-
const label = linked();
|
|
4736
|
-
return [{
|
|
4737
|
-
ariaLabel: label,
|
|
4738
|
-
childCount: 0,
|
|
4739
|
-
className: mergeClassNames(MaskIcon, 'MaskIconLinkExternal', ExtensionListItemLinkedIcon),
|
|
4740
|
-
role: Image,
|
|
4741
|
-
title: 'Extension is linked',
|
|
4742
|
-
type: Div
|
|
4743
|
-
}];
|
|
4744
4680
|
};
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
description,
|
|
4749
|
-
disabled = false,
|
|
4750
|
-
downloadCount = 'n/a',
|
|
4751
|
-
focused,
|
|
4752
|
-
icon,
|
|
4753
|
-
id,
|
|
4754
|
-
linked = false,
|
|
4755
|
-
name,
|
|
4756
|
-
posInSet,
|
|
4757
|
-
publisher,
|
|
4758
|
-
rating = 'n/a',
|
|
4759
|
-
setSize,
|
|
4760
|
-
status
|
|
4761
|
-
} = extension;
|
|
4762
|
-
const actionsDom = getExtensionActionsVirtualDom(id, builtin, disabled, status);
|
|
4763
|
-
const hasStatistics = !builtin;
|
|
4764
|
-
const dom = [{
|
|
4765
|
-
ariaPosInSet: posInSet,
|
|
4766
|
-
ariaRoleDescription: Extension,
|
|
4767
|
-
ariaSetSize: setSize,
|
|
4768
|
-
childCount: 2,
|
|
4769
|
-
className: getExtensionListItemClassName(focused, disabled),
|
|
4770
|
-
id: getExtensionListItemId(focused),
|
|
4771
|
-
role: ListItem,
|
|
4772
|
-
type: Div
|
|
4773
|
-
}, {
|
|
4774
|
-
childCount: 0,
|
|
4775
|
-
className: ExtensionListItemIcon,
|
|
4776
|
-
role: None,
|
|
4777
|
-
src: icon,
|
|
4778
|
-
type: Img
|
|
4779
|
-
}, getListItemDetail(linked), listItemName, text(name), listItemDescription, text(description), getExtensionListItemFooter(hasStatistics), listItemAuthorName, text(publisher), ...getExtensionListItemStatisticsVirtualDom(hasStatistics, downloadCount, rating), ...actionsDom, ...getLinkedIconVirtualDom(linked)];
|
|
4780
|
-
return dom;
|
|
4681
|
+
|
|
4682
|
+
const initialize = async () => {
|
|
4683
|
+
await initializeExtensionManagementWorker();
|
|
4781
4684
|
};
|
|
4782
4685
|
|
|
4783
|
-
const
|
|
4784
|
-
|
|
4785
|
-
return
|
|
4686
|
+
const installAnotherVersion = async state => {
|
|
4687
|
+
await invoke$4('ConfirmPrompt.prompt', 'not implemented', undefined);
|
|
4688
|
+
return state;
|
|
4786
4689
|
};
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
onWheel: HandleWheel,
|
|
4801
|
-
role: List$1,
|
|
4802
|
-
tabIndex: Focusable,
|
|
4803
|
-
type: Div
|
|
4804
|
-
}, ...visibleExtensions.flatMap(getExtensionListItemVirtualDom)];
|
|
4805
|
-
return dom;
|
|
4690
|
+
|
|
4691
|
+
const Small = 1;
|
|
4692
|
+
const Normal = 2;
|
|
4693
|
+
const Large = 3;
|
|
4694
|
+
|
|
4695
|
+
const getViewletSize = width => {
|
|
4696
|
+
if (width < 180) {
|
|
4697
|
+
return Small;
|
|
4698
|
+
}
|
|
4699
|
+
if (width < 768) {
|
|
4700
|
+
return Normal;
|
|
4701
|
+
}
|
|
4702
|
+
return Large;
|
|
4806
4703
|
};
|
|
4807
4704
|
|
|
4808
|
-
const
|
|
4809
|
-
const
|
|
4810
|
-
|
|
4811
|
-
return dom;
|
|
4705
|
+
const getIsFirefox = () => {
|
|
4706
|
+
const globalWithNavigator = globalThis;
|
|
4707
|
+
return globalWithNavigator.navigator?.userAgent.toLowerCase().includes('firefox') ?? false;
|
|
4812
4708
|
};
|
|
4813
4709
|
|
|
4814
|
-
const
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4710
|
+
const getSavedValue = savedState => {
|
|
4711
|
+
if (savedState && typeof savedState === 'object' && 'searchValue' in savedState && typeof savedState.searchValue === 'string') {
|
|
4712
|
+
return savedState.searchValue;
|
|
4713
|
+
}
|
|
4714
|
+
return '';
|
|
4818
4715
|
};
|
|
4819
|
-
const
|
|
4820
|
-
|
|
4716
|
+
const getSavedDeltaY = savedState => {
|
|
4717
|
+
if (savedState && typeof savedState === 'object' && 'deltaY' in savedState && typeof savedState.deltaY === 'number' && !Number.isNaN(savedState.deltaY)) {
|
|
4718
|
+
return savedState.deltaY;
|
|
4719
|
+
}
|
|
4720
|
+
return 0;
|
|
4821
4721
|
};
|
|
4822
4722
|
|
|
4823
|
-
const
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
};
|
|
4830
|
-
const scrollBarThumbNode = {
|
|
4831
|
-
childCount: 0,
|
|
4832
|
-
className: ScrollBarThumb,
|
|
4833
|
-
type: Div
|
|
4723
|
+
const restoreState = savedState => {
|
|
4724
|
+
const searchValue = getSavedValue(savedState);
|
|
4725
|
+
const savedDeltaY = getSavedDeltaY(savedState);
|
|
4726
|
+
return {
|
|
4727
|
+
deltaY: savedDeltaY,
|
|
4728
|
+
searchValue
|
|
4729
|
+
};
|
|
4834
4730
|
};
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4731
|
+
|
|
4732
|
+
const loadContentWithContext = async (context, savedState) => {
|
|
4733
|
+
const {
|
|
4734
|
+
uid
|
|
4735
|
+
} = context.getState();
|
|
4736
|
+
const loadToken = getToken(uid);
|
|
4737
|
+
try {
|
|
4738
|
+
const initialState = context.getState();
|
|
4739
|
+
const {
|
|
4740
|
+
assetDir,
|
|
4741
|
+
platform,
|
|
4742
|
+
width
|
|
4743
|
+
} = initialState;
|
|
4744
|
+
const {
|
|
4745
|
+
deltaY,
|
|
4746
|
+
searchValue: restoredSearchValue
|
|
4747
|
+
} = restoreState(savedState);
|
|
4748
|
+
const size = getViewletSize(width);
|
|
4749
|
+
const scrollSensitivity = getIsFirefox() ? 2.5 : 1;
|
|
4750
|
+
await context.updateState(state => {
|
|
4751
|
+
if (!state.initial) {
|
|
4752
|
+
return state;
|
|
4753
|
+
}
|
|
4754
|
+
return {
|
|
4755
|
+
...state,
|
|
4756
|
+
deltaY,
|
|
4757
|
+
initial: false,
|
|
4758
|
+
inputSource: Script,
|
|
4759
|
+
scrollSensitivity,
|
|
4760
|
+
searchValue: restoredSearchValue,
|
|
4761
|
+
size
|
|
4762
|
+
};
|
|
4763
|
+
});
|
|
4764
|
+
const allExtensions = await getAllExtensions(assetDir, platform);
|
|
4765
|
+
const normalized = normalizeExtensions(allExtensions, platform, assetDir);
|
|
4766
|
+
await context.updateState(state => ({
|
|
4767
|
+
...state,
|
|
4768
|
+
allExtensions: normalized
|
|
4769
|
+
}));
|
|
4770
|
+
await handleChangeWithContext(context, {}, false);
|
|
4771
|
+
} finally {
|
|
4772
|
+
finish(uid, loadToken);
|
|
4839
4773
|
}
|
|
4840
|
-
return [scrollBarNode, scrollBarThumbNode];
|
|
4841
4774
|
};
|
|
4842
4775
|
|
|
4843
|
-
const
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
disabled,
|
|
4849
|
-
downloadCount,
|
|
4850
|
-
icon,
|
|
4851
|
-
id,
|
|
4852
|
-
linked,
|
|
4853
|
-
name,
|
|
4854
|
-
publisher,
|
|
4855
|
-
rating,
|
|
4856
|
-
status
|
|
4857
|
-
} = item;
|
|
4776
|
+
const openSuggest = state => {
|
|
4777
|
+
const completionItems = getCompletionItems(state.searchValue, state.cursorOffset);
|
|
4778
|
+
if (completionItems.length === 0) {
|
|
4779
|
+
return state;
|
|
4780
|
+
}
|
|
4858
4781
|
return {
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
focused: i === focusedIndex,
|
|
4864
|
-
icon,
|
|
4865
|
-
id,
|
|
4866
|
-
index: i,
|
|
4867
|
-
linked,
|
|
4868
|
-
name,
|
|
4869
|
-
posInSet: i + 1,
|
|
4870
|
-
publisher,
|
|
4871
|
-
rating,
|
|
4872
|
-
setSize,
|
|
4873
|
-
status,
|
|
4874
|
-
top: (i - minLineY) * itemHeight - relative
|
|
4782
|
+
...state,
|
|
4783
|
+
completionFocusedIndex: 0,
|
|
4784
|
+
completionItems,
|
|
4785
|
+
suggestOpen: true
|
|
4875
4786
|
};
|
|
4876
4787
|
};
|
|
4877
4788
|
|
|
4878
|
-
const
|
|
4789
|
+
const getCss = state => {
|
|
4879
4790
|
const {
|
|
4791
|
+
cursorOffset,
|
|
4880
4792
|
deltaY,
|
|
4881
|
-
|
|
4793
|
+
headerHeight,
|
|
4882
4794
|
itemHeight,
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4795
|
+
scrollBarHeight,
|
|
4796
|
+
scrollBarY,
|
|
4797
|
+
width
|
|
4886
4798
|
} = state;
|
|
4887
|
-
const
|
|
4888
|
-
const
|
|
4889
|
-
const
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
}
|
|
4894
|
-
|
|
4895
|
-
}
|
|
4799
|
+
const relative = -(deltaY % itemHeight);
|
|
4800
|
+
const roundedScrollBarY = Math.round(scrollBarY);
|
|
4801
|
+
const maximumCompletionLeft = Math.max(8, width - 168);
|
|
4802
|
+
const completionLeft = Math.min(Math.round(8 + cursorOffset * 7.5), maximumCompletionLeft);
|
|
4803
|
+
const completionTop = Math.max(0, headerHeight - 10);
|
|
4804
|
+
return `.Extensions .ScrollBarThumb {
|
|
4805
|
+
height: ${scrollBarHeight}px;
|
|
4806
|
+
translate: 0 ${roundedScrollBarY}px;
|
|
4807
|
+
}
|
|
4896
4808
|
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4809
|
+
|
|
4810
|
+
/* TODO: avoid using negative margin. find a better way*/
|
|
4811
|
+
.ExtensionListItem:nth-child(1) {
|
|
4812
|
+
margin-top: ${relative}px;
|
|
4813
|
+
}
|
|
4814
|
+
|
|
4815
|
+
.ExtensionListItem {
|
|
4816
|
+
box-sizing: border-box;
|
|
4817
|
+
position: relative !important;
|
|
4818
|
+
flex-shrink: 0;
|
|
4819
|
+
}
|
|
4820
|
+
|
|
4821
|
+
.ExtensionListItemLinkedIcon {
|
|
4822
|
+
position: absolute;
|
|
4823
|
+
top: 6px;
|
|
4824
|
+
right: 6px;
|
|
4825
|
+
width: 14px;
|
|
4826
|
+
height: 14px;
|
|
4827
|
+
color: var(--WorkbenchForeground, rgb(188, 190, 190));
|
|
4828
|
+
opacity: 0.8;
|
|
4829
|
+
}
|
|
4830
|
+
|
|
4831
|
+
.ExtensionListItemDisabled:not(.ExtensionActive) {
|
|
4832
|
+
background: color-mix(in srgb, var(--SideBarBackground, rgb(30, 35, 36)) 95%, black);
|
|
4833
|
+
color: var(--ExtensionDisabledForeground, color-mix(in srgb, var(--WorkbenchForeground) 70%, black));
|
|
4834
|
+
}
|
|
4835
|
+
|
|
4836
|
+
.Extensions .ListItems {
|
|
4837
|
+
display: flex;
|
|
4838
|
+
flex-direction: column;
|
|
4839
|
+
gap: 0;
|
|
4840
|
+
overflow-y: hidden;
|
|
4841
|
+
}
|
|
4842
|
+
|
|
4843
|
+
.ExtensionHeader {
|
|
4844
|
+
contain: layout style;
|
|
4845
|
+
position: relative;
|
|
4846
|
+
z-index: 1;
|
|
4847
|
+
}
|
|
4848
|
+
|
|
4849
|
+
.ExtensionListItemFooter {
|
|
4850
|
+
justify-content: flex-end;
|
|
4851
|
+
padding-right: 2px;
|
|
4852
|
+
}
|
|
4853
|
+
|
|
4854
|
+
.ExtensionListItemAuthorName {
|
|
4855
|
+
flex: 1;
|
|
4856
|
+
}
|
|
4857
|
+
|
|
4858
|
+
.ExtensionActions {
|
|
4859
|
+
display: flex;
|
|
4860
|
+
gap: 6px;
|
|
4861
|
+
}
|
|
4862
|
+
|
|
4863
|
+
.ExtensionActionButton {
|
|
4864
|
+
padding: 0 5px;
|
|
4865
|
+
}
|
|
4866
|
+
|
|
4867
|
+
.ExtensionSearchCompletionWidget {
|
|
4868
|
+
position: absolute;
|
|
4869
|
+
left: ${completionLeft}px;
|
|
4870
|
+
top: ${completionTop}px;
|
|
4871
|
+
width: min(320px, calc(100% - ${completionLeft + 8}px));
|
|
4872
|
+
max-height: 240px;
|
|
4873
|
+
overflow-y: auto;
|
|
4874
|
+
z-index: 10;
|
|
4875
|
+
box-sizing: border-box;
|
|
4876
|
+
border: 1px solid var(--CompletionListBorder, #95a29d);
|
|
4877
|
+
background: var(--CompletionListBackground, #282e2f);
|
|
4878
|
+
color: var(--CompletionListForeground, white);
|
|
4879
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.36);
|
|
4880
|
+
font-size: 13px;
|
|
4881
|
+
line-height: 20px;
|
|
4882
|
+
user-select: none;
|
|
4883
|
+
}
|
|
4884
|
+
|
|
4885
|
+
.ExtensionSearchCompletionItem {
|
|
4886
|
+
display: block;
|
|
4887
|
+
width: 100%;
|
|
4888
|
+
min-height: 20px;
|
|
4889
|
+
padding: 0 6px;
|
|
4890
|
+
border: 0;
|
|
4891
|
+
background: transparent;
|
|
4892
|
+
color: inherit;
|
|
4893
|
+
font: inherit;
|
|
4894
|
+
line-height: inherit;
|
|
4895
|
+
text-align: left;
|
|
4896
|
+
overflow: hidden;
|
|
4897
|
+
text-overflow: ellipsis;
|
|
4898
|
+
white-space: nowrap;
|
|
4899
|
+
cursor: pointer;
|
|
4900
|
+
}
|
|
4901
|
+
|
|
4902
|
+
.ExtensionSearchCompletionItem:hover {
|
|
4903
|
+
background: var(--CompletionListItemHoverBackground, rgba(64, 92, 80, 0.2));
|
|
4904
|
+
}
|
|
4905
|
+
|
|
4906
|
+
.ExtensionSearchCompletionItemFocused {
|
|
4907
|
+
background: var(--CompletionListItemActiveBackground, #405c50);
|
|
4908
|
+
color: var(--CompletionListItemActiveForeground);
|
|
4909
|
+
}
|
|
4910
|
+
|
|
4911
|
+
.ExtensionSearchCompletionHighlight {
|
|
4912
|
+
color: var(--CompletionHighlightForeground, #e1b974);
|
|
4913
|
+
font-weight: 700;
|
|
4914
|
+
}
|
|
4915
|
+
`;
|
|
4901
4916
|
};
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4917
|
+
|
|
4918
|
+
const renderCss = newState => {
|
|
4919
|
+
const {
|
|
4920
|
+
uid
|
|
4921
|
+
} = newState;
|
|
4922
|
+
const css = getCss(newState);
|
|
4923
|
+
return [SetCss, uid, css];
|
|
4909
4924
|
};
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4925
|
+
|
|
4926
|
+
const getSelector = focus => {
|
|
4927
|
+
switch (focus) {
|
|
4928
|
+
case Input:
|
|
4929
|
+
return `[name="${Extensions}"]`;
|
|
4930
|
+
case List$2:
|
|
4931
|
+
return '.ListItems';
|
|
4932
|
+
default:
|
|
4933
|
+
return '';
|
|
4913
4934
|
}
|
|
4914
|
-
return [contentNode, ...getExtensionsVirtualDom(visibleExtensions, focusOutline), ...getScrollBarVirtualDom(scrollBarHeight)];
|
|
4915
4935
|
};
|
|
4916
|
-
const
|
|
4917
|
-
const visibleExtensions = getVisible(state);
|
|
4936
|
+
const renderFocus = newState => {
|
|
4918
4937
|
const {
|
|
4919
|
-
completionFocusedIndex,
|
|
4920
|
-
completionItems,
|
|
4921
4938
|
focus,
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
} = state;
|
|
4930
|
-
const focusOutline = focusedIndex === -1 && focus === List$2;
|
|
4931
|
-
return [extensionsNode, ...getExtensionHeaderVirtualDom(placeholder, inputActions, completionItems, completionFocusedIndex, suggestOpen), ...getContentVirtualDom(visibleExtensions, message, scrollBarHeight, scrollBarY, focusOutline)];
|
|
4939
|
+
uid
|
|
4940
|
+
} = newState;
|
|
4941
|
+
if (!focus) {
|
|
4942
|
+
return [];
|
|
4943
|
+
}
|
|
4944
|
+
const selector = getSelector(focus);
|
|
4945
|
+
return [FocusSelector, uid, selector];
|
|
4932
4946
|
};
|
|
4933
4947
|
|
|
4934
|
-
const
|
|
4948
|
+
const renderFocusContext = newState => {
|
|
4935
4949
|
const {
|
|
4936
|
-
initial,
|
|
4937
4950
|
uid
|
|
4938
4951
|
} = newState;
|
|
4939
|
-
if (
|
|
4940
|
-
return [
|
|
4952
|
+
if (newState.focus === Input) {
|
|
4953
|
+
return ['Viewlet.setFocusContext', uid, FocusExtensionsInput];
|
|
4941
4954
|
}
|
|
4942
|
-
|
|
4943
|
-
|
|
4955
|
+
if (newState.focus === List$2) {
|
|
4956
|
+
return ['Viewlet.setFocusContext', uid, FocusExtensions];
|
|
4957
|
+
}
|
|
4958
|
+
return [];
|
|
4959
|
+
};
|
|
4960
|
+
|
|
4961
|
+
const renderHeader = newState => {
|
|
4962
|
+
const actions = getInputActions(newState.searchValue.length > 0);
|
|
4963
|
+
const dom = getExtensionHeaderVirtualDom(newState.placeholder, actions, newState.completionItems, newState.completionFocusedIndex, newState.suggestOpen);
|
|
4964
|
+
return ['setHeaderDom', dom];
|
|
4944
4965
|
};
|
|
4945
4966
|
|
|
4946
4967
|
// TODO cache rendered dom so that it can be used for dom diffing
|
|
@@ -4980,7 +5001,7 @@ const renderScrollBar = newState => {
|
|
|
4980
5001
|
};
|
|
4981
5002
|
|
|
4982
5003
|
const renderSearchValue = newState => {
|
|
4983
|
-
return [/* method */'Viewlet.setValueByName', newState.uid, Extensions
|
|
5004
|
+
return [/* method */'Viewlet.setValueByName', newState.uid, Extensions, newState.searchValue];
|
|
4984
5005
|
};
|
|
4985
5006
|
|
|
4986
5007
|
const titleFilters = [{
|
|
@@ -5102,7 +5123,7 @@ const getIconVirtualDom = (icon, type = Div) => {
|
|
|
5102
5123
|
return {
|
|
5103
5124
|
childCount: 0,
|
|
5104
5125
|
className: mergeClassNames(MaskIcon, `MaskIcon${icon}`),
|
|
5105
|
-
role: None,
|
|
5126
|
+
role: None$1,
|
|
5106
5127
|
type
|
|
5107
5128
|
};
|
|
5108
5129
|
};
|
|
@@ -5333,6 +5354,7 @@ const commandMap = {
|
|
|
5333
5354
|
'SearchExtensions.enable': wrapCommand(enable$1),
|
|
5334
5355
|
'SearchExtensions.enableWorkspace': wrapCommand(enableWorkspace),
|
|
5335
5356
|
'SearchExtensions.filterByBuiltin': wrapAsyncCommand(createFilterCommand(Builtin)),
|
|
5357
|
+
'SearchExtensions.filterByCategory': wrapAsyncCommand(filterByValueWithContext),
|
|
5336
5358
|
'SearchExtensions.filterByDisabled': wrapAsyncCommand(createFilterCommand(Disabled$2)),
|
|
5337
5359
|
'SearchExtensions.filterByEnabled': wrapAsyncCommand(createFilterCommand(Enabled$1)),
|
|
5338
5360
|
'SearchExtensions.filterByFeatured': wrapAsyncCommand(createFilterCommand(Featured)),
|
|
@@ -5353,6 +5375,7 @@ const commandMap = {
|
|
|
5353
5375
|
'SearchExtensions.focusPreviousPage': wrapCommand(focusPreviousPage),
|
|
5354
5376
|
'SearchExtensions.getActions': getActions,
|
|
5355
5377
|
'SearchExtensions.getCommandIds': getCommandIds,
|
|
5378
|
+
'SearchExtensions.getComponentDom': getComponentDom,
|
|
5356
5379
|
'SearchExtensions.getComponentState': getComponentState,
|
|
5357
5380
|
'SearchExtensions.getKeyBindings': getKeyBindings,
|
|
5358
5381
|
'SearchExtensions.getMenuEntries': getMenuEntriesList,
|