@jsenv/core 29.8.6 → 29.9.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.
Files changed (43) hide show
  1. package/README.md +1 -1
  2. package/dist/js/autoreload.js +1 -1
  3. package/dist/main.js +50 -2085
  4. package/package.json +2 -2
  5. package/src/build/build.js +33 -33
  6. package/src/plugins/plugins.js +1 -1
  7. package/src/plugins/ribbon/jsenv_plugin_ribbon.js +6 -1
  8. package/src/plugins/url_resolution/jsenv_plugin_url_resolution.js +6 -2
  9. package/src/plugins/url_resolution/node_esm_resolver.js +6 -1
  10. package/dist/js/html_src_set.js +0 -20
  11. package/src/plugins/toolbar/client/animation/toolbar_animation.js +0 -39
  12. package/src/plugins/toolbar/client/eventsource/eventsource.css +0 -83
  13. package/src/plugins/toolbar/client/eventsource/toolbar_eventsource.js +0 -57
  14. package/src/plugins/toolbar/client/execution/execution.css +0 -79
  15. package/src/plugins/toolbar/client/execution/toolbar_execution.js +0 -88
  16. package/src/plugins/toolbar/client/focus/focus.css +0 -61
  17. package/src/plugins/toolbar/client/focus/toolbar_focus.js +0 -19
  18. package/src/plugins/toolbar/client/jsenv_logo.svg +0 -140
  19. package/src/plugins/toolbar/client/notification/toolbar_notification.js +0 -181
  20. package/src/plugins/toolbar/client/responsive/overflow_menu.css +0 -61
  21. package/src/plugins/toolbar/client/responsive/toolbar_responsive.js +0 -103
  22. package/src/plugins/toolbar/client/settings/settings.css +0 -201
  23. package/src/plugins/toolbar/client/settings/toolbar_settings.js +0 -47
  24. package/src/plugins/toolbar/client/theme/jsenv_theme.css +0 -77
  25. package/src/plugins/toolbar/client/theme/light_theme.css +0 -106
  26. package/src/plugins/toolbar/client/theme/toolbar_theme.js +0 -34
  27. package/src/plugins/toolbar/client/toolbar.html +0 -457
  28. package/src/plugins/toolbar/client/toolbar_injector.js +0 -218
  29. package/src/plugins/toolbar/client/toolbar_main.css +0 -172
  30. package/src/plugins/toolbar/client/toolbar_main.js +0 -197
  31. package/src/plugins/toolbar/client/tooltip/tooltip.css +0 -61
  32. package/src/plugins/toolbar/client/tooltip/tooltip.js +0 -39
  33. package/src/plugins/toolbar/client/util/animation.js +0 -305
  34. package/src/plugins/toolbar/client/util/dom.js +0 -108
  35. package/src/plugins/toolbar/client/util/fetch_using_xhr.js +0 -400
  36. package/src/plugins/toolbar/client/util/fetching.js +0 -14
  37. package/src/plugins/toolbar/client/util/iframe_to_parent_href.js +0 -10
  38. package/src/plugins/toolbar/client/util/jsenv_logger.js +0 -28
  39. package/src/plugins/toolbar/client/util/preferences.js +0 -10
  40. package/src/plugins/toolbar/client/util/responsive.js +0 -112
  41. package/src/plugins/toolbar/client/util/util.js +0 -19
  42. package/src/plugins/toolbar/client/variant/variant.js +0 -74
  43. package/src/plugins/toolbar/jsenv_plugin_toolbar.js +0 -62
