@jsenv/core 24.1.0-alpha.0 → 24.3.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.
Files changed (180) hide show
  1. package/{license → LICENSE} +0 -0
  2. package/dist/browser_runtime/browser_runtime-fbd309a1.js +5137 -0
  3. package/dist/browser_runtime/browser_runtime-fbd309a1.js.map +1064 -0
  4. package/dist/{jsenv_browser_system.js → browser_system/browser_system-29eda202.js} +12 -12
  5. package/dist/{jsenv_browser_system.js.map → browser_system/browser_system-29eda202.js.map} +64 -64
  6. package/dist/build_manifest.js +12 -0
  7. package/dist/compile_proxy/assets/s.js-749702e8.map +242 -0
  8. package/dist/compile_proxy/compile_proxy-405777e6.html +2074 -0
  9. package/dist/compile_proxy/compile_proxy.html__inline__20-39c0801c.js.map +385 -0
  10. package/dist/event_source_client/event_source_client-9f14c8b9.js +356 -0
  11. package/dist/event_source_client/event_source_client-9f14c8b9.js.map +127 -0
  12. package/dist/redirector/assets/s.js-749702e8.map +242 -0
  13. package/dist/redirector/redirector-237cd168.html +2118 -0
  14. package/dist/redirector/redirector.html__inline__15-33acb0b9.js.map +390 -0
  15. package/dist/toolbar/assets/compilation.css-209d68b4.map +12 -0
  16. package/dist/toolbar/assets/eventsource.css-38cd0a36.map +12 -0
  17. package/dist/toolbar/assets/execution.css-0ebe522f.map +12 -0
  18. package/dist/toolbar/assets/focus.css-3f9c156d.map +12 -0
  19. package/dist/toolbar/assets/light-theme.css-78b19a80.map +12 -0
  20. package/dist/toolbar/assets/overflow-menu.css-d9688a1c.map +12 -0
  21. package/dist/toolbar/assets/s.js-749702e8.map +242 -0
  22. package/dist/toolbar/assets/settings.css-2b81b245.map +12 -0
  23. package/dist/toolbar/assets/toolbar.main.css-846920e9.map +28 -0
  24. package/dist/toolbar/assets/tooltip.css-03395ee6.map +12 -0
  25. package/dist/toolbar/toolbar-d3d98c2e.html +4778 -0
  26. package/dist/toolbar/toolbar.main-cab36c15.js.map +795 -0
  27. package/dist/toolbar_injector/assets/jsenv-logo-188b9ca6.svg +95 -0
  28. package/dist/{jsenv_toolbar_injector.js → toolbar_injector/toolbar_injector-01f71ce3.js} +62 -137
  29. package/dist/toolbar_injector/toolbar_injector-01f71ce3.js.map +294 -0
  30. package/main.js +0 -1
  31. package/package.json +4 -2
  32. package/readme.md +10 -7
  33. package/src/buildProject.js +8 -2
  34. package/src/dev_server.js +45 -102
  35. package/src/importUsingChildProcess.js +1 -1
  36. package/src/internal/{runtime/detectBrowser/detectBrowser.js → browser_detection/browser_detection.js} +0 -0
  37. package/src/internal/{runtime/detectBrowser → browser_detection}/detectAndroid.js +0 -0
  38. package/src/internal/{runtime/detectBrowser → browser_detection}/detectChrome.js +0 -0
  39. package/src/internal/{runtime/detectBrowser → browser_detection}/detectEdge.js +0 -0
  40. package/src/internal/{runtime/detectBrowser → browser_detection}/detectElectron.js +0 -0
  41. package/src/internal/{runtime/detectBrowser → browser_detection}/detectFirefox.js +0 -0
  42. package/src/internal/{runtime/detectBrowser → browser_detection}/detectIOS.js +0 -0
  43. package/src/internal/{runtime/detectBrowser → browser_detection}/detectInternetExplorer.js +0 -0
  44. package/src/internal/{runtime/detectBrowser → browser_detection}/detectOpera.js +0 -0
  45. package/src/internal/{runtime/detectBrowser → browser_detection}/detectSafari.js +0 -0
  46. package/src/internal/{runtime/detectBrowser → browser_detection}/util.js +0 -0
  47. package/src/internal/{runtime/createBrowserRuntime/scanBrowserRuntimeFeatures.js → browser_feature_detection/browser_feature_detection.js} +116 -81
  48. package/src/internal/browser_feature_detection/compile_proxy.html +27 -0
  49. package/src/internal/{browser-launcher → browser_launcher}/createSharing.js +0 -0
  50. package/src/internal/{browser-launcher → browser_launcher}/executeHtmlFile.js +7 -4
  51. package/src/internal/{browser-launcher → browser_launcher}/trackPageToNotify.js +0 -0
  52. package/src/internal/{browser-launcher/jsenv-browser-system.js → browser_runtime/browser_runtime.js} +4 -4
  53. package/src/internal/{runtime/createBrowserRuntime/createBrowserSystem.js → browser_runtime/browser_system.js} +3 -2
  54. package/src/internal/{runtime/createBrowserRuntime → browser_runtime}/createBrowserRuntime.js +7 -5
  55. package/src/internal/{browser-launcher → browser_runtime}/displayErrorInDocument.js +0 -0
  56. package/src/internal/{browser-launcher → browser_runtime}/displayErrorNotification.js +2 -4
  57. package/src/internal/{runtime/createBrowserRuntime → browser_runtime}/evalSource.js +2 -0
  58. package/src/internal/{runtime/createBrowserRuntime → browser_runtime}/makeNamespaceTransferable.js +0 -0
  59. package/src/internal/{browser-utils → browser_utils}/fetch-browser.js +2 -0
  60. package/src/internal/{browser-utils → browser_utils}/fetchAndEvalUsingFetch.js +3 -0
  61. package/src/internal/{browser-utils → browser_utils}/fetchAndEvalUsingScript.js +2 -0
  62. package/src/internal/{browser-utils → browser_utils}/fetchJson.js +0 -0
  63. package/src/internal/{browser-utils → browser_utils}/fetchUsingXHR.js +4 -4
  64. package/src/internal/building/buildUsingRollup.js +4 -0
  65. package/src/internal/building/createJsenvRollupPlugin.js +19 -9
  66. package/src/internal/building/css/applyPostCss.js +19 -8
  67. package/src/internal/building/css/moveCssUrls.js +44 -0
  68. package/src/internal/building/css/parseCssRessource.js +67 -17
  69. package/src/internal/building/css/parseCssUrls.js +29 -23
  70. package/src/internal/building/css/postcss_plugin_url_visitor.js +11 -20
  71. package/src/internal/building/css/replaceCssUrls.js +38 -19
  72. package/src/internal/building/css_module.js +6 -10
  73. package/src/internal/building/html/parseHtmlRessource.js +37 -11
  74. package/src/internal/building/parseRessource.js +3 -0
  75. package/src/internal/building/ressource_builder.js +12 -3
  76. package/src/internal/compiling/babel_plugin_import_assertions.js +1 -2
  77. package/src/internal/compiling/compile-directory/validateCache.js +0 -5
  78. package/src/internal/compiling/compileFile.js +17 -54
  79. package/src/internal/compiling/createCompiledFileService.js +2 -0
  80. package/src/internal/compiling/html_source_file_service.js +49 -13
  81. package/src/internal/compiling/jsenvCompilerForHtml.js +29 -12
  82. package/src/internal/compiling/startCompileServer.js +39 -33
  83. package/src/internal/dev_server/event_source_client/event_source_client.js +63 -0
  84. package/src/internal/{toolbar/eventsource/connectEventSource.js → dev_server/event_source_client/event_source_connection.js} +66 -88
  85. package/src/internal/dev_server/event_source_client/file_changes.js +82 -0
  86. package/src/internal/dev_server/event_source_client/livereload_preference.js +13 -0
  87. package/src/internal/{exploring → dev_server/exploring}/exploring.css +0 -0
  88. package/src/internal/{exploring → dev_server/exploring}/exploring.html +8 -3
  89. package/src/internal/{exploring → dev_server/exploring}/exploring.js +0 -0
  90. package/src/internal/{exploring → dev_server/exploring}/fetchExploringJson.js +4 -9
  91. package/src/internal/dev_server/redirector/redirector.html +48 -0
  92. package/src/internal/{toolbar → dev_server/toolbar}/animation/toolbar.animation.js +0 -0
  93. package/src/internal/{toolbar → dev_server/toolbar}/compilation/compilation.css +0 -0
  94. package/src/internal/{toolbar → dev_server/toolbar}/compilation/toolbar.compilation.js +4 -7
  95. package/src/internal/{toolbar → dev_server/toolbar}/eventsource/eventsource.css +0 -0
  96. package/src/internal/dev_server/toolbar/eventsource/toolbar.eventsource.js +83 -0
  97. package/src/internal/{toolbar → dev_server/toolbar}/execution/execution.css +0 -0
  98. package/src/internal/{toolbar → dev_server/toolbar}/execution/toolbar.execution.js +0 -0
  99. package/src/internal/{toolbar → dev_server/toolbar}/focus/focus.css +0 -0
  100. package/src/internal/{toolbar → dev_server/toolbar}/focus/toolbar.focus.js +0 -0
  101. package/src/internal/{toolbar → dev_server/toolbar}/jsenv-logo.svg +0 -0
  102. package/src/internal/dev_server/toolbar/notification/toolbar.notification.js +152 -0
  103. package/src/internal/{toolbar → dev_server/toolbar}/responsive/overflow-menu.css +0 -0
  104. package/src/internal/{toolbar → dev_server/toolbar}/responsive/toolbar.responsive.js +0 -0
  105. package/src/internal/{toolbar → dev_server/toolbar}/settings/settings.css +0 -0
  106. package/src/internal/{toolbar → dev_server/toolbar}/settings/toolbar.settings.js +0 -0
  107. package/src/internal/{toolbar → dev_server/toolbar}/theme/jsenv-theme.css +0 -0
  108. package/src/internal/{toolbar → dev_server/toolbar}/theme/light-theme.css +0 -0
  109. package/src/internal/{toolbar → dev_server/toolbar}/theme/toolbar.theme.js +0 -0
  110. package/src/internal/{toolbar → dev_server/toolbar}/toolbar.html +35 -42
  111. package/src/internal/{toolbar → dev_server/toolbar}/toolbar.injector.js +53 -125
  112. package/src/internal/{toolbar → dev_server/toolbar}/toolbar.main.css +0 -0
  113. package/src/internal/{toolbar → dev_server/toolbar}/toolbar.main.js +44 -31
  114. package/src/internal/{toolbar → dev_server/toolbar}/tooltip/tooltip.css +0 -0
  115. package/src/internal/{toolbar → dev_server/toolbar}/tooltip/tooltip.js +0 -0
  116. package/src/internal/{toolbar → dev_server/toolbar}/util/animation.js +0 -0
  117. package/src/internal/{toolbar → dev_server/toolbar}/util/dom.js +0 -0
  118. package/src/internal/{toolbar → dev_server/toolbar}/util/fetching.js +2 -2
  119. package/src/internal/{toolbar → dev_server/toolbar}/util/jsenvLogger.js +0 -0
  120. package/src/internal/{toolbar → dev_server/toolbar}/util/preferences.js +0 -0
  121. package/src/internal/{toolbar → dev_server/toolbar}/util/responsive.js +0 -0
  122. package/src/internal/{toolbar → dev_server/toolbar}/util/util.js +0 -0
  123. package/src/internal/{toolbar → dev_server/toolbar}/variant/variant.js +0 -0
  124. package/src/internal/generateGroupMap/one_runtime_compat.js +1 -1
  125. package/src/internal/generateGroupMap/runtime_compat_composition.js +1 -1
  126. package/src/internal/generateGroupMap/runtime_support.js +1 -1
  127. package/src/internal/jsenvInternalFiles.js +0 -84
  128. package/src/internal/jsenv_builds.js +19 -0
  129. package/src/internal/{runtime/node-feature-detect/feature-detect-dynamic-import.mjs → node_feature_detection/feature_detect_dynamic_import.mjs} +0 -0
  130. package/src/internal/{runtime/node-feature-detect/feature-detect-top-level-await.mjs → node_feature_detection/feature_detect_top_level_await.mjs} +0 -0
  131. package/src/internal/{runtime/node-feature-detect → node_feature_detection}/nodeSupportsDynamicImport.js +0 -0
  132. package/src/internal/node_feature_detection/nodeSupportsTopLevelAwait.js +16 -0
  133. package/src/internal/{runtime/createNodeRuntime/scanNodeRuntimeFeatures.js → node_feature_detection/node_feature_detection.js} +12 -13
  134. package/src/internal/{node-launcher → node_launcher}/createChildProcessOptions.js +0 -0
  135. package/src/internal/{node-launcher → node_launcher}/createControllableNodeProcess.js +9 -14
  136. package/src/internal/{node-launcher → node_launcher}/kill_process_tree.js +0 -0
  137. package/src/internal/{node-launcher → node_launcher}/processOptions.js +0 -0
  138. package/src/internal/{runtime/detectNode → node_runtime}/detectNode.js +0 -0
  139. package/src/internal/{runtime/createNodeRuntime → node_runtime}/evalSource.js +1 -1
  140. package/src/internal/{runtime/createNodeRuntime → node_runtime}/fetchSource.js +1 -1
  141. package/src/internal/{node-launcher → node_runtime}/nodeControllableFile.mjs +14 -11
  142. package/src/internal/{runtime/createNodeRuntime/createNodeExecutionWithDynamicImport.js → node_runtime/node_execution_dynamic_import.js} +34 -6
  143. package/src/internal/node_runtime/node_execution_performance.js +67 -0
  144. package/src/internal/{runtime/createNodeRuntime/createNodeExecutionWithSystemJs.js → node_runtime/node_execution_systemjs.js} +38 -24
  145. package/src/internal/{runtime/createNodeRuntime/createNodeSystem.js → node_runtime/node_system.js} +4 -4
  146. package/src/internal/runtime/computeCompileIdFromGroupId.js +1 -0
  147. package/src/internal/runtime/resolveGroup.js +1 -1
  148. package/src/internal/runtime/resolveRuntimeGroup.js +2 -2
  149. package/src/internal/{semantic-versioning → semantic_versioning}/findHighestVersion.js +0 -0
  150. package/src/internal/{semantic-versioning → semantic_versioning}/findLowestVersion.js +0 -0
  151. package/src/internal/{semantic-versioning → semantic_versioning}/index.js +0 -0
  152. package/src/internal/{semantic-versioning → semantic_versioning}/valueToVersion.js +0 -0
  153. package/src/internal/{semantic-versioning → semantic_versioning}/versionCompare.js +0 -0
  154. package/src/internal/{semantic-versioning → semantic_versioning}/versionIsAbove.js +0 -0
  155. package/src/internal/{semantic-versioning → semantic_versioning}/versionIsBelow.js +0 -0
  156. package/src/internal/{semantic-versioning → semantic_versioning}/versionIsEqual.js +0 -0
  157. package/src/launchBrowser.js +3 -3
  158. package/src/launchNode.js +33 -7
  159. package/src/requireUsingChildProcess.js +1 -1
  160. package/dist/jsenv_compile_proxy.js +0 -1339
  161. package/dist/jsenv_compile_proxy.js.map +0 -378
  162. package/dist/jsenv_exploring_index.js +0 -1092
  163. package/dist/jsenv_exploring_index.js.map +0 -353
  164. package/dist/jsenv_exploring_redirector.js +0 -1386
  165. package/dist/jsenv_exploring_redirector.js.map +0 -384
  166. package/dist/jsenv_toolbar.js +0 -3347
  167. package/dist/jsenv_toolbar.js.map +0 -846
  168. package/dist/jsenv_toolbar_injector.js.map +0 -320
  169. package/src/internal/browser-launcher/jsenv_compile_proxy.html +0 -13
  170. package/src/internal/browser-launcher/jsenv_compile_proxy.js +0 -5
  171. package/src/internal/exploring/exploring.redirector.html +0 -13
  172. package/src/internal/exploring/exploring.redirector.js +0 -28
  173. package/src/internal/node-launcher/node-js-file.js +0 -110
  174. package/src/internal/runtime/createNodeRuntime/createNodeRuntime.js +0 -32
  175. package/src/internal/runtime/node-feature-detect/nodeSupportsTopLevelAwait.js +0 -18
  176. package/src/internal/toolbar/backtolist/toolbar.backtolist.js +0 -33
  177. package/src/internal/toolbar/eventsource/connectCompileServerEventSource.js +0 -74
  178. package/src/internal/toolbar/eventsource/toolbar.eventsource.js +0 -239
  179. package/src/internal/toolbar/notification/toolbar.notification.js +0 -121
  180. package/src/nodeRuntime.js +0 -5
