@jsenv/core 39.3.3 → 39.3.5

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.
@@ -15032,6 +15032,8 @@ const jsenvPluginDirectoryReferenceEffect = (
15032
15032
  actionForDirectory = "copy";
15033
15033
  } else if (reference.type === "filesystem") {
15034
15034
  actionForDirectory = "copy";
15035
+ } else if (reference.type === "http_request") {
15036
+ actionForDirectory = "preserve";
15035
15037
  } else if (typeof directoryReferenceEffect === "string") {
15036
15038
  actionForDirectory = directoryReferenceEffect;
15037
15039
  } else if (typeof directoryReferenceEffect === "function") {
@@ -15049,7 +15051,9 @@ const jsenvPluginDirectoryReferenceEffect = (
15049
15051
  throw error;
15050
15052
  }
15051
15053
  if (actionForDirectory === "preserve") {
15052
- return `ignore:${reference.specifier}`;
15054
+ return reference.ownerUrlInfo.context.dev
15055
+ ? null
15056
+ : `ignore:${reference.specifier}`;
15053
15057
  }
15054
15058
  return null;
15055
15059
  },
@@ -17486,7 +17490,7 @@ const applyPackageSpecifierResolution = (specifier, resolutionContext) => {
17486
17490
  }
17487
17491
  const packageResolution = applyPackageResolve(specifier, resolutionContext);
17488
17492
  const search = new URL(specifier, "file:///").search;
17489
- if (search) {
17493
+ if (search && !new URL(packageResolution.url).search) {
17490
17494
  packageResolution.url = `${packageResolution.url}${search}`;
17491
17495
  }
17492
17496
  return packageResolution;
@@ -18408,6 +18412,11 @@ const jsenvPluginNodeEsmResolution = (resolutionConfig = {}) => {
18408
18412
  }
18409
18413
  },