@@ -1,400 +0,0 @@
1
- export const fetchUsingXHR = async (
2
- url,
3
- {
4
- signal,
5
- method = "GET",
6
- credentials = "same-origin",
7
- headers = {},
8
- body = null,
9
- } = {},
10
- ) => {
11
- const headersPromise = createPromiseAndHooks()
12
- const bodyPromise = createPromiseAndHooks()
13
-
14
- const xhr = new XMLHttpRequest()
15
-
16
- const failure = (error) => {
17
- // if it was already resolved, we must reject the body promise
18
- if (headersPromise.settled) {
19
- bodyPromise.reject(error)
20
- } else {
21
- headersPromise.reject(error)
22
- }
23
- }
24
-
25
- const cleanup = () => {
26
- xhr.ontimeout = null
27
- xhr.onerror = null
28
- xhr.onload = null
29
- xhr.onreadystatechange = null
30
- }
31
-
32
- xhr.ontimeout = () => {
33
- cleanup()
34
- failure(new Error(`xhr request timeout on ${url}.`))
35
- }
36
-
37
- xhr.onerror = (error) => {
38
- cleanup()
39
- // unfortunately with have no clue why it fails
40
- // might be cors for instance
41
- failure(createRequestError(error, { url }))
42
- }
43
-
44
- xhr.onload = () => {
45
- cleanup()
46
- bodyPromise.resolve()
47
- }
48
-
49
- signal.addEventListener("abort", () => {
50
- xhr.abort()
51
- const abortError = new Error("aborted")
52
- abortError.name = "AbortError"
53
- failure(abortError)
54
- })
55
-
56
- xhr.onreadystatechange = () => {
57
- // https://developer.mozilla.org/fr/docs/Web/API/XMLHttpRequest/readyState
58
- const { readyState } = xhr
59
-
60
- if (readyState === 2) {
61
- headersPromise.resolve()
62
- } else if (readyState === 4) {
63
- cleanup()
64
- bodyPromise.resolve()
65
- }
66
- }
67
-
68
- xhr.open(method, url, true)
69
- Object.keys(headers).forEach((key) => {
70
- xhr.setRequestHeader(key, headers[key])
71
- })
72
- xhr.withCredentials = computeWithCredentials({ credentials, url })
73
- if ("responseType" in xhr && hasBlob) {
74
- xhr.responseType = "blob"
75
- }
76
- xhr.send(body)
77
-
78
- await headersPromise
79
-
80
- // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseURL
81
- const responseUrl =
82
- "responseURL" in xhr ? xhr.responseURL : headers["x-request-url"]
83
- let responseStatus = xhr.status
84
- const responseStatusText = xhr.statusText
85
- const responseHeaders = getHeadersFromXHR(xhr)
86
-
87
- const readBody = async () => {
88
- await bodyPromise
89
-
90
- const { status } = xhr
91
- // in Chrome on file:/// URLs, status is 0
92
- if (status === 0) {
93
- responseStatus = 200
94
- }
95
-
96
- const body = "response" in xhr ? xhr.response : xhr.responseText
97
-
98
- return {
99
- responseBody: body,
100
- responseBodyType: detectBodyType(body),
101
- }
102
- }
103
-
104
- const text = async () => {
105
- const { responseBody, responseBodyType } = await readBody()
106
-
107
- if (responseBodyType === "blob") {
108
- return blobToText(responseBody)
109
- }
110
- if (responseBodyType === "formData") {
111
- throw new Error("could not read FormData body as text")
112
- }
113
- if (responseBodyType === "dataView") {
114
- return arrayBufferToText(responseBody.buffer)
115
- }
116
- if (responseBodyType === "arrayBuffer") {
117
- return arrayBufferToText(responseBody)
118
- }
119
- return String(responseBody)
120
- }
121
-
122
- const json = async () => {
123
- const responseText = await text()
124
- return JSON.parse(responseText)
125
- }
126
-
127
- const blob = async () => {
128
- if (!hasBlob) {
129
- throw new Error(`blob not supported`)
130
- }
131
-
132
- const { responseBody, responseBodyType } = await readBody()
133
-
134
- if (responseBodyType === "blob") {
135
- return responseBody
136
- }
137
- if (responseBodyType === "dataView") {
138
- return new Blob([cloneBuffer(responseBody.buffer)])
139
- }
140
- if (responseBodyType === "arrayBuffer") {
141
- return new Blob([cloneBuffer(responseBody)])
142
- }
143
- if (responseBodyType === "formData") {
144
- throw new Error("could not read FormData body as blob")
145
- }
146
- return new Blob([String(responseBody)])
147
- }
148
-
149
- const arrayBuffer = async () => {
150
- const { responseBody, responseBodyType } = await readBody()
151
-
152
- if (responseBodyType === "arrayBuffer") {
153
- return cloneBuffer(responseBody)
154
- }
155
- const responseBlob = await blob()
156
- return blobToArrayBuffer(responseBlob)
157
- }
158
-
159
- const formData = async () => {
160
- if (!hasFormData) {
161
- throw new Error(`formData not supported`)
162
- }
163
- const responseText = await text()
164
- return textToFormData(responseText)
165
- }
166
-
167
- return {
168
- url: responseUrl,
169
- status: responseStatus,
170
- statusText: responseStatusText,
171
- headers: responseHeaders,
172
- text,
173
- json,
174
- blob,
175
- arrayBuffer,
176
- formData,
177
- }
178
- }
179
-
180
- const canUseBlob = () => {
181
- if (typeof window.FileReader !== "function") return false
182
-
183
- if (typeof window.Blob !== "function") return false
184
-
185
- try {
186
- // eslint-disable-next-line no-new
187
- new Blob()
188
- return true
189
- } catch (e) {
190
- return false
191
- }
192
- }
193
-
194
- const hasBlob = canUseBlob()
195
-
196
- const hasFormData = typeof window.FormData === "function"
197
-
198
- const hasArrayBuffer = typeof window.ArrayBuffer === "function"
199
-
200
- const hasSearchParams = typeof window.URLSearchParams === "function"
201
-
202
- const createRequestError = (error, { url }) => {
203
- return new Error(
204
- `error during xhr request on ${url}.
205
- --- error stack ---
206
- ${error.stack}`,
207
- )
208
- }
209
-
210
- const createPromiseAndHooks = () => {
211
- let resolve
212
- let reject
213
- const promise = new Promise((res, rej) => {
214
- resolve = (value) => {
215
- promise.settled = true
216
- res(value)
217
- }
218
- reject = (value) => {
219
- promise.settled = true
220
- rej(value)
221
- }
222
- })
223
- promise.resolve = resolve
224
- promise.reject = reject
225
- return promise
226
- }
227
-
228
- // https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
229
- const computeWithCredentials = ({ credentials, url }) => {
230
- if (credentials === "same-origin") {
231
- return originSameAsGlobalOrigin(url)
232
- }
233
- return credentials === "include"
234
- }
235
-
236
- const originSameAsGlobalOrigin = (url) => {
237
- // if we cannot read globalOrigin from window.location.origin, let's consider it's ok
238
- if (typeof window !== "object") return true
239
- if (typeof window.location !== "object") return true
240
- const globalOrigin = window.location.origin
241
- if (globalOrigin === "null") return true
242
- return hrefToOrigin(url) === globalOrigin
243
- }
244
-
245
- const detectBodyType = (body) => {
246
- if (!body) {
247
- return ""
248
- }
249
- if (typeof body === "string") {
250
- return "text"
251
- }
252
- if (hasBlob && Blob.prototype.isPrototypeOf(body)) {
253
- return "blob"
254
- }
255
- if (hasFormData && FormData.prototype.isPrototypeOf(body)) {
256
- return "formData"
257
- }
258
- if (hasArrayBuffer) {
259
- if (hasBlob && isDataView(body)) {
260
- return `dataView`
261
- }
262
- if (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body)) {
263
- return `arrayBuffer`
264
- }
265
- }
266
- if (hasSearchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
267
- return "searchParams"
268
- }
269
- return ""
270
- }
271
-
272
- // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/getAllResponseHeaders#Example
273
- const getHeadersFromXHR = (xhr) => {
274
- const headerMap = {}
275
-
276
- const headersString = xhr.getAllResponseHeaders()
277
- if (headersString === "") return headerMap
278
-
279
- const lines = headersString.trim().split(/[\r\n]+/)
280
- lines.forEach((line) => {
281
- const parts = line.split(": ")
282
- const name = parts.shift()
283
- const value = parts.join(": ")
284
- headerMap[name.toLowerCase()] = value
285
- })
286
-
287
- return headerMap
288
- }
289
-
290
- const hrefToOrigin = (href) => {
291
- const scheme = hrefToScheme(href)
292
-
293
- if (scheme === "file") {
294
- return "file://"
295
- }
296
-
297
- if (scheme === "http" || scheme === "https") {
298
- const secondProtocolSlashIndex = scheme.length + "://".length
299
- const pathnameSlashIndex = href.indexOf("/", secondProtocolSlashIndex)
300
-
301
- if (pathnameSlashIndex === -1) return href
302
- return href.slice(0, pathnameSlashIndex)
303
- }
304
-
305
- return href.slice(0, scheme.length + 1)
306
- }
307
-
308
- const hrefToScheme = (href) => {
309
- const colonIndex = href.indexOf(":")
310
- if (colonIndex === -1) return ""
311
- return href.slice(0, colonIndex)
312
- }
313
-
314
- const isDataView = (obj) => {
315
- return obj && DataView.prototype.isPrototypeOf(obj)
316
- }
317
-
318
- const isArrayBufferView =
319
- ArrayBuffer.isView ||
320
- (() => {
321
- const viewClasses = [
322
- "[object Int8Array]",
323
- "[object Uint8Array]",
324
- "[object Uint8ClampedArray]",
325
- "[object Int16Array]",
326
- "[object Uint16Array]",
327
- "[object Int32Array]",
328
- "[object Uint32Array]",
329
- "[object Float32Array]",
330
- "[object Float64Array]",
331
- ]
332
-
333
- return (value) => {
334
- return (
335
- value && viewClasses.includes(Object.prototype.toString.call(value))
336
- )
337
- }
338
- })()
339
-
340
- const textToFormData = (text) => {
341
- const form = new FormData()
342
- text
343
- .trim()
344
- .split("&")
345
- .forEach(function (bytes) {
346
- if (bytes) {
347
- const split = bytes.split("=")
348
- const name = split.shift().replace(/\+/g, " ")
349
- const value = split.join("=").replace(/\+/g, " ")
350
- form.append(decodeURIComponent(name), decodeURIComponent(value))
351
- }
352
- })
353
- return form
354
- }
355
-
356
- const blobToArrayBuffer = async (blob) => {
357
- const reader = new FileReader()
358
- const promise = fileReaderReady(reader)
359
- reader.readAsArrayBuffer(blob)
360
- return promise
361
- }
362
-
363
- const blobToText = (blob) => {
364
- const reader = new FileReader()
365
- const promise = fileReaderReady(reader)
366
- reader.readAsText(blob)
367
- return promise
368
- }
369
-
370
- const arrayBufferToText = (arrayBuffer) => {
371
- const view = new Uint8Array(arrayBuffer)
372
- const chars = new Array(view.length)
373
- let i = 0
374
- while (i < view.length) {
375
- chars[i] = String.fromCharCode(view[i])
376
-
377
- i++
378
- }
379
- return chars.join("")
380
- }
381
-
382
- const fileReaderReady = (reader) => {
383
- return new Promise(function (resolve, reject) {
384
- reader.onload = function () {
385
- resolve(reader.result)
386
- }
387
- reader.onerror = function () {
388
- reject(reader.error)
389
- }
390
- })
391
- }
392
-
393
- const cloneBuffer = (buffer) => {
394
- if (buffer.slice) {
395
- return buffer.slice(0)
396
- }
397
- const view = new Uint8Array(buffer.byteLength)
398
- view.set(new Uint8Array(buffer))
399
- return view.buffer
400
- }
@@ -1,14 +0,0 @@
1
- import { memoize } from "@jsenv/utils/src/memoize/memoize.js"
2
-
3
- const fetchPolyfill = async (...args) => {
4
- const { fetchUsingXHR } = await loadPolyfill()
5
- return fetchUsingXHR(...args)
6
- }
7
-
8
- const loadPolyfill = memoize(() => import("./fetch_using_xhr.js"))
9
-
10
- export const fetchUrl =
11
- typeof window.fetch === "function" &&
12
- typeof window.AbortController === "function"
13
- ? window.fetch
14
- : fetchPolyfill
@@ -1,10 +0,0 @@
1
- export const setLinkHrefForParentWindow = (a, href) => {
2
- a.href = href
3
- a.onclick = (e) => {
4
- if (e.ctrlKey || e.metaKey) {
5
- return
6
- }
7
- e.preventDefault()
8
- window.parent.location.href = href
9
- }
10
- }
@@ -1,28 +0,0 @@
1
- const JSENV_LOG_ENABLED = false
2
-
3
- export const jsenvLogger = {
4
- log: (...args) => {
5
- // prevent logs for now (do not mess with user logs)
6
- if (JSENV_LOG_ENABLED) {
7
- console.log(...prefixArgs(...args))
8
- }
9
- },
10
-
11
- debug: (...args) => {
12
- if (JSENV_LOG_ENABLED) {
13
- console.log(...prefixArgs(...args))
14
- }
15
- },
16
- }
17
-
18
- // a nice yellow:ffdc00
19
- const backgroundColor = "#F7931E" // jsenv logo color
20
-
21
- // eslint-disable-next-line no-unused-vars
22
- const prefixArgs = (...args) => {
23
- return [
24
- `%cjsenv`,
25
- `background: ${backgroundColor}; color: black; padding: 1px 3px; margin: 0 1px`,
26
- ...args,
27
- ]
28
- }
@@ -1,10 +0,0 @@
1
- export const createPreference = (name) => {
2
- return {
3
- has: () => localStorage.hasOwnProperty(name),
4
- get: () =>
5
- localStorage.hasOwnProperty(name)
6
- ? JSON.parse(localStorage.getItem(name))
7
- : undefined,
8
- set: (value) => localStorage.setItem(name, JSON.stringify(value)),
9
- }
10
- }
@@ -1,112 +0,0 @@
1
- export const createHorizontalBreakpoint = (breakpointValue) => {
2
- return createBreakpoint(windowWidthMeasure, breakpointValue)
3
- }
4
-
5
- const createMeasure = ({ compute, register }) => {
6
- let currentValue = compute()
7
-
8
- const get = () => compute()
9
-
10
- const changed = createSignal()
11
-
12
- let unregister = () => {}
13
- if (register) {
14
- unregister = register(() => {
15
- const value = compute()
16
- if (value !== currentValue) {
17
- const previousValue = value
18
- currentValue = value
19
- changed.notify(value, previousValue)
20
- }
21
- })
22
- }
23
-
24
- return { get, changed, unregister }
25
- }
26
-
27
- const createSignal = () => {
28
- const callbackArray = []
29
-
30
- const listen = (callback) => {
31
- callbackArray.push(callback)
32
- return () => {
33
- const index = callbackArray.indexOf(callback)
34
- if (index > -1) {
35
- callbackArray.splice(index, 1)
36
- }
37
- }
38
- }
39
-
40
- const notify = (...args) => {
41
- callbackArray.slice().forEach((callback) => {
42
- callback(...args)
43
- })
44
- }
45
-
46
- return { listen, notify }
47
- }
48
-
49
- const windowWidthMeasure = createMeasure({
50
- name: "window-width",
51
- compute: () => window.innerWidth,
52
- register: (onchange) => {
53
- window.addEventListener("resize", onchange)
54
- window.addEventListener("orientationchange", onchange)
55
- return () => {
56
- window.removeEventListener("resize", onchange)
57
- window.removeEventListener("orientationchange", onchange)
58
- }
59
- },
60
- })
61
-
62
- const createBreakpoint = (measure, breakpointValue) => {
63
- const getBreakpointState = () => {
64
- const value = measure.get()
65
-
66
- if (value < breakpointValue) {
67
- return "below"
68
- }
69
- if (value > breakpointValue) {
70
- return "above"
71
- }
72
- return "equals"
73
- }
74
-
75
- let currentBreakpointState = getBreakpointState()
76
-
77
- const isAbove = () => {
78
- return measure.get() > breakpointValue
79
- }
80
-
81
- const isBelow = () => {
82
- return measure.get() < breakpointValue
83
- }
84
-
85
- const breakpointChanged = createSignal()
86
-
87
- measure.changed.listen(() => {
88
- const breakpointState = getBreakpointState()
89
- if (breakpointState !== currentBreakpointState) {
90
- const breakpointStatePrevious = currentBreakpointState
91
- currentBreakpointState = breakpointState
92
- breakpointChanged.notify(breakpointState, breakpointStatePrevious)
93
- }
94
- })
95
-
96
- return {
97
- isAbove,
98
- isBelow,
99
- changed: breakpointChanged,
100
- }
101
- }
102
-
103
- // const windowScrollTop = createMeasure({
104
- // name: "window-scroll-top",
105
- // compute: () => window.scrollTop,
106
- // register: (onchange) => {
107
- // window.addEventListener("scroll", onchange)
108
- // return () => {
109
- // window.removeEventListener("scroll", onchange)
110
- // }
111
- // },
112
- // })
@@ -1,19 +0,0 @@
1
- export const createPromiseAndHooks = () => {
2
- let resolve
3
- let reject
4
- const promise = new Promise((res, rej) => {
5
- resolve = res
6
- reject = rej
7
- })
8
- promise.resolve = resolve
9
- promise.reject = reject
10
- return promise
11
- }
12
-
13
- export const moveElement = (element, from, to) => {
14
- to.appendChild(element)
15
- }
16
-
17
- export const replaceElement = (elementToReplace, otherElement) => {
18
- elementToReplace.parentNode.replaceChild(otherElement, elementToReplace)
19
- }
@@ -1,74 +0,0 @@
1
- export const enableVariant = (rootNode, variables) => {
2
- const nodesNotMatching = Array.from(
3
- rootNode.querySelectorAll(`[${attributeIndicatingACondition}]`),
4
- )
5
- nodesNotMatching.forEach((nodeNotMatching) => {
6
- const conditionAttributeValue = nodeNotMatching.getAttribute(
7
- attributeIndicatingACondition,
8
- )
9
- const matches = testCondition(conditionAttributeValue, variables)
10
- if (matches) {
11
- renameAttribute(
12
- nodeNotMatching,
13
- attributeIndicatingACondition,
14
- attributeIndicatingAMatch,
15
- )
16
- }
17
- })
18
-
19
- const nodesMatching = Array.from(
20
- rootNode.querySelectorAll(`[${attributeIndicatingAMatch}]`),
21
- )
22
- nodesMatching.forEach((nodeMatching) => {
23
- const conditionAttributeValue = nodeMatching.getAttribute(
24
- attributeIndicatingAMatch,
25
- )
26
- const matches = testCondition(conditionAttributeValue, variables)
27
- if (!matches) {
28
- renameAttribute(
29
- nodeMatching,
30
- attributeIndicatingAMatch,
31
- attributeIndicatingACondition,
32
- )
33
- }
34
- })
35
- }
36
-
37
- const testCondition = (conditionAttributeValue, variables) => {
38
- const condition = parseCondition(conditionAttributeValue)
39
- return Object.keys(variables).some((key) => {
40
- if (condition.key !== key) {
41
- return false
42
- }
43
- // the condition do not specify a value, any value is ok
44
- if (condition.value === undefined) {
45
- return true
46
- }
47
- if (condition.value === variables[key]) {
48
- return true
49
- }
50
- return false
51
- })
52
- }
53
-
54
- const parseCondition = (conditionAttributeValue) => {
55
- const colonIndex = conditionAttributeValue.indexOf(":")
56
- if (colonIndex === -1) {
57
- return {
58
- key: conditionAttributeValue,
59
- value: undefined,
60
- }
61
- }
62
- return {
63
- key: conditionAttributeValue.slice(0, colonIndex),
64
- value: conditionAttributeValue.slice(colonIndex + 1),
65
- }
66
- }
67
-
68
- const attributeIndicatingACondition = `data-when`
69
- const attributeIndicatingAMatch = `data-when-active`
70
-
71
- const renameAttribute = (node, name, newName) => {
72
- node.setAttribute(newName, node.getAttribute(name))
73
- node.removeAttribute(name)
74
- }