@jsenv/core 35.0.5 → 36.0.1
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/README.md +1 -1
- package/dist/js/inline_content.js +5 -4
- package/dist/jsenv_core.js +1127 -1497
- package/package.json +8 -8
- package/src/build/build.js +49 -41
- package/src/dev/file_service.js +7 -17
- package/src/dev/start_dev_server.js +12 -7
- package/src/kitchen/kitchen.js +38 -19
- package/src/kitchen/url_graph.js +1 -1
- package/src/plugins/autoreload/jsenv_plugin_hmr.js +2 -2
- package/src/plugins/file_urls/jsenv_plugin_file_urls.js +4 -4
- package/src/plugins/http_urls/jsenv_plugin_http_urls.js +1 -1
- package/src/plugins/importmap/jsenv_plugin_importmap.js +1 -1
- package/src/plugins/inlining/jsenv_plugin_inlining.js +1 -1
- package/src/plugins/inlining/jsenv_plugin_inlining_as_data_url.js +13 -2
- package/src/plugins/plugin_controller.js +19 -10
- package/src/plugins/plugins.js +21 -25
- package/src/plugins/{url_analysis/css/css_urls.js → reference_analysis/css/jsenv_plugin_css_reference_analysis.js} +11 -1
- package/src/plugins/{inline_content_analysis/jsenv_plugin_data_urls.js → reference_analysis/data_urls/jsenv_plugin_data_urls_analysis.js} +19 -19
- package/src/plugins/reference_analysis/directory/jsenv_plugin_directory_reference_analysis.js +51 -0
- package/src/plugins/reference_analysis/html/jsenv_plugin_html_reference_analysis.js +429 -0
- package/src/plugins/reference_analysis/inline_content.js +7 -0
- package/src/plugins/reference_analysis/js/jsenv_plugin_js_reference_analysis.js +161 -0
- package/src/plugins/reference_analysis/jsenv_plugin_reference_analysis.js +120 -0
- package/src/plugins/{url_analysis → reference_analysis}/jsenv_plugin_reference_expected_types.js +19 -12
- package/src/plugins/{url_analysis/webmanifest/webmanifest_urls.js → reference_analysis/webmanifest/jsenv_plugin_webmanifest_reference_analysis.js} +13 -1
- package/src/plugins/resolution_node_esm/jsenv_plugin_node_esm_resolution.js +74 -0
- package/src/plugins/{url_resolution → resolution_node_esm}/node_esm_resolver.js +8 -0
- package/src/plugins/resolution_web/jsenv_plugin_web_resolution.js +45 -0
- package/src/plugins/transpilation/as_js_module/jsenv_plugin_as_js_module.js +1 -1
- package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +1 -1
- package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +4 -6
- package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_conversion.js +1 -1
- package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_fallback_inside_html.js +4 -6
- package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_fallback_on_workers.js +1 -1
- package/src/plugins/url_type_from_reference.js +13 -0
- package/src/plugins/{url_version/jsenv_plugin_url_version.js → version_search_param/jsenv_plugin_version_search_param.js} +4 -4
- package/dist/html/explorer.html +0 -559
- package/dist/other/jsenv.png +0 -0
- package/src/plugins/explorer/client/explorer.html +0 -608
- package/src/plugins/explorer/client/jsenv.png +0 -0
- package/src/plugins/explorer/jsenv_plugin_explorer.js +0 -86
- package/src/plugins/inline_content_analysis/client/inline_content.js +0 -6
- package/src/plugins/inline_content_analysis/jsenv_plugin_html_inline_content_analysis.js +0 -206
- package/src/plugins/inline_content_analysis/jsenv_plugin_inline_content_analysis.js +0 -34
- package/src/plugins/inline_content_analysis/jsenv_plugin_js_inline_content_analysis.js +0 -314
- package/src/plugins/url_analysis/html/html_urls.js +0 -313
- package/src/plugins/url_analysis/js/js_urls.js +0 -65
- package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +0 -116
- package/src/plugins/url_resolution/jsenv_plugin_url_resolution.js +0 -140
|
@@ -1,608 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<title>Exploring</title>
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<meta charset="utf-8" />
|
|
7
|
-
<link rel="icon" href="ignore:FAVICON_HREF" />
|
|
8
|
-
<style>
|
|
9
|
-
button:focus,
|
|
10
|
-
a:focus,
|
|
11
|
-
input:focus,
|
|
12
|
-
*[data-contains-hidden-input] input:focus + * {
|
|
13
|
-
outline-style: none;
|
|
14
|
-
outline-offset: -2px;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
*[data-contains-hidden-input] input:focus + * {
|
|
18
|
-
outline-width: 4px;
|
|
19
|
-
outline-offset: -2px;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
html[data-last-interaction="keyboard"] button:focus,
|
|
23
|
-
html[data-last-interaction="keyboard"] a:focus,
|
|
24
|
-
html[data-last-interaction="keyboard"] input:focus,
|
|
25
|
-
html[data-last-interaction="keyboard"]
|
|
26
|
-
*[data-contains-hidden-input]
|
|
27
|
-
input:focus
|
|
28
|
-
+ * {
|
|
29
|
-
outline-style: auto;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
html[data-last-interaction="keyboard"]
|
|
33
|
-
*[data-contains-hidden-input]
|
|
34
|
-
input:focus
|
|
35
|
-
+ * {
|
|
36
|
-
outline-color: rgb(0, 150, 255);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/*
|
|
40
|
-
Don't try to replace @-moz-document url-prefix() this by
|
|
41
|
-
-moz-outline or -moz-outline-color
|
|
42
|
-
Because firefox would take into account outline instead of -moz-outline
|
|
43
|
-
:moz-focus-ring
|
|
44
|
-
Because for some element we set the focus outline on a div which would not match :focusring
|
|
45
|
-
*/
|
|
46
|
-
@-moz-document url-prefix() {
|
|
47
|
-
html[data-last-interaction="keyboard"] button:focus,
|
|
48
|
-
html[data-last-interaction="keyboard"] a:focus,
|
|
49
|
-
html[data-last-interaction="keyboard"] input:focus,
|
|
50
|
-
html[data-last-interaction="keyboard"]
|
|
51
|
-
*[data-input-customized]
|
|
52
|
-
input:focus
|
|
53
|
-
+ * {
|
|
54
|
-
outline-width: 2px;
|
|
55
|
-
outline-offset: 0;
|
|
56
|
-
outline-style: solid;
|
|
57
|
-
/*
|
|
58
|
-
force a blue color for firefox otherwise
|
|
59
|
-
it uses outline-color: inherit
|
|
60
|
-
making it unpredictible and sometimes hard to see
|
|
61
|
-
*/
|
|
62
|
-
outline-color: rgb(0, 150, 255);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
::-moz-focus-inner {
|
|
66
|
-
border: 0;
|
|
67
|
-
}
|
|
68
|
-
</style>
|
|
69
|
-
<style>
|
|
70
|
-
/* reset stuff */
|
|
71
|
-
* {
|
|
72
|
-
box-sizing: border-box;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
[data-force-hide] {
|
|
76
|
-
display: none !important;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
html,
|
|
80
|
-
body {
|
|
81
|
-
margin: 0;
|
|
82
|
-
padding: 0;
|
|
83
|
-
display: flex;
|
|
84
|
-
flex-direction: column;
|
|
85
|
-
flex: 1;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
html {
|
|
89
|
-
font-family: arial, sans;
|
|
90
|
-
height: 100%;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
main {
|
|
94
|
-
display: flex;
|
|
95
|
-
flex-direction: column;
|
|
96
|
-
flex: 1;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
main > * {
|
|
100
|
-
min-width: 100%;
|
|
101
|
-
flex: 1;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
hr {
|
|
105
|
-
color: black;
|
|
106
|
-
background-color: black;
|
|
107
|
-
border-color: black;
|
|
108
|
-
margin: 15px 0;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
article[data-page="file-list"] {
|
|
112
|
-
background-color: #204143;
|
|
113
|
-
color: #97a0a0;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
nav,
|
|
117
|
-
#explorables-message {
|
|
118
|
-
background: #1f262c;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
#explorables nav {
|
|
122
|
-
/* overflow hidden to ensure it wraps li which have margins
|
|
123
|
-
otherwise the background color is not the one from <nav> */
|
|
124
|
-
overflow: hidden;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
#explorables-message {
|
|
128
|
-
overflow: auto; /* propagate background to margins cause by h4 inside */
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
article h2 {
|
|
132
|
-
margin: 0;
|
|
133
|
-
display: flex;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
article h2 svg {
|
|
137
|
-
margin-right: 15px;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
#main_html_file {
|
|
141
|
-
padding: 25px;
|
|
142
|
-
padding-bottom: 0;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
#main_file_link {
|
|
146
|
-
color: #e7f2f3;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
h2 {
|
|
150
|
-
margin: 20px 0;
|
|
151
|
-
color: #24b1b0;
|
|
152
|
-
display: inline-block;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
h4 {
|
|
156
|
-
font-weight: normal;
|
|
157
|
-
font-size: 15px;
|
|
158
|
-
color: #97a0a0;
|
|
159
|
-
padding: 0 25px;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
#explorables {
|
|
163
|
-
word-break: break-word;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
#explorables-header {
|
|
167
|
-
/* padding-bottom: 10px; */
|
|
168
|
-
width: 100%;
|
|
169
|
-
position: sticky;
|
|
170
|
-
top: 0;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
#explorables_header_and_menu {
|
|
174
|
-
padding-left: 25px;
|
|
175
|
-
padding-right: 25px;
|
|
176
|
-
padding-top: 25px;
|
|
177
|
-
background-color: #204143;
|
|
178
|
-
position: relative;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
#explorables_header_bottom_spacing {
|
|
182
|
-
height: 20px;
|
|
183
|
-
background: #1f262c;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
#directory_relative_url {
|
|
187
|
-
color: orange;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
#explorables ul {
|
|
191
|
-
padding: 0px 25px 25px 25px;
|
|
192
|
-
margin: 0;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
#explorables li {
|
|
196
|
-
list-style-type: none;
|
|
197
|
-
margin: 10px 0;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
#explorables li:first-child {
|
|
201
|
-
margin-top: 0;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
#explorables li .execution-link {
|
|
205
|
-
width: 100%;
|
|
206
|
-
word-break: break-all;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
.execution-link {
|
|
210
|
-
background: #204143;
|
|
211
|
-
padding: 6px 12px;
|
|
212
|
-
font-size: 14px;
|
|
213
|
-
display: inline-block;
|
|
214
|
-
color: #e7f2f3;
|
|
215
|
-
font-family: monospace;
|
|
216
|
-
text-decoration: unset;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/* icons */
|
|
220
|
-
#main_file_icon {
|
|
221
|
-
fill: #24b1b0;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
#explorables_icon {
|
|
225
|
-
width: 25px;
|
|
226
|
-
height: 25px;
|
|
227
|
-
stroke: none;
|
|
228
|
-
fill: #24b1b0;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
#explorables fieldset {
|
|
232
|
-
border: none;
|
|
233
|
-
padding: 0;
|
|
234
|
-
margin: 0;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
#explorables fieldset label {
|
|
238
|
-
display: inline-block;
|
|
239
|
-
padding: 0;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
#explorables fieldset input {
|
|
243
|
-
opacity: 0;
|
|
244
|
-
position: absolute;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
#explorables fieldset label input + * {
|
|
248
|
-
display: block;
|
|
249
|
-
padding: 0.7em 1em;
|
|
250
|
-
background-color: #204143;
|
|
251
|
-
border-radius: 0.1em;
|
|
252
|
-
min-width: 8em;
|
|
253
|
-
text-align: center;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
#explorables fieldset input:checked + * {
|
|
257
|
-
color: orange;
|
|
258
|
-
background: #1f262c;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/* scrolable menu */
|
|
262
|
-
.menu-wrapper {
|
|
263
|
-
position: relative;
|
|
264
|
-
max-width: 100%;
|
|
265
|
-
overflow-x: hidden;
|
|
266
|
-
overflow-y: hidden;
|
|
267
|
-
transition: 300ms;
|
|
268
|
-
margin-top: 25px;
|
|
269
|
-
}
|
|
270
|
-
.menu {
|
|
271
|
-
box-sizing: border-box;
|
|
272
|
-
white-space: nowrap;
|
|
273
|
-
overflow-x: auto;
|
|
274
|
-
overflow-y: hidden;
|
|
275
|
-
-webkit-overflow-scrolling: touch;
|
|
276
|
-
}
|
|
277
|
-
.menu .item {
|
|
278
|
-
display: inline-block;
|
|
279
|
-
height: 100%;
|
|
280
|
-
padding: 1em;
|
|
281
|
-
box-sizing: border-box;
|
|
282
|
-
}
|
|
283
|
-
.paddle {
|
|
284
|
-
position: absolute;
|
|
285
|
-
height: 36px;
|
|
286
|
-
bottom: 0;
|
|
287
|
-
border: none;
|
|
288
|
-
background: #24b1b0;
|
|
289
|
-
color: #1f262c;
|
|
290
|
-
}
|
|
291
|
-
.left-paddle {
|
|
292
|
-
left: 0;
|
|
293
|
-
}
|
|
294
|
-
.right-paddle {
|
|
295
|
-
right: 0;
|
|
296
|
-
}
|
|
297
|
-
.hidden {
|
|
298
|
-
display: none;
|
|
299
|
-
}
|
|
300
|
-
</style>
|
|
301
|
-
</head>
|
|
302
|
-
|
|
303
|
-
<body>
|
|
304
|
-
<main></main>
|
|
305
|
-
<div style="display: none">
|
|
306
|
-
<article data-page="file-list">
|
|
307
|
-
<!--
|
|
308
|
-
<section id="main_html_file">
|
|
309
|
-
<h2>
|
|
310
|
-
<svg id="main_file_icon" viewBox="0 0 16 16" width="25px" height="25px">
|
|
311
|
-
<path
|
|
312
|
-
d="M15.45,7L14,5.551V2c0-0.55-0.45-1-1-1h-1c-0.55,0-1,0.45-1,1v0.553L9,0.555C8.727,0.297,8.477,0,8,0S7.273,0.297,7,0.555 L0.55,7C0.238,7.325,0,7.562,0,8c0,0.563,0.432,1,1,1h1v6c0,0.55,0.45,1,1,1h3v-5c0-0.55,0.45-1,1-1h2c0.55,0,1,0.45,1,1v5h3 c0.55,0,1-0.45,1-1V9h1c0.568,0,1-0.437,1-1C16,7.562,15.762,7.325,15.45,7z"
|
|
313
|
-
/>
|
|
314
|
-
</svg>
|
|
315
|
-
<span
|
|
316
|
-
>Main html file:
|
|
317
|
-
<a id="main_file_link" href="javascript:void(0)">${mainFileRelativeUrl}</a></span
|
|
318
|
-
>
|
|
319
|
-
</h2>
|
|
320
|
-
<div>
|
|
321
|
-
<iframe id="main_file_iframe" src="about:blank"></iframe>
|
|
322
|
-
</div>
|
|
323
|
-
</section>
|
|
324
|
-
<hr />
|
|
325
|
-
!-->
|
|
326
|
-
<section id="explorables">
|
|
327
|
-
<div id="explorables-header">
|
|
328
|
-
<div id="explorables_header_and_menu">
|
|
329
|
-
<h2>
|
|
330
|
-
<svg
|
|
331
|
-
id="explorables_icon"
|
|
332
|
-
viewBox="0 0 24 24"
|
|
333
|
-
width="32"
|
|
334
|
-
height="32"
|
|
335
|
-
>
|
|
336
|
-
<path d="M0 0h24v24H0V0z" fill="none" />
|
|
337
|
-
<path
|
|
338
|
-
d="M8 16h8v2H8zm0-4h8v2H8zm6-10H6c-1.1 0-2 .9-2 2v16c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm4 18H6V4h7v5h5v11z"
|
|
339
|
-
/>
|
|
340
|
-
</svg>
|
|
341
|
-
<span
|
|
342
|
-
>File(s) to explore in
|
|
343
|
-
<span id="directory_relative_url" title="${directoryUrl}"
|
|
344
|
-
>${directoryName}</span
|
|
345
|
-
></span
|
|
346
|
-
>
|
|
347
|
-
</h2>
|
|
348
|
-
<div class="menu-wrapper">
|
|
349
|
-
<fieldset id="filter-group-set" class="menu"></fieldset>
|
|
350
|
-
</div>
|
|
351
|
-
<div class="paddles">
|
|
352
|
-
<button class="left-paddle paddle hidden"><</button>
|
|
353
|
-
<button class="right-paddle paddle">></button>
|
|
354
|
-
</div>
|
|
355
|
-
</div>
|
|
356
|
-
<div id="explorables_header_bottom_spacing"></div>
|
|
357
|
-
</div>
|
|
358
|
-
<div>
|
|
359
|
-
<div id="explorables-message">
|
|
360
|
-
<h4 style="margin-top: 0">${message}</h4>
|
|
361
|
-
</div>
|
|
362
|
-
<nav>
|
|
363
|
-
<ul></ul>
|
|
364
|
-
</nav>
|
|
365
|
-
</div>
|
|
366
|
-
</section>
|
|
367
|
-
</article>
|
|
368
|
-
</div>
|
|
369
|
-
<script no-supervisor>
|
|
370
|
-
// eslint-disable-next-line no-undef
|
|
371
|
-
const { rootDirectoryUrl, groups, files } = SERVER_PARAMS;
|
|
372
|
-
|
|
373
|
-
const groupPreference = {
|
|
374
|
-
has: () => localStorage.hasOwnProperty("explorer_active_group"),
|
|
375
|
-
get: () =>
|
|
376
|
-
localStorage.hasOwnProperty("explorer_active_group")
|
|
377
|
-
? JSON.parse(localStorage.getItem("explorer_active_group"))
|
|
378
|
-
: undefined,
|
|
379
|
-
set: (value) =>
|
|
380
|
-
localStorage.setItem("explorer_active_group", JSON.stringify(value)),
|
|
381
|
-
};
|
|
382
|
-
const directoryNameFromUrl = (directoryUrl) => {
|
|
383
|
-
const slashLastIndex = directoryUrl.lastIndexOf(
|
|
384
|
-
"/",
|
|
385
|
-
// ignore last slash
|
|
386
|
-
directoryUrl.length - 2,
|
|
387
|
-
);
|
|
388
|
-
if (slashLastIndex === -1) return "";
|
|
389
|
-
return directoryUrl.slice(slashLastIndex + 1);
|
|
390
|
-
};
|
|
391
|
-
const urlToVisitFromRelativeUrl = (relativeUrl) => {
|
|
392
|
-
return `${window.origin}/${relativeUrl}`;
|
|
393
|
-
};
|
|
394
|
-
|
|
395
|
-
const fileListElement = document
|
|
396
|
-
.querySelector(`[data-page="file-list"]`)
|
|
397
|
-
.cloneNode(true);
|
|
398
|
-
const directoryName = directoryNameFromUrl(rootDirectoryUrl);
|
|
399
|
-
const span = fileListElement.querySelector("#directory_relative_url");
|
|
400
|
-
span.title = rootDirectoryUrl;
|
|
401
|
-
span.textContent = directoryName;
|
|
402
|
-
|
|
403
|
-
const h4 = fileListElement.querySelector("h4");
|
|
404
|
-
const ul = fileListElement.querySelector("ul");
|
|
405
|
-
ul.innerHTML = files
|
|
406
|
-
.map(
|
|
407
|
-
(file) =>
|
|
408
|
-
`<li>
|
|
409
|
-
<a
|
|
410
|
-
class="execution-link"
|
|
411
|
-
data-relative-url=${file.relativeUrl}
|
|
412
|
-
href=${urlToVisitFromRelativeUrl(file.relativeUrl)}
|
|
413
|
-
>
|
|
414
|
-
${file.relativeUrl}
|
|
415
|
-
</a>
|
|
416
|
-
</li>`,
|
|
417
|
-
)
|
|
418
|
-
.join("");
|
|
419
|
-
|
|
420
|
-
const groupFieldset = fileListElement.querySelector("#filter-group-set");
|
|
421
|
-
const groupNames = Object.keys(groups);
|
|
422
|
-
groupFieldset.innerHTML = groupNames
|
|
423
|
-
.map(
|
|
424
|
-
(key) => `<label data-contains-hidden-input class="item">
|
|
425
|
-
<input type="radio" name="filter-group" value="${key}"/>
|
|
426
|
-
<span>${key}</span>
|
|
427
|
-
</label>`,
|
|
428
|
-
)
|
|
429
|
-
.join("");
|
|
430
|
-
|
|
431
|
-
const groupFromLocalStorage = groupPreference.get();
|
|
432
|
-
const currentGroup =
|
|
433
|
-
groupFromLocalStorage && groupNames.includes(groupFromLocalStorage)
|
|
434
|
-
? groupFromLocalStorage
|
|
435
|
-
: groupNames[0];
|
|
436
|
-
Array.from(groupFieldset.querySelectorAll("input")).forEach(
|
|
437
|
-
(inputRadio) => {
|
|
438
|
-
inputRadio.checked = inputRadio.value === currentGroup;
|
|
439
|
-
inputRadio.onchange = () => {
|
|
440
|
-
if (inputRadio.checked) {
|
|
441
|
-
groupPreference.set(inputRadio.value);
|
|
442
|
-
enableGroup(inputRadio.value);
|
|
443
|
-
}
|
|
444
|
-
};
|
|
445
|
-
},
|
|
446
|
-
);
|
|
447
|
-
|
|
448
|
-
const enableGroup = (groupName) => {
|
|
449
|
-
const arrayOfElementToShow = [];
|
|
450
|
-
const arrayOfElementToHide = [];
|
|
451
|
-
files.forEach((file) => {
|
|
452
|
-
const fileLink = fileListElement.querySelector(
|
|
453
|
-
`a[data-relative-url="${file.relativeUrl}"]`,
|
|
454
|
-
);
|
|
455
|
-
const fileLi = fileLink.parentNode;
|
|
456
|
-
if (file.meta[groupName]) {
|
|
457
|
-
arrayOfElementToShow.push(fileLi);
|
|
458
|
-
} else {
|
|
459
|
-
arrayOfElementToHide.push(fileLi);
|
|
460
|
-
}
|
|
461
|
-
});
|
|
462
|
-
arrayOfElementToShow.forEach((element) => {
|
|
463
|
-
element.removeAttribute("data-force-hide");
|
|
464
|
-
});
|
|
465
|
-
arrayOfElementToHide.forEach((element) => {
|
|
466
|
-
element.setAttribute("data-force-hide", "");
|
|
467
|
-
});
|
|
468
|
-
|
|
469
|
-
h4.innerHTML =
|
|
470
|
-
arrayOfElementToShow.length === 0
|
|
471
|
-
? `No file found.
|
|
472
|
-
Config for this section: <pre>${JSON.stringify(
|
|
473
|
-
groups[groupName],
|
|
474
|
-
null,
|
|
475
|
-
" ",
|
|
476
|
-
)}</pre>`
|
|
477
|
-
: `${arrayOfElementToShow.length} files found. Click on the one you want to execute`;
|
|
478
|
-
};
|
|
479
|
-
enableGroup(currentGroup);
|
|
480
|
-
|
|
481
|
-
document.querySelector("main").appendChild(fileListElement);
|
|
482
|
-
</script>
|
|
483
|
-
<script no-supervisor>
|
|
484
|
-
// make menu scrollable
|
|
485
|
-
const getMenuWrapperSize = () => {
|
|
486
|
-
return document.querySelector(".menu-wrapper").getBoundingClientRect()
|
|
487
|
-
.width;
|
|
488
|
-
};
|
|
489
|
-
const getMenuSize = () => {
|
|
490
|
-
return document.querySelector(".menu").getBoundingClientRect().width;
|
|
491
|
-
};
|
|
492
|
-
const getMenuPosition = () => {
|
|
493
|
-
return document.querySelector(".menu-wrapper").scrollLeft;
|
|
494
|
-
};
|
|
495
|
-
|
|
496
|
-
let menuWrapperSize = getMenuWrapperSize();
|
|
497
|
-
let menuSize = getMenuSize();
|
|
498
|
-
const menuVisibleSize = menuWrapperSize;
|
|
499
|
-
let menuInvisibleSize = menuSize - menuVisibleSize;
|
|
500
|
-
const scrollDuration = 300;
|
|
501
|
-
const leftPaddle = document.querySelector(".left-paddle");
|
|
502
|
-
const rightPaddle = document.querySelector(".right-paddle");
|
|
503
|
-
|
|
504
|
-
const handleMenuScroll = () => {
|
|
505
|
-
menuInvisibleSize = menuSize - menuWrapperSize;
|
|
506
|
-
const menuPosition = getMenuPosition();
|
|
507
|
-
const menuEndOffset = menuInvisibleSize;
|
|
508
|
-
// show & hide the paddles, depending on scroll position
|
|
509
|
-
if (menuPosition <= 0 && menuEndOffset <= 0) {
|
|
510
|
-
// hide both paddles if the window is large enough to display all tabs
|
|
511
|
-
leftPaddle.classList.add("hidden");
|
|
512
|
-
rightPaddle.classList.add("hidden");
|
|
513
|
-
} else if (menuPosition <= 0) {
|
|
514
|
-
leftPaddle.classList.add("hidden");
|
|
515
|
-
rightPaddle.classList.remove("hidden");
|
|
516
|
-
} else if (menuPosition < Math.floor(menuEndOffset)) {
|
|
517
|
-
// show both paddles in the middle
|
|
518
|
-
leftPaddle.classList.remove("hidden");
|
|
519
|
-
rightPaddle.classList.remove("hidden");
|
|
520
|
-
} else if (menuPosition >= Math.floor(menuEndOffset)) {
|
|
521
|
-
leftPaddle.classList.remove("hidden");
|
|
522
|
-
rightPaddle.classList.add("hidden");
|
|
523
|
-
}
|
|
524
|
-
};
|
|
525
|
-
handleMenuScroll();
|
|
526
|
-
|
|
527
|
-
window.onresize = () => {
|
|
528
|
-
menuWrapperSize = getMenuWrapperSize();
|
|
529
|
-
menuSize = getMenuSize();
|
|
530
|
-
handleMenuScroll();
|
|
531
|
-
};
|
|
532
|
-
// finally, what happens when we are actually scrolling the menu
|
|
533
|
-
document.querySelector(".menu-wrapper").onscroll = () => {
|
|
534
|
-
handleMenuScroll();
|
|
535
|
-
};
|
|
536
|
-
|
|
537
|
-
const startJavaScriptAnimation = ({
|
|
538
|
-
duration = 300,
|
|
539
|
-
timingFunction = (t) => t,
|
|
540
|
-
onProgress = () => {},
|
|
541
|
-
onCancel = () => {},
|
|
542
|
-
onComplete = () => {},
|
|
543
|
-
}) => {
|
|
544
|
-
duration = parseInt(duration, 10);
|
|
545
|
-
const startMs = performance.now();
|
|
546
|
-
let currentRequestAnimationFrameId;
|
|
547
|
-
let done = false;
|
|
548
|
-
let rawProgress = 0;
|
|
549
|
-
let progress = 0;
|
|
550
|
-
const handler = () => {
|
|
551
|
-
currentRequestAnimationFrameId = null;
|
|
552
|
-
const nowMs = performance.now();
|
|
553
|
-
rawProgress = Math.min((nowMs - startMs) / duration, 1);
|
|
554
|
-
progress = timingFunction(rawProgress);
|
|
555
|
-
done = rawProgress === 1;
|
|
556
|
-
onProgress({
|
|
557
|
-
done,
|
|
558
|
-
rawProgress,
|
|
559
|
-
progress,
|
|
560
|
-
});
|
|
561
|
-
if (done) {
|
|
562
|
-
onComplete();
|
|
563
|
-
} else {
|
|
564
|
-
currentRequestAnimationFrameId =
|
|
565
|
-
window.requestAnimationFrame(handler);
|
|
566
|
-
}
|
|
567
|
-
};
|
|
568
|
-
handler();
|
|
569
|
-
const stop = () => {
|
|
570
|
-
if (currentRequestAnimationFrameId) {
|
|
571
|
-
window.cancelAnimationFrame(currentRequestAnimationFrameId);
|
|
572
|
-
currentRequestAnimationFrameId = null;
|
|
573
|
-
}
|
|
574
|
-
if (!done) {
|
|
575
|
-
done = true;
|
|
576
|
-
onCancel({
|
|
577
|
-
rawProgress,
|
|
578
|
-
progress,
|
|
579
|
-
});
|
|
580
|
-
}
|
|
581
|
-
};
|
|
582
|
-
return stop;
|
|
583
|
-
};
|
|
584
|
-
rightPaddle.onclick = () => {
|
|
585
|
-
const scrollStart = document.querySelector(".menu-wrapper").scrollLeft;
|
|
586
|
-
const scrollEnd = scrollStart + menuWrapperSize;
|
|
587
|
-
startJavaScriptAnimation({
|
|
588
|
-
duration: scrollDuration,
|
|
589
|
-
onProgress: ({ progress }) => {
|
|
590
|
-
document.querySelector(".menu-wrapper").scrollLeft =
|
|
591
|
-
scrollStart + (scrollEnd - scrollStart) * progress;
|
|
592
|
-
},
|
|
593
|
-
});
|
|
594
|
-
};
|
|
595
|
-
leftPaddle.onclick = () => {
|
|
596
|
-
const scrollStart = document.querySelector(".menu-wrapper").scrollLeft;
|
|
597
|
-
const scrollEnd = scrollStart - menuWrapperSize;
|
|
598
|
-
startJavaScriptAnimation({
|
|
599
|
-
duration: scrollDuration,
|
|
600
|
-
onProgress: ({ progress }) => {
|
|
601
|
-
document.querySelector(".menu-wrapper").scrollLeft =
|
|
602
|
-
scrollStart + (scrollEnd - scrollStart) * progress;
|
|
603
|
-
},
|
|
604
|
-
});
|
|
605
|
-
};
|
|
606
|
-
</script>
|
|
607
|
-
</body>
|
|
608
|
-
</html>
|
|
Binary file
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
2
|
-
import { DATA_URL } from "@jsenv/urls";
|
|
3
|
-
import { collectFiles } from "@jsenv/filesystem";
|
|
4
|
-
import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js";
|
|
5
|
-
|
|
6
|
-
export const explorerHtmlFileUrl = String(
|
|
7
|
-
new URL("./client/explorer.html", import.meta.url),
|
|
8
|
-
);
|
|
9
|
-
|
|
10
|
-
export const jsenvPluginExplorer = ({
|
|
11
|
-
groups = {
|
|
12
|
-
src: {
|
|
13
|
-
"./**/*.html": true,
|
|
14
|
-
"./**/*.test.html": false,
|
|
15
|
-
},
|
|
16
|
-
tests: {
|
|
17
|
-
"./**/*.test.html": true,
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
}) => {
|
|
21
|
-
const faviconClientFileUrl = new URL("./client/jsenv.png", import.meta.url);
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
name: "jsenv:explorer",
|
|
25
|
-
appliesDuring: "dev",
|
|
26
|
-
transformUrlContent: {
|
|
27
|
-
html: async (urlInfo, context) => {
|
|
28
|
-
if (urlInfo.url !== explorerHtmlFileUrl) {
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
let html = urlInfo.content;
|
|
32
|
-
if (html.includes("ignore:FAVICON_HREF")) {
|
|
33
|
-
html = html.replace(
|
|
34
|
-
"ignore:FAVICON_HREF",
|
|
35
|
-
DATA_URL.stringify({
|
|
36
|
-
contentType: CONTENT_TYPE.fromUrlExtension(faviconClientFileUrl),
|
|
37
|
-
base64Flag: true,
|
|
38
|
-
data: readFileSync(new URL(faviconClientFileUrl)).toString(
|
|
39
|
-
"base64",
|
|
40
|
-
),
|
|
41
|
-
}),
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
if (html.includes("SERVER_PARAMS")) {
|
|
45
|
-
const associationsForExplorable = {};
|
|
46
|
-
Object.keys(groups).forEach((groupName) => {
|
|
47
|
-
const groupConfig = groups[groupName];
|
|
48
|
-
associationsForExplorable[groupName] = {
|
|
49
|
-
"**/.jsenv/": false, // avoid visting .jsenv directory in jsenv itself
|
|
50
|
-
...groupConfig,
|
|
51
|
-
};
|
|
52
|
-
});
|
|
53
|
-
const matchingFileResultArray = await collectFiles({
|
|
54
|
-
directoryUrl: context.rootDirectoryUrl,
|
|
55
|
-
associations: associationsForExplorable,
|
|
56
|
-
predicate: (meta) =>
|
|
57
|
-
Object.keys(meta).some((group) => Boolean(meta[group])),
|
|
58
|
-
});
|
|
59
|
-
const files = matchingFileResultArray.map(
|
|
60
|
-
({ relativeUrl, meta }) => ({
|
|
61
|
-
relativeUrl,
|
|
62
|
-
meta,
|
|
63
|
-
}),
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
html = html.replace(
|
|
67
|
-
"SERVER_PARAMS",
|
|
68
|
-
JSON.stringify(
|
|
69
|
-
{
|
|
70
|
-
rootDirectoryUrl: context.rootDirectoryUrl,
|
|
71
|
-
groups,
|
|
72
|
-
files,
|
|
73
|
-
},
|
|
74
|
-
null,
|
|
75
|
-
" ",
|
|
76
|
-
),
|
|
77
|
-
);
|
|
78
|
-
Object.assign(urlInfo.headers, {
|
|
79
|
-
"cache-control": "no-store",
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
return html;
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
};
|
|
86
|
-
};
|