@@ -0,0 +1,152 @@
1
+ import { createPreference } from "../util/preferences.js"
2
+ import { enableVariant } from "../variant/variant.js"
3
+
4
+ const notificationAvailable = typeof window.Notification === "function"
5
+ const notificationPreference = createPreference("notification")
6
+
7
+ const arrayOfOpenedNotifications = []
8
+ export const renderToolbarNotification = () => {
9
+ const notifCheckbox = document.querySelector("#toggle-notifs")
10
+ if (!notificationAvailable) {
11
+ const notifSetting = document.querySelector(".settings-notification")
12
+ notifSetting.setAttribute("data-disabled", "true")
13
+ notifSetting.setAttribute(
14
+ "title",
15
+ `Notification not available in the browser`,
16
+ )
17
+ notifCheckbox.disabled = true
18
+ return
19
+ }
20
+
21
+ const updatePermission = () => {
22
+ if (Notification.permission === "denied") {
23
+ const notifSetting = document.querySelector(".settings-notification")
24
+ notifSetting.setAttribute("data-disabled", "true")
25
+ notifSetting.setAttribute("title", `Notification denied`)
26
+ notifCheckbox.disabled = true
27
+ return
28
+ }
29
+
30
+ notifCheckbox.checked = getNotificationPreference()
31
+ notifCheckbox.onchange = () => {
32
+ setNotificationPreference(notifCheckbox.checked)
33
+ if (!notifCheckbox.checked) {
34
+ // slice because arrayOfOpenedNotifications can be mutated while looping
35
+ arrayOfOpenedNotifications.slice().forEach((notification) => {
36
+ notification.close()
37
+ })
38
+ }
39
+ }
40
+ const notifPermission = Notification.permission
41
+ enableVariant(document.querySelector(".notification-text"), {
42
+ notif_permission: notifPermission === "granted" ? "yes" : "no",
43
+ })
44
+ if (notifPermission === "default") {
45
+ document.querySelector("a.request_notification_permission").onclick =
46
+ () => {
47
+ requestPermission().then(() => {
48
+ updatePermission()
49
+ })
50
+ }
51
+ }
52
+ }
53
+ updatePermission()
54
+ }
55
+
56
+ export const notifyExecutionResult = (
57
+ executedFileRelativeUrl,
58
+ execution,
59
+ previousExecution,
60
+ ) => {
61
+ const notificationEnabled = getNotificationPreference()
62
+ if (!notificationEnabled) return
63
+
64
+ const notificationOptions = {
65
+ lang: "en",
66
+ icon: getFaviconHref(),
67
+ clickToFocus: true,
68
+ clickToClose: true,
69
+ }
70
+
71
+ if (execution.status === "errored") {
72
+ if (previousExecution) {
73
+ if (previousExecution.status === "completed") {
74
+ notify("Broken", {
75
+ ...notificationOptions,
76
+ body: `${executedFileRelativeUrl} execution now failing.`,
77
+ })
78
+ } else {
79
+ notify("Still failing", {
80
+ ...notificationOptions,
81
+ body: `${executedFileRelativeUrl} execution still failing.`,
82
+ })
83
+ }
84
+ } else {
85
+ notify("Failing", {
86
+ ...notificationOptions,
87
+ body: `${executedFileRelativeUrl} execution failed.`,
88
+ })
89
+ }
90
+ } else if (previousExecution && previousExecution.status === "errored") {
91
+ notify("Fixed", {
92
+ ...notificationOptions,
93
+ body: `${executedFileRelativeUrl} execution fixed.`,
94
+ })
95
+ }
96
+ }
97
+
98
+ const getNotificationPreference = () =>
99
+ notificationPreference.has() ? notificationPreference.get() : true
100
+
101
+ const setNotificationPreference = (value) => notificationPreference.set(value)
102
+
103
+ const getFaviconHref = () => {
104
+ const link = document.querySelector('link[rel="icon"]')
105
+ return link ? link.href : undefined
106
+ }
107
+
108
+ let permission = "default"
109
+
110
+ const notify = notificationAvailable
111
+ ? async (
112
+ title,
113
+ { clickToFocus = false, clickToClose = false, ...options } = {},
114
+ ) => {
115
+ if (permission !== "granted") {
116
+ return null
117
+ }
118
+
119
+ const notification = new Notification(title, options)
120
+ arrayOfOpenedNotifications.push(notification)
121
+ notification.onclick = () => {
122
+ // but if the user navigated inbetween
123
+ // focusing window will show something else
124
+ // in that case it could be great to do something
125
+ // maybe like showing a message saying this execution
126
+ // is no longer visible
127
+ // we could also navigauate to this file execution but
128
+ // there is no guarantee re-executing the file would give same output
129
+ // and it would also trigger an other notification
130
+ if (clickToFocus) window.focus()
131
+ if (clickToClose) notification.close()
132
+ }
133
+ notification.onclose = () => {
134
+ const index = arrayOfOpenedNotifications.indexOf(notification)
135
+ if (index > -1) {
136
+ arrayOfOpenedNotifications.splice(index, 1)
137
+ }
138
+ }
139
+ return notification
140
+ }
141
+ : () => {}
142
+
143
+ let requestPromise
144
+ const requestPermission = notificationAvailable
145
+ ? async () => {
146
+ if (requestPromise) return requestPromise
147
+ requestPromise = Notification.requestPermission()
148
+ permission = await requestPromise
149
+ requestPromise = undefined
150
+ return permission
151
+ }
152
+ : () => Promise.resolve("default")
@@ -5,7 +5,12 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <meta charset="utf-8" />
7
7
  <link rel="icon" href="data:," />
