@lvce-editor/extension-detail-view 4.4.0 → 4.6.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.
@@ -305,7 +305,7 @@ const Features$1 = 'Features';
305
305
  const FeaturesList = 'FeaturesList';
306
306
  const FeatureWebView = 'FeatureWebView';
307
307
  const Large$1 = 'Large';
308
- const Link = 'Link';
308
+ const Link$1 = 'Link';
309
309
  const Markdown = 'Markdown';
310
310
  const MoreInfo = 'MoreInfo';
311
311
  const MoreInfoEntry = 'MoreInfoEntry';
@@ -323,6 +323,7 @@ const SettingsIcon = 'SettingsIcon';
323
323
  const Small$1 = 'Small';
324
324
  const Table = 'Table';
325
325
  const TableCell = 'TableCell';
326
+ const TableCellInvalid = 'TableCellInvalid';
326
327
  const TableHeading = 'TableHeading';
327
328
  const Viewlet = 'Viewlet';
328
329
 
@@ -363,6 +364,7 @@ const getActivationEventsVirtualDom = state => {
363
364
 
364
365
  const Text = 1;
365
366
  const Code = 2;
367
+ const Link = 7;
366
368
 
367
369
  const getCommandTableEntry = command => {
368
370
  // TODO watch out for command being null/undefined/number/string/array
@@ -424,22 +426,44 @@ const getTableHeadingVirtualDom = heading => {
424
426
  }, text(heading)];
425
427
  };
426
428
 
