@jsenv/core 27.5.0 → 27.5.3
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/dist/js/html_supervisor_installer.js +372 -289
- package/dist/main.js +63 -18
- package/package.json +2 -1
- package/src/dev/start_dev_server.js +5 -3
- package/src/plugins/html_supervisor/client/error_formatter.js +305 -0
- package/src/plugins/html_supervisor/client/error_overlay.js +60 -268
- package/src/plugins/html_supervisor/client/html_supervisor_installer.js +23 -32
- package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +53 -15
- package/src/test/execute_test_plan.js +1 -2
|
@@ -10,213 +10,170 @@ const unevalException = value => {
|
|
|
10
10
|
});
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
const
|
|
14
|
-
const displayErrorInDocument = (error, {
|
|
13
|
+
const formatError = (error, {
|
|
15
14
|
rootDirectoryUrl,
|
|
15
|
+
errorBaseUrl,
|
|
16
16
|
openInEditor,
|
|
17
17
|
url,
|
|
18
18
|
line,
|
|
19
19
|
column,
|
|
20
|
-
|
|
21
|
-
requestedRessource
|
|
20
|
+
codeFrame,
|
|
21
|
+
requestedRessource,
|
|
22
|
+
reportedBy
|
|
22
23
|
}) => {
|
|
23
|
-
|
|
24
|
-
node.parentNode.removeChild(node);
|
|
25
|
-
});
|
|
26
|
-
const {
|
|
27
|
-
theme,
|
|
28
|
-
title,
|
|
24
|
+
let {
|
|
29
25
|
message,
|
|
30
|
-
stack
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
stack
|
|
27
|
+
} = normalizeErrorParts(error);
|
|
28
|
+
let codeFramePromiseReference = {
|
|
29
|
+
current: null
|
|
30
|
+
};
|
|
31
|
+
let tip = formatTip({
|
|
36
32
|
reportedBy,
|
|
37
33
|
requestedRessource
|
|
38
34
|
});
|
|
39
|
-
let
|
|
40
|
-
theme,
|
|
41
|
-
title,
|
|
42
|
-
text: createErrorText({
|
|
43
|
-
rootDirectoryUrl,
|
|
44
|
-
openInEditor,
|
|
45
|
-
message,
|
|
46
|
-
stack
|
|
47
|
-
}),
|
|
48
|
-
tip
|
|
49
|
-
});
|
|
50
|
-
document.body.appendChild(jsenvErrorOverlay);
|
|
35
|
+
let errorUrlSite;
|
|
51
36
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
37
|
+
const resolveUrlSite = ({
|
|
38
|
+
url,
|
|
39
|
+
line,
|
|
40
|
+
column
|
|
41
|
+
}) => {
|
|
42
|
+
const inlineUrlMatch = url.match(/@L([0-9]+)\-L([0-9]+)\.[\w]+$/);
|
|
43
|
+
|
|
44
|
+
if (inlineUrlMatch) {
|
|
45
|
+
const htmlUrl = url.slice(0, inlineUrlMatch.index);
|
|
46
|
+
const tagLine = parseInt(inlineUrlMatch[1]);
|
|
47
|
+
const tagColumn = parseInt(inlineUrlMatch[2]);
|
|
48
|
+
url = htmlUrl;
|
|
49
|
+
line = tagLine + parseInt(line) - 1;
|
|
50
|
+
column = tagColumn + parseInt(column);
|
|
56
51
|
}
|
|
57
|
-
};
|
|
58
52
|
|
|
59
|
-
|
|
60
|
-
window.__reloader__.onstatuschange = () => {
|
|
61
|
-
if (window.__reloader__.status === "reloading") {
|
|
62
|
-
removeErrorOverlay();
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
}
|
|
53
|
+
let urlObject = new URL(url);
|
|
66
54
|
|
|
67
|
-
|
|
68
|
-
};
|
|
55
|
+
if (urlObject.origin === window.origin) {
|
|
56
|
+
urlObject = new URL(`${urlObject.pathname.slice(1)}${urlObject.search}`, rootDirectoryUrl);
|
|
57
|
+
}
|
|
69
58
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
openInEditor,
|
|
73
|
-
message,
|
|
74
|
-
stack
|
|
75
|
-
}) => {
|
|
76
|
-
if (message && stack) {
|
|
77
|
-
return `${replaceLinks(message, {
|
|
78
|
-
rootDirectoryUrl,
|
|
79
|
-
openInEditor
|
|
80
|
-
})}\n${replaceLinks(stack, {
|
|
81
|
-
rootDirectoryUrl,
|
|
82
|
-
openInEditor
|
|
83
|
-
})}`;
|
|
84
|
-
}
|
|
59
|
+
if (urlObject.href.startsWith("file:")) {
|
|
60
|
+
const atFsIndex = urlObject.pathname.indexOf("/@fs/");
|
|
85
61
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
62
|
+
if (atFsIndex > -1) {
|
|
63
|
+
const afterAtFs = urlObject.pathname.slice(atFsIndex + "/@fs/".length);
|
|
64
|
+
url = new URL(afterAtFs, "file:///").href;
|
|
65
|
+
} else {
|
|
66
|
+
url = urlObject.href;
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
url = urlObject.href;
|
|
70
|
+
}
|
|
92
71
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
};
|
|
72
|
+
return {
|
|
73
|
+
url,
|
|
74
|
+
line,
|
|
75
|
+
column
|
|
76
|
+
};
|
|
77
|
+
};
|
|
98
78
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
this.root.innerHTML = overlayHtml;
|
|
79
|
+
const generateClickableText = text => {
|
|
80
|
+
const textWithHtmlLinks = makeLinksClickable(text, {
|
|
81
|
+
createLink: (url, {
|
|
82
|
+
line,
|
|
83
|
+
column
|
|
84
|
+
}) => {
|
|
85
|
+
const urlSite = resolveUrlSite({
|
|
86
|
+
url,
|
|
87
|
+
line,
|
|
88
|
+
column
|
|
89
|
+
});
|
|
111
90
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
91
|
+
if (!errorUrlSite && text === stack) {
|
|
92
|
+
onErrorLocated(urlSite);
|
|
93
|
+
}
|
|
117
94
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
95
|
+
if (errorBaseUrl) {
|
|
96
|
+
if (urlSite.url.startsWith(rootDirectoryUrl)) {
|
|
97
|
+
urlSite.url = `${errorBaseUrl}${urlSite.url.slice(rootDirectoryUrl.length)}`;
|
|
98
|
+
} else {
|
|
99
|
+
urlSite.url = "file:///mocked_for_snapshots";
|
|
100
|
+
}
|
|
101
|
+
}
|
|
121
102
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
103
|
+
const urlWithLineAndColumn = formatUrlWithLineAndColumn(urlSite);
|
|
104
|
+
return {
|
|
105
|
+
href: url.startsWith("file:") && openInEditor ? `javascript:window.fetch('/__open_in_editor__/${urlWithLineAndColumn}')` : urlSite.url,
|
|
106
|
+
text: urlWithLineAndColumn
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
return textWithHtmlLinks;
|
|
111
|
+
};
|
|
127
112
|
|
|
128
|
-
|
|
113
|
+
const onErrorLocated = urlSite => {
|
|
114
|
+
errorUrlSite = urlSite;
|
|
129
115
|
|
|
130
|
-
if (
|
|
131
|
-
|
|
132
|
-
}
|
|
116
|
+
if (codeFrame) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
133
119
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
position: fixed;
|
|
138
|
-
z-index: 99999;
|
|
139
|
-
top: 0;
|
|
140
|
-
left: 0;
|
|
141
|
-
width: 100%;
|
|
142
|
-
height: 100%;
|
|
143
|
-
overflow-y: scroll;
|
|
144
|
-
margin: 0;
|
|
145
|
-
background: rgba(0, 0, 0, 0.66);
|
|
146
|
-
}
|
|
120
|
+
if (reportedBy !== "browser") {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
147
123
|
|
|
148
|
-
.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
124
|
+
codeFramePromiseReference.current = (async () => {
|
|
125
|
+
const response = await window.fetch(`/__get_code_frame__/${formatUrlWithLineAndColumn(urlSite)}`);
|
|
126
|
+
const codeFrame = await response.text();
|
|
127
|
+
const codeFrameClickable = generateClickableText(codeFrame);
|
|
128
|
+
return codeFrameClickable;
|
|
129
|
+
})();
|
|
130
|
+
}; // error.stack is more reliable than url/line/column reported on window error events
|
|
131
|
+
// so use it only when error.stack is not available
|
|
155
132
|
|
|
156
|
-
.overlay {
|
|
157
|
-
position: relative;
|
|
158
|
-
background: rgba(0, 0, 0, 0.95);
|
|
159
|
-
width: 800px;
|
|
160
|
-
margin: 30px auto;
|
|
161
|
-
padding: 25px 40px;
|
|
162
|
-
padding-top: 0;
|
|
163
|
-
overflow: hidden; /* for h1 margins */
|
|
164
|
-
border-radius: 4px 8px;
|
|
165
|
-
box-shadow: 0 20px 40px rgb(0 0 0 / 30%), 0 15px 12px rgb(0 0 0 / 20%);
|
|
166
|
-
box-sizing: border-box;
|
|
167
|
-
font-family: monospace;
|
|
168
|
-
direction: ltr;
|
|
169
|
-
}
|
|
170
133
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
134
|
+
if (url && !stack && // ignore window.reportError() it gives no valuable info
|
|
135
|
+
!url.endsWith("html_supervisor_installer.js")) {
|
|
136
|
+
onErrorLocated(resolveUrlSite({
|
|
137
|
+
url,
|
|
138
|
+
line,
|
|
139
|
+
column
|
|
140
|
+
}));
|
|
141
|
+
}
|
|
175
142
|
|
|
176
|
-
|
|
177
|
-
overflow: auto;
|
|
178
|
-
max-width: 100%;
|
|
179
|
-
/* padding is nice + prevents scrollbar from hiding the text behind it */
|
|
180
|
-
/* does not work nicely on firefox though https://bugzilla.mozilla.org/show_bug.cgi?id=748518 */
|
|
181
|
-
padding: 20px;
|
|
182
|
-
}
|
|
143
|
+
let text;
|
|
183
144
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
145
|
+
if (message && stack) {
|
|
146
|
+
text = `${generateClickableText(message)}\n${generateClickableText(stack)}`;
|
|
147
|
+
} else if (stack) {
|
|
148
|
+
text = generateClickableText(stack);
|
|
149
|
+
} else {
|
|
150
|
+
text = generateClickableText(message);
|
|
151
|
+
}
|
|
188
152
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
[data-theme="dark"] pre {
|
|
193
|
-
background: #111;
|
|
194
|
-
border: 1px solid #333;
|
|
195
|
-
color: #eee;
|
|
196
|
-
}
|
|
153
|
+
if (codeFrame) {
|
|
154
|
+
text += `\n\n${generateClickableText(codeFrame)}`;
|
|
155
|
+
}
|
|
197
156
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
157
|
+
return {
|
|
158
|
+
theme: error && error.cause && error.cause.code === "PARSE_ERROR" ? "light" : "dark",
|
|
159
|
+
title: "An error occured",
|
|
160
|
+
text,
|
|
161
|
+
codeFramePromise: codeFramePromiseReference.current,
|
|
162
|
+
tip: `${tip}
|
|
163
|
+
<br />
|
|
164
|
+
Click outside to close.`
|
|
165
|
+
};
|
|
166
|
+
};
|
|
206
167
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
</div>
|
|
217
|
-
`;
|
|
218
|
-
|
|
219
|
-
const parseErrorInfo = error => {
|
|
168
|
+
const formatUrlWithLineAndColumn = ({
|
|
169
|
+
url,
|
|
170
|
+
line,
|
|
171
|
+
column
|
|
172
|
+
}) => {
|
|
173
|
+
return line === undefined && column === undefined ? url : column === undefined ? `${url}:${line}` : `${url}:${line}:${column}`;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const normalizeErrorParts = error => {
|
|
220
177
|
if (error === undefined) {
|
|
221
178
|
return {
|
|
222
179
|
message: "undefined"
|
|
@@ -294,42 +251,6 @@ const getErrorStackWithoutErrorMessage = error => {
|
|
|
294
251
|
return stack;
|
|
295
252
|
};
|
|
296
253
|
|
|
297
|
-
const errorToHTML = (error, {
|
|
298
|
-
url,
|
|
299
|
-
line,
|
|
300
|
-
column,
|
|
301
|
-
reportedBy,
|
|
302
|
-
requestedRessource
|
|
303
|
-
}) => {
|
|
304
|
-
let {
|
|
305
|
-
message,
|
|
306
|
-
stack
|
|
307
|
-
} = parseErrorInfo(error);
|
|
308
|
-
|
|
309
|
-
if (url) {
|
|
310
|
-
if (!stack || error && error.name === "SyntaxError") {
|
|
311
|
-
stack = ` at ${appendLineAndColumn(url, {
|
|
312
|
-
line,
|
|
313
|
-
column
|
|
314
|
-
})}`;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
let tip = formatTip({
|
|
319
|
-
reportedBy,
|
|
320
|
-
requestedRessource
|
|
321
|
-
});
|
|
322
|
-
return {
|
|
323
|
-
theme: error && error.cause && error.cause.code === "PARSE_ERROR" ? "light" : "dark",
|
|
324
|
-
title: "An error occured",
|
|
325
|
-
message,
|
|
326
|
-
stack,
|
|
327
|
-
tip: `${tip}
|
|
328
|
-
<br />
|
|
329
|
-
Click outside to close.`
|
|
330
|
-
};
|
|
331
|
-
};
|
|
332
|
-
|
|
333
254
|
const formatTip = ({
|
|
334
255
|
reportedBy,
|
|
335
256
|
requestedRessource
|
|
@@ -341,9 +262,8 @@ const formatTip = ({
|
|
|
341
262
|
return `Reported by the server while serving <code>${requestedRessource}</code>`;
|
|
342
263
|
};
|
|
343
264
|
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
openInEditor
|
|
265
|
+
const makeLinksClickable = (string, {
|
|
266
|
+
createLink = url => url
|
|
347
267
|
}) => {
|
|
348
268
|
// normalize line breaks
|
|
349
269
|
string = string.replace(/\n/g, "\n");
|
|
@@ -354,44 +274,16 @@ const replaceLinks = (string, {
|
|
|
354
274
|
line,
|
|
355
275
|
column
|
|
356
276
|
}) => {
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
const afterAtFs = fileUrlObject.pathname.slice(atFsIndex + "/@fs/".length);
|
|
365
|
-
fileUrl = new URL(afterAtFs, "file:///").href;
|
|
366
|
-
} else {
|
|
367
|
-
fileUrl = fileUrlObject.href;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
fileUrl = appendLineAndColumn(fileUrl, {
|
|
371
|
-
line,
|
|
372
|
-
column
|
|
373
|
-
});
|
|
374
|
-
return link({
|
|
375
|
-
href: openInEditor ? `javascript:window.fetch('/__open_in_editor__/${fileUrl}')` : fileUrl,
|
|
376
|
-
text: fileUrl
|
|
377
|
-
});
|
|
378
|
-
};
|
|
379
|
-
|
|
380
|
-
if (urlObject.origin === window.origin) {
|
|
381
|
-
const fileUrlObject = new URL(`${urlObject.pathname.slice(1)}${urlObject.search}`, rootDirectoryUrl);
|
|
382
|
-
return onFileUrl(fileUrlObject);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
if (urlObject.href.startsWith("file:")) {
|
|
386
|
-
return onFileUrl(urlObject);
|
|
387
|
-
}
|
|
388
|
-
|
|
277
|
+
const {
|
|
278
|
+
href,
|
|
279
|
+
text
|
|
280
|
+
} = createLink(url, {
|
|
281
|
+
line,
|
|
282
|
+
column
|
|
283
|
+
});
|
|
389
284
|
return link({
|
|
390
|
-
href
|
|
391
|
-
text
|
|
392
|
-
line,
|
|
393
|
-
column
|
|
394
|
-
})
|
|
285
|
+
href,
|
|
286
|
+
text
|
|
395
287
|
});
|
|
396
288
|
}
|
|
397
289
|
});
|
|
@@ -400,21 +292,6 @@ const replaceLinks = (string, {
|
|
|
400
292
|
|
|
401
293
|
const escapeHtml = string => {
|
|
402
294
|
return string.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
403
|
-
};
|
|
404
|
-
|
|
405
|
-
const appendLineAndColumn = (url, {
|
|
406
|
-
line,
|
|
407
|
-
column
|
|
408
|
-
}) => {
|
|
409
|
-
if (line !== undefined && column !== undefined) {
|
|
410
|
-
return `${url}:${line}:${column}`;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
if (line !== undefined) {
|
|
414
|
-
return `${url}:${line}`;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
return url;
|
|
418
295
|
}; // `Error: yo
|
|
419
296
|
// at Object.execute (http://127.0.0.1:57300/build/src/__test__/file-throw.js:9:13)
|
|
420
297
|
// at doExec (http://127.0.0.1:3000/src/__test__/file-throw.js:452:38)
|
|
@@ -481,6 +358,210 @@ const link = ({
|
|
|
481
358
|
text = href
|
|
482
359
|
}) => `<a href="${href}">${text}</a>`;
|
|
483
360
|
|
|
361
|
+
const JSENV_ERROR_OVERLAY_TAGNAME = "jsenv-error-overlay";
|
|
362
|
+
let previousErrorInfo = null;
|
|
363
|
+
const displayErrorInDocument = (error, {
|
|
364
|
+
rootDirectoryUrl,
|
|
365
|
+
errorBaseUrl,
|
|
366
|
+
openInEditor,
|
|
367
|
+
url,
|
|
368
|
+
line,
|
|
369
|
+
column,
|
|
370
|
+
codeFrame,
|
|
371
|
+
reportedBy,
|
|
372
|
+
requestedRessource
|
|
373
|
+
}) => {
|
|
374
|
+
const nowMs = Date.now(); // ensure error dispatched on window by browser is displayed first
|
|
375
|
+
// then the server error replaces it (because it contains more information)
|
|
376
|
+
|
|
377
|
+
if (previousErrorInfo) {
|
|
378
|
+
const previousErrorReportedBy = previousErrorInfo.reportedBy;
|
|
379
|
+
const msEllapsedSincePreviousError = nowMs - previousErrorInfo.ms;
|
|
380
|
+
|
|
381
|
+
if (previousErrorReportedBy === "server" && reportedBy === "browser" && msEllapsedSincePreviousError < 50) {
|
|
382
|
+
return () => {};
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
previousErrorInfo = {
|
|
387
|
+
ms: nowMs,
|
|
388
|
+
reportedBy
|
|
389
|
+
};
|
|
390
|
+
const {
|
|
391
|
+
theme,
|
|
392
|
+
title,
|
|
393
|
+
text,
|
|
394
|
+
codeFramePromise,
|
|
395
|
+
tip
|
|
396
|
+
} = formatError(error, {
|
|
397
|
+
rootDirectoryUrl,
|
|
398
|
+
errorBaseUrl,
|
|
399
|
+
openInEditor,
|
|
400
|
+
url,
|
|
401
|
+
line,
|
|
402
|
+
column,
|
|
403
|
+
codeFrame,
|
|
404
|
+
reportedBy,
|
|
405
|
+
requestedRessource
|
|
406
|
+
});
|
|
407
|
+
let jsenvErrorOverlay = new JsenvErrorOverlay({
|
|
408
|
+
theme,
|
|
409
|
+
title,
|
|
410
|
+
text,
|
|
411
|
+
codeFramePromise,
|
|
412
|
+
tip
|
|
413
|
+
});
|
|
414
|
+
document.querySelectorAll(JSENV_ERROR_OVERLAY_TAGNAME).forEach(node => {
|
|
415
|
+
node.parentNode.removeChild(node);
|
|
416
|
+
});
|
|
417
|
+
document.body.appendChild(jsenvErrorOverlay);
|
|
418
|
+
|
|
419
|
+
const removeErrorOverlay = () => {
|
|
420
|
+
if (jsenvErrorOverlay && jsenvErrorOverlay.parentNode) {
|
|
421
|
+
document.body.removeChild(jsenvErrorOverlay);
|
|
422
|
+
jsenvErrorOverlay = null;
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
if (window.__reloader__) {
|
|
427
|
+
window.__reloader__.onstatuschange = () => {
|
|
428
|
+
if (window.__reloader__.status === "reloading") {
|
|
429
|
+
removeErrorOverlay();
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
return removeErrorOverlay;
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
class JsenvErrorOverlay extends HTMLElement {
|
|
438
|
+
constructor({
|
|
439
|
+
theme,
|
|
440
|
+
title,
|
|
441
|
+
text,
|
|
442
|
+
codeFramePromise,
|
|
443
|
+
tip
|
|
444
|
+
}) {
|
|
445
|
+
super();
|
|
446
|
+
this.root = this.attachShadow({
|
|
447
|
+
mode: "open"
|
|
448
|
+
});
|
|
449
|
+
this.root.innerHTML = `
|
|
450
|
+
<style>
|
|
451
|
+
${overlayCSS}
|
|
452
|
+
</style>
|
|
453
|
+
<div class="backdrop"></div>
|
|
454
|
+
<div class="overlay" data-theme=${theme}>
|
|
455
|
+
<h1 class="title">
|
|
456
|
+
${title}
|
|
457
|
+
</h1>
|
|
458
|
+
<pre class="text">${text}</pre>
|
|
459
|
+
<div class="tip">
|
|
460
|
+
${tip}
|
|
461
|
+
</div>
|
|
462
|
+
</div>`;
|
|
463
|
+
|
|
464
|
+
this.root.querySelector(".backdrop").onclick = () => {
|
|
465
|
+
if (!this.parentNode) {
|
|
466
|
+
// not in document anymore
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
this.root.querySelector(".backdrop").onclick = null;
|
|
471
|
+
this.parentNode.removeChild(this);
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
if (codeFramePromise) {
|
|
475
|
+
codeFramePromise.then(codeFrame => {
|
|
476
|
+
if (this.parentNode) {
|
|
477
|
+
this.root.querySelector(".text").innerHTML += `\n\n${codeFrame}`;
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (customElements && !customElements.get(JSENV_ERROR_OVERLAY_TAGNAME)) {
|
|
486
|
+
customElements.define(JSENV_ERROR_OVERLAY_TAGNAME, JsenvErrorOverlay);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
const overlayCSS = `
|
|
490
|
+
:host {
|
|
491
|
+
position: fixed;
|
|
492
|
+
z-index: 99999;
|
|
493
|
+
top: 0;
|
|
494
|
+
left: 0;
|
|
495
|
+
width: 100%;
|
|
496
|
+
height: 100%;
|
|
497
|
+
overflow-y: scroll;
|
|
498
|
+
margin: 0;
|
|
499
|
+
background: rgba(0, 0, 0, 0.66);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
.backdrop {
|
|
503
|
+
position: absolute;
|
|
504
|
+
left: 0;
|
|
505
|
+
right: 0;
|
|
506
|
+
top: 0;
|
|
507
|
+
bottom: 0;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
.overlay {
|
|
511
|
+
position: relative;
|
|
512
|
+
background: rgba(0, 0, 0, 0.95);
|
|
513
|
+
width: 800px;
|
|
514
|
+
margin: 30px auto;
|
|
515
|
+
padding: 25px 40px;
|
|
516
|
+
padding-top: 0;
|
|
517
|
+
overflow: hidden; /* for h1 margins */
|
|
518
|
+
border-radius: 4px 8px;
|
|
519
|
+
box-shadow: 0 20px 40px rgb(0 0 0 / 30%), 0 15px 12px rgb(0 0 0 / 20%);
|
|
520
|
+
box-sizing: border-box;
|
|
521
|
+
font-family: monospace;
|
|
522
|
+
direction: ltr;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
h1 {
|
|
526
|
+
color: red;
|
|
527
|
+
text-align: center;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
pre {
|
|
531
|
+
overflow: auto;
|
|
532
|
+
max-width: 100%;
|
|
533
|
+
/* padding is nice + prevents scrollbar from hiding the text behind it */
|
|
534
|
+
/* does not work nicely on firefox though https://bugzilla.mozilla.org/show_bug.cgi?id=748518 */
|
|
535
|
+
padding: 20px;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
.tip {
|
|
539
|
+
border-top: 1px solid #999;
|
|
540
|
+
padding-top: 12px;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
[data-theme="dark"] {
|
|
544
|
+
color: #999;
|
|
545
|
+
}
|
|
546
|
+
[data-theme="dark"] pre {
|
|
547
|
+
background: #111;
|
|
548
|
+
border: 1px solid #333;
|
|
549
|
+
color: #eee;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
[data-theme="light"] {
|
|
553
|
+
color: #EEEEEE;
|
|
554
|
+
}
|
|
555
|
+
[data-theme="light"] pre {
|
|
556
|
+
background: #1E1E1E;
|
|
557
|
+
border: 1px solid white;
|
|
558
|
+
color: #EEEEEE;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
pre a {
|
|
562
|
+
color: inherit;
|
|
563
|
+
}`;
|
|
564
|
+
|
|
484
565
|
const {
|
|
485
566
|
Notification
|
|
486
567
|
} = window;
|
|
@@ -514,6 +595,7 @@ const installHtmlSupervisor = ({
|
|
|
514
595
|
logs,
|
|
515
596
|
measurePerf,
|
|
516
597
|
errorOverlay,
|
|
598
|
+
errorBaseUrl,
|
|
517
599
|
openInEditor
|
|
518
600
|
}) => {
|
|
519
601
|
|
|
@@ -751,14 +833,18 @@ const installHtmlSupervisor = ({
|
|
|
751
833
|
}
|
|
752
834
|
|
|
753
835
|
const {
|
|
754
|
-
error
|
|
836
|
+
error,
|
|
837
|
+
filename,
|
|
838
|
+
lineno,
|
|
839
|
+
colno
|
|
755
840
|
} = errorEvent;
|
|
756
841
|
displayErrorInDocument(error, {
|
|
757
842
|
rootDirectoryUrl,
|
|
843
|
+
errorBaseUrl,
|
|
758
844
|
openInEditor,
|
|
759
|
-
url:
|
|
760
|
-
line:
|
|
761
|
-
column:
|
|
845
|
+
url: filename,
|
|
846
|
+
line: lineno,
|
|
847
|
+
column: colno,
|
|
762
848
|
reportedBy: "browser"
|
|
763
849
|
});
|
|
764
850
|
});
|
|
@@ -799,25 +885,22 @@ const installHtmlSupervisor = ({
|
|
|
799
885
|
|
|
800
886
|
if (isFaviconAutoRequest) {
|
|
801
887
|
return;
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
requestedRessource
|
|
819
|
-
});
|
|
820
|
-
}, 10);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
displayErrorInDocument({
|
|
891
|
+
message,
|
|
892
|
+
stack
|
|
893
|
+
}, {
|
|
894
|
+
rootDirectoryUrl,
|
|
895
|
+
errorBaseUrl,
|
|
896
|
+
openInEditor,
|
|
897
|
+
url: traceUrl,
|
|
898
|
+
line: traceLine,
|
|
899
|
+
column: traceColumn,
|
|
900
|
+
codeFrame: traceMessage,
|
|
901
|
+
reportedBy: "server",
|
|
902
|
+
requestedRessource
|
|
903
|
+
});
|
|
821
904
|
}
|
|
822
905
|
});
|
|
823
906
|
}
|