8
- <link rel="stylesheet" type="text/css" href="./toolbar.main.css" />
8
+ <link
9
+ rel="stylesheet"
10
+ type="text/css"
11
+ href="./toolbar.main.css"
12
+ data-jsenv-force-inline
13
+ />
9
14
  </head>
10
15
  <body>
11
16
  <div id="toolbar-overlay"></div>
@@ -13,7 +18,7 @@
13
18
  <div id="toolbar">
14
19
  <div id="toolbar-wrapper">
15
20
  <section id="file-list-link" data-responsive-toolbar-element>
16
- <a class="toolbar-icon-wrapper" href="">
21
+ <a class="toolbar-icon-wrapper" href="/">
17
22
  <svg
18
23
  id="fileIconSvg"
19
24
  class="iconToolbar"
@@ -130,9 +135,9 @@
130
135
  </svg>
131
136
  </button>
132
137
  </div>
133
- <div data-when="eventsource:failed">
138
+ <div data-when="eventsource:disconnected">
134
139
  <div class="tooltip">
135
- Cannot connect to server
140
+ Disconnected from server
136
141
  <br />
137
142
  <div class="tooltipAction">
138
143
  <a href="javascript:void(0);">
@@ -147,7 +152,7 @@
147
152
  d="M16 9v4.66l-3.5 3.51V19h-1v-1.83L8 13.65V9h8m0-6h-2v4h-4V3H8v4h-.01C6.9 6.99 6 7.89 6 8.98v5.52L9.5 18v3h5v-3l3.5-3.51V9c0-1.1-.9-2-2-2V3z"
