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