@lvce-editor/extension-detail-view 3.2.0 → 3.4.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.
@@ -430,10 +430,10 @@ const create$4 = (method, params) => {
430
430
  };
431
431
  };
432
432
  const callbacks = Object.create(null);
433
- const set$1 = (id, fn) => {
433
+ const set$2 = (id, fn) => {
434
434
  callbacks[id] = fn;
435
435
  };
436
- const get$1 = id => {
436
+ const get$2 = id => {
437
437
  return callbacks[id];
438
438
  };
439
439
  const remove = id => {
@@ -449,13 +449,13 @@ const registerPromise = () => {
449
449
  resolve,
450
450
  promise
451
451
  } = Promise.withResolvers();
452
- set$1(id, resolve);
452
+ set$2(id, resolve);
453
453
  return {
454
454
  id,
455
455
  promise
456
456
  };
457
457
  };
458
- const create$2 = (method, params) => {
458
+ const create$2$1 = (method, params) => {
459
459
  const {
460
460
  id,
461
461
  promise
@@ -606,7 +606,7 @@ const warn = (...args) => {
606
606
  console.warn(...args);
607
607
  };
608
608
  const resolve = (id, response) => {
609
- const fn = get$1(id);
609
+ const fn = get$2(id);
610
610
  if (!fn) {
611
611
  console.log(response);
612
612
  warn(`callback ${id} may already be disposed`);
@@ -645,7 +645,7 @@ const getErrorProperty = (error, prettyError) => {
645
645
  }
646
646
  };
647
647
  };
648
- const create$1 = (message, error) => {
648
+ const create$1$1 = (message, error) => {
649
649
  return {
650
650
  jsonrpc: Two,
651
651
  id: message.id,
@@ -656,7 +656,7 @@ const getErrorResponse = (message, error, preparePrettyError, logError) => {
656
656
  const prettyError = preparePrettyError(error);
657
657
  logError(error, prettyError);
658
658
  const errorProperty = getErrorProperty(error, prettyError);
659
- return create$1(message, errorProperty);
659
+ return create$1$1(message, errorProperty);
660
660
  };
661
661
  const create$5 = (message, result) => {
662
662
  return {
@@ -747,7 +747,7 @@ const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
747
747
  const {
748
748
  message,
749
749
  promise
750
- } = create$2(method, params);
750
+ } = create$2$1(method, params);
751
751
  if (useSendAndTransfer && ipc.sendAndTransfer) {
752
752
  ipc.sendAndTransfer(message);
753
753
  } else {
@@ -831,7 +831,7 @@ const listen$1 = async (module, options) => {
831
831
  const ipc = module.wrap(rawIpc);
832
832
  return ipc;
833
833
  };
834
- const create = async ({
834
+ const create$2 = async ({
835
835
  commandMap
836
836
  }) => {
837
837
  // TODO create a commandMap per rpc instance
@@ -843,21 +843,78 @@ const create = async ({
843
843
  };
844
844
  const WebWorkerRpcClient = {
845
845
  __proto__: null,
846
- create
846
+ create: create$2
847
847
  };
848
848
 
849
+ const create$1 = () => {
850
+ const states = Object.create(null);
851
+ return {
852
+ get(uid) {
853
+ return states[uid];
854
+ },
855
+ set(uid, oldState, newState) {
856
+ states[uid] = {
857
+ oldState,
858
+ newState
859
+ };
860
+ }
861
+ };
862
+ };
863
+
864
+ const {
865
+ get: get$1,
866
+ set: set$1
867
+ } = create$1();
868
+
869
+ const create = (uid, uri, width, height, platform) => {
870
+ const state = {
871
+ description: '',
872
+ iconSrc: '',
873
+ selectedFeature: '',
874
+ name: '',
875
+ sanitizedReadmeHtml: '',
876
+ selectedTab: '',
877
+ size: 0,
878
+ width,
879
+ uri,
880
+ entries: [],
881
+ secondEntries: [],
882
+ categories: [],
883
+ resources: [],
884
+ selectedFeatureMarkdownDom: '',
885
+ extension: {},
886
+ baseUrl: ''
887
+ };
888
+ set$1(uid, state, state);
889
+ };
890
+
891
+ const AdditionalDetails = 'AdditionalDetails';
892
+ const AdditionalDetailsEntry = 'AdditionalDetailsEntry';
893
+ const AdditionalDetailsTitle = 'AdditionalDetailsTitle';
894
+ const Aside$2 = 'Aside';
895
+ const Categories = 'Categories';
896
+ const Category = 'Category';
897
+ const Changelog$1 = 'Changelog';
849
898
  const ExtensionDetail = 'ExtensionDetail';
850
899
  const ExtensionDetailDescription = 'ExtensionDetailDescription';
851
900
  const ExtensionDetailHeader = 'ExtensionDetailHeader';
852
901
  const ExtensionDetailHeaderDetails = 'ExtensionDetailHeaderDetails';
853
- const Changelog$1 = 'Changelog';
854
- const Features$1 = 'Features';
855
902
  const ExtensionDetailIcon = 'ExtensionDetailIcon';
856
903
  const ExtensionDetailName = 'ExtensionDetailName';
904
+ const ExtensionDetailPanel = 'ExtensionDetailPanel';
857
905
  const ExtensionDetailTab = 'ExtensionDetailTab';
858
906
  const ExtensionDetailTabs = 'ExtensionDetailTabs';
859
907
  const ExtensionDetailTabSelected = 'ExtensionDetailTabSelected';
908
+ const Feature = 'Feature';
909
+ const Features$1 = 'Features';
910
+ const FeaturesList = 'FeaturesList';
860
911
  const Markdown = 'Markdown';
912
+ const MoreInfo = 'MoreInfo';
913
+ const MoreInfoEntry = 'MoreInfoEntry';
914
+ const MoreInfoEntryKey = 'MoreInfoEntryKey';
915
+ const MoreInfoEntryValue = 'MoreInfoEntryValue';
916
+ const Resource = 'Resource';
917
+ const Resources = 'Resources';
861
918
  const Viewlet = 'Viewlet';
862
919
 
863
920
  const Button = 1;
@@ -914,10 +971,118 @@ const getChangelogVirtualDom = () => {
914
971
  const Document = 'document';
915
972
  const TabList = 'tablist';
916
973
  const Tab = 'tab';
974
+ const Panel = 'panel';
917
975
 
918
976
  const HandleReadmeContextMenu = 'handleReadmeContextMenu';
919
977
  const HandleTabsClick = 'handleTabsClick';
920
978
 
979
+ const getCategoryVirtualDom = category => {
980
+ const {
981
+ label
982
+ } = category;
983
+ return [{
984
+ type: Div$1,
985
+ className: Category,
986
+ childCount: 1
987
+ }, text(label)];
988
+ };
989
+
990
+ const getCategoriesDom = categories => {
991
+ return [{
992
+ type: Div$1,
993
+ className: Categories,
994
+ childCount: categories.length
995
+ }, ...categories.flatMap(getCategoryVirtualDom)];
996
+ };
997
+
998
+ const getMoreInfoEntryVirtualDom = item => {
999
+ const {
1000
+ key,
1001
+ value
1002
+ } = item;
1003
+ return [{
1004
+ type: Div$1,
1005
+ className: MoreInfoEntry,
1006
+ childCount: 2
1007
+ }, {
1008
+ type: Div$1,
1009
+ className: MoreInfoEntryKey,
1010
+ childCount: 1
1011
+ }, text(key), {
1012
+ type: Div$1,
1013
+ className: MoreInfoEntryValue,
1014
+ childCount: 1
1015
+ }, text(value)];
1016
+ };
1017
+
1018
+ const getMoreInfoVirtualDom = items => {
1019
+ return [{
1020
+ type: Div$1,
1021
+ className: MoreInfo,
1022
+ childCount: items.length
1023
+ }, ...items.flatMap(getMoreInfoEntryVirtualDom)];
1024
+ };
1025
+
1026
+ const getResourceVirtualDom = resource => {
1027
+ const {
1028
+ label
1029
+ } = resource;
1030
+ return [{
1031
+ // TODO use link with url
1032
+ type: Div$1,
1033
+ className: Resource,
1034
+ childCount: 1
1035
+ }, text(label)];
1036
+ };
1037
+
1038
+ const getResourcesVirtualDom = resources => {
1039
+ return [{
1040
+ type: Div$1,
1041
+ className: Resources,
1042
+ childCount: resources.length
1043
+ }, ...resources.flatMap(getResourceVirtualDom)];
1044
+ };
1045
+
1046
+ const getAdditionalDetailsVirtualDom = (firstHeading, entries, secondHeading, secondEntries, thirdHeading, categories, fourthHeading, resources) => {
1047
+ return [{
1048
+ type: Div$1,
1049
+ className: AdditionalDetails,
1050
+ childCount: 4
1051
+ }, {
1052
+ type: Div$1,
1053
+ className: AdditionalDetailsEntry,
1054
+ childCount: 2
1055
+ }, {
1056
+ type: Div$1,
1057
+ className: AdditionalDetailsTitle,
1058
+ childCount: 1
1059
+ }, text(firstHeading), ...getMoreInfoVirtualDom(entries), {
1060
+ type: Div$1,
1061
+ className: AdditionalDetailsEntry,
1062
+ childCount: 2
1063
+ }, {
1064
+ type: Div$1,
1065
+ className: AdditionalDetailsTitle,
1066
+ childCount: 1
1067
+ }, text(secondHeading), ...getMoreInfoVirtualDom(secondEntries), {
1068
+ type: Div$1,
1069
+ className: AdditionalDetailsEntry,
1070
+ childCount: 2
1071
+ }, {
1072
+ type: Div$1,
1073
+ className: AdditionalDetailsTitle,
1074
+ childCount: 1
1075
+ }, text(thirdHeading), ...getCategoriesDom(categories), {
1076
+ type: Div$1,
1077
+ className: AdditionalDetailsEntry,
1078
+ childCount: 2
1079
+ }, {
1080
+ type: Div$1,
1081
+ className: AdditionalDetailsTitle,
1082
+ childCount: 1
1083
+ }, text(fourthHeading), ...getResourcesVirtualDom(resources)];
1084
+ };
1085
+
921
1086
  const allowedMarkdownAttributes = ['src', 'id', 'className', 'title', 'alt', 'href', 'target', 'rel'];
922
1087
 
923
1088
  const Div = 'div';
@@ -1383,35 +1548,128 @@ const getVirtualDomChildCount = markdownDom => {
1383
1548
  const getDetailsVirtualDom = sanitizedReadmeHtml => {
1384
1549
  const markdownDom = getMarkdownVirtualDom(sanitizedReadmeHtml);
1385
1550
  const childCount = getVirtualDomChildCount(markdownDom);
1551
+ const firstHeading = 'Installation';
1552
+ const entries = [{
1553
+ key: 'Identifier',
1554
+ value: 'abc'
1555
+ }, {
1556
+ key: 'Version',
1557
+ value: '1.9.5'
1558
+ }, {
1559
+ key: 'Last Updated',
1560
+ value: 'n/a'
1561
+ }];
1562
+ const secondHeading = 'Marketplace';
1563
+ const secondEntries = [{
1564
+ key: 'Published',
1565
+ value: 'n/a'
1566
+ }, {
1567
+ key: 'Last Released',
1568
+ value: 'n/a'
1569
+ }];
1570
+ const thirdHeading = 'Categories';
1571
+ const categories = [{
1572
+ id: 'themes',
1573
+ label: 'Themes'
1574
+ }];
1575
+ const fourthHeading = 'Resources';
1576
+ const resources = [{
1577
+ label: 'Marketplace',
1578
+ url: '#'
1579
+ }, {
1580
+ label: 'Issues',
1581
+ url: '#'
1582
+ }, {
1583
+ label: 'Repository',
1584
+ url: '#'
1585
+ }, {
1586
+ label: 'License',
1587
+ url: '#'
1588
+ }];
1386
1589
  const dom = [{
1590
+ type: Div$1,
1591
+ className: ExtensionDetailPanel,
1592
+ childCount: 2,
1593
+ role: Panel
1594
+ }, {
1387
1595
  type: Div$1,
1388
1596
  className: Markdown,
1389
1597
  role: Document,
1390
1598
  onContextMenu: HandleReadmeContextMenu,
1391
1599
  childCount
1392
- }, ...markdownDom];
1600
+ }, ...markdownDom, {
1601
+ type: Div$1,
1602
+ className: Aside$2,
1603
+ childCount: 1
1604
+ }, ...getAdditionalDetailsVirtualDom(firstHeading, entries, secondHeading, secondEntries, thirdHeading, categories, fourthHeading, resources)];
1393
1605
  return dom;
1394
1606
  };
1395
1607
 
1396
- const getFeaturesVirtualDom = () => {
1397
- // TODO set tabpanel role
1608
+ const getFeatureListItemVirtualDom = feature => {
1609
+ const {
1610
+ label
1611
+ } = feature;
1398
1612
  return [{
1613
+ // TODO use role list item or tab
1399
1614
  type: Div$1,
1400
- className: Features$1,
1615
+ className: Feature,
1401
1616
  childCount: 1
1402
- }, text('Not Implemented')];
1617
+ }, text(label)];
1618
+ };
1619
+
1620
+ const getFeatureListVirtualDom = features => {
1621
+ return [{
1622
+ // TODO use either list or tabs role
1623
+ type: Div$1,
1624
+ className: FeaturesList,
1625
+ childCount: features.length
1626
+ }, ...features.flatMap(getFeatureListItemVirtualDom)];
1627
+ };
1628
+
1629
+ const getFeatureThemesVirtualDom = themesHtml => {
1630
+ const markdownDom = getMarkdownVirtualDom(themesHtml);
1631
+ const childCount = getVirtualDomChildCount(markdownDom);
1632
+ const heading = 'Themes';
1633
+ return [{
1634
+ type: Div$1,
1635
+ className: 'FeatureTheme',
1636
+ childCount: 2
1637
+ }, {
1638
+ type: H1$1,
1639
+ childCount: 1
1640
+ }, text(heading), {
1641
+ type: Div$1,
1642
+ className: 'DefaultMarkdown',
1643
+ childCount
1644
+ }, ...markdownDom];
1645
+ };
1646
+
1647
+ const getFeaturesVirtualDom = themesHtml => {
1648
+ const features = [{
1649
+ id: 'theme',
1650
+ label: 'Theme'
1651
+ }];
1652
+ return [{
1653
+ type: Div$1,
1654
+ className: Features$1,
1655
+ childCount: 3
1656
+ }, ...getFeatureListVirtualDom(features), {
1657
+ type: Div$1,
1658
+ className: 'Sash SashVertical',
1659
+ childCount: 0
1660
+ }, ...getFeatureThemesVirtualDom(themesHtml)];
1403
1661
  };
1404
1662
 
1405
1663
  const Details = 'Details';
1406
1664
  const Features = 'Features';
1407
1665
  const Changelog = 'Changelog';
1408
1666
 
1409
- const getExtensionDetailContentVirtualDom = (sanitizedReadmeHtml, selectedTab) => {
1667
+ const getExtensionDetailContentVirtualDom = (sanitizedReadmeHtml, themesHtml, selectedTab) => {
1410
1668
  switch (selectedTab) {
1411
1669
  case Details:
1412
1670
  return getDetailsVirtualDom(sanitizedReadmeHtml);
1413
1671
  case Features:
1414
- return getFeaturesVirtualDom();
1672
+ return getFeaturesVirtualDom(themesHtml);
1415
1673
  case Changelog:
1416
1674
  return getChangelogVirtualDom();
1417
1675
  default:
@@ -1477,20 +1735,24 @@ const mergeClassNames = (...classNames) => {
1477
1735
  return joinBySpace(...classNames.filter(Boolean));
1478
1736
  };
1479
1737
 
1738
+ const selectedClassName = mergeClassNames(ExtensionDetailTab, ExtensionDetailTabSelected);
1739
+ const defaultClassName = ExtensionDetailTab;
1480
1740
  const getTabVirtualDom = tab => {
1481
1741
  const {
1482
1742
  label,
1483
1743
  selected,
1484
1744
  name
1485
1745
  } = tab;
1486
- const className = selected ? mergeClassNames(ExtensionDetailTab, ExtensionDetailTabSelected) : ExtensionDetailTab;
1746
+ const className = selected ? selectedClassName : defaultClassName;
1747
+ const ariaSelected = selected ? 'true' : 'false';
1487
1748
  return [{
1488
1749
  type: Button,
1489
1750
  role: Tab,
1490
1751
  name,
1491
1752
  className,
1492
1753
  childCount: 1,
1493
- tabIndex: -1
1754
+ tabIndex: -1,
1755
+ ariaSelected
1494
1756
  }, text(label)];
1495
1757
  };
1496
1758
 
@@ -1505,13 +1767,14 @@ const getTabsVirtualDom = tabs => {
1505
1767
  }, ...tabs.flatMap(getTabVirtualDom)];
1506
1768
  };
1507
1769
 
1508
- const getExtensionDetailVirtualDom = (extensionDetail, sanitizedReadmeHtml, selectedTab) => {
1770
+ const getExtensionDetailVirtualDom = (extensionDetail, sanitizedReadmeHtml, selectedTab, newState) => {
1771
+ const themesHtml = newState?.selectedFeatureMarkdownDom || '';
1509
1772
  const tabs = getTabs(selectedTab);
1510
1773
  const dom = [{
1511
1774
  type: Div$1,
1512
1775
  className: mergeClassNames(Viewlet, ExtensionDetail),
1513
1776
  childCount: 3
1514
- }, ...getExtensionDetailHeaderVirtualDom(extensionDetail), ...getTabsVirtualDom(tabs), ...getExtensionDetailContentVirtualDom(sanitizedReadmeHtml, selectedTab)];
1777
+ }, ...getExtensionDetailHeaderVirtualDom(extensionDetail), ...getTabsVirtualDom(tabs), ...getExtensionDetailContentVirtualDom(sanitizedReadmeHtml, themesHtml, selectedTab)];
1515
1778
  return dom;
1516
1779
  };
1517
1780
 
@@ -1607,142 +1870,52 @@ const handleIconError = state => {
1607
1870
  };
1608
1871
  };
1609
1872
 
1610
- const Web = 1;
1611
- const Electron = 2;
1612
- const Remote = 3;
1613
-
1614
- const isLanguageBasicsExtension = extension => {
1615
- return extension.name && extension.name.startsWith('Language Basics');
1616
- };
1617
- const isThemeExtension = extension => {
1618
- return extension.name && extension.name.endsWith(' Theme');
1619
- };
1620
- const getIcon = (extension, platform) => {
1621
- if (!extension) {
1622
- return ExtensionDefaultIcon;
1623
- }
1624
- if (!extension.path || !extension.icon) {
1625
- if (isLanguageBasicsExtension(extension)) {
1626
- return ExtensionLanguageBasics;
1627
- }
1628
- if (isThemeExtension(extension)) {
1629
- return ExtensionTheme;
1630
- }
1631
- return ExtensionDefaultIcon;
1632
- }
1633
- if (platform === Remote || platform === Electron) {
1634
- if (extension.builtin) {
1635
- return `${assetDir}/extensions/${extension.id}/${extension.icon}`;
1636
- }
1637
- return `/remote/${extension.path}/${extension.icon}`; // TODO support windows paths
1638
- }
1639
- return '';
1640
- };
1641
-
1642
- // TODO handle case when extension is of type number|array|null|string
1643
-
1644
- const getName = extension => {
1645
- if (extension && extension.name) {
1646
- return extension.name;
1647
- }
1648
- if (extension && extension.id) {
1649
- return extension.id;
1650
- }
1651
- return 'n/a';
1652
- };
1653
- const getDescription = extension => {
1654
- if (!extension || !extension.description) {
1655
- return 'n/a';
1656
- }
1657
- return extension.description;
1658
- };
1659
-
1660
- const RendererWorker = 1;
1661
-
1662
- const rpcs = Object.create(null);
1663
- const set = (id, rpc) => {
1664
- rpcs[id] = rpc;
1665
- };
1666
- const get = id => {
1667
- return rpcs[id];
1873
+ const selectTabChangelog = async state => {
1874
+ return {
1875
+ ...state,
1876
+ selectedTab: Changelog
1877
+ };
1668
1878
  };
1669
1879
 
1670
- const invoke = (method, ...params) => {
1671
- const rpc = get(RendererWorker);
1672
- return rpc.invoke(method, ...params);
1880
+ const selectTabDetails = async state => {
1881
+ // TODO load readmo markdown here
1882
+ return {
1883
+ ...state,
1884
+ selectedTab: Details
1885
+ };
1673
1886
  };
1674
1887
 
1675
- const getAllExtensions = async platform => {
1676
- if (platform === Web) {
1677
- return [];
1678
- }
1679
- return invoke('ExtensionManagement.getAllExtensions');
1680
- };
1681
- const getExtension = async (id, platform) => {
1682
- const allExtensions = await getAllExtensions(platform);
1683
- for (const extension of allExtensions) {
1684
- if (extension.id === id) {
1685
- return extension;
1888
+ const getThemeItemMarkdown = (heading, items) => {
1889
+ let markdown = '';
1890
+ if (items.length > 0) {
1891
+ markdown += `### ${heading}`;
1892
+ markdown += '\n\n';
1893
+ for (const item of items) {
1894
+ markdown += `- ${item.label}`;
1895
+ markdown += '\n';
1686
1896
  }
1687
1897
  }
1688
- return undefined;
1689
- };
1690
-
1691
- const getRemoteSrc = uri => {
1692
- const src = `/remote${uri}`;
1693
- return src;
1694
- };
1695
-
1696
- const getBaseUrl = (extensionPath, platform) => {
1697
- switch (platform) {
1698
- case Remote:
1699
- case Electron:
1700
- return getRemoteSrc(extensionPath + '/');
1701
- default:
1702
- return extensionPath;
1703
- }
1704
- };
1705
-
1706
- const Small = 1;
1707
- const Normal = 2;
1708
- const Large = 3;
1709
-
1710
- const getViewletSize = width => {
1711
- if (width < 180) {
1712
- return Small;
1713
- }
1714
- if (width < 768) {
1715
- return Normal;
1716
- }
1717
- return Large;
1898
+ return markdown;
1718
1899
  };
1719
1900
 
1720
- const readFile = async uri => {
1721
- return invoke('FileSystem.readFile', uri);
1901
+ const getColorThemeMarkdown = themes => {
1902
+ const heading = 'Color Themes';
1903
+ return getThemeItemMarkdown(heading, themes);
1722
1904
  };
1723
-
1724
- const ENOENT = 'ENOENT';
1725
-
1726
- const isEnoentError = error => {
1727
- return error && error.code === ENOENT;
1905
+ const getIconThemeMarkdown = iconThemes => {
1906
+ const heading = 'File Icon Themes';
1907
+ return getThemeItemMarkdown(heading, iconThemes);
1728
1908
  };
1729
-
1730
- const join = (pathSeparator, ...parts) => {
1731
- return parts.join(pathSeparator);
1909
+ const getProductIconThemeMarkdown = iconThemes => {
1910
+ const heading = 'Product Icon Themes';
1911
+ return getThemeItemMarkdown(heading, iconThemes);
1732
1912
  };
1733
-
1734
- const loadReadmeContent = async path => {
1735
- try {
1736
- const readmeUrl = join('/', path, 'README.md');
1737
- const readmeContent = await readFile(readmeUrl);
1738
- return readmeContent;
1739
- } catch (error) {
1740
- if (isEnoentError(error)) {
1741
- return '';
1742
- }
1743
- console.error(error);
1744
- return `${error}`;
1745
- }
1913
+ const getThemeMarkdown = (themes, iconThemes, productIconThemes) => {
1914
+ let markdown = '';
1915
+ markdown += getColorThemeMarkdown(themes);
1916
+ markdown += getIconThemeMarkdown(iconThemes);
1917
+ markdown += getProductIconThemeMarkdown(productIconThemes);
1918
+ return markdown;
1746
1919
  };
1747
1920
 
1748
1921
  /**
@@ -4234,7 +4407,196 @@ const renderMarkdown = async (markdown, options = {}) => {
4234
4407
  return html;
4235
4408
  };
4236
4409
 
4237
- const loadContent = async (state, platform) => {
4410
+ const selectTab$1 = async state => {
4411
+ const {
4412
+ extension,
4413
+ baseUrl
4414
+ } = state;
4415
+ const {
4416
+ colorThemes,
4417
+ iconThemes,
4418
+ productIconThemes
4419
+ } = extension;
4420
+ const markdown = getThemeMarkdown(colorThemes || [], iconThemes || [], productIconThemes || []);
4421
+ const rendered = await renderMarkdown(markdown, {
4422
+ baseUrl
4423
+ });
4424
+ return {
4425
+ ...state,
4426
+ selectedTab: Features,
4427
+ selectedFeatureMarkdownDom: rendered
4428
+ };
4429
+ };
4430
+
4431
+ const getSelectTabHandler = selectedTab => {
4432
+ switch (selectedTab) {
4433
+ case Details:
4434
+ return selectTabDetails;
4435
+ case Features:
4436
+ return selectTab$1;
4437
+ case Changelog:
4438
+ return selectTabChangelog;
4439
+ default:
4440
+ throw new Error(`unexpected tab`);
4441
+ }
4442
+ };
4443
+
4444
+ const selectTab = (state, name) => {
4445
+ const fn = getSelectTabHandler(name);
4446
+ return fn(state);
4447
+ };
4448
+
4449
+ const handleTabsClick = (state, name) => {
4450
+ return selectTab(state, name);
4451
+ };
4452
+
4453
+ const isLanguageBasicsExtension = extension => {
4454
+ return extension.name && extension.name.startsWith('Language Basics');
4455
+ };
4456
+
4457
+ const isThemeExtension = extension => {
4458
+ return extension.name && extension.name.endsWith(' Theme');
4459
+ };
4460
+
4461
+ const Web = 1;
4462
+ const Electron = 2;
4463
+ const Remote = 3;
4464
+
4465
+ const getIcon = (extension, platform) => {
4466
+ if (!extension) {
4467
+ return ExtensionDefaultIcon;
4468
+ }
4469
+ if (!extension.path || !extension.icon) {
4470
+ if (isLanguageBasicsExtension(extension)) {
4471
+ return ExtensionLanguageBasics;
4472
+ }
4473
+ if (isThemeExtension(extension)) {
4474
+ return ExtensionTheme;
4475
+ }
4476
+ return ExtensionDefaultIcon;
4477
+ }
4478
+ if (platform === Remote || platform === Electron) {
4479
+ if (extension.builtin) {
4480
+ return `${assetDir}/extensions/${extension.id}/${extension.icon}`;
4481
+ }
4482
+ return `/remote/${extension.path}/${extension.icon}`; // TODO support windows paths
4483
+ }
4484
+ return '';
4485
+ };
4486
+
4487
+ const getDescription = extension => {
4488
+ if (!extension || !extension.description) {
4489
+ return 'n/a';
4490
+ }
4491
+ return extension.description;
4492
+ };
4493
+
4494
+ const getName = extension => {
4495
+ if (extension && extension.name) {
4496
+ return extension.name;
4497
+ }
4498
+ if (extension && extension.id) {
4499
+ return extension.id;
4500
+ }
4501
+ return 'n/a';
4502
+ };
4503
+
4504
+ const RendererWorker = 1;
4505
+
4506
+ const rpcs = Object.create(null);
4507
+ const set = (id, rpc) => {
4508
+ rpcs[id] = rpc;
4509
+ };
4510
+ const get = id => {
4511
+ return rpcs[id];
4512
+ };
4513
+
4514
+ const invoke = (method, ...params) => {
4515
+ const rpc = get(RendererWorker);
4516
+ return rpc.invoke(method, ...params);
4517
+ };
4518
+
4519
+ const getAllExtensions = async platform => {
4520
+ if (platform === Web) {
4521
+ return [];
4522
+ }
4523
+ return invoke('ExtensionManagement.getAllExtensions');
4524
+ };
4525
+ const getExtension = async (id, platform) => {
4526
+ const allExtensions = await getAllExtensions(platform);
4527
+ for (const extension of allExtensions) {
4528
+ if (extension.id === id) {
4529
+ return extension;
4530
+ }
4531
+ }
4532
+ return undefined;
4533
+ };
4534
+
4535
+ const getRemoteSrc = uri => {
4536
+ const src = `/remote${uri}`;
4537
+ return src;
4538
+ };
4539
+
4540
+ const getBaseUrl = (extensionPath, platform) => {
4541
+ switch (platform) {
4542
+ case Remote:
4543
+ case Electron:
4544
+ return getRemoteSrc(extensionPath + '/');
4545
+ default:
4546
+ return extensionPath;
4547
+ }
4548
+ };
4549
+
4550
+ const getSavedSelectedTab = savedState => {
4551
+ if (savedState && typeof savedState === 'object' && 'selectedTab' in savedState && typeof savedState.selectedTab === 'string') {
4552
+ return savedState.selectedTab;
4553
+ }
4554
+ return Details;
4555
+ };
4556
+
4557
+ const Small = 1;
4558
+ const Normal = 2;
4559
+ const Large = 3;
4560
+
4561
+ const getViewletSize = width => {
4562
+ if (width < 180) {
4563
+ return Small;
4564
+ }
4565
+ if (width < 768) {
4566
+ return Normal;
4567
+ }
4568
+ return Large;
4569
+ };
4570
+
4571
+ const readFile = async uri => {
4572
+ return invoke('FileSystem.readFile', uri);
4573
+ };
4574
+
4575
+ const ENOENT = 'ENOENT';
4576
+
4577
+ const isEnoentError = error => {
4578
+ return error && error.code === ENOENT;
4579
+ };
4580
+
4581
+ const join = (pathSeparator, ...parts) => {
4582
+ return parts.join(pathSeparator);
4583
+ };
4584
+
4585
+ const loadReadmeContent = async path => {
4586
+ try {
4587
+ const readmeUrl = join('/', path, 'README.md');
4588
+ const readmeContent = await readFile(readmeUrl);
4589
+ return readmeContent;
4590
+ } catch (error) {
4591
+ if (isEnoentError(error)) {
4592
+ return '';
4593
+ }
4594
+ console.error(error);
4595
+ return `${error}`;
4596
+ }
4597
+ };
4598
+
4599
+ const loadContent = async (state, platform, savedState) => {
4238
4600
  const {
4239
4601
  uri,
4240
4602
  width
@@ -4242,7 +4604,6 @@ const loadContent = async (state, platform) => {
4242
4604
  const id = uri.slice('extension-detail://'.length);
4243
4605
  const extension = await getExtension(id, platform);
4244
4606
  const readmeContent = await loadReadmeContent(extension.path);
4245
- // @ts-ignore
4246
4607
  const baseUrl = getBaseUrl(extension.path, platform);
4247
4608
  const readmeHtml = await renderMarkdown(readmeContent, {
4248
4609
  baseUrl
@@ -4253,7 +4614,41 @@ const loadContent = async (state, platform) => {
4253
4614
  const description = getDescription(extension);
4254
4615
  const name = getName(extension);
4255
4616
  const size = getViewletSize(width);
4256
- const selectedTab = Details;
4617
+ const selectedTab = getSavedSelectedTab(savedState);
4618
+ const entries = [{
4619
+ key: 'Identifier',
4620
+ value: 'abc'
4621
+ }, {
4622
+ key: 'Version',
4623
+ value: '1.9.5'
4624
+ }, {
4625
+ key: 'Last Updated',
4626
+ value: 'n/a'
4627
+ }];
4628
+ const secondEntries = [{
4629
+ key: 'Published',
4630
+ value: 'n/a'
4631
+ }, {
4632
+ key: 'Last Released',
4633
+ value: 'n/a'
4634
+ }];
4635
+ const categories = [{
4636
+ id: 'themes',
4637
+ label: 'Themes'
4638
+ }];
4639
+ const resources = [{
4640
+ label: 'Marketplace',
4641
+ url: '#'
4642
+ }, {
4643
+ label: 'Issues',
4644
+ url: '#'
4645
+ }, {
4646
+ label: 'Repository',
4647
+ url: '#'
4648
+ }, {
4649
+ label: 'License',
4650
+ url: '#'
4651
+ }];
4257
4652
  return {
4258
4653
  ...state,
4259
4654
  selectedTab,
@@ -4261,15 +4656,22 @@ const loadContent = async (state, platform) => {
4261
4656
  iconSrc,
4262
4657
  name,
4263
4658
  description,
4264
- size
4659
+ size,
4660
+ entries,
4661
+ secondEntries,
4662
+ categories,
4663
+ resources,
4664
+ extension,
4665
+ baseUrl
4265
4666
  };
4266
4667
  };
4267
4668
 
4268
- const handleTabsClick = (state, name) => {
4269
- // TODO load the tabs content if needed
4669
+ const saveState = state => {
4670
+ const {
4671
+ selectedTab
4672
+ } = state;
4270
4673
  return {
4271
- ...state,
4272
- selectedTab: name
4674
+ selectedTab
4273
4675
  };
4274
4676
  };
4275
4677
 
@@ -4278,12 +4680,15 @@ const terminate = () => {
4278
4680
  };
4279
4681
 
4280
4682
  const commandMap = {
4683
+ 'ExtensionDetail.create': create,
4684
+ 'ExtensionDetail.saveState': saveState,
4281
4685
  'ExtensionDetail.getMenuEntries': getMenuEntries,
4282
4686
  'ExtensionDetail.getVirtualDom': getExtensionDetailVirtualDom,
4283
4687
  'ExtensionDetail.loadContent': loadContent,
4284
4688
  'ExtensionDetail.terminate': terminate,
4285
4689
  'ExtensionDetail.handleTabsClick': handleTabsClick,
4286
4690
  'ExtensionDetail.handleIconError': handleIconError,
4691
+ 'ExtensionDetail.selectTab': selectTab,
4287
4692
  // deprecated
4288
4693
  'HandleIconError.handleIconError': handleIconError,
4289
4694
  'RenderMarkdown.renderMarkdown': renderMarkdown
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@lvce-editor/extension-detail-view",
3
- "version": "3.2.0",
3
+ "version": "3.4.0",
4
4
  "description": "Extension Detail View Worker",
5
- "main": "dist/extensionDetailViewWorkerMain.js",
6
- "type": "module",
7
5
  "keywords": [],
6
+ "license": "MIT",
8
7
  "author": "Lvce Editor",
9
- "license": "MIT"
8
+ "type": "module",
9
+ "main": "dist/extensionDetailViewWorkerMain.js"
10
10
  }