18410
18414
  resolveReference: (reference) => {
18415
+ if (reference.specifier.startsWith("node_esm:")) {
18416
+ reference.specifier = reference.specifier.slice("node_esm:".length);
18417
+ const result = nodeEsmResolverDefault(reference);
18418
+ return result;
18419
+ }
18411
18420
  const urlType = urlTypeFromReference(reference);
18412
18421
  const resolver = resolvers[urlType];
18413
18422
  return resolver ? resolver(reference) : null;
@@ -18434,7 +18443,6 @@ const urlTypeFromReference = (reference) => {
18434
18443
  if (reference.injected) {
18435
18444
  return reference.expectedType;
18436
18445
  }
18437
-
18438
18446
  return reference.ownerUrlInfo.type;
18439
18447
  };
18440
18448
 
@@ -18600,15 +18608,14 @@ const resolveSymlink = (fileUrl) => {
18600
18608
  return realUrlObject.href;
18601
18609
  };
18602
18610
 
18603
- const html404AndParentDirIsEmptyFileUrl = new URL(
18604
- "./html/html_404_and_parent_dir_is_empty.html",
18605
- import.meta.url,
18606
- );
18607
18611
  const html404AndParentDirFileUrl = new URL(
18608
18612
  "./html/html_404_and_parent_dir.html",
18609
18613
  import.meta.url,
18610
18614
  );
18611
- const htmlFileUrlForDirectory = new URL("./html/directory.html", import.meta.url);
18615
+ const htmlFileUrlForDirectory = new URL(
18616
+ "./html/directory.html",
18617
+ import.meta.url,
18618
+ );
18612
18619
 
18613
18620
  const jsenvPluginProtocolFile = ({
18614
18621
  magicExtensions,
@@ -18685,12 +18692,14 @@ const jsenvPluginProtocolFile = ({
18685
18692
  ? pickContentType(urlInfo.context.request, ["text/html"])
18686
18693
  : false;
18687
18694
  if (acceptsHtml) {
18695
+ firstReference.expectedType = "html";
18688
18696
  const html = generateHtmlForDirectory(
18689
18697
  urlObject.href,
18690
18698
  directoryContentArray,
18691
18699
  urlInfo.context.rootDirectoryUrl,
18692
18700
  );
18693
18701
  return {
18702
+ type: "html",
18694
18703
  contentType: "text/html",
18695
18704
  content: html,
18696
18705
  };
@@ -18731,6 +18740,9 @@ const jsenvPluginProtocolFile = ({
18731
18740
  return {
18732
18741
  contentType: "text/html",
18733
18742
  content: html,
18743
+ headers: {
18744
+ "cache-control": "no-cache",
18745
+ },
18734
18746
  };
18735
18747
  }
18736
18748
  }
@@ -18754,10 +18766,13 @@ const generateHtmlForDirectory = (
18754
18766
  rootDirectoryUrl,
18755
18767
  ) => {
18756
18768
  directoryUrl = assertAndNormalizeDirectoryUrl(directoryUrl);
18769
+
18757
18770
  const htmlForDirectory = String(readFileSync(htmlFileUrlForDirectory));
18771
+ const directoryRelativeUrl = urlToRelativeUrl(directoryUrl, rootDirectoryUrl);
18758
18772
  const replacers = {
18759
- directoryRelativeUrl: urlToRelativeUrl(directoryUrl, rootDirectoryUrl),
18760
18773
  directoryUrl,
18774
+ directoryNav: () =>
18775
+ generateDirectoryNav(directoryRelativeUrl, rootDirectoryUrl),
18761
18776
  directoryContent: () =>
18762
18777
  generateDirectoryContent(
18763
18778
  directoryContentArray,
@@ -18774,30 +18789,21 @@ const generateHtmlForENOENTOnHtmlFile = (
18774
18789
  parentDirectoryUrl,
18775
18790
  rootDirectoryUrl,
18776
18791
  ) => {
18777
- if (parentDirectoryContentArray.length === 0) {
18778
- const htmlFor404AndParentDirIsEmpty = String(
18779
- readFileSync(html404AndParentDirIsEmptyFileUrl),
18780
- );
18781
- return replacePlaceholders$1(htmlFor404AndParentDirIsEmpty, {
18782
- fileRelativeUrl: urlToRelativeUrl(url, rootDirectoryUrl),
18783
- parentDirectoryRelativeUrl: urlToRelativeUrl(
18784
- parentDirectoryUrl,
18785
- rootDirectoryUrl,
18786
- ),
18787
- });
18788
- }
18789
18792
  const htmlFor404AndParentDir = String(
18790
18793
  readFileSync(html404AndParentDirFileUrl),
18791
18794
  );
18792
-
18795
+ const fileRelativeUrl = urlToRelativeUrl(url, rootDirectoryUrl);
18796
+ const parentDirectoryRelativeUrl = urlToRelativeUrl(
18797
+ parentDirectoryUrl,
18798
+ rootDirectoryUrl,
18799
+ );
18793
18800
  const replacers = {
18794
18801
  fileUrl: url,
18795
- fileRelativeUrl: urlToRelativeUrl(url, rootDirectoryUrl),
18802
+ fileRelativeUrl,
18796
18803
  parentDirectoryUrl,
18797
- parentDirectoryRelativeUrl: urlToRelativeUrl(
18798
- parentDirectoryUrl,
18799
- rootDirectoryUrl,
18800
- ),
18804
+ parentDirectoryRelativeUrl,
18805
+ parentDirectoryNav: () =>
18806
+ generateDirectoryNav(parentDirectoryRelativeUrl, rootDirectoryUrl),
18801
18807
  parentDirectoryContent: () =>
18802
18808
  generateDirectoryContent(
18803
18809
  parentDirectoryContentArray,
@@ -18808,11 +18814,51 @@ const generateHtmlForENOENTOnHtmlFile = (
18808
18814
  const html = replacePlaceholders$1(htmlFor404AndParentDir, replacers);
18809
18815
  return html;
18810
18816
  };
18817
+ const generateDirectoryNav = (relativeUrl, rootDirectoryUrl) => {
18818
+ const rootDirectoryUrlName = urlToFilename$1(rootDirectoryUrl);
18819
+ const relativeUrlWithRoot = relativeUrl
18820
+ ? `${rootDirectoryUrlName}/${relativeUrl}`
18821
+ : `${rootDirectoryUrlName}/`;
18822
+ const isDir = relativeUrlWithRoot.endsWith("/");
18823
+ const parts = isDir
18824
+ ? relativeUrlWithRoot.slice(0, -1).split("/")
18825
+ : relativeUrlWithRoot.split("/");
18826
+ let dirPartsHtml = "";
18827
+ let i = 0;
18828
+ while (i < parts.length) {
18829
+ const part = parts[i];
18830
+ const href = i === 0 ? "/" : `/${parts.slice(1, i + 1).join("/")}/`;
18831
+ const text = part;
18832
+ const isLastPart = i === parts.length - 1;
18833
+ if (isLastPart) {
18834
+ dirPartsHtml += `
18835
+ <span class="directory_nav_item" data-current>
18836
+ ${text}
18837
+ </span>`;
18838
+ break;
18839
+ }
18840
+ dirPartsHtml += `
18841
+ <a class="directory_nav_item" href="${href}">
18842
+ ${text}
18843
+ </a>`;
18844
+ dirPartsHtml += `
18845
+ <span class="directory_separator">/</span>`;
18846
+ i++;
18847
+ }
18848
+ if (isDir) {
18849
+ dirPartsHtml += `
18850
+ <span class="directory_separator">/</span>`;
18851
+ }
18852
+ return dirPartsHtml;
18853
+ };
18811
18854
  const generateDirectoryContent = (
18812
18855
  directoryContentArray,
18813
18856
  directoryUrl,
18814
18857
  rootDirectoryUrl,
18815
18858
  ) => {
18859
+ if (directoryContentArray.length === 0) {
18860
+ return `<p>Directory is empty</p>`;
18861
+ }
18816
18862
  const sortedNames = [];
18817
18863
  for (const filename of directoryContentArray) {
18818
18864
  const fileUrlObject = new URL(filename, directoryUrl);
@@ -18823,15 +18869,20 @@ const generateDirectoryContent = (
18823
18869
  }
18824
18870
  }
18825
18871
  sortedNames.sort(comparePathnames);
18826
- return sortedNames.map((filename) => {
18872
+ let html = `<ul class="directory_content">`;
18873
+ for (const filename of sortedNames) {
18827
18874
  const fileUrlObject = new URL(filename, directoryUrl);
18828
18875
  const fileUrl = String(fileUrlObject);
18829
- let fileUrlRelative = urlToRelativeUrl(fileUrl, rootDirectoryUrl);
18830
- return `<li>
18831
- <a href="/${fileUrlRelative}">/${fileUrlRelative}</a>
18832
- </li>`;
18833
- }).join(`
18834
- `);
18876
+ const fileUrlRelativeToParent = urlToRelativeUrl(fileUrl, directoryUrl);
18877
+ const fileUrlRelativeToRoot = urlToRelativeUrl(fileUrl, rootDirectoryUrl);
18878
+ const type = fileUrlRelativeToParent.endsWith("/") ? "dir" : "file";
18879
+ html += `
18880
+ <li class="directory_child" data-type="${type}">
18881
+ <a href="/${fileUrlRelativeToRoot}">${fileUrlRelativeToParent}</a>
18882
+ </li>`;
18883
+ }
18884
+ html += `\n </ul>`;
18885
+ return html;
18835
18886
  };
18836
18887
  const replacePlaceholders$1 = (html, replacers) => {
18837
18888
  return html.replace(/\$\{(\w+)\}/g, (match, name) => {
@@ -20646,9 +20697,14 @@ const createBuildSpecifierManager = ({
20646
20697
 
20647
20698
  let buildSpecifier;
20648
20699
  if (base === "./") {
20649
- const parentBuildUrl = reference.ownerUrlInfo.isRoot
20700
+ const { ownerUrlInfo } = reference;
20701
+ const parentBuildUrl = ownerUrlInfo.isRoot
20650
20702
  ? buildDirectoryUrl
20651
- : urlInfoToBuildUrlMap.get(reference.ownerUrlInfo);
20703
+ : urlInfoToBuildUrlMap.get(
20704
+ ownerUrlInfo.isInline
20705
+ ? ownerUrlInfo.findParentIfInline()
20706
+ : ownerUrlInfo,
20707
+ );
20652
20708
  const urlRelativeToParent = urlToRelativeUrl(buildUrl, parentBuildUrl);
20653
20709
  if (urlRelativeToParent[0] === ".") {
20654
20710
  buildSpecifier = urlRelativeToParent;
@@ -21975,7 +22031,7 @@ const build = async ({
21975
22031
  process.env.CAPTURING_SIDE_EFFECTS ||
21976
22032
  urlIsInsideOf(sourceDirectoryUrl, jsenvCoreDirectoryUrl)
21977
22033
  ) {
21978
- outDirectoryUrl = new URL("../.jsenv/", sourceDirectoryUrl);
22034
+ outDirectoryUrl = new URL("../.jsenv_b/", sourceDirectoryUrl);
21979
22035
  } else {
21980
22036
  const packageDirectoryUrl = lookupPackageDirectory(sourceDirectoryUrl);
21981
22037
  if (packageDirectoryUrl) {
@@ -22291,9 +22347,23 @@ build ${entryPointKeys.length} entry points`);
22291
22347
  addToBundlerIfAny(rawUrlInfo);
22292
22348
  }
22293
22349
  if (rawUrlInfo.type === "html") {
22294
- rawUrlInfo.referenceToOthersSet.forEach((referenceToOther) => {
22350
+ for (const referenceToOther of rawUrlInfo.referenceToOthersSet) {
22351
+ if (
22352
+ referenceToOther.isResourceHint &&
22353
+ referenceToOther.expectedType === "js_module"
22354
+ ) {
22355
+ const referencedUrlInfo = referenceToOther.urlInfo;
22356
+ if (
22357
+ referencedUrlInfo &&
22358
+ // something else than the resource hint is using this url
22359
+ referencedUrlInfo.referenceFromOthersSet.size > 0
22360
+ ) {
22361
+ addToBundlerIfAny(referencedUrlInfo);
22362
+ continue;
22363
+ }
22364
+ }
22295
22365
  if (referenceToOther.isWeak) {
22296
- return;
22366
+ continue;
22297
22367
  }
22298
22368
  const referencedUrlInfo = referenceToOther.urlInfo;
22299
22369
  if (referencedUrlInfo.isInline) {
@@ -22309,50 +22379,38 @@ build ${entryPointKeys.length} entry points`);
22309
22379
  );
22310
22380
  }
22311
22381
  // inline content cannot be bundled
22312
- return;
22382
+ continue;
22313
22383
  }
22314
22384
  addToBundlerIfAny(referencedUrlInfo);
22315
- });
22316
- rawUrlInfo.referenceToOthersSet.forEach((referenceToOther) => {
22317
- if (
22318
- referenceToOther.isResourceHint &&
22319
- referenceToOther.expectedType === "js_module"
22320
- ) {
22321
- const referencedUrlInfo = referenceToOther.urlInfo;
22322
- if (
22323
- referencedUrlInfo &&
22324
- // something else than the resource hint is using this url
22325
- referencedUrlInfo.referenceFromOthersSet.size > 0
22326
- ) {
22327
- addToBundlerIfAny(referencedUrlInfo);
22328
- }
22329
- }
22330
- });
22385
+ }
22331
22386
  return;
22332
22387
  }
22333
22388
  // File referenced with new URL('./file.js', import.meta.url)
22334
22389
  // are entry points that should be bundled
22335
22390
  // For instance we will bundle service worker/workers detected like this
22336
22391
  if (rawUrlInfo.type === "js_module") {
22337
- rawUrlInfo.referenceToOthersSet.forEach((referenceToOther) => {
22392
+ for (const referenceToOther of rawUrlInfo.referenceToOthersSet) {
22338
22393
  if (referenceToOther.type === "js_url") {
22339
22394
  const referencedUrlInfo = referenceToOther.urlInfo;
22395
+ let isAlreadyBundled = false;
22340
22396
  for (const referenceFromOther of referencedUrlInfo.referenceFromOthersSet) {
22341
22397
  if (referenceFromOther.url === referencedUrlInfo.url) {
22342
22398
  if (
22343
22399
  referenceFromOther.subtype === "import_dynamic" ||
22344
22400
  referenceFromOther.type === "script"
22345
22401
  ) {
22346
- // will already be bundled
22347
- return;
22402
+ isAlreadyBundled = true;
22403
+ break;
22348
22404
  }
22349
22405
  }
22350
22406
  }
22351
- addToBundlerIfAny(referencedUrlInfo);
22352
- return;
22407
+ if (!isAlreadyBundled) {
22408
+ addToBundlerIfAny(referencedUrlInfo);
22409
+ }
22410
+ continue;
22353
22411
  }
22354
22412
  if (referenceToOther.type === "js_inline_content") ;
22355
- });
22413
+ }
22356
22414
  }
22357
22415
  },
22358
22416
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "39.3.3",
3
+ "version": "39.3.5",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -74,7 +74,7 @@
74
74
  "@jsenv/importmap": "1.2.1",
75
75
  "@jsenv/integrity": "0.0.2",
76
76
  "@jsenv/js-module-fallback": "1.3.37",
77
- "@jsenv/node-esm-resolution": "1.0.2",
77
+ "@jsenv/node-esm-resolution": "1.0.5",
78
78
  "@jsenv/plugin-bundling": "2.7.7",
79
79
  "@jsenv/plugin-minification": "1.5.5",
80
80
  "@jsenv/plugin-supervisor": "1.5.18",
@@ -154,7 +154,7 @@ export const build = async ({
154
154
  process.env.CAPTURING_SIDE_EFFECTS ||
155
155
  urlIsInsideOf(sourceDirectoryUrl, jsenvCoreDirectoryUrl)
156
156
  ) {
157
- outDirectoryUrl = new URL("../.jsenv/", sourceDirectoryUrl);
157
+ outDirectoryUrl = new URL("../.jsenv_b/", sourceDirectoryUrl);
158
158
  } else {
159
159
  const packageDirectoryUrl = lookupPackageDirectory(sourceDirectoryUrl);
160
160
  if (packageDirectoryUrl) {
@@ -470,9 +470,23 @@ build ${entryPointKeys.length} entry points`);
470
470
  addToBundlerIfAny(rawUrlInfo);
471
471
  }
472
472
  if (rawUrlInfo.type === "html") {
473
- rawUrlInfo.referenceToOthersSet.forEach((referenceToOther) => {
473
+ for (const referenceToOther of rawUrlInfo.referenceToOthersSet) {
474
+ if (
475
+ referenceToOther.isResourceHint &&
476
+ referenceToOther.expectedType === "js_module"
477
+ ) {
478
+ const referencedUrlInfo = referenceToOther.urlInfo;
479
+ if (
480
+ referencedUrlInfo &&
481
+ // something else than the resource hint is using this url
482
+ referencedUrlInfo.referenceFromOthersSet.size > 0
483
+ ) {
484
+ addToBundlerIfAny(referencedUrlInfo);
485
+ continue;
486
+ }
487
+ }
474
488
  if (referenceToOther.isWeak) {
475
- return;
489
+ continue;
476
490
  }
477
491
  const referencedUrlInfo = referenceToOther.urlInfo;
478
492
  if (referencedUrlInfo.isInline) {
@@ -488,52 +502,40 @@ build ${entryPointKeys.length} entry points`);
488
502
  );
489
503
  }
490
504
  // inline content cannot be bundled
491
- return;
505
+ continue;
492
506
  }
493
507
  addToBundlerIfAny(referencedUrlInfo);
494
- });
495
- rawUrlInfo.referenceToOthersSet.forEach((referenceToOther) => {
496
- if (
497
- referenceToOther.isResourceHint &&
498
- referenceToOther.expectedType === "js_module"
499
- ) {
500
- const referencedUrlInfo = referenceToOther.urlInfo;
501
- if (
502
- referencedUrlInfo &&
503
- // something else than the resource hint is using this url
504
- referencedUrlInfo.referenceFromOthersSet.size > 0
505
- ) {
506
- addToBundlerIfAny(referencedUrlInfo);
507
- }
508
- }
509
- });
508
+ }
510
509
  return;
511
510
  }
512
511
  // File referenced with new URL('./file.js', import.meta.url)
513
512
  // are entry points that should be bundled
514
513
  // For instance we will bundle service worker/workers detected like this
515
514
  if (rawUrlInfo.type === "js_module") {
516
- rawUrlInfo.referenceToOthersSet.forEach((referenceToOther) => {
515
+ for (const referenceToOther of rawUrlInfo.referenceToOthersSet) {
517
516
  if (referenceToOther.type === "js_url") {
518
517
  const referencedUrlInfo = referenceToOther.urlInfo;
518
+ let isAlreadyBundled = false;
519
519
  for (const referenceFromOther of referencedUrlInfo.referenceFromOthersSet) {
520
520
  if (referenceFromOther.url === referencedUrlInfo.url) {
521
521
  if (
522
522
  referenceFromOther.subtype === "import_dynamic" ||
523
523
  referenceFromOther.type === "script"
524
524
  ) {
525
- // will already be bundled
526
- return;
525
+ isAlreadyBundled = true;
526
+ break;
527
527
  }
528
528
  }
529
529
  }
530
- addToBundlerIfAny(referencedUrlInfo);
531
- return;
530
+ if (!isAlreadyBundled) {
531
+ addToBundlerIfAny(referencedUrlInfo);
532
+ }
533
+ continue;
532
534
  }
533
535
  if (referenceToOther.type === "js_inline_content") {
534
536
  // we should bundle it too right?
535
537
  }
536
- });
538
+ }
537
539
  }
538
540
  },
539
541
  );
@@ -87,9 +87,14 @@ export const createBuildSpecifierManager = ({
87
87
 
88
88
  let buildSpecifier;
89
89
  if (base === "./") {
90
- const parentBuildUrl = reference.ownerUrlInfo.isRoot
90
+ const { ownerUrlInfo } = reference;
91
+ const parentBuildUrl = ownerUrlInfo.isRoot
91
92
  ? buildDirectoryUrl
92
- : urlInfoToBuildUrlMap.get(reference.ownerUrlInfo);
93
+ : urlInfoToBuildUrlMap.get(
94
+ ownerUrlInfo.isInline
95
+ ? ownerUrlInfo.findParentIfInline()
96
+ : ownerUrlInfo,
97
+ );
93
98
  const urlRelativeToParent = urlToRelativeUrl(buildUrl, parentBuildUrl);
94
99
  if (urlRelativeToParent[0] === ".") {
95
100
  buildSpecifier = urlRelativeToParent;
@@ -38,6 +38,8 @@ export const jsenvPluginDirectoryReferenceEffect = (
38
38
  actionForDirectory = "copy";
39
39
  } else if (reference.type === "filesystem") {
40
40
  actionForDirectory = "copy";
41
+ } else if (reference.type === "http_request") {
42
+ actionForDirectory = "preserve";
41
43
  } else if (typeof directoryReferenceEffect === "string") {
42
44
  actionForDirectory = directoryReferenceEffect;
43
45
  } else if (typeof directoryReferenceEffect === "function") {
@@ -55,7 +57,9 @@ export const jsenvPluginDirectoryReferenceEffect = (
55
57
  throw error;
56
58
  }
57
59
  if (actionForDirectory === "preserve") {
58
- return `ignore:${reference.specifier}`;
60
+ return reference.ownerUrlInfo.context.dev
61
+ ? null
62
+ : `ignore:${reference.specifier}`;
59
63
  }
60
64
  return null;
61
65
  },
@@ -0,0 +1,133 @@
1
+ html,
2
+ body,
3
+ h1,
4
+ div,
5
+ p,
6
+ ul,
7
+ li,
8
+ a,
9
+ p,
10
+ button {
11
+ margin: 0;
12
+ padding: 0;
13
+ border: 0;
14
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
15
+ -webkit-font-smoothing: antialiased;
16
+ -moz-osx-font-smoothing: grayscale;
17
+ }
18
+ .directory_nav {
19
+ font-size: 16px;
20
+ font-weight: bold;
21
+ margin: 20px 25px 15px 25px;
22
+ display: flex;
23
+ }
24
+ .directory_nav_item {
25
+ text-decoration: none;
26
+ position: relative;
27
+ }
28
+ .directory_separator {
29
+ margin: 0 0.3em;
30
+ }
31
+ .directory_separator:first-child {
32
+ margin-left: 0;
33
+ }
34
+ .directory_content {
35
+ margin: 10px 15px 10px 15px;
36
+ list-style-type: none;
37
+ border-radius: 3px;
38
+ }
39
+ .directory_child {
40
+ position: relative;
41
+ padding: 10px 15px 10px 15px;
42
+ background-size: 16px 16px;
43
+ background-position: 15px center;
44
+ background-repeat: no-repeat;
45
+ text-indent: 30px;
46
+ font-size: 15px;
47
+ min-height: 19px;
48
+ box-sizing: border-box;
49
+ }
50
+ .directory_child::after {
51
+ position: absolute;
52
+ content: " ";
53
+ display: block;
54
+ bottom: 0;
55
+ left: 15px;
56
+ right: 0;
57
+ }
58
+ .directory_child:last-child {
59
+ border-bottom: none;
60
+ padding-bottom: 10px;
61
+ }
62
+ .directory_child:last-child::after {
63
+ content: none;
64
+ }
65
+ .directory_child[data-type="file"] {
66
+ background-image: url("./file.png?inline");
67
+ }
68
+ .directory_child[data-type="dir"] {
69
+ background-image: url("./dir.png?inline");
70
+ }
71
+ .directory_child[data-type="dir"]::before {
72
+ content: " ";
73
+ position: absolute;
74
+ display: block;
75
+ width: 5px;
76
+ height: 5px;
77
+ border-top-right-radius: 1px;
78
+ transform: rotate(45deg);
79
+ right: 15px;
80
+ top: 16px;
81
+ }
82
+ .directory_child a {
83
+ text-decoration: none;
84
+ display: block;
85
+ }
86
+
87
+ body[data-theme="dark"] {
88
+ background: #121212;
89
+ }
90
+ body[data-theme="light"] {
91
+ background: #f1f1f1;
92
+ }
93
+ body[data-theme="dark"] .directory_nav_item {
94
+ color: #999999;
95
+ }
96
+ body[data-theme="dark"] .directory_nav_item[data-current] {
97
+ color: #f1f1f1;
98
+ }
99
+ body[data-theme="light"] .directory_nav_item {
100
+ color: #000000;
101
+ }
102
+ body[data-theme="dark"] .directory_separator {
103
+ color: #666666;
104
+ }
105
+ body[data-theme="light"] .directory_separator {
106
+ color: #999999;
107
+ }
108
+ body[data-theme="dark"] .directory_content {
109
+ background: #1e1e1e;
110
+ }
111
+ body[data-theme="light"] .directory_content {
112
+ background: #fefefe;
113
+ }
114
+ body[data-theme="dark"] .directory_child {
115
+ border-bottom: 1px solid #121212;
116
+ }
117
+ body[data-theme="light"] .directory_child {
118
+ border-bottom: 1px solid #f1f1f1;
119
+ }
120
+ body[data-theme="dark"] .directory_child[data-type="dir"]::before {
121
+ border-top: 2px solid #666666;
122
+ border-right: 2px solid #666666;
123
+ }
124
+ body[data-theme="light"] .directory_child[data-type="file"]::before {
125
+ border-top: 2px solid #999999;
126
+ border-right: 2px solid #999999;
127
+ }
128
+ body[data-theme="dark"] .directory_child a {
129
+ color: #ffffff;
130
+ }
131
+ body[data-theme="light"] .directory_child a {
132
+ color: #000000;
133
+ }
@@ -0,0 +1,17 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>Directory explorer</title>
5
+ <meta charset="utf-8" />
6
+ <link rel="icon" href="data:," />
7
+ <link
8
+ rel="stylesheet"
9
+ href="node_esm:@jsenv/core/src/plugins/protocol_file/client/assets/directory.css?inline"
10
+ />
11
+ </head>
12
+
13
+ <body data-theme="dark">
14
+ <h1 class="directory_nav">${directoryNav}</h1>
15
+ ${directoryContent}
16
+ </body>
17
+ </html>