148
153
  />
149
154
  </svg>
150
- retry
155
+ connect
151
156
  </a>
152
157
  </div>
153
158
  </div>
@@ -155,7 +160,7 @@
155
160
  <svg>
156
161
  <circle
157
162
  class="eventsource-circle"
158
- data-variant="failed"
163
+ data-variant="off"
159
164
  cx="20"
160
165
  cy="20"
161
166
  r="5"
@@ -218,39 +223,6 @@
218
223
  </svg>
219
224
  </button>
220
225
  </div>
221
- <div data-when="eventsource:disabled">
222
- <div class="tooltip">
223
- Disconnected from server
224
- <br />
225
- <div class="tooltipAction">
226
- <a href="javascript:void(0);">
227
- <svg
228
- xmlns="http://www.w3.org/2000/svg"
229
- viewBox="0 0 24 24"
230
- id="powerIconSvg"
231
- class="tooltipIcon"
232
- >
233
- <path d="M0 0h24v24H0V0z" fill="none" />
234
- <path
235
- d="M16 9v4.66l-3.5 3.51V19h-1v-1.83L8 13.65V9h8m0-6h-2v4h-4V3H8v4h-.01C6.9 6.99 6 7.89 6 8.98v5.52L9.5 18v3h5v-3l3.5-3.51V9c0-1.1-.9-2-2-2V3z"
236
- />
237
- </svg>
238
- connect
239
- </a>
240
- </div>
241
- </div>
242
- <button>
243
- <svg>
244
- <circle
245
- class="eventsource-circle"
246
- data-variant="off"
247
- cx="20"
248
- cy="20"
249
- r="5"
250
- />
251
- </svg>
252
- </button>
253
- </div>
254
226
  </section>
