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