427
- const getCellCodeVirtualDom = value => {
429
+ const getCellCodeVirtualDom = (value, props) => {
430
+ const tdClassName = props?.className ? `${TableCell} ${props.className}` : TableCell;
428
431
  return [{
429
432
  type: Td,
430
- className: TableCell,
431
- childCount: 1
433
+ className: tdClassName,
434
+ childCount: 1,
435
+ ...(props?.title ? {
436
+ title: props.title
437
+ } : {})
432
438
  }, {
433
439
  type: Code$2,
434
440
  childCount: 1
435
441
  }, text(value)];
436
442
  };
437
443
 
438
- const getCellTextVirtualDom = value => {
444
+ const getCellLinkVirtualDom = (value, {
445
+ href
446
+ }) => {
439
447
  return [{
440
448
  type: Td,
441
449
  className: TableCell,
442
450
  childCount: 1
451
+ }, {
452
+ type: A,
453
+ href,
454
+ childCount: 1
455
+ }, text(value)];
456
+ };
457
+
458
+ const getCellTextVirtualDom = (value, props) => {
459
+ const tdClassName = props?.className ? `${TableCell} ${props.className}` : TableCell;
460
+ return [{
461
+ type: Td,
462
+ className: tdClassName,
463
+ childCount: 1,
464
+ ...(props?.title ? {
465
+ title: props.title
466
+ } : {})
443
467
  }, text(value)];
444
468
  };
445
469
 
@@ -449,6 +473,8 @@ const getCellRenderer = type => {
449
473
  return getCellCodeVirtualDom;
450
474
  case Text:
451
475
  return getCellTextVirtualDom;
476
+ case Link:
477
+ return getCellLinkVirtualDom;
452
478
  default:
453
479
  throw new Error(`unexpected cell type ${type}`);
454
480
  }
@@ -457,10 +483,11 @@ const getCellRenderer = type => {
457
483
  const getCellVirtualDom = entry => {
458
484
  const {
459
485
  value,
460
- type
486
+ type,
487
+ ...props
461
488
  } = entry;
462
489
  const fn = getCellRenderer(type);
463
- return fn(value);
490
+ return fn(value, props);
464
491
  };
465
492
 
466
493
  const getTableRowVirtualDom = entries => {
@@ -509,24 +536,94 @@ const getCommandsVirtualDom = state => {
509
536
  return getFeatureCommandsVirtualDom(state.commands);
510
537
  };
511
538
 
512
- const getJsonValidationTableEntry = validation => {
513
- // TODO handle case when validation is invalid like null
539
+ const stringifyValue = value => {
540
+ return JSON.stringify(value);
541
+ };
542
+ const getLinkOrTextEntry = (schema, schemaLinkUrl) => {
543
+ if (typeof schema !== 'string') {
544
+ return {
545
+ type: Text,
546
+ value: stringifyValue(schema)
547
+ };
548
+ }
549
+ if (schemaLinkUrl) {
550
+ return {
551
+ type: Link,
552
+ value: schema,
553
+ href: schemaLinkUrl
554
+ };
555
+ }
556
+ return {
557
+ type: Text,
558
+ value: schema
559
+ };
560
+ };
561
+
562
+ const isExternalLink = schema => {
563
+ return schema.startsWith('http://') || schema.startsWith('https://');
564
+ };
565
+ const getSchemaLinkUrl = (schema, extensionUri) => {
566
+ if (!schema) {
567
+ return '';
568
+ }
569
+ if (typeof schema !== 'string') {
570
+ return '';
571
+ }
572
+ if (isExternalLink(schema)) {
573
+ return schema;
574
+ }
575
+ return new URL(schema, extensionUri).toString();
576
+ };
577
+
578
+ const stringify = value => {
579
+ try {
580
+ return JSON.stringify(value);
581
+ } catch {
582
+ return String(value);
583
+ }
584
+ };
585
+ const getJsonValidationTableEntry = (validation, extensionUri) => {
586
+ const invalidProps = {
587
+ className: TableCellInvalid,
588
+ title: 'property must be a string'
589
+ };
590
+ if (!validation || typeof validation !== 'object' || Array.isArray(validation)) {
591
+ const shown = stringify(validation);
592
+ return [{
593
+ type: Text,
594
+ value: shown,
595
+ ...invalidProps
596
+ }, {
597
+ type: Text,
598
+ value: shown,
599
+ ...invalidProps
600
+ }];
601
+ }
514
602
  const {
515
603
  fileMatch
516
604
  } = validation;
517
605
  const schema = validation.schema ?? validation.url;
518
- return [{
606
+ const schemaLinkUrl = getSchemaLinkUrl(schema, extensionUri);
607
+ const leftCell = typeof fileMatch === 'string' || Array.isArray(fileMatch) ? {
519
608
  type: Code,
520
609
  value: fileMatch
521
- }, {
522
- type: Code,
523
- value: schema
524
- }];
610
+ } : {
611
+ type: Text,
612
+ value: stringify(fileMatch),
613
+ ...invalidProps
614
+ };
615
+ const rightEntry = typeof schema === 'string' ? getLinkOrTextEntry(schema, schemaLinkUrl) : {
616
+ type: Text,
617
+ value: stringify(schema),
618
+ ...invalidProps
619
+ };
620
+ return [leftCell, rightEntry];
525
621
  };
526
622
 
527
623
  const getJsonValidationDetails = async extension => {
528
624
  const validations = extension.jsonValidation || [];
529
- const rows = validations.map(getJsonValidationTableEntry);
625
+ const extensionUri = extension.uri || '';
626
+ const rows = validations.map(validation => getJsonValidationTableEntry(validation, extensionUri));
530
627
  return {
531
628
  jsonValidation: rows
532
629
  };
@@ -738,7 +835,7 @@ class AssertionError extends Error {
738
835
  const Object$1 = 1;
739
836
  const Number$1 = 2;
740
837
  const Array$1 = 3;
741
- const String = 4;
838
+ const String$1 = 4;
742
839
  const Boolean$1 = 5;
743
840
  const Function = 6;
744
841
  const Null = 7;
@@ -750,7 +847,7 @@ const getType = value => {
750
847
  case 'function':
751
848
  return Function;
752
849
  case 'string':
753
- return String;
850
+ return String$1;
754
851
  case 'object':
755
852
  if (value === null) {
756
853
  return Null;
@@ -767,7 +864,7 @@ const getType = value => {
767
864
  };
768
865
  const string = value => {
769
866
  const type = getType(value);
770
- if (type !== String) {
867
+ if (type !== String$1) {
771
868
  throw new AssertionError('expected value to be of type string');
772
869
  }
773
870
  };
@@ -2382,20 +2479,21 @@ const getSettingsVirtualDom = state => {
2382
2479
  return getFeatureSettingsVirtualDom(state.settings);
2383
2480
  };
2384
2481
 
2385
- const HandleClickCategory = 'handleClickCategory';
2386
- const HandleClickDisable = 'handleClickDisable';
2387
- const HandleClickEnable = 'handleClickEnable';
2388
- const HandleClickScrollToTop = 'handleClickScrollToTop';
2389
- const HandleClickSetColorTheme = 'handleClickSetColorTheme';
2390
- const HandleClickSettings = 'handleClickSettings';
2391
- const HandleClickSize = 'handleClickSize';
2392
- const HandleClickUninstall = 'handleClickUninstall';
2393
- const HandleFeaturesClick = 'handleFeaturesClick';
2394
- const HandleIconError = 'handleIconError';
2395
- const HandleImageContextMenu = 'handleImageContextMenu';
2396
- const HandleReadmeContextMenu = 'handleReadmeContextMenu';
2397
- const HandleReadmeScroll = 'handleReadmeScroll';
2398
- const HandleTabsClick = 'handleTabsClick';
2482
+ const HandleClickCategory = 1;
2483
+ const HandleClickDisable = 2;
2484
+ const HandleClickEnable = 3;
2485
+ const HandleClickScrollToTop = 4;
2486
+ const HandleClickSetColorTheme = 5;
2487
+ const HandleClickSettings = 6;
2488
+ const HandleClickSize = 7;
2489
+ const HandleClickUninstall = 8;
2490
+ const HandleFeaturesClick = 9;
2491
+ const HandleIconError = 10;
2492
+ const HandleImageContextMenu = 11;
2493
+ const HandleReadmeContextMenu = 12;
2494
+ const HandleReadmeScroll = 13;
2495
+ const HandleTabsClick = 14;
2496
+ const HandleAdditionalDetailContextMenu = 15;
2399
2497
 
2400
2498
  const ActivationEvents = 'ActivationEvents';
2401
2499
  const Changelog = 'Changelog';
@@ -2484,6 +2582,18 @@ const getThemeMarkdown = (themes, iconThemes, productIconThemes) => {
2484
2582
  return markdown;
2485
2583
  };
2486
2584
 
2585
+ const supportsNormalCacheKey = locationProtocol => {
2586
+ return locationProtocol === 'http:' || locationProtocol === 'https:';
2587
+ };
2588
+
2589
+ const getMarkdownCacheKey = (hash, locationProtocol) => {
2590
+ if (supportsNormalCacheKey(locationProtocol)) {
2591
+ return `/markdown/${hash}`;
2592
+ }
2593
+ // workaround for electron bug
2594
+ return `https://-/markdown/${hash}`;
2595
+ };
2596
+
2487
2597
  const hash = async content => {
2488
2598
  const sourceBytes = new TextEncoder().encode(content);
2489
2599
  const digest = await crypto.subtle.digest('SHA-256', sourceBytes);
@@ -2548,9 +2658,9 @@ const set$3 = async (key, value) => {
2548
2658
  }));
2549
2659
  };
2550
2660
 
2551
- const renderMarkdownCached = async (markdown, options = {}) => {
2661
+ const renderMarkdownCached = async (markdown, options) => {
2552
2662
  const markdownHash = await hash(markdown); // TODO hash options also
2553
- const cacheKey = `/markdown/${markdownHash}`;
2663
+ const cacheKey = getMarkdownCacheKey(markdownHash, options.locationProtocol);
2554
2664
  const hasItem = await has(cacheKey);
2555
2665
  if (hasItem) {
2556
2666
  const value = await get$1(cacheKey);
@@ -2561,12 +2671,12 @@ const renderMarkdownCached = async (markdown, options = {}) => {
2561
2671
  return html;
2562
2672
  };
2563
2673
 
2564
- const renderMarkdown = async (markdown, options = {}) => {
2674
+ const renderMarkdown = async (markdown, options) => {
2565
2675
  const html = await renderMarkdownCached(markdown, options);
2566
2676
  return html;
2567
2677
  };
2568
2678
 
2569
- const getThemeDetails = async (extension, baseUrl) => {
2679
+ const getThemeDetails = async (extension, baseUrl, locationProtocol) => {
2570
2680
  const {
2571
2681
  colorThemes,
2572
2682
  iconThemes,
@@ -2574,7 +2684,8 @@ const getThemeDetails = async (extension, baseUrl) => {
2574
2684
  } = extension;
2575
2685
  const markdown = getThemeMarkdown(colorThemes || [], iconThemes || [], productIconThemes || []);
2576
2686
  const rendered = await renderMarkdown(markdown, {
2577
- baseUrl
2687
+ baseUrl,
2688
+ locationProtocol
2578
2689
  });
2579
2690
  const themesMarkdownDom = await getMarkdownVirtualDom(rendered);
2580
2691
  return {
@@ -3000,7 +3111,8 @@ const create = (uid, uri, x, y, width, height, platform, assetDir) => {
3000
3111
  paddingLeft: 0,
3001
3112
  paddingRight: 0,
3002
3113
  showSideBar: true,
3003
- sideBarWidth: 0
3114
+ sideBarWidth: 0,
3115
+ locationProtocol: ''
3004
3116
  };
3005
3117
  set(uid, state, state);
3006
3118
  };
@@ -3121,6 +3233,10 @@ const getMenus = () => {
3121
3233
  }];
3122
3234
  };
3123
3235
 
3236
+ const handleAdditionalDetailContextMenu = state => {
3237
+ return state;
3238
+ };
3239
+
3124
3240
  const openExtensionSearch = async searchValue => {
3125
3241
  await openExtensionSearch$1();
3126
3242
  await setExtensionsSearchValue(searchValue);
@@ -3237,7 +3353,8 @@ const selectFeature = async (state, name) => {
3237
3353
  const {
3238
3354
  features,
3239
3355
  extension,
3240
- baseUrl
3356
+ baseUrl,
3357
+ locationProtocol
3241
3358
  } = state;
3242
3359
  const newFeatures = features.map(feature => {
3243
3360
  if (feature.id === name) {
@@ -3252,7 +3369,7 @@ const selectFeature = async (state, name) => {
3252
3369
  };
3253
3370
  });
3254
3371
  const fn = getFeatureDetailsHandler(name);
3255
- const partialNewState = await fn(extension, baseUrl);
3372
+ const partialNewState = await fn(extension, baseUrl, locationProtocol);
3256
3373
  return {
3257
3374
  ...state,
3258
3375
  ...partialNewState,
@@ -3413,11 +3530,13 @@ const selectTabChangelog = async state => {
3413
3530
  const {
3414
3531
  extension,
3415
3532
  baseUrl,
3416
- tabs
3533
+ tabs,
3534
+ locationProtocol
3417
3535
  } = state;
3418
3536
  const changelogContent = await loadChangelogContent(extension.path); // TODO use uri
3419
3537
  const changelogMarkdownHtml = await renderMarkdown(changelogContent, {
3420
- baseUrl
3538
+ baseUrl,
3539
+ locationProtocol
3421
3540
  });
3422
3541
  const changelogDom = await getMarkdownVirtualDom(changelogMarkdownHtml);
3423
3542
  const newTabs = tabs.map(tab => {
@@ -3457,12 +3576,14 @@ const selectTabDetails = async state => {
3457
3576
  const {
3458
3577
  baseUrl,
3459
3578
  readmeUrl,
3460
- tabs
3579
+ tabs,
3580
+ locationProtocol
3461
3581
  } = state;
3462
3582
  const readmeContent = await loadReadmeContent(readmeUrl);
3463
3583
  const readmeHtml = await renderMarkdown(readmeContent, {
3464
3584
  baseUrl,
3465
- linksExternal: true
3585
+ linksExternal: true,
3586
+ locationProtocol
3466
3587
  });
3467
3588
  const detailsDom = await getMarkdownVirtualDom(readmeHtml);
3468
3589
  const newTabs = tabs.map(tab => {
@@ -3485,14 +3606,15 @@ const selectTabFeatures = async state => {
3485
3606
  baseUrl,
3486
3607
  selectedFeature,
3487
3608
  features,
3488
- tabs
3609
+ tabs,
3610
+ locationProtocol
3489
3611
  } = state;
3490
3612
  if (features.length === 0) {
3491
3613
  return state;
3492
3614
  }
3493
3615
  const actualSelectedFeature = selectedFeature || Theme;
3494
3616
  const fn = getFeatureDetailsHandler(actualSelectedFeature);
3495
- const partialNewState = await fn(extension, baseUrl);
3617
+ const partialNewState = await fn(extension, baseUrl, locationProtocol);
3496
3618
  const newTabs = tabs.map(tab => {
3497
3619
  return {
3498
3620
  ...tab,
@@ -4111,9 +4233,11 @@ const loadContent = async (state, platform, savedState, isTest = false) => {
4111
4233
  const [hasReadme, hasChangelog] = await Promise.all([existsFile(readmeUrl), existsFile(changelogUrl)]);
4112
4234
  const readmeContent = hasReadme ? await loadReadmeContent(readmeUrl) : noReadmeFound();
4113
4235
  const baseUrl = getBaseUrl(extension.path, platform);
4236
+ const locationProtocol = location.protocol;
4114
4237
  const readmeHtml = await renderMarkdown(readmeContent, {
4115
4238
  baseUrl,
4116
- linksExternal: true
4239
+ linksExternal: true,
4240
+ locationProtocol
4117
4241
  });
4118
4242
  const detailsVirtualDom = await getMarkdownVirtualDom(readmeHtml, {
4119
4243
  scrollToTopEnabled: true
@@ -4181,7 +4305,8 @@ const loadContent = async (state, platform, savedState, isTest = false) => {
4181
4305
  sideBarWidth,
4182
4306
  sizeOnDisk: size,
4183
4307
  sizeValue,
4184
- tabs: enabledTabs
4308
+ tabs: enabledTabs,
4309
+ locationProtocol
4185
4310
  };
4186
4311
  };
4187
4312
 
@@ -4280,7 +4405,7 @@ const getMoreInfoEntryKeyVirtualDom = item => {
4280
4405
  return [parentNode, text(key)];
4281
4406
  };
4282
4407
 
4283
- const classLink = mergeClassNames(MoreInfoEntryValue, Link);
4408
+ const classLink = mergeClassNames(MoreInfoEntryValue, Link$1);
4284
4409
  const classCode = mergeClassNames(MoreInfoEntryValue, Code$1);
4285
4410
  const getMoreInfoEntryValueClassName = (onClick, code) => {
4286
4411
  if (onClick) {
@@ -4302,13 +4427,15 @@ const getMoreInfoEntryValueTag = (onClick, code) => {
4302
4427
  return Dd;
4303
4428
  };
4304
4429
 
4305
- const getExtraProps = title => {
4430
+ const getExtraProps = (title, onClick) => {
4431
+ const props = Object.create(null);
4306
4432
  if (title) {
4307
- return {
4308
- title
4309
- };
4433
+ props.title = title;
4310
4434
  }
4311
- return {};
4435
+ if (onClick) {
4436
+ props.tabIndex = 0;
4437
+ }
4438
+ return props;
4312
4439
  };
4313
4440
  const getMoreInfoEntryValueVirtualDom = item => {
4314
4441
  const {
@@ -4319,7 +4446,7 @@ const getMoreInfoEntryValueVirtualDom = item => {
4319
4446
  } = item;
4320
4447
  const type = getMoreInfoEntryValueTag(onClick, code);
4321
4448
  const className = getMoreInfoEntryValueClassName(onClick, code);
4322
- const extraProps = getExtraProps(title);
4449
+ const extraProps = getExtraProps(title, onClick);
4323
4450
  return [{
4324
4451
  type,
4325
4452
  className,
@@ -4388,7 +4515,8 @@ const getAdditionalDetailsVirtualDom = (showAdditionalDetails, firstHeading, ent
4388
4515
  type: Div,
4389
4516
  className: AdditionalDetails,
4390
4517
  tabIndex: 0,
4391
- childCount: 4
4518
+ childCount: 4,
4519
+ onClick: HandleAdditionalDetailContextMenu
4392
4520
  }, ...getAdditionalDetailsEntryVirtualDom(firstHeading, entries, getMoreInfoVirtualDom), ...getAdditionalDetailsEntryVirtualDom(secondHeading, secondEntries, getMoreInfoVirtualDom), ...getAdditionalDetailsEntryVirtualDom(thirdHeading, categories, getCategoriesDom), ...getAdditionalDetailsEntryVirtualDom(fourthHeading, resources, getResourcesVirtualDom)];
4393
4521
  };
4394
4522
 
@@ -4731,8 +4859,13 @@ const render2 = (uid, diffResult) => {
4731
4859
  return commands;
4732
4860
  };
4733
4861
 
4862
+ // @ts-nocheck
4734
4863
  const renderEventListeners = () => {
4735
4864
  return [{
4865
+ name: HandleAdditionalDetailContextMenu,
4866
+ params: ['handleAdditionalDetailsContextMenu'],
4867
+ preventDefault: true
4868
+ }, {
4736
4869
  name: HandleClickCategory,
4737
4870
  params: ['handleClickCategory', TargetName]
4738
4871
  }, {
@@ -4816,6 +4949,7 @@ const commandMap = {
4816
4949
  'ExtensionDetail.getMenuEntries': getMenuEntries,
4817
4950
  'ExtensionDetail.getMenus': getMenus,
4818
4951
  'ExtensionDetail.handleClickCategory': wrapCommand(handleClickCategory),
4952
+ 'ExtensionDetail.handleAdditionalDetailsContextMenu': wrapCommand(handleAdditionalDetailContextMenu),
4819
4953
  'ExtensionDetail.handleClickDisable': wrapCommand(handleClickDisable),
4820
4954
  'ExtensionDetail.handleClickEnable': wrapCommand(handleClickEnable),
4821
4955
  'ExtensionDetail.handleClickScrollToTop': wrapCommand(handleClickScrollToTop),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/extension-detail-view",
3
- "version": "4.4.0",
3
+ "version": "4.6.0",
4
4
  "description": "Extension Detail View Worker",
5
5
  "repository": {
6
6
  "type": "git",