255
227
 
256
228
  <section id="settings" data-responsive-toolbar-element>
@@ -284,7 +256,7 @@
284
256
  </div>
285
257
  <div id="settings-box-body">
286
258
  <div class="settings-box-items-wrapper">
287
- <div class="settings-box-item">
259
+ <div class="settings-box-item settings-notification">
288
260
  <div class="category-title">
289
261
  <svg
290
262
  xmlns="http://www.w3.org/2000/svg"
@@ -307,6 +279,14 @@
307
279
  </label>
308
280
  <div class="category-subtitle">
309
281
  Send system notification when execution fails or is fixed.
282
+ <div class="notification-text">
283
+ <a
284
+ data-when="notif_permission:no"
285
+ class="request_notification_permission"
286
+ href="javascript:void(0);"
287
+ >Enable notification</a
288
+ >
289
+ </div>
310
290
  </div>
311
291
  </div>
312
292
  <div class="settings-box-item settings-livereload">
@@ -559,7 +539,7 @@
559
539
  <!--
560
540
  Reusable svg(s)
561
541
  -->
562
- <div style="display: none">
542
+ <div style="display: none; position: absolute">
563
543
  <svg
564
544
  id="loading_svg"
565
545
  xmlns="http://www.w3.org/2000/svg"
@@ -584,6 +564,19 @@
584
564
  module approach wil be faster because
