@lvce-editor/extension-detail-view 3.19.0 → 3.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/extensionDetailViewWorkerMain.js +1249 -1226
- package/package.json +1 -1
|
@@ -430,7 +430,7 @@ const set$2 = (id, fn) => {
|
|
|
430
430
|
const get$2 = id => {
|
|
431
431
|
return callbacks[id];
|
|
432
432
|
};
|
|
433
|
-
const remove
|
|
433
|
+
const remove = id => {
|
|
434
434
|
delete callbacks[id];
|
|
435
435
|
};
|
|
436
436
|
let id$1 = 0;
|
|
@@ -607,7 +607,7 @@ const resolve = (id, response) => {
|
|
|
607
607
|
return;
|
|
608
608
|
}
|
|
609
609
|
fn(response);
|
|
610
|
-
remove
|
|
610
|
+
remove(id);
|
|
611
611
|
};
|
|
612
612
|
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
|
|
613
613
|
const getErrorType = prettyError => {
|
|
@@ -857,8 +857,35 @@ const create$1 = () => {
|
|
|
857
857
|
newState
|
|
858
858
|
};
|
|
859
859
|
},
|
|
860
|
-
|
|
860
|
+
dispose(uid) {
|
|
861
861
|
delete states[uid];
|
|
862
|
+
},
|
|
863
|
+
getKeys() {
|
|
864
|
+
return Object.keys(states).map(key => {
|
|
865
|
+
return Number.parseInt(key);
|
|
866
|
+
});
|
|
867
|
+
},
|
|
868
|
+
clear() {
|
|
869
|
+
for (const key of Object.keys(states)) {
|
|
870
|
+
delete states[key];
|
|
871
|
+
}
|
|
872
|
+
},
|
|
873
|
+
wrapCommand(fn) {
|
|
874
|
+
const wrapped = async (uid, ...args) => {
|
|
875
|
+
const {
|
|
876
|
+
newState
|
|
877
|
+
} = states[uid];
|
|
878
|
+
const newerState = await fn(newState, ...args);
|
|
879
|
+
if (newState === newerState) {
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
const latest = states[uid];
|
|
883
|
+
states[uid] = {
|
|
884
|
+
oldState: latest.oldState,
|
|
885
|
+
newState: newerState
|
|
886
|
+
};
|
|
887
|
+
};
|
|
888
|
+
return wrapped;
|
|
862
889
|
}
|
|
863
890
|
};
|
|
864
891
|
};
|
|
@@ -866,10 +893,11 @@ const create$1 = () => {
|
|
|
866
893
|
const {
|
|
867
894
|
get: get$1,
|
|
868
895
|
set: set$1,
|
|
869
|
-
|
|
896
|
+
dispose: dispose$1,
|
|
897
|
+
wrapCommand
|
|
870
898
|
} = create$1();
|
|
871
899
|
|
|
872
|
-
const create = (uid, uri, width, height, platform, assetDir$1) => {
|
|
900
|
+
const create = (uid, uri, x, y, width, height, platform, assetDir$1) => {
|
|
873
901
|
const state = {
|
|
874
902
|
description: '',
|
|
875
903
|
iconSrc: '',
|
|
@@ -927,7 +955,7 @@ const diff2 = uid => {
|
|
|
927
955
|
};
|
|
928
956
|
|
|
929
957
|
const dispose = uid => {
|
|
930
|
-
|
|
958
|
+
dispose$1(uid);
|
|
931
959
|
};
|
|
932
960
|
|
|
933
961
|
const commandIds = ['getMenuEntries', 'handleClickDisable', 'handleClickSize', 'handleClickUninstall', 'handleFeaturesClick', 'handleIconError', 'handleTabsClick', 'renderEventListeners', 'resize', 'saveState', 'selectTab', 'terminate'];
|
|
@@ -936,124 +964,6 @@ const getCommandIds = () => {
|
|
|
936
964
|
return commandIds;
|
|
937
965
|
};
|
|
938
966
|
|
|
939
|
-
const AdditionalDetails = 'AdditionalDetails';
|
|
940
|
-
const AdditionalDetailsEntry = 'AdditionalDetailsEntry';
|
|
941
|
-
const AdditionalDetailsTitle = 'AdditionalDetailsTitle';
|
|
942
|
-
const Aside = 'Aside';
|
|
943
|
-
const Button$1 = 'Button';
|
|
944
|
-
const ButtonPrimary = 'ButtonPrimary';
|
|
945
|
-
const DefaultMarkdown = 'DefaultMarkdown';
|
|
946
|
-
const Categories = 'Categories';
|
|
947
|
-
const Category = 'Category';
|
|
948
|
-
const Changelog$1 = 'Changelog';
|
|
949
|
-
const DefinitionListItem = 'DefinitionListItem';
|
|
950
|
-
const DefinitionListItemHeading = 'DefinitionListItemHeading';
|
|
951
|
-
const DefinitionListItemValue = 'DefinitionListItemValue';
|
|
952
|
-
const ExtensionDetail = 'ExtensionDetail';
|
|
953
|
-
const ExtensionDetailDescription = 'ExtensionDetailDescription';
|
|
954
|
-
const ExtensionDetailHeader = 'ExtensionDetailHeader';
|
|
955
|
-
const ExtensionDetailHeaderActions = 'ExtensionDetailHeaderActions';
|
|
956
|
-
const ExtensionDetailHeaderDetails = 'ExtensionDetailHeaderDetails';
|
|
957
|
-
const ExtensionDetailIcon = 'ExtensionDetailIcon';
|
|
958
|
-
const ExtensionDetailName = 'ExtensionDetailName';
|
|
959
|
-
const ExtensionDetailPanel = 'ExtensionDetailPanel';
|
|
960
|
-
const ExtensionDetailTab = 'ExtensionDetailTab';
|
|
961
|
-
const ExtensionDetailTabs = 'ExtensionDetailTabs';
|
|
962
|
-
const ExtensionDetailTabSelected = 'ExtensionDetailTabSelected';
|
|
963
|
-
const Feature = 'Feature';
|
|
964
|
-
const FeatureContent = 'FeatureContent';
|
|
965
|
-
const Features$1 = 'Features';
|
|
966
|
-
const FeaturesList = 'FeaturesList';
|
|
967
|
-
const FeatureWebView = 'FeatureWebView';
|
|
968
|
-
const Large$1 = 'Large';
|
|
969
|
-
const Sash = 'Sash';
|
|
970
|
-
const SashVertical = 'SashVertical';
|
|
971
|
-
const MoreInfo = 'MoreInfo';
|
|
972
|
-
const MoreInfoEntry = 'MoreInfoEntry';
|
|
973
|
-
const MoreInfoEntryKey = 'MoreInfoEntryKey';
|
|
974
|
-
const MoreInfoEntryOdd = 'MoreInfoEntryOdd';
|
|
975
|
-
const MoreInfoEntryValue = 'MoreInfoEntryValue';
|
|
976
|
-
const Normal$1 = 'Normal';
|
|
977
|
-
const Resource = 'Resource';
|
|
978
|
-
const Resources = 'Resources';
|
|
979
|
-
const Small$1 = 'Small';
|
|
980
|
-
const Table$1 = 'Table';
|
|
981
|
-
const TableCell = 'TableCell';
|
|
982
|
-
const TableHeading = 'TableHeading';
|
|
983
|
-
const Viewlet = 'Viewlet';
|
|
984
|
-
|
|
985
|
-
const BYTE_UNITS = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
986
|
-
const BIBYTE_UNITS = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
|
|
987
|
-
const BIT_UNITS = ['b', 'kbit', 'Mbit', 'Gbit', 'Tbit', 'Pbit', 'Ebit', 'Zbit', 'Ybit'];
|
|
988
|
-
const BIBIT_UNITS = ['b', 'kibit', 'Mibit', 'Gibit', 'Tibit', 'Pibit', 'Eibit', 'Zibit', 'Yibit'];
|
|
989
|
-
|
|
990
|
-
/*
|
|
991
|
-
Formats the given number using `Number#toLocaleString`.
|
|
992
|
-
- If locale is a string, the value is expected to be a locale-key (for example: `de`).
|
|
993
|
-
- If locale is true, the system default locale is used for translation.
|
|
994
|
-
- If no value for locale is specified, the number is returned unmodified.
|
|
995
|
-
*/
|
|
996
|
-
const toLocaleString = (number, locale, options) => {
|
|
997
|
-
let result = number;
|
|
998
|
-
if (typeof locale === 'string' || Array.isArray(locale)) {
|
|
999
|
-
result = number.toLocaleString(locale, options);
|
|
1000
|
-
} else if (locale === true || options !== undefined) {
|
|
1001
|
-
result = number.toLocaleString(undefined, options);
|
|
1002
|
-
}
|
|
1003
|
-
return result;
|
|
1004
|
-
};
|
|
1005
|
-
function prettyBytes(number, options) {
|
|
1006
|
-
if (!Number.isFinite(number)) {
|
|
1007
|
-
throw new TypeError(`Expected a finite number, got ${typeof number}: ${number}`);
|
|
1008
|
-
}
|
|
1009
|
-
options = {
|
|
1010
|
-
bits: false,
|
|
1011
|
-
binary: false,
|
|
1012
|
-
space: true,
|
|
1013
|
-
...options
|
|
1014
|
-
};
|
|
1015
|
-
const UNITS = options.bits ? options.binary ? BIBIT_UNITS : BIT_UNITS : options.binary ? BIBYTE_UNITS : BYTE_UNITS;
|
|
1016
|
-
const separator = options.space ? ' ' : '';
|
|
1017
|
-
if (options.signed && number === 0) {
|
|
1018
|
-
return ` 0${separator}${UNITS[0]}`;
|
|
1019
|
-
}
|
|
1020
|
-
const isNegative = number < 0;
|
|
1021
|
-
const prefix = isNegative ? '-' : options.signed ? '+' : '';
|
|
1022
|
-
if (isNegative) {
|
|
1023
|
-
number = -number;
|
|
1024
|
-
}
|
|
1025
|
-
let localeOptions;
|
|
1026
|
-
if (options.minimumFractionDigits !== undefined) {
|
|
1027
|
-
localeOptions = {
|
|
1028
|
-
minimumFractionDigits: options.minimumFractionDigits
|
|
1029
|
-
};
|
|
1030
|
-
}
|
|
1031
|
-
if (options.maximumFractionDigits !== undefined) {
|
|
1032
|
-
localeOptions = {
|
|
1033
|
-
maximumFractionDigits: options.maximumFractionDigits,
|
|
1034
|
-
...localeOptions
|
|
1035
|
-
};
|
|
1036
|
-
}
|
|
1037
|
-
if (number < 1) {
|
|
1038
|
-
const numberString = toLocaleString(number, options.locale, localeOptions);
|
|
1039
|
-
return prefix + numberString + separator + UNITS[0];
|
|
1040
|
-
}
|
|
1041
|
-
const exponent = Math.min(Math.floor(options.binary ? Math.log(number) / Math.log(1024) : Math.log10(number) / 3), UNITS.length - 1);
|
|
1042
|
-
number /= (options.binary ? 1024 : 1000) ** exponent;
|
|
1043
|
-
if (!localeOptions) {
|
|
1044
|
-
number = number.toPrecision(3);
|
|
1045
|
-
}
|
|
1046
|
-
const numberString = toLocaleString(Number(number), options.locale, localeOptions);
|
|
1047
|
-
const unit = UNITS[exponent];
|
|
1048
|
-
return prefix + numberString + separator + unit;
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
const getDisplaySize = size => {
|
|
1052
|
-
return prettyBytes(size, {
|
|
1053
|
-
maximumFractionDigits: 1
|
|
1054
|
-
});
|
|
1055
|
-
};
|
|
1056
|
-
|
|
1057
967
|
const emptyObject = {};
|
|
1058
968
|
const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
|
|
1059
969
|
const i18nString = (key, placeholders = emptyObject) => {
|
|
@@ -1144,1328 +1054,1459 @@ const notImplemented = () => {
|
|
|
1144
1054
|
return i18nString(NotImplemented);
|
|
1145
1055
|
};
|
|
1146
1056
|
|
|
1147
|
-
const
|
|
1148
|
-
const Button = 1;
|
|
1149
|
-
const Div = 4;
|
|
1150
|
-
const H1 = 5;
|
|
1151
|
-
const H2 = 22;
|
|
1152
|
-
const Img = 17;
|
|
1153
|
-
const Pre = 51;
|
|
1154
|
-
const Table = 9;
|
|
1155
|
-
const TBody = 10;
|
|
1156
|
-
const Td = 11;
|
|
1157
|
-
const Th = 13;
|
|
1158
|
-
const THead = 14;
|
|
1159
|
-
const Tr = 15;
|
|
1057
|
+
const None = 0;
|
|
1160
1058
|
|
|
1161
|
-
const
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1059
|
+
const getCopyMenuEntry = () => ({
|
|
1060
|
+
id: 'copy',
|
|
1061
|
+
label: copy(),
|
|
1062
|
+
flags: None,
|
|
1063
|
+
command: 'ClipBoard.execCopy'
|
|
1064
|
+
});
|
|
1065
|
+
|
|
1066
|
+
const getImageMenuEntries = props => {
|
|
1067
|
+
if (!props.isImage) {
|
|
1068
|
+
return [];
|
|
1069
|
+
}
|
|
1070
|
+
return [{
|
|
1071
|
+
id: 'openImageInNewTab',
|
|
1072
|
+
label: openImageInNewTab(),
|
|
1073
|
+
flags: None,
|
|
1074
|
+
command: 'Open.openUrl',
|
|
1075
|
+
args: [props.url || '']
|
|
1076
|
+
}, {
|
|
1077
|
+
id: 'saveImageAs',
|
|
1078
|
+
label: saveImageAs(),
|
|
1079
|
+
flags: None,
|
|
1080
|
+
command: 'SaveFileAs.saveFileAs',
|
|
1081
|
+
args: ['image.png', props.url || '']
|
|
1082
|
+
}];
|
|
1171
1083
|
};
|
|
1172
1084
|
|
|
1173
|
-
const
|
|
1174
|
-
|
|
1175
|
-
|
|
1085
|
+
const getLinkMenuEntries = props => {
|
|
1086
|
+
if (!props.isLink) {
|
|
1087
|
+
return [];
|
|
1088
|
+
}
|
|
1176
1089
|
return [{
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1090
|
+
id: 'openInNewTab',
|
|
1091
|
+
label: openInNewTab(),
|
|
1092
|
+
flags: None,
|
|
1093
|
+
command: 'Open.openUrl',
|
|
1094
|
+
args: [props.url || '']
|
|
1095
|
+
}];
|
|
1181
1096
|
};
|
|
1182
1097
|
|
|
1183
|
-
const
|
|
1184
|
-
const Tab = 'tab';
|
|
1185
|
-
const Panel = 'panel';
|
|
1098
|
+
const getMenuEntries = props => [...getLinkMenuEntries(props), ...getImageMenuEntries(props), getCopyMenuEntry()];
|
|
1186
1099
|
|
|
1187
|
-
const
|
|
1188
|
-
return
|
|
1189
|
-
type: Div,
|
|
1190
|
-
className: AdditionalDetailsEntry,
|
|
1191
|
-
childCount: 2
|
|
1192
|
-
}, {
|
|
1193
|
-
type: Div,
|
|
1194
|
-
className: AdditionalDetailsTitle,
|
|
1195
|
-
childCount: 1
|
|
1196
|
-
}, text(heading), ...renderer(items)];
|
|
1100
|
+
const handleClickDisable = async state => {
|
|
1101
|
+
return state;
|
|
1197
1102
|
};
|
|
1198
1103
|
|
|
1199
|
-
const
|
|
1104
|
+
const selectFeature = async (state, name) => {
|
|
1105
|
+
if (!name) {
|
|
1106
|
+
return state;
|
|
1107
|
+
}
|
|
1200
1108
|
const {
|
|
1201
|
-
|
|
1202
|
-
} =
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1109
|
+
features
|
|
1110
|
+
} = state;
|
|
1111
|
+
const newFeatures = features.map(feature => {
|
|
1112
|
+
if (feature.id === name) {
|
|
1113
|
+
return {
|
|
1114
|
+
...feature,
|
|
1115
|
+
selected: true
|
|
1116
|
+
};
|
|
1117
|
+
}
|
|
1118
|
+
return {
|
|
1119
|
+
...feature,
|
|
1120
|
+
selected: false
|
|
1121
|
+
};
|
|
1122
|
+
});
|
|
1123
|
+
return {
|
|
1124
|
+
...state,
|
|
1125
|
+
selectedFeature: name,
|
|
1126
|
+
features: newFeatures
|
|
1127
|
+
};
|
|
1208
1128
|
};
|
|
1209
1129
|
|
|
1210
|
-
const
|
|
1211
|
-
return
|
|
1212
|
-
type: Div,
|
|
1213
|
-
className: Categories,
|
|
1214
|
-
childCount: categories.length
|
|
1215
|
-
}, ...categories.flatMap(getCategoryVirtualDom)];
|
|
1130
|
+
const handleClickFeatures = async (state, name) => {
|
|
1131
|
+
return selectFeature(state, name);
|
|
1216
1132
|
};
|
|
1217
1133
|
|
|
1218
|
-
const
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1134
|
+
const RendererWorker = 1;
|
|
1135
|
+
|
|
1136
|
+
const rpcs = Object.create(null);
|
|
1137
|
+
const set = (id, rpc) => {
|
|
1138
|
+
rpcs[id] = rpc;
|
|
1222
1139
|
};
|
|
1223
|
-
const
|
|
1224
|
-
|
|
1225
|
-
key
|
|
1226
|
-
} = item;
|
|
1227
|
-
return [parentNode, text(key)];
|
|
1140
|
+
const get = id => {
|
|
1141
|
+
return rpcs[id];
|
|
1228
1142
|
};
|
|
1229
1143
|
|
|
1230
|
-
const
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
}
|
|
1234
|
-
if (code) {
|
|
1235
|
-
// TODO use code tag
|
|
1236
|
-
return Div;
|
|
1237
|
-
}
|
|
1238
|
-
return Div;
|
|
1239
|
-
};
|
|
1240
|
-
const getClassName = (onClick, code) => {
|
|
1241
|
-
if (onClick) {
|
|
1242
|
-
return MoreInfoEntryValue + ' Link';
|
|
1243
|
-
}
|
|
1244
|
-
if (code) {
|
|
1245
|
-
return MoreInfoEntryValue + ' Code';
|
|
1246
|
-
}
|
|
1247
|
-
return MoreInfoEntryValue;
|
|
1144
|
+
const invoke = (method, ...params) => {
|
|
1145
|
+
const rpc = get(RendererWorker);
|
|
1146
|
+
return rpc.invoke(method, ...params);
|
|
1248
1147
|
};
|
|
1249
|
-
|
|
1148
|
+
|
|
1149
|
+
const handleClickSize = async state => {
|
|
1250
1150
|
const {
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
const type = getTag(onClick, code);
|
|
1256
|
-
const className = getClassName(onClick, code);
|
|
1257
|
-
return [{
|
|
1258
|
-
type: type,
|
|
1259
|
-
className,
|
|
1260
|
-
childCount: 1,
|
|
1261
|
-
onClick
|
|
1262
|
-
}, text(value)];
|
|
1151
|
+
uri
|
|
1152
|
+
} = state.extension;
|
|
1153
|
+
await invoke('OpenNativeFolder.openNativeFolder', uri);
|
|
1154
|
+
return state;
|
|
1263
1155
|
};
|
|
1264
1156
|
|
|
1265
|
-
const
|
|
1266
|
-
|
|
1267
|
-
className: MoreInfoEntry,
|
|
1268
|
-
childCount: 2
|
|
1157
|
+
const handleClickUninstall = async state => {
|
|
1158
|
+
return state;
|
|
1269
1159
|
};
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
childCount: 2
|
|
1160
|
+
|
|
1161
|
+
const extensionDefaultIcon = assetDir => {
|
|
1162
|
+
return `${assetDir}/icons/extensionDefaultIcon.png`;
|
|
1274
1163
|
};
|
|
1275
|
-
const
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
return [node, ...getMoreInfoEntryKeyVirtualDom(item), ...getMoreInfoEntryValueVirtualDom(item)];
|
|
1164
|
+
const extensionLanguageBasics = assetDir => {
|
|
1165
|
+
return `${assetDir}/icons/language-icon.svg`;
|
|
1166
|
+
};
|
|
1167
|
+
const extensionTheme = assetDir => {
|
|
1168
|
+
return `${assetDir}/icons/theme-icon.png`;
|
|
1281
1169
|
};
|
|
1282
1170
|
|
|
1283
|
-
const
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1171
|
+
const handleIconError = state => {
|
|
1172
|
+
const {
|
|
1173
|
+
iconSrc,
|
|
1174
|
+
assetDir
|
|
1175
|
+
} = state;
|
|
1176
|
+
if (iconSrc === extensionDefaultIcon(assetDir)) {
|
|
1177
|
+
return state;
|
|
1178
|
+
}
|
|
1179
|
+
return {
|
|
1180
|
+
...state,
|
|
1181
|
+
iconSrc: extensionDefaultIcon(assetDir)
|
|
1182
|
+
};
|
|
1289
1183
|
};
|
|
1290
1184
|
|
|
1291
|
-
const
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1185
|
+
const Changelog$1 = 'Changelog';
|
|
1186
|
+
const Commands = 'Commands';
|
|
1187
|
+
const Details = 'Details';
|
|
1188
|
+
const Features$1 = 'Features';
|
|
1189
|
+
const JsonValidation = 'JsonValidation';
|
|
1190
|
+
const ProgrammingLanguages = 'ProgrammingLanguages';
|
|
1191
|
+
const Settings = 'Settings';
|
|
1192
|
+
const WebViews = 'WebViews';
|
|
1193
|
+
const Theme = 'Theme';
|
|
1194
|
+
|
|
1195
|
+
const selectTabChangelog = async state => {
|
|
1196
|
+
return {
|
|
1197
|
+
...state,
|
|
1198
|
+
selectedTab: Changelog$1
|
|
1199
|
+
};
|
|
1296
1200
|
};
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
} = resource;
|
|
1301
|
-
return [resourceNode, text(label)];
|
|
1201
|
+
|
|
1202
|
+
const selectTabDefault = async state => {
|
|
1203
|
+
return state;
|
|
1302
1204
|
};
|
|
1303
1205
|
|
|
1304
|
-
const
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
}
|
|
1206
|
+
const selectTabDetails = async state => {
|
|
1207
|
+
// TODO load readmo markdown here
|
|
1208
|
+
return {
|
|
1209
|
+
...state,
|
|
1210
|
+
selectedTab: Details
|
|
1211
|
+
};
|
|
1310
1212
|
};
|
|
1311
1213
|
|
|
1312
|
-
const
|
|
1313
|
-
|
|
1314
|
-
|
|
1214
|
+
const getThemeItemMarkdown = (heading, items) => {
|
|
1215
|
+
let markdown = '';
|
|
1216
|
+
if (items.length > 0) {
|
|
1217
|
+
markdown += `### ${heading}`;
|
|
1218
|
+
markdown += '\n\n';
|
|
1219
|
+
for (const item of items) {
|
|
1220
|
+
markdown += `- ${item.label}`;
|
|
1221
|
+
markdown += '\n';
|
|
1222
|
+
}
|
|
1315
1223
|
}
|
|
1316
|
-
return
|
|
1317
|
-
type: Div,
|
|
1318
|
-
className: Aside,
|
|
1319
|
-
childCount: 1
|
|
1320
|
-
}, {
|
|
1321
|
-
type: Div,
|
|
1322
|
-
className: AdditionalDetails,
|
|
1323
|
-
tabIndex: 0,
|
|
1324
|
-
childCount: 4
|
|
1325
|
-
}, ...getAdditionalDetailsEntryVirtualDom(firstHeading, entries, getMoreInfoVirtualDom), ...getAdditionalDetailsEntryVirtualDom(secondHeading, secondEntries, getMoreInfoVirtualDom), ...getAdditionalDetailsEntryVirtualDom(thirdHeading, categories, getCategoriesDom), ...getAdditionalDetailsEntryVirtualDom(fourthHeading, resources, getResourcesVirtualDom)];
|
|
1224
|
+
return markdown;
|
|
1326
1225
|
};
|
|
1327
1226
|
|
|
1328
|
-
const
|
|
1329
|
-
const
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
const
|
|
1333
|
-
const
|
|
1334
|
-
|
|
1227
|
+
const getColorThemeMarkdown = themes => {
|
|
1228
|
+
const heading = 'Color Themes';
|
|
1229
|
+
return getThemeItemMarkdown(heading, themes);
|
|
1230
|
+
};
|
|
1231
|
+
const getIconThemeMarkdown = iconThemes => {
|
|
1232
|
+
const heading = 'File Icon Themes';
|
|
1233
|
+
return getThemeItemMarkdown(heading, iconThemes);
|
|
1234
|
+
};
|
|
1235
|
+
const getProductIconThemeMarkdown = iconThemes => {
|
|
1236
|
+
const heading = 'Product Icon Themes';
|
|
1237
|
+
return getThemeItemMarkdown(heading, iconThemes);
|
|
1238
|
+
};
|
|
1239
|
+
const getThemeMarkdown = (themes, iconThemes, productIconThemes) => {
|
|
1240
|
+
let markdown = '';
|
|
1241
|
+
markdown += getColorThemeMarkdown(themes);
|
|
1242
|
+
markdown += getIconThemeMarkdown(iconThemes);
|
|
1243
|
+
markdown += getProductIconThemeMarkdown(productIconThemes);
|
|
1244
|
+
return markdown;
|
|
1245
|
+
};
|
|
1335
1246
|
|
|
1336
|
-
const
|
|
1337
|
-
const
|
|
1338
|
-
|
|
1339
|
-
value: extensionId,
|
|
1340
|
-
odd: true,
|
|
1341
|
-
code: true
|
|
1342
|
-
}, {
|
|
1343
|
-
key: 'Version',
|
|
1344
|
-
value: extensionVersion,
|
|
1345
|
-
code: true
|
|
1346
|
-
}, {
|
|
1347
|
-
key: 'Last Updated',
|
|
1348
|
-
value: 'n/a',
|
|
1349
|
-
odd: true
|
|
1350
|
-
}, {
|
|
1351
|
-
key: 'Size',
|
|
1352
|
-
value: displaySize,
|
|
1353
|
-
onClick: HandleClickSize
|
|
1354
|
-
}];
|
|
1355
|
-
return entries;
|
|
1247
|
+
const renderMarkdown = async (markdown, options = {}) => {
|
|
1248
|
+
const html = await invoke('Markdown.renderMarkdown', markdown, options);
|
|
1249
|
+
return html;
|
|
1356
1250
|
};
|
|
1357
1251
|
|
|
1358
|
-
const
|
|
1252
|
+
const selectTab$1 = async state => {
|
|
1253
|
+
const {
|
|
1254
|
+
extension,
|
|
1255
|
+
baseUrl
|
|
1256
|
+
} = state;
|
|
1257
|
+
const {
|
|
1258
|
+
colorThemes,
|
|
1259
|
+
iconThemes,
|
|
1260
|
+
productIconThemes
|
|
1261
|
+
} = extension;
|
|
1262
|
+
// TODO do this depending on featured tab content
|
|
1263
|
+
const markdown = getThemeMarkdown(colorThemes || [], iconThemes || [], productIconThemes || []);
|
|
1264
|
+
const rendered = await renderMarkdown(markdown, {
|
|
1265
|
+
baseUrl
|
|
1266
|
+
});
|
|
1267
|
+
return {
|
|
1268
|
+
...state,
|
|
1269
|
+
selectedTab: Features$1,
|
|
1270
|
+
selectedFeatureMarkdownDom: rendered
|
|
1271
|
+
};
|
|
1272
|
+
};
|
|
1359
1273
|
|
|
1360
|
-
const
|
|
1361
|
-
|
|
1362
|
-
|
|
1274
|
+
const getSelectTabHandler = selectedTab => {
|
|
1275
|
+
switch (selectedTab) {
|
|
1276
|
+
case Details:
|
|
1277
|
+
return selectTabDetails;
|
|
1278
|
+
case Features$1:
|
|
1279
|
+
return selectTab$1;
|
|
1280
|
+
case Changelog$1:
|
|
1281
|
+
return selectTabChangelog;
|
|
1282
|
+
default:
|
|
1283
|
+
return selectTabDefault;
|
|
1284
|
+
}
|
|
1363
1285
|
};
|
|
1364
|
-
|
|
1365
|
-
|
|
1286
|
+
|
|
1287
|
+
const selectTab = (state, name) => {
|
|
1288
|
+
const fn = getSelectTabHandler(name);
|
|
1289
|
+
return fn(state);
|
|
1366
1290
|
};
|
|
1367
1291
|
|
|
1368
|
-
const
|
|
1369
|
-
|
|
1370
|
-
return rpc.invoke(method, ...params);
|
|
1292
|
+
const handleTabsClick = (state, name) => {
|
|
1293
|
+
return selectTab(state, name);
|
|
1371
1294
|
};
|
|
1372
1295
|
|
|
1373
|
-
const
|
|
1374
|
-
|
|
1375
|
-
const dom = await invoke('Markdown.getVirtualDom', html);
|
|
1376
|
-
return dom;
|
|
1296
|
+
const isLanguageBasicsExtension = extension => {
|
|
1297
|
+
return extension.name && extension.name.startsWith('Language Basics');
|
|
1377
1298
|
};
|
|
1378
1299
|
|
|
1379
|
-
const
|
|
1380
|
-
return
|
|
1381
|
-
key: 'Published',
|
|
1382
|
-
value: 'n/a',
|
|
1383
|
-
odd: true
|
|
1384
|
-
}, {
|
|
1385
|
-
key: 'Last Released',
|
|
1386
|
-
value: 'n/a'
|
|
1387
|
-
}];
|
|
1300
|
+
const isThemeExtension = extension => {
|
|
1301
|
+
return extension.name && extension.name.endsWith(' Theme');
|
|
1388
1302
|
};
|
|
1389
1303
|
|
|
1390
|
-
const
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
const secondHeading = 'Marketplace';
|
|
1394
|
-
const secondEntries = getMarketplaceEntries();
|
|
1395
|
-
const thirdHeading = 'Categories';
|
|
1396
|
-
const categories = [{
|
|
1397
|
-
id: 'themes',
|
|
1398
|
-
label: 'Themes'
|
|
1399
|
-
}];
|
|
1400
|
-
const fourthHeading = 'Resources';
|
|
1401
|
-
const resources = [{
|
|
1402
|
-
label: 'Marketplace',
|
|
1403
|
-
url: '#'
|
|
1404
|
-
}, {
|
|
1405
|
-
label: 'Issues',
|
|
1406
|
-
url: '#'
|
|
1407
|
-
}, {
|
|
1408
|
-
label: 'Repository',
|
|
1409
|
-
url: '#'
|
|
1410
|
-
}, {
|
|
1411
|
-
label: 'License',
|
|
1412
|
-
url: '#'
|
|
1413
|
-
}];
|
|
1414
|
-
const showAdditionalDetailsBreakpoint = 600;
|
|
1415
|
-
const showAdditionalDetails = width > showAdditionalDetailsBreakpoint;
|
|
1416
|
-
const childCount = showAdditionalDetails ? 2 : 1;
|
|
1417
|
-
const dom = [{
|
|
1418
|
-
type: Div,
|
|
1419
|
-
className: ExtensionDetailPanel,
|
|
1420
|
-
childCount: childCount,
|
|
1421
|
-
role: Panel
|
|
1422
|
-
}, ...(await getMarkdownVirtualDom(sanitizedReadmeHtml)), ...getAdditionalDetailsVirtualDom(showAdditionalDetails, firstHeading, entries, secondHeading, secondEntries, thirdHeading, categories, fourthHeading, resources)];
|
|
1423
|
-
return dom;
|
|
1424
|
-
};
|
|
1425
|
-
|
|
1426
|
-
const Text = 1;
|
|
1427
|
-
const Code = 2;
|
|
1304
|
+
const Web = 1;
|
|
1305
|
+
const Electron = 2;
|
|
1306
|
+
const Remote = 3;
|
|
1428
1307
|
|
|
1429
|
-
const
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
}
|
|
1308
|
+
const getIcon = (extension, platform, assetDir) => {
|
|
1309
|
+
if (!extension) {
|
|
1310
|
+
return extensionDefaultIcon(assetDir);
|
|
1311
|
+
}
|
|
1312
|
+
if (!extension.path || !extension.icon) {
|
|
1313
|
+
if (isLanguageBasicsExtension(extension)) {
|
|
1314
|
+
return extensionLanguageBasics(assetDir);
|
|
1315
|
+
}
|
|
1316
|
+
if (isThemeExtension(extension)) {
|
|
1317
|
+
return extensionTheme(assetDir);
|
|
1318
|
+
}
|
|
1319
|
+
return extensionDefaultIcon(assetDir);
|
|
1320
|
+
}
|
|
1321
|
+
if (platform === Remote || platform === Electron) {
|
|
1322
|
+
if (extension.builtin) {
|
|
1323
|
+
return `${assetDir}/extensions/${extension.id}/${extension.icon}`;
|
|
1324
|
+
}
|
|
1325
|
+
return `/remote/${extension.path}/${extension.icon}`; // TODO support windows paths
|
|
1326
|
+
}
|
|
1327
|
+
return '';
|
|
1442
1328
|
};
|
|
1443
1329
|
|
|
1444
|
-
const
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
rows
|
|
1450
|
-
};
|
|
1330
|
+
const getDescription = extension => {
|
|
1331
|
+
if (!extension || !extension.description) {
|
|
1332
|
+
return 'n/a';
|
|
1333
|
+
}
|
|
1334
|
+
return extension.description;
|
|
1451
1335
|
};
|
|
1452
1336
|
|
|
1453
|
-
const
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1337
|
+
const getName = extension => {
|
|
1338
|
+
if (extension && extension.name) {
|
|
1339
|
+
return extension.name;
|
|
1340
|
+
}
|
|
1341
|
+
if (extension && extension.id) {
|
|
1342
|
+
return extension.id;
|
|
1343
|
+
}
|
|
1344
|
+
return 'n/a';
|
|
1458
1345
|
};
|
|
1459
1346
|
|
|
1460
|
-
const
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1347
|
+
const getAllExtensions = async platform => {
|
|
1348
|
+
if (platform === Web) {
|
|
1349
|
+
return [];
|
|
1350
|
+
}
|
|
1351
|
+
return invoke('ExtensionManagement.getAllExtensions');
|
|
1352
|
+
};
|
|
1353
|
+
const getExtension$1 = async (id, platform) => {
|
|
1354
|
+
// TODO only ask one extension from renderer worker instead of all
|
|
1355
|
+
const allExtensions = await getAllExtensions(platform);
|
|
1356
|
+
for (const extension of allExtensions) {
|
|
1357
|
+
if (extension.id === id) {
|
|
1358
|
+
return extension;
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
return undefined;
|
|
1466
1362
|
};
|
|
1467
1363
|
|
|
1468
|
-
const
|
|
1469
|
-
return
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
}, text(value)];
|
|
1364
|
+
const getExtensionNew = async id => {
|
|
1365
|
+
return invoke('ExtensionManagement.getExtension', id);
|
|
1366
|
+
};
|
|
1367
|
+
const getExtension = async (id, platform) => {
|
|
1368
|
+
try {
|
|
1369
|
+
return await getExtensionNew(id);
|
|
1370
|
+
} catch {
|
|
1371
|
+
return getExtension$1(id, platform);
|
|
1372
|
+
}
|
|
1478
1373
|
};
|
|
1479
1374
|
|
|
1480
|
-
const
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
className: TableCell,
|
|
1484
|
-
childCount: 1
|
|
1485
|
-
}, text(value)];
|
|
1375
|
+
const getRemoteSrc = uri => {
|
|
1376
|
+
const src = `/remote${uri}`;
|
|
1377
|
+
return src;
|
|
1486
1378
|
};
|
|
1487
1379
|
|
|
1488
|
-
const
|
|
1489
|
-
switch (
|
|
1490
|
-
case
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
return getCellTextVirtualDom;
|
|
1380
|
+
const getBaseUrl = (extensionPath, platform) => {
|
|
1381
|
+
switch (platform) {
|
|
1382
|
+
case Remote:
|
|
1383
|
+
case Electron:
|
|
1384
|
+
return getRemoteSrc(extensionPath + '/');
|
|
1494
1385
|
default:
|
|
1495
|
-
|
|
1386
|
+
return extensionPath;
|
|
1496
1387
|
}
|
|
1497
1388
|
};
|
|
1498
1389
|
|
|
1499
|
-
const
|
|
1500
|
-
const
|
|
1501
|
-
|
|
1502
|
-
type
|
|
1503
|
-
} = entry;
|
|
1504
|
-
const fn = getCellRenderer(type);
|
|
1505
|
-
return fn(value);
|
|
1390
|
+
const getExtensionIdFromUri = uri => {
|
|
1391
|
+
const id = uri.slice('extension-detail://'.length);
|
|
1392
|
+
return id;
|
|
1506
1393
|
};
|
|
1507
1394
|
|
|
1508
|
-
const
|
|
1509
|
-
return
|
|
1510
|
-
type: Tr,
|
|
1511
|
-
childCount: entries.length
|
|
1512
|
-
}, ...entries.flatMap(getCellVirtualDom)];
|
|
1395
|
+
const hasThemes = extension => {
|
|
1396
|
+
return extension && (extension.colorThemes || extension.iconThemes || extension.productIconThemes);
|
|
1513
1397
|
};
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
const {
|
|
1517
|
-
headings,
|
|
1518
|
-
rows
|
|
1519
|
-
} = tableInfo;
|
|
1520
|
-
return [{
|
|
1521
|
-
type: Table,
|
|
1522
|
-
className: Table$1,
|
|
1523
|
-
childCount: 2
|
|
1524
|
-
}, {
|
|
1525
|
-
type: THead,
|
|
1526
|
-
childCount: 1
|
|
1527
|
-
}, {
|
|
1528
|
-
type: Tr,
|
|
1529
|
-
childCount: headings.length
|
|
1530
|
-
}, ...headings.flatMap(getTableHeadingVirtualDom), {
|
|
1531
|
-
type: TBody,
|
|
1532
|
-
childCount: rows.length
|
|
1533
|
-
}, ...rows.flatMap(getTableRowVirtualDom)];
|
|
1398
|
+
const hasCommands = extension => {
|
|
1399
|
+
return extension && extension.commands;
|
|
1534
1400
|
};
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
const getFeatureCommandsVirtualDom = extension => {
|
|
1538
|
-
const heading = commands();
|
|
1539
|
-
const tableInfo = getCommandTableEntries(extension);
|
|
1540
|
-
return [{
|
|
1541
|
-
type: Div,
|
|
1542
|
-
className: FeatureContent,
|
|
1543
|
-
childCount: 2
|
|
1544
|
-
}, ...getFeatureContentHeadingVirtualDom(heading), ...getTableVirtualDom(tableInfo)];
|
|
1401
|
+
const hasJsonValidation = extension => {
|
|
1402
|
+
return extension && extension.jsonValidation;
|
|
1545
1403
|
};
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1404
|
+
const hasProgrammingLanguages = extension => {
|
|
1405
|
+
return extension && extension.programmingLanguages;
|
|
1406
|
+
};
|
|
1407
|
+
const hasSettings = extension => {
|
|
1408
|
+
return extension && extension.settings;
|
|
1409
|
+
};
|
|
1410
|
+
const hasWebViews = extension => {
|
|
1411
|
+
return extension && extension.webViews;
|
|
1412
|
+
};
|
|
1413
|
+
const ifElseFeature = (id, label, isEnabled, selectedFeature, extension) => {
|
|
1414
|
+
if (!isEnabled(extension)) {
|
|
1415
|
+
return [];
|
|
1416
|
+
}
|
|
1552
1417
|
return [{
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
type: Code,
|
|
1557
|
-
value: schema
|
|
1418
|
+
id,
|
|
1419
|
+
label,
|
|
1420
|
+
selected: selectedFeature === id
|
|
1558
1421
|
}];
|
|
1559
1422
|
};
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1423
|
+
const getFeatures = (selectedFeature, extension) => {
|
|
1424
|
+
if (!selectedFeature) {
|
|
1425
|
+
selectedFeature = Theme;
|
|
1426
|
+
}
|
|
1427
|
+
const textTheme = theme();
|
|
1428
|
+
const textCommands = commands();
|
|
1429
|
+
const textJsonValidation = jsonValidation();
|
|
1430
|
+
const programmingLanguages$1 = programmingLanguages();
|
|
1431
|
+
const settings$1 = settings();
|
|
1432
|
+
const webViews$1 = webViews();
|
|
1433
|
+
const features = [...ifElseFeature(Theme, textTheme, hasThemes, selectedFeature, extension), ...ifElseFeature(Commands, textCommands, hasCommands, selectedFeature, extension), ...ifElseFeature(JsonValidation, textJsonValidation, hasJsonValidation, selectedFeature, extension), ...ifElseFeature(ProgrammingLanguages, programmingLanguages$1, hasProgrammingLanguages, selectedFeature, extension), ...ifElseFeature(Settings, settings$1, hasSettings, selectedFeature, extension), ...ifElseFeature(WebViews, webViews$1, hasWebViews, selectedFeature, extension)];
|
|
1434
|
+
return features;
|
|
1568
1435
|
};
|
|
1569
1436
|
|
|
1570
|
-
const
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1437
|
+
const getFolderSize = async uri => {
|
|
1438
|
+
if (!uri) {
|
|
1439
|
+
throw new VError(`uri is required`);
|
|
1440
|
+
}
|
|
1441
|
+
try {
|
|
1442
|
+
return await invoke('FileSystem.getFolderSize', uri);
|
|
1443
|
+
} catch {
|
|
1444
|
+
return 0;
|
|
1445
|
+
}
|
|
1578
1446
|
};
|
|
1579
1447
|
|
|
1580
|
-
const
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
type: Div,
|
|
1584
|
-
className: FeatureContent,
|
|
1585
|
-
childCount: 1
|
|
1586
|
-
}, {
|
|
1587
|
-
type: H1,
|
|
1588
|
-
childCount: 1
|
|
1589
|
-
}, text(heading)];
|
|
1590
|
-
};
|
|
1448
|
+
const Small$1 = 1;
|
|
1449
|
+
const Normal$1 = 2;
|
|
1450
|
+
const Large$1 = 3;
|
|
1591
1451
|
|
|
1592
|
-
const
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1452
|
+
const getViewletSize = width => {
|
|
1453
|
+
if (width < 180) {
|
|
1454
|
+
return Small$1;
|
|
1455
|
+
}
|
|
1456
|
+
if (width < 768) {
|
|
1457
|
+
return Normal$1;
|
|
1458
|
+
}
|
|
1459
|
+
return Large$1;
|
|
1600
1460
|
};
|
|
1601
1461
|
|
|
1602
|
-
const
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
type: Text,
|
|
1613
|
-
value: label
|
|
1614
|
-
}];
|
|
1462
|
+
const readFile = async uri => {
|
|
1463
|
+
if (uri.startsWith('http://') || uri.startsWith('https://')) {
|
|
1464
|
+
const response = await fetch(uri);
|
|
1465
|
+
if (!response.ok) {
|
|
1466
|
+
throw new Error(response.statusText);
|
|
1467
|
+
}
|
|
1468
|
+
const result = await response.text();
|
|
1469
|
+
return result;
|
|
1470
|
+
}
|
|
1471
|
+
return invoke('FileSystem.readFile', uri);
|
|
1615
1472
|
};
|
|
1616
1473
|
|
|
1617
|
-
const
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
const textLabel = label();
|
|
1622
|
-
return {
|
|
1623
|
-
headings: [textId, textLabel],
|
|
1624
|
-
rows
|
|
1625
|
-
};
|
|
1474
|
+
const ENOENT = 'ENOENT';
|
|
1475
|
+
|
|
1476
|
+
const isEnoentError = error => {
|
|
1477
|
+
return error && error.code === ENOENT;
|
|
1626
1478
|
};
|
|
1627
1479
|
|
|
1628
|
-
const
|
|
1629
|
-
|
|
1630
|
-
const tableInfo = getSettingsTableEntries(extension);
|
|
1631
|
-
return [{
|
|
1632
|
-
type: Div,
|
|
1633
|
-
className: FeatureContent,
|
|
1634
|
-
childCount: 2
|
|
1635
|
-
}, ...getFeatureContentHeadingVirtualDom(heading), ...getTableVirtualDom(tableInfo)];
|
|
1480
|
+
const join = (pathSeparator, ...parts) => {
|
|
1481
|
+
return parts.join(pathSeparator);
|
|
1636
1482
|
};
|
|
1637
1483
|
|
|
1638
|
-
const
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1484
|
+
const loadReadmeContent = async path => {
|
|
1485
|
+
try {
|
|
1486
|
+
const readmeUrl = join('/', path, 'README.md');
|
|
1487
|
+
const readmeContent = await readFile(readmeUrl);
|
|
1488
|
+
return readmeContent;
|
|
1489
|
+
} catch (error) {
|
|
1490
|
+
if (isEnoentError(error)) {
|
|
1491
|
+
return '';
|
|
1645
1492
|
}
|
|
1646
|
-
|
|
1493
|
+
console.error(new VError(error, 'Failed to load Readme content'));
|
|
1494
|
+
return `${error}`;
|
|
1647
1495
|
}
|
|
1648
|
-
return stack.length;
|
|
1649
1496
|
};
|
|
1650
1497
|
|
|
1651
|
-
const
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
return
|
|
1656
|
-
type: Div,
|
|
1657
|
-
className: FeatureContent,
|
|
1658
|
-
childCount: 2
|
|
1659
|
-
}, ...getFeatureContentHeadingVirtualDom(heading), {
|
|
1660
|
-
type: Div,
|
|
1661
|
-
className: DefaultMarkdown,
|
|
1662
|
-
childCount
|
|
1663
|
-
}, ...markdownDom];
|
|
1498
|
+
const getSavedSelectedFeature = savedState => {
|
|
1499
|
+
if (savedState && typeof savedState === 'object' && 'selectedFeature' in savedState && typeof savedState.selectedFeature === 'string') {
|
|
1500
|
+
return savedState.selectedFeature;
|
|
1501
|
+
}
|
|
1502
|
+
return Details;
|
|
1664
1503
|
};
|
|
1665
1504
|
|
|
1666
|
-
const
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
elements
|
|
1672
|
-
} = rawWebView;
|
|
1673
|
-
return {
|
|
1674
|
-
id,
|
|
1675
|
-
selectorString: JSON.stringify(selector),
|
|
1676
|
-
contentSecurityPolicyString: JSON.stringify(contentSecurityPolicy),
|
|
1677
|
-
elementsString: JSON.stringify(elements, null, 2)
|
|
1678
|
-
};
|
|
1505
|
+
const getSavedSelectedTab = savedState => {
|
|
1506
|
+
if (savedState && typeof savedState === 'object' && 'selectedTab' in savedState && typeof savedState.selectedTab === 'string') {
|
|
1507
|
+
return savedState.selectedTab;
|
|
1508
|
+
}
|
|
1509
|
+
return Details;
|
|
1679
1510
|
};
|
|
1680
1511
|
|
|
1681
|
-
const
|
|
1682
|
-
const
|
|
1683
|
-
|
|
1512
|
+
const restoreState = savedState => {
|
|
1513
|
+
const selectedTab = getSavedSelectedTab(savedState);
|
|
1514
|
+
const selectedFeature = getSavedSelectedFeature(savedState);
|
|
1515
|
+
return {
|
|
1516
|
+
selectedFeature,
|
|
1517
|
+
selectedTab
|
|
1518
|
+
};
|
|
1684
1519
|
};
|
|
1685
1520
|
|
|
1686
|
-
const
|
|
1687
|
-
type: H2,
|
|
1688
|
-
className: DefinitionListItemHeading,
|
|
1689
|
-
childCount: 1
|
|
1690
|
-
};
|
|
1691
|
-
const pre = {
|
|
1692
|
-
type: Pre,
|
|
1693
|
-
className: DefinitionListItemValue,
|
|
1694
|
-
childCount: 1
|
|
1695
|
-
};
|
|
1696
|
-
const item = {
|
|
1697
|
-
type: Div,
|
|
1698
|
-
className: DefinitionListItem,
|
|
1699
|
-
childCount: 2
|
|
1700
|
-
};
|
|
1701
|
-
const getWebViewVirtualDom = webView => {
|
|
1521
|
+
const loadContent = async (state, platform, savedState) => {
|
|
1702
1522
|
const {
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
const
|
|
1709
|
-
const
|
|
1710
|
-
const
|
|
1711
|
-
const
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1523
|
+
uri,
|
|
1524
|
+
width,
|
|
1525
|
+
assetDir
|
|
1526
|
+
} = state;
|
|
1527
|
+
const id = getExtensionIdFromUri(uri);
|
|
1528
|
+
const extension = await getExtension(id, platform);
|
|
1529
|
+
const readmeContent = await loadReadmeContent(extension.path);
|
|
1530
|
+
const baseUrl = getBaseUrl(extension.path, platform);
|
|
1531
|
+
const readmeHtml = await renderMarkdown(readmeContent, {
|
|
1532
|
+
baseUrl
|
|
1533
|
+
});
|
|
1534
|
+
const sanitizedReadmeHtml = readmeHtml;
|
|
1535
|
+
const normalizedReadmeHtml = sanitizedReadmeHtml;
|
|
1536
|
+
const iconSrc = getIcon(extension, platform, assetDir);
|
|
1537
|
+
const description = getDescription(extension);
|
|
1538
|
+
const name = getName(extension);
|
|
1539
|
+
const size = getViewletSize(width);
|
|
1540
|
+
const {
|
|
1541
|
+
selectedFeature,
|
|
1542
|
+
selectedTab
|
|
1543
|
+
} = restoreState(savedState);
|
|
1544
|
+
const features = getFeatures(selectedFeature, extension);
|
|
1545
|
+
const extensionUri = extension.uri || extension.path;
|
|
1546
|
+
const folderSize = await getFolderSize(extensionUri);
|
|
1547
|
+
const entries = [{
|
|
1548
|
+
key: 'Identifier',
|
|
1549
|
+
value: 'abc'
|
|
1550
|
+
}, {
|
|
1551
|
+
key: 'Version',
|
|
1552
|
+
value: '1.9.5'
|
|
1553
|
+
}, {
|
|
1554
|
+
key: 'Last Updated',
|
|
1555
|
+
value: 'n/a'
|
|
1556
|
+
}];
|
|
1557
|
+
const secondEntries = [{
|
|
1558
|
+
key: 'Published',
|
|
1559
|
+
value: 'n/a'
|
|
1560
|
+
}, {
|
|
1561
|
+
key: 'Last Released',
|
|
1562
|
+
value: 'n/a'
|
|
1563
|
+
}];
|
|
1564
|
+
const categories = [{
|
|
1565
|
+
id: 'themes',
|
|
1566
|
+
label: 'Themes'
|
|
1567
|
+
}];
|
|
1568
|
+
const resources = [{
|
|
1569
|
+
label: 'Marketplace',
|
|
1570
|
+
url: '#'
|
|
1571
|
+
}, {
|
|
1572
|
+
label: 'Issues',
|
|
1573
|
+
url: '#'
|
|
1574
|
+
}, {
|
|
1575
|
+
label: 'Repository',
|
|
1576
|
+
url: '#'
|
|
1577
|
+
}, {
|
|
1578
|
+
label: 'License',
|
|
1579
|
+
url: '#'
|
|
1580
|
+
}];
|
|
1581
|
+
return {
|
|
1582
|
+
...state,
|
|
1583
|
+
selectedTab,
|
|
1584
|
+
sanitizedReadmeHtml: normalizedReadmeHtml,
|
|
1585
|
+
iconSrc,
|
|
1586
|
+
name,
|
|
1587
|
+
description,
|
|
1588
|
+
sizeOnDisk: size,
|
|
1589
|
+
entries,
|
|
1590
|
+
secondEntries,
|
|
1591
|
+
categories,
|
|
1592
|
+
resources,
|
|
1593
|
+
extension,
|
|
1594
|
+
baseUrl,
|
|
1595
|
+
features,
|
|
1596
|
+
folderSize
|
|
1597
|
+
};
|
|
1717
1598
|
};
|
|
1718
1599
|
|
|
1719
|
-
const
|
|
1720
|
-
|
|
1721
|
-
const heading = webViews();
|
|
1722
|
-
return [{
|
|
1723
|
-
type: Div,
|
|
1724
|
-
className: FeatureContent,
|
|
1725
|
-
childCount: 2
|
|
1726
|
-
}, ...getFeatureContentHeadingVirtualDom(heading), {
|
|
1727
|
-
type: Div,
|
|
1728
|
-
childCount: webViews$1.length
|
|
1729
|
-
}, ...webViews$1.flatMap(getWebViewVirtualDom)];
|
|
1600
|
+
const loadContent2 = async (state, savedState) => {
|
|
1601
|
+
return loadContent(state, state.platform, savedState);
|
|
1730
1602
|
};
|
|
1731
1603
|
|
|
1604
|
+
const AdditionalDetails = 'AdditionalDetails';
|
|
1605
|
+
const AdditionalDetailsEntry = 'AdditionalDetailsEntry';
|
|
1606
|
+
const AdditionalDetailsTitle = 'AdditionalDetailsTitle';
|
|
1607
|
+
const Aside = 'Aside';
|
|
1608
|
+
const Button$1 = 'Button';
|
|
1609
|
+
const ButtonPrimary = 'ButtonPrimary';
|
|
1610
|
+
const DefaultMarkdown = 'DefaultMarkdown';
|
|
1611
|
+
const Categories = 'Categories';
|
|
1612
|
+
const Category = 'Category';
|
|
1732
1613
|
const Changelog = 'Changelog';
|
|
1733
|
-
const
|
|
1734
|
-
const
|
|
1614
|
+
const DefinitionListItem = 'DefinitionListItem';
|
|
1615
|
+
const DefinitionListItemHeading = 'DefinitionListItemHeading';
|
|
1616
|
+
const DefinitionListItemValue = 'DefinitionListItemValue';
|
|
1617
|
+
const ExtensionDetail = 'ExtensionDetail';
|
|
1618
|
+
const ExtensionDetailDescription = 'ExtensionDetailDescription';
|
|
1619
|
+
const ExtensionDetailHeader = 'ExtensionDetailHeader';
|
|
1620
|
+
const ExtensionDetailHeaderActions = 'ExtensionDetailHeaderActions';
|
|
1621
|
+
const ExtensionDetailHeaderDetails = 'ExtensionDetailHeaderDetails';
|
|
1622
|
+
const ExtensionDetailIcon = 'ExtensionDetailIcon';
|
|
1623
|
+
const ExtensionDetailName = 'ExtensionDetailName';
|
|
1624
|
+
const ExtensionDetailPanel = 'ExtensionDetailPanel';
|
|
1625
|
+
const ExtensionDetailTab = 'ExtensionDetailTab';
|
|
1626
|
+
const ExtensionDetailTabs = 'ExtensionDetailTabs';
|
|
1627
|
+
const ExtensionDetailTabSelected = 'ExtensionDetailTabSelected';
|
|
1628
|
+
const Feature = 'Feature';
|
|
1629
|
+
const FeatureContent = 'FeatureContent';
|
|
1735
1630
|
const Features = 'Features';
|
|
1736
|
-
const
|
|
1737
|
-
const
|
|
1738
|
-
const
|
|
1739
|
-
const
|
|
1740
|
-
const
|
|
1631
|
+
const FeaturesList = 'FeaturesList';
|
|
1632
|
+
const FeatureWebView = 'FeatureWebView';
|
|
1633
|
+
const Large = 'Large';
|
|
1634
|
+
const Sash = 'Sash';
|
|
1635
|
+
const SashVertical = 'SashVertical';
|
|
1636
|
+
const MoreInfo = 'MoreInfo';
|
|
1637
|
+
const MoreInfoEntry = 'MoreInfoEntry';
|
|
1638
|
+
const MoreInfoEntryKey = 'MoreInfoEntryKey';
|
|
1639
|
+
const MoreInfoEntryOdd = 'MoreInfoEntryOdd';
|
|
1640
|
+
const MoreInfoEntryValue = 'MoreInfoEntryValue';
|
|
1641
|
+
const Normal = 'Normal';
|
|
1642
|
+
const Resource = 'Resource';
|
|
1643
|
+
const Resources = 'Resources';
|
|
1644
|
+
const Small = 'Small';
|
|
1645
|
+
const Table$1 = 'Table';
|
|
1646
|
+
const TableCell = 'TableCell';
|
|
1647
|
+
const TableHeading = 'TableHeading';
|
|
1648
|
+
const Viewlet = 'Viewlet';
|
|
1741
1649
|
|
|
1742
|
-
const
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1650
|
+
const BYTE_UNITS = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
1651
|
+
const BIBYTE_UNITS = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
|
|
1652
|
+
const BIT_UNITS = ['b', 'kbit', 'Mbit', 'Gbit', 'Tbit', 'Pbit', 'Ebit', 'Zbit', 'Ybit'];
|
|
1653
|
+
const BIBIT_UNITS = ['b', 'kibit', 'Mibit', 'Gibit', 'Tibit', 'Pibit', 'Eibit', 'Zibit', 'Yibit'];
|
|
1654
|
+
|
|
1655
|
+
/*
|
|
1656
|
+
Formats the given number using `Number#toLocaleString`.
|
|
1657
|
+
- If locale is a string, the value is expected to be a locale-key (for example: `de`).
|
|
1658
|
+
- If locale is true, the system default locale is used for translation.
|
|
1659
|
+
- If no value for locale is specified, the number is returned unmodified.
|
|
1660
|
+
*/
|
|
1661
|
+
const toLocaleString = (number, locale, options) => {
|
|
1662
|
+
let result = number;
|
|
1663
|
+
if (typeof locale === 'string' || Array.isArray(locale)) {
|
|
1664
|
+
result = number.toLocaleString(locale, options);
|
|
1665
|
+
} else if (locale === true || options !== undefined) {
|
|
1666
|
+
result = number.toLocaleString(undefined, options);
|
|
1758
1667
|
}
|
|
1668
|
+
return result;
|
|
1759
1669
|
};
|
|
1670
|
+
function prettyBytes(number, options) {
|
|
1671
|
+
if (!Number.isFinite(number)) {
|
|
1672
|
+
throw new TypeError(`Expected a finite number, got ${typeof number}: ${number}`);
|
|
1673
|
+
}
|
|
1674
|
+
options = {
|
|
1675
|
+
bits: false,
|
|
1676
|
+
binary: false,
|
|
1677
|
+
space: true,
|
|
1678
|
+
...options
|
|
1679
|
+
};
|
|
1680
|
+
const UNITS = options.bits ? options.binary ? BIBIT_UNITS : BIT_UNITS : options.binary ? BIBYTE_UNITS : BYTE_UNITS;
|
|
1681
|
+
const separator = options.space ? ' ' : '';
|
|
1682
|
+
if (options.signed && number === 0) {
|
|
1683
|
+
return ` 0${separator}${UNITS[0]}`;
|
|
1684
|
+
}
|
|
1685
|
+
const isNegative = number < 0;
|
|
1686
|
+
const prefix = isNegative ? '-' : options.signed ? '+' : '';
|
|
1687
|
+
if (isNegative) {
|
|
1688
|
+
number = -number;
|
|
1689
|
+
}
|
|
1690
|
+
let localeOptions;
|
|
1691
|
+
if (options.minimumFractionDigits !== undefined) {
|
|
1692
|
+
localeOptions = {
|
|
1693
|
+
minimumFractionDigits: options.minimumFractionDigits
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1696
|
+
if (options.maximumFractionDigits !== undefined) {
|
|
1697
|
+
localeOptions = {
|
|
1698
|
+
maximumFractionDigits: options.maximumFractionDigits,
|
|
1699
|
+
...localeOptions
|
|
1700
|
+
};
|
|
1701
|
+
}
|
|
1702
|
+
if (number < 1) {
|
|
1703
|
+
const numberString = toLocaleString(number, options.locale, localeOptions);
|
|
1704
|
+
return prefix + numberString + separator + UNITS[0];
|
|
1705
|
+
}
|
|
1706
|
+
const exponent = Math.min(Math.floor(options.binary ? Math.log(number) / Math.log(1024) : Math.log10(number) / 3), UNITS.length - 1);
|
|
1707
|
+
number /= (options.binary ? 1024 : 1000) ** exponent;
|
|
1708
|
+
if (!localeOptions) {
|
|
1709
|
+
number = number.toPrecision(3);
|
|
1710
|
+
}
|
|
1711
|
+
const numberString = toLocaleString(Number(number), options.locale, localeOptions);
|
|
1712
|
+
const unit = UNITS[exponent];
|
|
1713
|
+
return prefix + numberString + separator + unit;
|
|
1714
|
+
}
|
|
1760
1715
|
|
|
1761
|
-
const
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
id
|
|
1766
|
-
} = feature;
|
|
1767
|
-
const className = selected ? 'Feature FeatureSelected' : Feature;
|
|
1768
|
-
return [{
|
|
1769
|
-
// TODO use role list item or tab
|
|
1770
|
-
type: Button,
|
|
1771
|
-
name: id,
|
|
1772
|
-
className,
|
|
1773
|
-
childCount: 1
|
|
1774
|
-
}, text(label)];
|
|
1716
|
+
const getDisplaySize = size => {
|
|
1717
|
+
return prettyBytes(size, {
|
|
1718
|
+
maximumFractionDigits: 1
|
|
1719
|
+
});
|
|
1775
1720
|
};
|
|
1776
1721
|
|
|
1777
|
-
const
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1722
|
+
const A = 53;
|
|
1723
|
+
const Button = 1;
|
|
1724
|
+
const Div = 4;
|
|
1725
|
+
const H1 = 5;
|
|
1726
|
+
const H2 = 22;
|
|
1727
|
+
const Img = 17;
|
|
1728
|
+
const Pre = 51;
|
|
1729
|
+
const Table = 9;
|
|
1730
|
+
const TBody = 10;
|
|
1731
|
+
const Td = 11;
|
|
1732
|
+
const Th = 13;
|
|
1733
|
+
const THead = 14;
|
|
1734
|
+
const Tr = 15;
|
|
1786
1735
|
|
|
1787
|
-
const
|
|
1788
|
-
|
|
1789
|
-
const none$1 = none();
|
|
1790
|
-
return [{
|
|
1791
|
-
type: Div,
|
|
1792
|
-
className: Features$1,
|
|
1793
|
-
childCount: 3
|
|
1794
|
-
}, text(none$1)];
|
|
1795
|
-
}
|
|
1796
|
-
return [{
|
|
1797
|
-
type: Div,
|
|
1798
|
-
className: Features$1,
|
|
1799
|
-
childCount: 3
|
|
1800
|
-
}, ...getFeatureListVirtualDom(features), {
|
|
1801
|
-
type: Div,
|
|
1802
|
-
className: mergeClassNames(Sash, SashVertical),
|
|
1803
|
-
childCount: 0
|
|
1804
|
-
}, ...(await getFeatureContentVirtualDom(features, themesHtml, selectedFeature, extension))];
|
|
1736
|
+
const mergeClassNames = (...classNames) => {
|
|
1737
|
+
return classNames.filter(Boolean).join(' ');
|
|
1805
1738
|
};
|
|
1806
|
-
|
|
1807
|
-
const
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
case Changelog:
|
|
1814
|
-
return getChangelogVirtualDom();
|
|
1815
|
-
default:
|
|
1816
|
-
return [];
|
|
1817
|
-
}
|
|
1739
|
+
const Text$1 = 12;
|
|
1740
|
+
const text = data => {
|
|
1741
|
+
return {
|
|
1742
|
+
type: Text$1,
|
|
1743
|
+
text: data,
|
|
1744
|
+
childCount: 0
|
|
1745
|
+
};
|
|
1818
1746
|
};
|
|
1819
1747
|
|
|
1820
|
-
const
|
|
1748
|
+
const getChangelogVirtualDom = () => {
|
|
1749
|
+
const notImplemented$1 = notImplemented();
|
|
1750
|
+
// TODO set tabpanel role
|
|
1821
1751
|
return [{
|
|
1822
|
-
type: Button,
|
|
1823
|
-
className: Button$1 + ' ' + ButtonPrimary,
|
|
1824
|
-
onClick,
|
|
1825
|
-
childCount: 1
|
|
1826
|
-
}, text(message)];
|
|
1827
|
-
};
|
|
1828
|
-
|
|
1829
|
-
const getExtensionDetailHeaderActionsVirtualDom = () => {
|
|
1830
|
-
const dom = [{
|
|
1831
1752
|
type: Div,
|
|
1832
|
-
className:
|
|
1833
|
-
childCount: 2
|
|
1834
|
-
}, ...getButtonVirtualDom('Disable', HandleClickDisable), ...getButtonVirtualDom('Uninstall', HandleClickUninstall)];
|
|
1835
|
-
return dom;
|
|
1836
|
-
};
|
|
1837
|
-
|
|
1838
|
-
const getExtensionDetailHeaderVirtualDom = extensionDetail => {
|
|
1839
|
-
const {
|
|
1840
|
-
name,
|
|
1841
|
-
iconSrc,
|
|
1842
|
-
description
|
|
1843
|
-
} = extensionDetail;
|
|
1844
|
-
const dom = [{
|
|
1845
|
-
type: Div,
|
|
1846
|
-
className: ExtensionDetailHeader,
|
|
1847
|
-
childCount: 2
|
|
1848
|
-
}, {
|
|
1849
|
-
type: Img,
|
|
1850
|
-
className: ExtensionDetailIcon,
|
|
1851
|
-
alt: '',
|
|
1852
|
-
draggable: false,
|
|
1853
|
-
childCount: 0,
|
|
1854
|
-
src: iconSrc
|
|
1855
|
-
}, {
|
|
1856
|
-
type: Div,
|
|
1857
|
-
className: ExtensionDetailHeaderDetails,
|
|
1858
|
-
childCount: 3
|
|
1859
|
-
}, {
|
|
1860
|
-
type: Div,
|
|
1861
|
-
className: ExtensionDetailName,
|
|
1753
|
+
className: Changelog,
|
|
1862
1754
|
childCount: 1
|
|
1863
|
-
}, text(
|
|
1864
|
-
type: Div,
|
|
1865
|
-
className: ExtensionDetailDescription,
|
|
1866
|
-
childCount: 1
|
|
1867
|
-
}, text(description), ...getExtensionDetailHeaderActionsVirtualDom()];
|
|
1868
|
-
return dom;
|
|
1755
|
+
}, text(notImplemented$1)];
|
|
1869
1756
|
};
|
|
1870
1757
|
|
|
1871
|
-
const
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
const hasCommands = extension => {
|
|
1875
|
-
return extension && extension.commands;
|
|
1876
|
-
};
|
|
1877
|
-
const hasJsonValidation = extension => {
|
|
1878
|
-
return extension && extension.jsonValidation;
|
|
1879
|
-
};
|
|
1880
|
-
const hasProgrammingLanguages = extension => {
|
|
1881
|
-
return extension && extension.programmingLanguages;
|
|
1882
|
-
};
|
|
1883
|
-
const hasSettings = extension => {
|
|
1884
|
-
return extension && extension.settings;
|
|
1885
|
-
};
|
|
1886
|
-
const hasWebViews = extension => {
|
|
1887
|
-
return extension && extension.webViews;
|
|
1888
|
-
};
|
|
1889
|
-
const ifElseFeature = (id, label, isEnabled, selectedFeature, extension) => {
|
|
1890
|
-
if (!isEnabled(extension)) {
|
|
1891
|
-
return [];
|
|
1892
|
-
}
|
|
1893
|
-
return [{
|
|
1894
|
-
id,
|
|
1895
|
-
label,
|
|
1896
|
-
selected: selectedFeature === id
|
|
1897
|
-
}];
|
|
1898
|
-
};
|
|
1899
|
-
const getFeatures = (selectedFeature, extension) => {
|
|
1900
|
-
if (!selectedFeature) {
|
|
1901
|
-
selectedFeature = Theme;
|
|
1902
|
-
}
|
|
1903
|
-
const textTheme = theme();
|
|
1904
|
-
const textCommands = commands();
|
|
1905
|
-
const textJsonValidation = jsonValidation();
|
|
1906
|
-
const programmingLanguages$1 = programmingLanguages();
|
|
1907
|
-
const settings$1 = settings();
|
|
1908
|
-
const webViews$1 = webViews();
|
|
1909
|
-
const features = [...ifElseFeature(Theme, textTheme, hasThemes, selectedFeature, extension), ...ifElseFeature(Commands, textCommands, hasCommands, selectedFeature, extension), ...ifElseFeature(JsonValidation, textJsonValidation, hasJsonValidation, selectedFeature, extension), ...ifElseFeature(ProgrammingLanguages, programmingLanguages$1, hasProgrammingLanguages, selectedFeature, extension), ...ifElseFeature(Settings, settings$1, hasSettings, selectedFeature, extension), ...ifElseFeature(WebViews, webViews$1, hasWebViews, selectedFeature, extension)];
|
|
1910
|
-
return features;
|
|
1911
|
-
};
|
|
1758
|
+
const TabList = 'tablist';
|
|
1759
|
+
const Tab = 'tab';
|
|
1760
|
+
const Panel = 'panel';
|
|
1912
1761
|
|
|
1913
|
-
const
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
}, {
|
|
1919
|
-
label: 'Features',
|
|
1920
|
-
name: Features,
|
|
1921
|
-
selected: selectedTab === Features
|
|
1762
|
+
const getAdditionalDetailsEntryVirtualDom = (heading, items, renderer) => {
|
|
1763
|
+
return [{
|
|
1764
|
+
type: Div,
|
|
1765
|
+
className: AdditionalDetailsEntry,
|
|
1766
|
+
childCount: 2
|
|
1922
1767
|
}, {
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
}];
|
|
1927
|
-
return tabs;
|
|
1768
|
+
type: Div,
|
|
1769
|
+
className: AdditionalDetailsTitle,
|
|
1770
|
+
childCount: 1
|
|
1771
|
+
}, text(heading), ...renderer(items)];
|
|
1928
1772
|
};
|
|
1929
1773
|
|
|
1930
|
-
const
|
|
1931
|
-
const defaultClassName = ExtensionDetailTab;
|
|
1932
|
-
const getTabVirtualDom = tab => {
|
|
1774
|
+
const getCategoryVirtualDom = category => {
|
|
1933
1775
|
const {
|
|
1934
|
-
label
|
|
1935
|
-
|
|
1936
|
-
name
|
|
1937
|
-
} = tab;
|
|
1938
|
-
const className = selected ? selectedClassName : defaultClassName;
|
|
1939
|
-
const ariaSelected = selected ? 'true' : 'false';
|
|
1776
|
+
label
|
|
1777
|
+
} = category;
|
|
1940
1778
|
return [{
|
|
1941
|
-
type:
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
className,
|
|
1945
|
-
childCount: 1,
|
|
1946
|
-
tabIndex: -1,
|
|
1947
|
-
ariaSelected
|
|
1779
|
+
type: Div,
|
|
1780
|
+
className: Category,
|
|
1781
|
+
childCount: 1
|
|
1948
1782
|
}, text(label)];
|
|
1949
1783
|
};
|
|
1950
1784
|
|
|
1951
|
-
const
|
|
1785
|
+
const getCategoriesDom = categories => {
|
|
1952
1786
|
return [{
|
|
1953
1787
|
type: Div,
|
|
1954
|
-
className:
|
|
1955
|
-
childCount:
|
|
1956
|
-
|
|
1957
|
-
onClick: HandleTabsClick,
|
|
1958
|
-
tabIndex: 0
|
|
1959
|
-
}, ...tabs.flatMap(getTabVirtualDom)];
|
|
1788
|
+
className: Categories,
|
|
1789
|
+
childCount: categories.length
|
|
1790
|
+
}, ...categories.flatMap(getCategoryVirtualDom)];
|
|
1960
1791
|
};
|
|
1961
1792
|
|
|
1962
|
-
const
|
|
1963
|
-
|
|
1964
|
-
|
|
1793
|
+
const parentNode$1 = {
|
|
1794
|
+
type: Div,
|
|
1795
|
+
className: MoreInfoEntryKey,
|
|
1796
|
+
childCount: 1
|
|
1797
|
+
};
|
|
1798
|
+
const getMoreInfoEntryKeyVirtualDom = item => {
|
|
1799
|
+
const {
|
|
1800
|
+
key
|
|
1801
|
+
} = item;
|
|
1802
|
+
return [parentNode$1, text(key)];
|
|
1803
|
+
};
|
|
1965
1804
|
|
|
1966
|
-
const
|
|
1967
|
-
if (
|
|
1968
|
-
return
|
|
1805
|
+
const getTag = (onClick, code) => {
|
|
1806
|
+
if (onClick) {
|
|
1807
|
+
return A;
|
|
1969
1808
|
}
|
|
1970
|
-
if (
|
|
1971
|
-
|
|
1809
|
+
if (code) {
|
|
1810
|
+
// TODO use code tag
|
|
1811
|
+
return Div;
|
|
1972
1812
|
}
|
|
1973
|
-
return
|
|
1813
|
+
return Div;
|
|
1974
1814
|
};
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
return Normal$1;
|
|
1982
|
-
case Large:
|
|
1983
|
-
return Large$1;
|
|
1984
|
-
default:
|
|
1985
|
-
return '';
|
|
1815
|
+
const getClassName = (onClick, code) => {
|
|
1816
|
+
if (onClick) {
|
|
1817
|
+
return MoreInfoEntryValue + ' Link';
|
|
1818
|
+
}
|
|
1819
|
+
if (code) {
|
|
1820
|
+
return MoreInfoEntryValue + ' Code';
|
|
1986
1821
|
}
|
|
1822
|
+
return MoreInfoEntryValue;
|
|
1823
|
+
};
|
|
1824
|
+
const getMoreInfoEntryValueVirtualDom = item => {
|
|
1825
|
+
const {
|
|
1826
|
+
value,
|
|
1827
|
+
onClick,
|
|
1828
|
+
code
|
|
1829
|
+
} = item;
|
|
1830
|
+
const type = getTag(onClick, code);
|
|
1831
|
+
const className = getClassName(onClick, code);
|
|
1832
|
+
return [{
|
|
1833
|
+
type: type,
|
|
1834
|
+
className,
|
|
1835
|
+
childCount: 1,
|
|
1836
|
+
onClick
|
|
1837
|
+
}, text(value)];
|
|
1987
1838
|
};
|
|
1988
1839
|
|
|
1989
|
-
const
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
const
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
const
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
1840
|
+
const parentNodeEven = {
|
|
1841
|
+
type: Div,
|
|
1842
|
+
className: MoreInfoEntry,
|
|
1843
|
+
childCount: 2
|
|
1844
|
+
};
|
|
1845
|
+
const parentNodeOdd = {
|
|
1846
|
+
type: Div,
|
|
1847
|
+
className: mergeClassNames(MoreInfoEntry, MoreInfoEntryOdd),
|
|
1848
|
+
childCount: 2
|
|
1849
|
+
};
|
|
1850
|
+
const getMoreInfoEntryVirtualDom = item => {
|
|
1851
|
+
const {
|
|
1852
|
+
odd
|
|
1853
|
+
} = item;
|
|
1854
|
+
const node = odd ? parentNodeOdd : parentNodeEven;
|
|
1855
|
+
return [node, ...getMoreInfoEntryKeyVirtualDom(item), ...getMoreInfoEntryValueVirtualDom(item)];
|
|
1856
|
+
};
|
|
1857
|
+
|
|
1858
|
+
const getMoreInfoVirtualDom = items => {
|
|
1859
|
+
return [{
|
|
2008
1860
|
type: Div,
|
|
2009
|
-
className:
|
|
2010
|
-
childCount:
|
|
2011
|
-
}, ...
|
|
2012
|
-
return dom;
|
|
1861
|
+
className: MoreInfo,
|
|
1862
|
+
childCount: items.length
|
|
1863
|
+
}, ...items.flatMap(getMoreInfoEntryVirtualDom)];
|
|
2013
1864
|
};
|
|
2014
1865
|
|
|
2015
|
-
const
|
|
1866
|
+
const resourceNode = {
|
|
1867
|
+
// TODO use link with url
|
|
1868
|
+
type: Div,
|
|
1869
|
+
className: Resource,
|
|
1870
|
+
childCount: 1
|
|
1871
|
+
};
|
|
1872
|
+
const getResourceVirtualDom = resource => {
|
|
2016
1873
|
const {
|
|
2017
|
-
|
|
2018
|
-
} =
|
|
2019
|
-
return
|
|
1874
|
+
label
|
|
1875
|
+
} = resource;
|
|
1876
|
+
return [resourceNode, text(label)];
|
|
2020
1877
|
};
|
|
2021
1878
|
|
|
2022
|
-
const
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
});
|
|
1879
|
+
const getResourcesVirtualDom = resources => {
|
|
1880
|
+
return [{
|
|
1881
|
+
type: Div,
|
|
1882
|
+
className: Resources,
|
|
1883
|
+
childCount: resources.length
|
|
1884
|
+
}, ...resources.flatMap(getResourceVirtualDom)];
|
|
1885
|
+
};
|
|
2030
1886
|
|
|
2031
|
-
const
|
|
2032
|
-
if (!
|
|
1887
|
+
const getAdditionalDetailsVirtualDom = (showAdditionalDetails, firstHeading, entries, secondHeading, secondEntries, thirdHeading, categories, fourthHeading, resources) => {
|
|
1888
|
+
if (!showAdditionalDetails) {
|
|
2033
1889
|
return [];
|
|
2034
1890
|
}
|
|
2035
1891
|
return [{
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
1892
|
+
type: Div,
|
|
1893
|
+
className: Aside,
|
|
1894
|
+
childCount: 1
|
|
1895
|
+
}, {
|
|
1896
|
+
type: Div,
|
|
1897
|
+
className: AdditionalDetails,
|
|
1898
|
+
tabIndex: 0,
|
|
1899
|
+
childCount: 4
|
|
1900
|
+
}, ...getAdditionalDetailsEntryVirtualDom(firstHeading, entries, getMoreInfoVirtualDom), ...getAdditionalDetailsEntryVirtualDom(secondHeading, secondEntries, getMoreInfoVirtualDom), ...getAdditionalDetailsEntryVirtualDom(thirdHeading, categories, getCategoriesDom), ...getAdditionalDetailsEntryVirtualDom(fourthHeading, resources, getResourcesVirtualDom)];
|
|
1901
|
+
};
|
|
1902
|
+
|
|
1903
|
+
const HandleClickDisable = 'handleClickDisable';
|
|
1904
|
+
const HandleClickSize = 'handleClickSize';
|
|
1905
|
+
const HandleClickUninstall = 'handleClickUninstall';
|
|
1906
|
+
const HandleFeaturesClick = 'handleFeaturesClick';
|
|
1907
|
+
const HandleIconError = 'handleIconError';
|
|
1908
|
+
const HandleReadmeContextMenu = 'handleReadmeContextMenu';
|
|
1909
|
+
const HandleTabsClick = 'handleTabsClick';
|
|
1910
|
+
|
|
1911
|
+
const getInstallationEntries = (displaySize, extensionId, extensionVersion) => {
|
|
1912
|
+
const entries = [{
|
|
1913
|
+
key: 'Identifier',
|
|
1914
|
+
value: extensionId,
|
|
1915
|
+
odd: true,
|
|
1916
|
+
code: true
|
|
1917
|
+
}, {
|
|
1918
|
+
key: 'Version',
|
|
1919
|
+
value: extensionVersion,
|
|
1920
|
+
code: true
|
|
1921
|
+
}, {
|
|
1922
|
+
key: 'Last Updated',
|
|
1923
|
+
value: 'n/a',
|
|
1924
|
+
odd: true
|
|
1925
|
+
}, {
|
|
1926
|
+
key: 'Size',
|
|
1927
|
+
value: displaySize,
|
|
1928
|
+
onClick: HandleClickSize
|
|
1929
|
+
}];
|
|
1930
|
+
return entries;
|
|
1931
|
+
};
|
|
1932
|
+
|
|
1933
|
+
const getMarkdownVirtualDom = async html => {
|
|
1934
|
+
string(html);
|
|
1935
|
+
const dom = await invoke('Markdown.getVirtualDom', html);
|
|
1936
|
+
return dom;
|
|
1937
|
+
};
|
|
1938
|
+
|
|
1939
|
+
const getMarketplaceEntries = () => {
|
|
1940
|
+
return [{
|
|
1941
|
+
key: 'Published',
|
|
1942
|
+
value: 'n/a',
|
|
1943
|
+
odd: true
|
|
1944
|
+
}, {
|
|
1945
|
+
key: 'Last Released',
|
|
1946
|
+
value: 'n/a'
|
|
1947
|
+
}];
|
|
1948
|
+
};
|
|
1949
|
+
|
|
1950
|
+
const getDetailsVirtualDom = async (sanitizedReadmeHtml, displaySize, extensionId, extensionVersion, width) => {
|
|
1951
|
+
const firstHeading = 'Installation';
|
|
1952
|
+
const entries = getInstallationEntries(displaySize, extensionId, extensionVersion);
|
|
1953
|
+
const secondHeading = 'Marketplace';
|
|
1954
|
+
const secondEntries = getMarketplaceEntries();
|
|
1955
|
+
const thirdHeading = 'Categories';
|
|
1956
|
+
const categories = [{
|
|
1957
|
+
id: 'themes',
|
|
1958
|
+
label: 'Themes'
|
|
1959
|
+
}];
|
|
1960
|
+
const fourthHeading = 'Resources';
|
|
1961
|
+
const resources = [{
|
|
1962
|
+
label: 'Marketplace',
|
|
1963
|
+
url: '#'
|
|
1964
|
+
}, {
|
|
1965
|
+
label: 'Issues',
|
|
1966
|
+
url: '#'
|
|
1967
|
+
}, {
|
|
1968
|
+
label: 'Repository',
|
|
1969
|
+
url: '#'
|
|
2041
1970
|
}, {
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
flags: None,
|
|
2045
|
-
command: 'SaveFileAs.saveFileAs',
|
|
2046
|
-
args: ['image.png', props.url || '']
|
|
1971
|
+
label: 'License',
|
|
1972
|
+
url: '#'
|
|
2047
1973
|
}];
|
|
1974
|
+
const showAdditionalDetailsBreakpoint = 600;
|
|
1975
|
+
const showAdditionalDetails = width > showAdditionalDetailsBreakpoint;
|
|
1976
|
+
const childCount = showAdditionalDetails ? 2 : 1;
|
|
1977
|
+
const dom = [{
|
|
1978
|
+
type: Div,
|
|
1979
|
+
className: ExtensionDetailPanel,
|
|
1980
|
+
childCount: childCount,
|
|
1981
|
+
role: Panel
|
|
1982
|
+
}, ...(await getMarkdownVirtualDom(sanitizedReadmeHtml)), ...getAdditionalDetailsVirtualDom(showAdditionalDetails, firstHeading, entries, secondHeading, secondEntries, thirdHeading, categories, fourthHeading, resources)];
|
|
1983
|
+
return dom;
|
|
2048
1984
|
};
|
|
2049
1985
|
|
|
2050
|
-
const
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
1986
|
+
const Text = 1;
|
|
1987
|
+
const Code = 2;
|
|
1988
|
+
|
|
1989
|
+
const getCommandTableEntry = command => {
|
|
1990
|
+
// TODO watch out for command being null/undefined/number/string/array
|
|
1991
|
+
const {
|
|
1992
|
+
id,
|
|
1993
|
+
label
|
|
1994
|
+
} = command;
|
|
2054
1995
|
return [{
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
1996
|
+
type: Code,
|
|
1997
|
+
value: id
|
|
1998
|
+
}, {
|
|
1999
|
+
type: Text,
|
|
2000
|
+
value: label
|
|
2060
2001
|
}];
|
|
2061
2002
|
};
|
|
2062
2003
|
|
|
2063
|
-
const
|
|
2064
|
-
|
|
2065
|
-
const
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
const selectFeature = async (state, name) => {
|
|
2070
|
-
if (!name) {
|
|
2071
|
-
return state;
|
|
2072
|
-
}
|
|
2073
|
-
const {
|
|
2074
|
-
features
|
|
2075
|
-
} = state;
|
|
2076
|
-
const newFeatures = features.map(feature => {
|
|
2077
|
-
if (feature.id === name) {
|
|
2078
|
-
return {
|
|
2079
|
-
...feature,
|
|
2080
|
-
selected: true
|
|
2081
|
-
};
|
|
2082
|
-
}
|
|
2083
|
-
return {
|
|
2084
|
-
...feature,
|
|
2085
|
-
selected: false
|
|
2086
|
-
};
|
|
2087
|
-
});
|
|
2004
|
+
const getCommandTableEntries = extension => {
|
|
2005
|
+
const commands = extension.commands || [];
|
|
2006
|
+
const rows = commands.map(getCommandTableEntry);
|
|
2007
|
+
const id$1 = id();
|
|
2008
|
+
const label$1 = label();
|
|
2088
2009
|
return {
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
features: newFeatures
|
|
2010
|
+
headings: [id$1, label$1],
|
|
2011
|
+
rows
|
|
2092
2012
|
};
|
|
2093
2013
|
};
|
|
2094
2014
|
|
|
2095
|
-
const
|
|
2096
|
-
return
|
|
2015
|
+
const getFeatureContentHeadingVirtualDom = heading => {
|
|
2016
|
+
return [{
|
|
2017
|
+
type: H1,
|
|
2018
|
+
childCount: 1
|
|
2019
|
+
}, text(heading)];
|
|
2097
2020
|
};
|
|
2098
2021
|
|
|
2099
|
-
const
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2022
|
+
const getTableHeadingVirtualDom = heading => {
|
|
2023
|
+
return [{
|
|
2024
|
+
type: Th,
|
|
2025
|
+
className: TableHeading,
|
|
2026
|
+
childCount: 1
|
|
2027
|
+
}, text(heading)];
|
|
2105
2028
|
};
|
|
2106
2029
|
|
|
2107
|
-
const
|
|
2108
|
-
return
|
|
2030
|
+
const getCellCodeVirtualDom = value => {
|
|
2031
|
+
return [{
|
|
2032
|
+
type: Td,
|
|
2033
|
+
className: TableCell,
|
|
2034
|
+
childCount: 1
|
|
2035
|
+
}, {
|
|
2036
|
+
type: Div,
|
|
2037
|
+
// TODO use code tag
|
|
2038
|
+
childCount: 1
|
|
2039
|
+
}, text(value)];
|
|
2109
2040
|
};
|
|
2110
2041
|
|
|
2111
|
-
const
|
|
2112
|
-
return
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
};
|
|
2117
|
-
const extensionTheme = assetDir => {
|
|
2118
|
-
return `${assetDir}/icons/theme-icon.png`;
|
|
2042
|
+
const getCellTextVirtualDom = value => {
|
|
2043
|
+
return [{
|
|
2044
|
+
type: Td,
|
|
2045
|
+
className: TableCell,
|
|
2046
|
+
childCount: 1
|
|
2047
|
+
}, text(value)];
|
|
2119
2048
|
};
|
|
2120
2049
|
|
|
2121
|
-
const
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2050
|
+
const getCellRenderer = type => {
|
|
2051
|
+
switch (type) {
|
|
2052
|
+
case Code:
|
|
2053
|
+
return getCellCodeVirtualDom;
|
|
2054
|
+
case Text:
|
|
2055
|
+
return getCellTextVirtualDom;
|
|
2056
|
+
default:
|
|
2057
|
+
throw new Error(`unexpected cell type ${type}`);
|
|
2128
2058
|
}
|
|
2129
|
-
return {
|
|
2130
|
-
...state,
|
|
2131
|
-
iconSrc: extensionDefaultIcon(assetDir)
|
|
2132
|
-
};
|
|
2133
|
-
};
|
|
2134
|
-
|
|
2135
|
-
const selectTabChangelog = async state => {
|
|
2136
|
-
return {
|
|
2137
|
-
...state,
|
|
2138
|
-
selectedTab: Changelog
|
|
2139
|
-
};
|
|
2140
2059
|
};
|
|
2141
2060
|
|
|
2142
|
-
const
|
|
2143
|
-
|
|
2061
|
+
const getCellVirtualDom = entry => {
|
|
2062
|
+
const {
|
|
2063
|
+
value,
|
|
2064
|
+
type
|
|
2065
|
+
} = entry;
|
|
2066
|
+
const fn = getCellRenderer(type);
|
|
2067
|
+
return fn(value);
|
|
2144
2068
|
};
|
|
2145
2069
|
|
|
2146
|
-
const
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
};
|
|
2070
|
+
const getTableRowVirtualDom = entries => {
|
|
2071
|
+
return [{
|
|
2072
|
+
type: Tr,
|
|
2073
|
+
childCount: entries.length
|
|
2074
|
+
}, ...entries.flatMap(getCellVirtualDom)];
|
|
2152
2075
|
};
|
|
2153
2076
|
|
|
2154
|
-
const
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
}
|
|
2164
|
-
|
|
2077
|
+
const getTableVirtualDom = tableInfo => {
|
|
2078
|
+
const {
|
|
2079
|
+
headings,
|
|
2080
|
+
rows
|
|
2081
|
+
} = tableInfo;
|
|
2082
|
+
return [{
|
|
2083
|
+
type: Table,
|
|
2084
|
+
className: Table$1,
|
|
2085
|
+
childCount: 2
|
|
2086
|
+
}, {
|
|
2087
|
+
type: THead,
|
|
2088
|
+
childCount: 1
|
|
2089
|
+
}, {
|
|
2090
|
+
type: Tr,
|
|
2091
|
+
childCount: headings.length
|
|
2092
|
+
}, ...headings.flatMap(getTableHeadingVirtualDom), {
|
|
2093
|
+
type: TBody,
|
|
2094
|
+
childCount: rows.length
|
|
2095
|
+
}, ...rows.flatMap(getTableRowVirtualDom)];
|
|
2165
2096
|
};
|
|
2166
2097
|
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
const heading = 'Product Icon Themes';
|
|
2177
|
-
return getThemeItemMarkdown(heading, iconThemes);
|
|
2178
|
-
};
|
|
2179
|
-
const getThemeMarkdown = (themes, iconThemes, productIconThemes) => {
|
|
2180
|
-
let markdown = '';
|
|
2181
|
-
markdown += getColorThemeMarkdown(themes);
|
|
2182
|
-
markdown += getIconThemeMarkdown(iconThemes);
|
|
2183
|
-
markdown += getProductIconThemeMarkdown(productIconThemes);
|
|
2184
|
-
return markdown;
|
|
2098
|
+
// TODO have typed view-model
|
|
2099
|
+
const getFeatureCommandsVirtualDom = extension => {
|
|
2100
|
+
const heading = commands();
|
|
2101
|
+
const tableInfo = getCommandTableEntries(extension);
|
|
2102
|
+
return [{
|
|
2103
|
+
type: Div,
|
|
2104
|
+
className: FeatureContent,
|
|
2105
|
+
childCount: 2
|
|
2106
|
+
}, ...getFeatureContentHeadingVirtualDom(heading), ...getTableVirtualDom(tableInfo)];
|
|
2185
2107
|
};
|
|
2186
2108
|
|
|
2187
|
-
const
|
|
2188
|
-
const
|
|
2189
|
-
|
|
2109
|
+
const getJsonValidationTableEntry = validation => {
|
|
2110
|
+
const {
|
|
2111
|
+
fileMatch,
|
|
2112
|
+
schema
|
|
2113
|
+
} = validation;
|
|
2114
|
+
return [{
|
|
2115
|
+
type: Code,
|
|
2116
|
+
value: fileMatch
|
|
2117
|
+
}, {
|
|
2118
|
+
type: Code,
|
|
2119
|
+
value: schema
|
|
2120
|
+
}];
|
|
2190
2121
|
};
|
|
2191
2122
|
|
|
2192
|
-
const
|
|
2193
|
-
const
|
|
2194
|
-
|
|
2195
|
-
baseUrl
|
|
2196
|
-
} = state;
|
|
2197
|
-
const {
|
|
2198
|
-
colorThemes,
|
|
2199
|
-
iconThemes,
|
|
2200
|
-
productIconThemes
|
|
2201
|
-
} = extension;
|
|
2202
|
-
// TODO do this depending on featured tab content
|
|
2203
|
-
const markdown = getThemeMarkdown(colorThemes || [], iconThemes || [], productIconThemes || []);
|
|
2204
|
-
const rendered = await renderMarkdown(markdown, {
|
|
2205
|
-
baseUrl
|
|
2206
|
-
});
|
|
2123
|
+
const getJsonValidationTableEntries = extension => {
|
|
2124
|
+
const validations = extension.jsonValidation || [];
|
|
2125
|
+
const rows = validations.map(getJsonValidationTableEntry);
|
|
2207
2126
|
return {
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
selectedFeatureMarkdownDom: rendered
|
|
2127
|
+
headings: [fileMatch(), schema()],
|
|
2128
|
+
rows
|
|
2211
2129
|
};
|
|
2212
2130
|
};
|
|
2213
2131
|
|
|
2214
|
-
const
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
return selectTabDefault;
|
|
2224
|
-
}
|
|
2132
|
+
const parentNode = {
|
|
2133
|
+
type: Div,
|
|
2134
|
+
className: FeatureContent,
|
|
2135
|
+
childCount: 2
|
|
2136
|
+
};
|
|
2137
|
+
const getFeatureJsonValidationVirtualDom = extension => {
|
|
2138
|
+
const heading = jsonValidation();
|
|
2139
|
+
const tableInfo = getJsonValidationTableEntries(extension);
|
|
2140
|
+
return [parentNode, ...getFeatureContentHeadingVirtualDom(heading), ...getTableVirtualDom(tableInfo)];
|
|
2225
2141
|
};
|
|
2226
2142
|
|
|
2227
|
-
const
|
|
2228
|
-
const
|
|
2229
|
-
return
|
|
2143
|
+
const getFeatureNotImplementedVirtualDom = () => {
|
|
2144
|
+
const heading = 'Not implemented';
|
|
2145
|
+
return [{
|
|
2146
|
+
type: Div,
|
|
2147
|
+
className: FeatureContent,
|
|
2148
|
+
childCount: 1
|
|
2149
|
+
}, {
|
|
2150
|
+
type: H1,
|
|
2151
|
+
childCount: 1
|
|
2152
|
+
}, text(heading)];
|
|
2230
2153
|
};
|
|
2231
2154
|
|
|
2232
|
-
const
|
|
2233
|
-
|
|
2155
|
+
const getFeatureProgrammingLanguagesVirtualDom = () => {
|
|
2156
|
+
const heading = programmingLanguages();
|
|
2157
|
+
// TODO
|
|
2158
|
+
return [{
|
|
2159
|
+
type: Div,
|
|
2160
|
+
className: FeatureContent,
|
|
2161
|
+
childCount: 1
|
|
2162
|
+
}, ...getFeatureContentHeadingVirtualDom(heading)];
|
|
2234
2163
|
};
|
|
2235
2164
|
|
|
2236
|
-
const
|
|
2237
|
-
|
|
2165
|
+
const getSettingsTableEntry = setting => {
|
|
2166
|
+
const {
|
|
2167
|
+
id,
|
|
2168
|
+
label
|
|
2169
|
+
} = setting;
|
|
2170
|
+
// TODO watch out for null/undefined/number/string/array
|
|
2171
|
+
return [{
|
|
2172
|
+
type: Text,
|
|
2173
|
+
value: id
|
|
2174
|
+
}, {
|
|
2175
|
+
type: Text,
|
|
2176
|
+
value: label
|
|
2177
|
+
}];
|
|
2238
2178
|
};
|
|
2239
2179
|
|
|
2240
|
-
const
|
|
2241
|
-
|
|
2180
|
+
const getSettingsTableEntries = extension => {
|
|
2181
|
+
const settings = extension.settings || [];
|
|
2182
|
+
const rows = settings.map(getSettingsTableEntry);
|
|
2183
|
+
const textId = id();
|
|
2184
|
+
const textLabel = label();
|
|
2185
|
+
return {
|
|
2186
|
+
headings: [textId, textLabel],
|
|
2187
|
+
rows
|
|
2188
|
+
};
|
|
2242
2189
|
};
|
|
2243
2190
|
|
|
2244
|
-
const
|
|
2245
|
-
const
|
|
2246
|
-
const
|
|
2191
|
+
const getFeatureSettingsVirtualDom = extension => {
|
|
2192
|
+
const heading = settings();
|
|
2193
|
+
const tableInfo = getSettingsTableEntries(extension);
|
|
2194
|
+
return [{
|
|
2195
|
+
type: Div,
|
|
2196
|
+
className: FeatureContent,
|
|
2197
|
+
childCount: 2
|
|
2198
|
+
}, ...getFeatureContentHeadingVirtualDom(heading), ...getTableVirtualDom(tableInfo)];
|
|
2199
|
+
};
|
|
2247
2200
|
|
|
2248
|
-
const
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
if (
|
|
2254
|
-
|
|
2255
|
-
}
|
|
2256
|
-
if (isThemeExtension(extension)) {
|
|
2257
|
-
return extensionTheme(assetDir);
|
|
2258
|
-
}
|
|
2259
|
-
return extensionDefaultIcon(assetDir);
|
|
2260
|
-
}
|
|
2261
|
-
if (platform === Remote || platform === Electron) {
|
|
2262
|
-
if (extension.builtin) {
|
|
2263
|
-
return `${assetDir}/extensions/${extension.id}/${extension.icon}`;
|
|
2201
|
+
const getVirtualDomChildCount = markdownDom => {
|
|
2202
|
+
const max = markdownDom.length - 1;
|
|
2203
|
+
let stack = [];
|
|
2204
|
+
for (let i = max; i >= 0; i--) {
|
|
2205
|
+
const element = markdownDom[i];
|
|
2206
|
+
if (element.childCount > 0) {
|
|
2207
|
+
stack = stack.slice(element.childCount);
|
|
2264
2208
|
}
|
|
2265
|
-
|
|
2209
|
+
stack.unshift(element);
|
|
2266
2210
|
}
|
|
2267
|
-
return
|
|
2211
|
+
return stack.length;
|
|
2268
2212
|
};
|
|
2269
2213
|
|
|
2270
|
-
const
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
return
|
|
2214
|
+
const getFeatureThemesVirtualDom = async themesHtml => {
|
|
2215
|
+
const markdownDom = await getMarkdownVirtualDom(themesHtml);
|
|
2216
|
+
const childCount = getVirtualDomChildCount(markdownDom);
|
|
2217
|
+
const heading = theme();
|
|
2218
|
+
return [{
|
|
2219
|
+
type: Div,
|
|
2220
|
+
className: FeatureContent,
|
|
2221
|
+
childCount: 2
|
|
2222
|
+
}, ...getFeatureContentHeadingVirtualDom(heading), {
|
|
2223
|
+
type: Div,
|
|
2224
|
+
className: DefaultMarkdown,
|
|
2225
|
+
childCount
|
|
2226
|
+
}, ...markdownDom];
|
|
2275
2227
|
};
|
|
2276
2228
|
|
|
2277
|
-
const
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
}
|
|
2284
|
-
return
|
|
2229
|
+
const toWebView = rawWebView => {
|
|
2230
|
+
const {
|
|
2231
|
+
id,
|
|
2232
|
+
selector,
|
|
2233
|
+
contentSecurityPolicy,
|
|
2234
|
+
elements
|
|
2235
|
+
} = rawWebView;
|
|
2236
|
+
return {
|
|
2237
|
+
id,
|
|
2238
|
+
selectorString: JSON.stringify(selector),
|
|
2239
|
+
contentSecurityPolicyString: JSON.stringify(contentSecurityPolicy),
|
|
2240
|
+
elementsString: JSON.stringify(elements, null, 2)
|
|
2241
|
+
};
|
|
2285
2242
|
};
|
|
2286
2243
|
|
|
2287
|
-
const
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
}
|
|
2291
|
-
return invoke('ExtensionManagement.getAllExtensions');
|
|
2292
|
-
};
|
|
2293
|
-
const getExtension$1 = async (id, platform) => {
|
|
2294
|
-
// TODO only ask one extension from renderer worker instead of all
|
|
2295
|
-
const allExtensions = await getAllExtensions(platform);
|
|
2296
|
-
for (const extension of allExtensions) {
|
|
2297
|
-
if (extension.id === id) {
|
|
2298
|
-
return extension;
|
|
2299
|
-
}
|
|
2300
|
-
}
|
|
2301
|
-
return undefined;
|
|
2244
|
+
const getWebViews = extension => {
|
|
2245
|
+
const rawWebViews = extension.webViews || [];
|
|
2246
|
+
return rawWebViews.map(toWebView);
|
|
2302
2247
|
};
|
|
2303
2248
|
|
|
2304
|
-
const
|
|
2305
|
-
|
|
2249
|
+
const heading = {
|
|
2250
|
+
type: H2,
|
|
2251
|
+
className: DefinitionListItemHeading,
|
|
2252
|
+
childCount: 1
|
|
2306
2253
|
};
|
|
2307
|
-
const
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
return getExtension$1(id, platform);
|
|
2312
|
-
}
|
|
2254
|
+
const pre = {
|
|
2255
|
+
type: Pre,
|
|
2256
|
+
className: DefinitionListItemValue,
|
|
2257
|
+
childCount: 1
|
|
2313
2258
|
};
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2259
|
+
const item = {
|
|
2260
|
+
type: Div,
|
|
2261
|
+
className: DefinitionListItem,
|
|
2262
|
+
childCount: 2
|
|
2318
2263
|
};
|
|
2319
|
-
|
|
2320
|
-
const
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2264
|
+
const getWebViewVirtualDom = webView => {
|
|
2265
|
+
const {
|
|
2266
|
+
id: id$1,
|
|
2267
|
+
selectorString,
|
|
2268
|
+
contentSecurityPolicyString,
|
|
2269
|
+
elementsString
|
|
2270
|
+
} = webView;
|
|
2271
|
+
const textId = id();
|
|
2272
|
+
const textSelector = selector();
|
|
2273
|
+
const textContentSecurityPolicy = contentSecurityPolicy();
|
|
2274
|
+
const textElements = elements();
|
|
2275
|
+
return [{
|
|
2276
|
+
type: Div,
|
|
2277
|
+
className: FeatureWebView,
|
|
2278
|
+
childCount: 5
|
|
2279
|
+
}, item, heading, text(textId), pre, text(id$1), item, heading, text(textSelector), pre, text(selectorString), item, heading, text(textContentSecurityPolicy), pre, text(contentSecurityPolicyString), item, heading, text(textElements), pre, text(elementsString)];
|
|
2328
2280
|
};
|
|
2329
2281
|
|
|
2330
|
-
const
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2282
|
+
const getFeatureWebViewsVirtualDom = extension => {
|
|
2283
|
+
const webViews$1 = getWebViews(extension);
|
|
2284
|
+
const heading = webViews();
|
|
2285
|
+
return [{
|
|
2286
|
+
type: Div,
|
|
2287
|
+
className: FeatureContent,
|
|
2288
|
+
childCount: 2
|
|
2289
|
+
}, ...getFeatureContentHeadingVirtualDom(heading), {
|
|
2290
|
+
type: Div,
|
|
2291
|
+
childCount: webViews$1.length
|
|
2292
|
+
}, ...webViews$1.flatMap(getWebViewVirtualDom)];
|
|
2336
2293
|
};
|
|
2337
2294
|
|
|
2338
|
-
const
|
|
2339
|
-
|
|
2295
|
+
const getFeatureContentVirtualDom = async (features, themesHtml, selectedFeature, extension) => {
|
|
2296
|
+
switch (selectedFeature) {
|
|
2297
|
+
case Theme:
|
|
2298
|
+
return await getFeatureThemesVirtualDom(themesHtml);
|
|
2299
|
+
case Commands:
|
|
2300
|
+
return getFeatureCommandsVirtualDom(extension);
|
|
2301
|
+
case JsonValidation:
|
|
2302
|
+
return getFeatureJsonValidationVirtualDom(extension);
|
|
2303
|
+
case ProgrammingLanguages:
|
|
2304
|
+
return getFeatureProgrammingLanguagesVirtualDom();
|
|
2305
|
+
case Settings:
|
|
2306
|
+
return getFeatureSettingsVirtualDom(extension);
|
|
2307
|
+
case WebViews:
|
|
2308
|
+
return getFeatureWebViewsVirtualDom(extension);
|
|
2309
|
+
default:
|
|
2310
|
+
return getFeatureNotImplementedVirtualDom();
|
|
2311
|
+
}
|
|
2340
2312
|
};
|
|
2341
2313
|
|
|
2342
|
-
const
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2314
|
+
const getFeatureListItemVirtualDom = feature => {
|
|
2315
|
+
const {
|
|
2316
|
+
label,
|
|
2317
|
+
selected,
|
|
2318
|
+
id
|
|
2319
|
+
} = feature;
|
|
2320
|
+
const className = selected ? 'Feature FeatureSelected' : Feature;
|
|
2321
|
+
return [{
|
|
2322
|
+
// TODO use role list item or tab
|
|
2323
|
+
type: Button,
|
|
2324
|
+
name: id,
|
|
2325
|
+
className,
|
|
2326
|
+
childCount: 1
|
|
2327
|
+
}, text(label)];
|
|
2346
2328
|
};
|
|
2347
2329
|
|
|
2348
|
-
const
|
|
2349
|
-
return
|
|
2330
|
+
const getFeatureListVirtualDom = features => {
|
|
2331
|
+
return [{
|
|
2332
|
+
// TODO use either list or tabs role
|
|
2333
|
+
type: Div,
|
|
2334
|
+
className: FeaturesList,
|
|
2335
|
+
childCount: features.length,
|
|
2336
|
+
onClick: HandleFeaturesClick
|
|
2337
|
+
}, ...features.flatMap(getFeatureListItemVirtualDom)];
|
|
2350
2338
|
};
|
|
2351
2339
|
|
|
2352
|
-
const
|
|
2353
|
-
|
|
2354
|
-
const
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
}
|
|
2361
|
-
console.error(new VError(error, 'Failed to load Readme content'));
|
|
2362
|
-
return `${error}`;
|
|
2340
|
+
const getFeaturesVirtualDom = async (features, themesHtml, selectedFeature, extension) => {
|
|
2341
|
+
if (features.length === 0) {
|
|
2342
|
+
const none$1 = none();
|
|
2343
|
+
return [{
|
|
2344
|
+
type: Div,
|
|
2345
|
+
className: Features,
|
|
2346
|
+
childCount: 3
|
|
2347
|
+
}, text(none$1)];
|
|
2363
2348
|
}
|
|
2349
|
+
return [{
|
|
2350
|
+
type: Div,
|
|
2351
|
+
className: Features,
|
|
2352
|
+
childCount: 3
|
|
2353
|
+
}, ...getFeatureListVirtualDom(features), {
|
|
2354
|
+
type: Div,
|
|
2355
|
+
className: mergeClassNames(Sash, SashVertical),
|
|
2356
|
+
childCount: 0
|
|
2357
|
+
}, ...(await getFeatureContentVirtualDom(features, themesHtml, selectedFeature, extension))];
|
|
2364
2358
|
};
|
|
2365
2359
|
|
|
2366
|
-
const
|
|
2367
|
-
|
|
2368
|
-
|
|
2360
|
+
const getExtensionDetailContentVirtualDom = async (sanitizedReadmeHtml, themesHtml, selectedTab, features, displaySize, extensionId, extensionVersion, selectedFeature, extension, width) => {
|
|
2361
|
+
switch (selectedTab) {
|
|
2362
|
+
case Details:
|
|
2363
|
+
return await getDetailsVirtualDom(sanitizedReadmeHtml, displaySize, extensionId, extensionVersion, width);
|
|
2364
|
+
case Features$1:
|
|
2365
|
+
return await getFeaturesVirtualDom(features, themesHtml, selectedFeature, extension);
|
|
2366
|
+
case Changelog$1:
|
|
2367
|
+
return getChangelogVirtualDom();
|
|
2368
|
+
default:
|
|
2369
|
+
return [];
|
|
2369
2370
|
}
|
|
2370
|
-
return Details;
|
|
2371
2371
|
};
|
|
2372
2372
|
|
|
2373
|
-
const
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2373
|
+
const getButtonVirtualDom = (message, onClick) => {
|
|
2374
|
+
return [{
|
|
2375
|
+
type: Button,
|
|
2376
|
+
className: mergeClassNames(Button$1, ButtonPrimary),
|
|
2377
|
+
onClick,
|
|
2378
|
+
childCount: 1
|
|
2379
|
+
}, text(message)];
|
|
2378
2380
|
};
|
|
2379
2381
|
|
|
2380
|
-
const
|
|
2381
|
-
const
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2382
|
+
const getExtensionDetailHeaderActionsVirtualDom = () => {
|
|
2383
|
+
const dom = [{
|
|
2384
|
+
type: Div,
|
|
2385
|
+
className: ExtensionDetailHeaderActions,
|
|
2386
|
+
childCount: 2
|
|
2387
|
+
}, ...getButtonVirtualDom('Disable', HandleClickDisable), ...getButtonVirtualDom('Uninstall', HandleClickUninstall)];
|
|
2388
|
+
return dom;
|
|
2387
2389
|
};
|
|
2388
2390
|
|
|
2389
|
-
const
|
|
2390
|
-
const {
|
|
2391
|
-
uri,
|
|
2392
|
-
width,
|
|
2393
|
-
assetDir
|
|
2394
|
-
} = state;
|
|
2395
|
-
const id = uri.slice('extension-detail://'.length);
|
|
2396
|
-
const extension = await getExtension(id, platform);
|
|
2397
|
-
const readmeContent = await loadReadmeContent(extension.path);
|
|
2398
|
-
const baseUrl = getBaseUrl(extension.path, platform);
|
|
2399
|
-
const readmeHtml = await renderMarkdown(readmeContent, {
|
|
2400
|
-
baseUrl
|
|
2401
|
-
});
|
|
2402
|
-
const sanitizedReadmeHtml = readmeHtml;
|
|
2403
|
-
const normalizedReadmeHtml = sanitizedReadmeHtml;
|
|
2404
|
-
const iconSrc = getIcon(extension, platform, assetDir);
|
|
2405
|
-
const description = getDescription(extension);
|
|
2406
|
-
const name = getName(extension);
|
|
2407
|
-
const size = getViewletSize(width);
|
|
2391
|
+
const getExtensionDetailHeaderVirtualDom = extensionDetail => {
|
|
2408
2392
|
const {
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
const
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
}, {
|
|
2418
|
-
key: 'Version',
|
|
2419
|
-
value: '1.9.5'
|
|
2393
|
+
name,
|
|
2394
|
+
iconSrc,
|
|
2395
|
+
description
|
|
2396
|
+
} = extensionDetail;
|
|
2397
|
+
const dom = [{
|
|
2398
|
+
type: Div,
|
|
2399
|
+
className: ExtensionDetailHeader,
|
|
2400
|
+
childCount: 2
|
|
2420
2401
|
}, {
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2402
|
+
type: Img,
|
|
2403
|
+
className: ExtensionDetailIcon,
|
|
2404
|
+
alt: '',
|
|
2405
|
+
draggable: false,
|
|
2406
|
+
childCount: 0,
|
|
2407
|
+
src: iconSrc
|
|
2427
2408
|
}, {
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
const categories = [{
|
|
2432
|
-
id: 'themes',
|
|
2433
|
-
label: 'Themes'
|
|
2434
|
-
}];
|
|
2435
|
-
const resources = [{
|
|
2436
|
-
label: 'Marketplace',
|
|
2437
|
-
url: '#'
|
|
2409
|
+
type: Div,
|
|
2410
|
+
className: ExtensionDetailHeaderDetails,
|
|
2411
|
+
childCount: 3
|
|
2438
2412
|
}, {
|
|
2439
|
-
|
|
2440
|
-
|
|
2413
|
+
type: Div,
|
|
2414
|
+
className: ExtensionDetailName,
|
|
2415
|
+
childCount: 1
|
|
2416
|
+
}, text(name), {
|
|
2417
|
+
type: Div,
|
|
2418
|
+
className: ExtensionDetailDescription,
|
|
2419
|
+
childCount: 1
|
|
2420
|
+
}, text(description), ...getExtensionDetailHeaderActionsVirtualDom()];
|
|
2421
|
+
return dom;
|
|
2422
|
+
};
|
|
2423
|
+
|
|
2424
|
+
const getTabs = selectedTab => {
|
|
2425
|
+
const tabs = [{
|
|
2426
|
+
label: 'Details',
|
|
2427
|
+
name: Details,
|
|
2428
|
+
selected: selectedTab === Details
|
|
2441
2429
|
}, {
|
|
2442
|
-
label: '
|
|
2443
|
-
|
|
2430
|
+
label: 'Features',
|
|
2431
|
+
name: Features$1,
|
|
2432
|
+
selected: selectedTab === Features$1
|
|
2444
2433
|
}, {
|
|
2445
|
-
label: '
|
|
2446
|
-
|
|
2434
|
+
label: 'Changelog',
|
|
2435
|
+
name: Changelog$1,
|
|
2436
|
+
selected: selectedTab === Changelog$1
|
|
2447
2437
|
}];
|
|
2448
|
-
return
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2438
|
+
return tabs;
|
|
2439
|
+
};
|
|
2440
|
+
|
|
2441
|
+
const selectedClassName = mergeClassNames(ExtensionDetailTab, ExtensionDetailTabSelected);
|
|
2442
|
+
const defaultClassName = ExtensionDetailTab;
|
|
2443
|
+
const getTabVirtualDom = tab => {
|
|
2444
|
+
const {
|
|
2445
|
+
label,
|
|
2446
|
+
selected,
|
|
2447
|
+
name
|
|
2448
|
+
} = tab;
|
|
2449
|
+
const className = selected ? selectedClassName : defaultClassName;
|
|
2450
|
+
const ariaSelected = selected ? 'true' : 'false';
|
|
2451
|
+
return [{
|
|
2452
|
+
type: Button,
|
|
2453
|
+
role: Tab,
|
|
2453
2454
|
name,
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
resources,
|
|
2460
|
-
extension,
|
|
2461
|
-
baseUrl,
|
|
2462
|
-
features,
|
|
2463
|
-
folderSize
|
|
2464
|
-
};
|
|
2455
|
+
className,
|
|
2456
|
+
childCount: 1,
|
|
2457
|
+
tabIndex: -1,
|
|
2458
|
+
ariaSelected
|
|
2459
|
+
}, text(label)];
|
|
2465
2460
|
};
|
|
2466
2461
|
|
|
2467
|
-
const
|
|
2468
|
-
return
|
|
2462
|
+
const getTabsVirtualDom = tabs => {
|
|
2463
|
+
return [{
|
|
2464
|
+
type: Div,
|
|
2465
|
+
className: ExtensionDetailTabs,
|
|
2466
|
+
childCount: tabs.length,
|
|
2467
|
+
role: TabList,
|
|
2468
|
+
onClick: HandleTabsClick,
|
|
2469
|
+
tabIndex: 0
|
|
2470
|
+
}, ...tabs.flatMap(getTabVirtualDom)];
|
|
2471
|
+
};
|
|
2472
|
+
|
|
2473
|
+
const getClassNames = size => {
|
|
2474
|
+
switch (size) {
|
|
2475
|
+
case Small$1:
|
|
2476
|
+
return Small;
|
|
2477
|
+
case Normal$1:
|
|
2478
|
+
return Normal;
|
|
2479
|
+
case Large$1:
|
|
2480
|
+
return Large;
|
|
2481
|
+
default:
|
|
2482
|
+
return '';
|
|
2483
|
+
}
|
|
2484
|
+
};
|
|
2485
|
+
|
|
2486
|
+
const getExtensionDetailVirtualDom = async (extensionDetail, sanitizedReadmeHtml, selectedTab, newState) => {
|
|
2487
|
+
// TODO move this to view model so that rendering occurs like
|
|
2488
|
+
// 1. state
|
|
2489
|
+
// 2. view model
|
|
2490
|
+
// 3. virtual dom
|
|
2491
|
+
// 4. dom
|
|
2492
|
+
const themesHtml = newState?.selectedFeatureMarkdownDom || '';
|
|
2493
|
+
const selectedFeature = newState?.selectedFeature || '';
|
|
2494
|
+
const extension = newState?.extension || {};
|
|
2495
|
+
const features = getFeatures(selectedFeature, extension);
|
|
2496
|
+
const size = newState.folderSize || 0;
|
|
2497
|
+
const extensionId = newState?.extension?.id || 'n/a';
|
|
2498
|
+
const extensionVersion = newState?.extension?.version || 'n/a';
|
|
2499
|
+
const displaySize = getDisplaySize(size);
|
|
2500
|
+
const width = newState?.width || 500;
|
|
2501
|
+
const tabs = getTabs(selectedTab);
|
|
2502
|
+
const sizeValue = getViewletSize(newState?.width || 0);
|
|
2503
|
+
const sizeClass = getClassNames(sizeValue);
|
|
2504
|
+
const dom = [{
|
|
2505
|
+
type: Div,
|
|
2506
|
+
className: mergeClassNames(Viewlet, ExtensionDetail, sizeClass),
|
|
2507
|
+
childCount: 3
|
|
2508
|
+
}, ...getExtensionDetailHeaderVirtualDom(extensionDetail), ...getTabsVirtualDom(tabs), ...(await getExtensionDetailContentVirtualDom(sanitizedReadmeHtml, themesHtml, selectedTab, features, displaySize, extensionId, extensionVersion, selectedFeature, extension, width))];
|
|
2509
|
+
return dom;
|
|
2469
2510
|
};
|
|
2470
2511
|
|
|
2471
2512
|
const renderDom = async (oldState, newState) => {
|
|
@@ -2557,21 +2598,6 @@ const terminate = () => {
|
|
|
2557
2598
|
globalThis.close();
|
|
2558
2599
|
};
|
|
2559
2600
|
|
|
2560
|
-
const wrapCommand = fn => {
|
|
2561
|
-
const wrapped = async (uid, ...args) => {
|
|
2562
|
-
const {
|
|
2563
|
-
newState
|
|
2564
|
-
} = get$1(uid);
|
|
2565
|
-
const newerState = await fn(newState, ...args);
|
|
2566
|
-
if (newState === newerState) {
|
|
2567
|
-
return;
|
|
2568
|
-
}
|
|
2569
|
-
const latest = get$1(uid);
|
|
2570
|
-
set$1(uid, latest.oldState, newerState);
|
|
2571
|
-
};
|
|
2572
|
-
return wrapped;
|
|
2573
|
-
};
|
|
2574
|
-
|
|
2575
2601
|
const commandMap = {
|
|
2576
2602
|
'ExtensionDetail.create': create,
|
|
2577
2603
|
'ExtensionDetail.diff2': diff2,
|
|
@@ -2590,10 +2616,7 @@ const commandMap = {
|
|
|
2590
2616
|
'ExtensionDetail.resize': resize,
|
|
2591
2617
|
'ExtensionDetail.saveState': saveState,
|
|
2592
2618
|
'ExtensionDetail.selectTab': wrapCommand(selectTab),
|
|
2593
|
-
'ExtensionDetail.terminate': terminate
|
|
2594
|
-
// deprecated
|
|
2595
|
-
'ExtensionDetail.getVirtualDom2': getExtensionDetailVirtualDom2,
|
|
2596
|
-
'ExtensionDetail.loadContent': wrapCommand(loadContent)
|
|
2619
|
+
'ExtensionDetail.terminate': terminate
|
|
2597
2620
|
};
|
|
2598
2621
|
|
|
2599
2622
|
const listen = async () => {
|