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