585
565
  no compilation will be necessary
586
566
  -->
587
- <script src="/.jsenv/toolbar.main.js"></script>
567
+ <script
568
+ type="importmap"
569
+ src="../../../../node_resolution.importmap"
570
+ ></script>
571
+ <script>
572
+ // here we should create something like window.toolbar = {}
573
+ // and a promise the toolbar injector can listen to act on the toolbar
574
+ // or we could just consider all communication should pass by postmessage
575
+ </script>
576
+ <script
577
+ type="module"
578
+ src="./toolbar.main.js"
579
+ data-jsenv-force-inline
580
+ ></script>
588
581
  </body>
589
582
  </html>
@@ -1,94 +1,9 @@
1
- import { fetchExploringJson } from "@jsenv/core/src/internal/exploring/fetchExploringJson.js"
1
+ import { fetchExploringJson } from "@jsenv/core/src/internal/dev_server/exploring/fetchExploringJson.js"
2
2
  import { setAttributes, setStyles } from "./util/dom.js"
3
3
 
4
- /*
5
- We must connect to livereload server asap so that if a file is modified
6
- while page is loading we are notified of it.
7
-
8
- Otherwise it's possible that a file is loaded and used by browser then its modified before
9
- livereload connection is established.
10
-
11
- When toolbar is loaded it will open an other connection to server sent events and close this one.
12
- */
13
- const connectLivereload = () => {
14
- const { EventSource } = window
15
- if (typeof EventSource !== "function") {
16
- return () => {}
17
- }
18
-
19
- const getLivereloadPreference = () => {
20
- return localStorage.hasOwnProperty("livereload")
21
- ? JSON.parse(localStorage.getItem("livereload"))
22
- : true
23
- }
24
-
25
- const url = document.location.href
26
- let isOpen = false
27
- let lastEventId
28
- const latestChangeMap = {}
29
-
30
- const events = {
31
- "file-modified": ({ data }) => {
32
- latestChangeMap[data] = "modified"
33
- if (getLivereloadPreference()) {
34
- window.location.reload(true)
35
- }
36
- },
37
- "file-removed": ({ data }) => {
38
- latestChangeMap[data] = "removed"
39
- if (getLivereloadPreference()) {
40
- window.location.reload(true)
41
- }
42
- },
43
- "file-added": ({ data }) => {
44
- latestChangeMap[data] = "added"
45
- if (getLivereloadPreference()) {
46
- window.location.reload(true)
47
- }
48
- },
49
- }
50
-
51
- const eventSourceOrigin = new URL(url).origin
52
- const eventSource = new EventSource(url, {
53
- withCredentials: true,
54
- })
55
-
56
- const disconnect = () => {
57
- eventSource.close()
58
- }
59
-
60
- eventSource.onopen = () => {
61
- isOpen = true
62
- }
63
-
64
- eventSource.onerror = (errorEvent) => {
65
- if (errorEvent.target.readyState === EventSource.CLOSED) {
66
- isOpen = false
67
- }
68
- }
69
-
70
- Object.keys(events).forEach((eventName) => {
71
- eventSource.addEventListener(eventName, (e) => {
72
- if (e.origin === eventSourceOrigin) {
73
- if (e.lastEventId) {
74
- lastEventId = e.lastEventId
75
- }
76
- events[eventName](e)
77
- }
78
- })
79
- })
80
-
81
- return () => {
82
- return {
83
- isOpen,
84
- latestChangeMap,
85
- lastEventId,
86
- disconnect,
87
- }
88
- }
89
- }
90
- // eslint-disable-next-line camelcase
91
- window.__jsenv_eventsource__ = connectLivereload()
4
+ // eslint-disable-next-line no-undef
5
+ const TOOLBAR_BUILD_RELATIVE_URL = __TOOLBAR_BUILD_RELATIVE_URL_
6
+ const jsenvLogoSvgUrl = new URL("./jsenv-logo.svg", import.meta.url)
92
7
 
