-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathcompose.html
More file actions
115 lines (115 loc) · 4.45 KB
/
compose.html
File metadata and controls
115 lines (115 loc) · 4.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; font-src 'self' data:; connect-src 'self' https://api.forwardemail.net wss://api.forwardemail.net; worker-src 'self' blob:; frame-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; media-src 'none'"
/>
<title>Compose — Forward Email</title>
</head>
<body>
<div id="compose-root"></div>
<div id="toasts-root"></div>
<script>
// Fatal-error diagnostic overlay — see index.html for full notes.
// Registered before /src/compose-main.ts so it catches module-init
// failures in the compose window's bundle (which has the same dep
// graph risks as the main window).
(function () {
var SHOWN = false;
function showFatal(detail) {
if (SHOWN) {
var prev = document.getElementById('fe-fatal-error');
if (prev) {
prev.textContent += '\n\n' + detail;
return;
}
}
SHOWN = true;
var d = document.createElement('div');
d.id = 'fe-fatal-error';
d.style.cssText = [
'position:fixed',
'inset:0',
'z-index:2147483647',
'background:#1a1a1a',
'color:#f5f5f5',
'font:12px/1.45 ui-monospace,Menlo,Consolas,monospace',
'padding:16px 18px',
'overflow:auto',
'white-space:pre-wrap',
'word-break:break-word',
].join(';');
d.textContent = detail;
(document.body || document.documentElement).appendChild(d);
}
function describe(label, err) {
var lines = [];
lines.push('Fatal (compose): ' + label);
lines.push('UA: ' + navigator.userAgent);
lines.push('URL: ' + location.href);
lines.push('Time: ' + new Date().toISOString());
lines.push('');
var name = (err && err.name) || 'Error';
var msg =
(err && (err.message || err.reason || (err.toString && err.toString()))) || String(err);
lines.push('Type: ' + name);
lines.push('Message: ' + msg);
if (err && err.fileName) lines.push('File: ' + err.fileName);
if (err && err.lineNumber != null) lines.push('Line: ' + err.lineNumber);
if (err && err.columnNumber != null) lines.push('Col: ' + err.columnNumber);
if (err && err.stack) {
lines.push('');
lines.push('Stack:');
lines.push(String(err.stack));
}
return lines.join('\n');
}
window.addEventListener(
'error',
function (event) {
var t = event.target;
if (t && t !== window && t.tagName) return;
var err = event.error || {
name: 'Error',
message: event.message || 'unknown error',
fileName: event.filename,
lineNumber: event.lineno,
columnNumber: event.colno,
};
try {
console.error('[fe-fatal][compose]', err, event);
} catch (_) {}
showFatal(describe('error', err));
},
true,
);
window.addEventListener('unhandledrejection', function (event) {
var reason = event.reason || { message: 'unhandled rejection' };
try {
console.error('[fe-fatal][compose][unhandledrejection]', reason);
} catch (_) {}
showFatal(describe('unhandledrejection', reason));
});
document.addEventListener('securitypolicyviolation', function (e) {
try {
console.error('[fe-fatal][compose][csp]', e);
} catch (_) {}
showFatal(
[
'CSP violation',
'directive: ' + e.violatedDirective,
'effective: ' + e.effectiveDirective,
'blockedURI: ' + e.blockedURI,
'sourceFile: ' + e.sourceFile + ':' + e.lineNumber + ':' + e.columnNumber,
'sample: ' + (e.sample || ''),
].join('\n'),
);
});
})();
</script>
<script type="module" src="/src/compose-main.ts"></script>
</body>
</html>