93
8
  const injectToolbar = async () => {
94
9
  await new Promise((resolve) => {
@@ -129,7 +44,7 @@ const injectToolbar = async () => {
129
44
  })
130
45
  const iframeLoadedPromise = iframeToLoadedPromise(iframe)
131
46
  const jsenvToolbarHtmlServerUrl = resolveUrl(
132
- "./src/internal/toolbar/toolbar.html",
47
+ TOOLBAR_BUILD_RELATIVE_URL,
133
48
  jsenvDirectoryServerUrl,
134
49
  )
135
50
  // set iframe src BEFORE putting it into the DOM (prevent firefox adding an history entry)
@@ -139,40 +54,11 @@ const injectToolbar = async () => {
139
54
  await iframeLoadedPromise
140
55
  iframe.removeAttribute("tabindex")
141
56
 
142
- const listenToolbarIframeEvent = (event, fn) => {
143
- window.addEventListener(
144
- "message",
145
- (messageEvent) => {
146
- const { data } = messageEvent
147
- if (typeof data !== "object") return
148
- const { jsenv } = data
149
- if (!jsenv) return
150
- const { type } = data
151
- if (type !== event) return
152
- fn(data.value)
153
- },
154
- false,
155
- )
156
- }
157
-
158
- listenToolbarIframeEvent("toolbar-visibility-change", (visible) => {
159
- if (visible) {
160
- hideToolbarTrigger()
161
- } else {
162
- showToolbarTrigger()
163
- }
164
- })
165
-
166
57
  const div = document.createElement("div")
167
- const jsenvLogoUrl = resolveUrl(
168
- "./src/internal/toolbar/jsenv-logo.svg",
169
- jsenvDirectoryServerUrl,
170
- )
171
- const jsenvLogoSvgSrc = jsenvLogoUrl
172
58
  div.innerHTML = `
173
59
  <div id="jsenv-toolbar-trigger">
174
60
  <svg id="jsenv-toolbar-trigger-icon">
175
- <use xlink:href="${jsenvLogoSvgSrc}#jsenv-logo"></use>
61
+ <use xlink:href="${jsenvLogoSvgUrl}#jsenv-logo"></use>
176
62
  </svg>
177
63
  <style>
178
64
  #jsenv-toolbar-trigger {
@@ -237,7 +123,7 @@ const injectToolbar = async () => {
237
123
  collapseToolbarTrigger()
238
124
  }
239
125
  toolbarTrigger.onclick = () => {
240
- window.__jsenv__.toolbar.show()
126
+ sendCommandToToolbar(iframe, "showToolbar")
241
127
  }
242
128
 
243
129
  const showToolbarTrigger = () => {
@@ -255,13 +141,54 @@ const injectToolbar = async () => {
255
141
  const collapseToolbarTrigger = () => {
256
142
  toolbarTrigger.removeAttribute("data-expanded", "")
257
143
  }
258
- hideToolbarTrigger()
259
144
 
260
- iframe.contentWindow.renderToolbar()
145
+ hideToolbarTrigger()
146
+ addToolbarEventCallback(iframe, "toolbar-visibility-change", (visible) => {
147
+ if (visible) {
148
+ hideToolbarTrigger()
149
+ } else {
150
+ showToolbarTrigger()
151
+ }
152
+ })
153
+ sendCommandToToolbar(iframe, "renderToolbar")
261
154
 
262
155
  return iframe
263
156
  }
264
157
 
158
+ const addToolbarEventCallback = (iframe, eventName, callback) => {
159
+ const messageEventCallback = (messageEvent) => {
160
+ const { data } = messageEvent
161
+ if (typeof data !== "object") {
162
+ return
163
+ }
164
+ const { __jsenv__ } = data
165
+ if (!__jsenv__) {
166
+ return
167
+ }
168
+ if (__jsenv__.event !== eventName) {
169
+ return
170
+ }
171
+ callback(__jsenv__.data)
172
+ }
173
+
174
+ window.addEventListener("message", messageEventCallback, false)
175
+ return () => {
176
+ window.removeEventListener("message", messageEventCallback, false)
177
+ }
178
+ }
179
+
180
+ const sendCommandToToolbar = (iframe, command, ...args) => {
181
+ iframe.contentWindow.postMessage(
182
+ {
183
+ __jsenv__: {
184
+ command,
185
+ args,
186
+ },
187
+ },
188
+ window.origin,
189
+ )
190
+ }
191
+
265
192
  const getToolbarPlaceholder = () => {
266
193
  const placeholder = queryPlaceholder()
267
194
  if (placeholder) {
@@ -277,8 +204,9 @@ const getToolbarPlaceholder = () => {
277
204
  return createTooolbarPlaceholder()
278
205
  }
279
206
 
280
- const queryPlaceholder = () =>
281
- document.querySelector("[data-jsenv-toolbar-placeholder]")
207
+ const queryPlaceholder = () => {
208
+ return document.querySelector("[data-jsenv-toolbar-placeholder]")
209
+ }
282
210
 
283
211
  const createTooolbarPlaceholder = () => {
284
212
  const placeholder = document.createElement("span")
@@ -4,7 +4,6 @@ import { urlToRelativeUrl } from "@jsenv/filesystem/src/urlToRelativeUrl.js"
4
4
  import { fetchExploringJson } from "../exploring/fetchExploringJson.js"
5
5
  import { startJavaScriptAnimation } from "../toolbar/util/animation.js"
6
6
  import "./focus/toolbar.focus.js"
7
- import { renderBackToListInToolbar } from "./backtolist/toolbar.backtolist.js"
8
7
  import {
9
8
  getToolbarIframe,
10
9
  deactivateToolbarSection,
@@ -45,16 +44,6 @@ const renderToolbar = async () => {
45
44
  hideSettings()
46
45
  }
47
46
 
48
- const toolbarElement = document.querySelector("#toolbar")
49
- exposeOnParentWindow({
50
- toolbar: {
51
- element: toolbarElement,
52
- show: showToolbar,
53
- hide: () => hideToolbar(),
54
- toggle: toogleToolbar,
55
- },
56
- })
57
-
58
47
  const toolbarVisible = toolbarVisibilityPreference.has()
59
48
  ? toolbarVisibilityPreference.get()
60
49
  : true
@@ -65,11 +54,6 @@ const renderToolbar = async () => {
65
54
  hideToolbar({ animate: false })
66
55
  }
67
56
 
68
- renderBackToListInToolbar({
69
- outDirectoryRelativeUrl,
70
- exploringHtmlFileRelativeUrl: exploringConfig.exploringHtmlFileRelativeUrl,
71
- })
72
-
73
57
  renderToolbarNotification()
74
58
  makeToolbarResponsive()
75
59
  renderToolbarSettings()
@@ -91,16 +75,6 @@ const renderToolbar = async () => {
91
75
  toogleToolbar()
92
76
  }
93
77
 
94
- const exposeOnParentWindow = (object) => {
95
- let { __jsenv__ } = window.parent
96
- if (!__jsenv__) {
97
- __jsenv__ = {}
98
- window.parent.__jsenv__ = {}
99
- }
100
-
101
- Object.assign(__jsenv__, object)
102
- }
103
-
104
78
  const toogleToolbar = () => {
105
79
  if (toolbarIsVisible()) {
106
80
  hideToolbar()
@@ -213,15 +187,54 @@ const getCompileGroup = ({
213
187
  }
214
188
  }
215
189
 
216
- const sendEventToParent = (type, value) => {
190
+ const addExternalCommandCallback = (command, callback) => {
191
+ const messageEventCallback = (messageEvent) => {
192
+ const { data } = messageEvent
193
+ if (typeof data !== "object") {
194
+ return
195
+ }
196
+ const { __jsenv__ } = data
197
+ if (!__jsenv__) {
198
+ return
199
+ }
200
+
201
+ if (__jsenv__.command !== command) {
202
+ return
203
+ }
204
+
205
+ callback(...__jsenv__.args)
206
+ }
207
+
208
+ window.addEventListener("message", messageEventCallback)
209
+ return () => {
210
+ window.removeEventListener("message", messageEventCallback)
211
+ }
212
+ }
213
+
214
+ const sendEventToParent = (name, data) => {
217
215
  window.parent.postMessage(
218
216
  {
219
- jsenv: true,
220
- type,
221
- value,
217
+ __jsenv__: {
218
+ event: name,
219
+ data,
220
+ },
222
221
  },
223
222
  "*",
224
223
  )
225
224
  }
226
225
 
227
- window.renderToolbar = renderToolbar
226
+ addExternalCommandCallback("renderToolbar", () => {
227
+ renderToolbar()
228
+ })
229
+ addExternalCommandCallback("showToolbar", () => {
230
+ showToolbar()
231
+ })
232
+ addExternalCommandCallback("hideToolbar", () => {
233
+ hideToolbar()
234
+ })
235
+
236
+ window.toolbar = {
237
+ render: renderToolbar,
238
+ show: showToolbar,
239
+ hide: () => hideToolbar(),
240
+ }
@@ -1,4 +1,4 @@
1
- import { memoize } from "../../memoize.js"
1
+ import { memoize } from "../../../memoize.js"
2
2
 
3
3
  const fetchPolyfill = async (...args) => {
4
4
  const { fetchUsingXHR } = await loadPolyfill()
@@ -6,7 +6,7 @@ const fetchPolyfill = async (...args) => {
6
6
  }
7
7
 
8
8
  const loadPolyfill = memoize(() =>
9
- import("../../browser-utils/fetchUsingXHR.js"),
9
+ import("../../../browser_utils/fetchUsingXHR.js"),
10
10
  )
11
11
 
12
12
  export const fetchUrl =