-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbrowser-error.js
More file actions
131 lines (117 loc) · 3.77 KB
/
Copy pathbrowser-error.js
File metadata and controls
131 lines (117 loc) · 3.77 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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
const FEATURE_LABELS = {
canvas: 'Canvas 2D API',
bigint: 'BigInt',
indexeddb: 'IndexedDB',
};
/**
* Render a user-friendly error screen when required browser features are missing.
*
* @param {HTMLElement} container - Parent element to render into
* @param {string[]} missingFeatures - Array of feature keys (e.g. ['bigint', 'canvas'])
* @returns {{ element: HTMLElement }}
*/
export function createBrowserError(container, missingFeatures) {
const overlay = document.createElement('div');
overlay.setAttribute('role', 'alert');
overlay.setAttribute('aria-live', 'assertive');
overlay.setAttribute('aria-atomic', 'true');
overlay.setAttribute('tabindex', '-1');
applyStyles(overlay, {
position: 'fixed',
inset: '0',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
background: '#1a1a2e',
color: '#e0e0e0',
fontFamily: 'system-ui, -apple-system, sans-serif',
zIndex: '9999',
padding: '2rem',
});
const card = document.createElement('div');
applyStyles(card, {
maxWidth: '480px',
width: '100%',
background: '#2a2a3e',
border: '1px solid #4a4a6a',
borderRadius: '12px',
padding: '2rem',
textAlign: 'center',
});
const icon = document.createElement('div');
icon.textContent = '⚠️';
icon.setAttribute('aria-hidden', 'true');
applyStyles(icon, { fontSize: '3rem', marginBottom: '1rem' });
const title = document.createElement('h2');
title.textContent = 'Browser Not Supported';
applyStyles(title, {
fontSize: '1.5rem',
fontWeight: '700',
color: '#ff6b6b',
marginBottom: '0.75rem',
});
const message = document.createElement('p');
message.textContent =
missingFeatures.length > 0
? 'Nayra requires the following browser features that are not available:'
: 'Your browser appears to be missing required features.';
applyStyles(message, {
color: '#b0b0c8',
marginBottom: '1.25rem',
lineHeight: '1.5',
});
card.appendChild(icon);
card.appendChild(title);
card.appendChild(message);
if (missingFeatures.length > 0) {
const list = document.createElement('ul');
list.setAttribute('aria-label', 'Missing browser features');
applyStyles(list, {
listStyle: 'none',
margin: '0 0 1.5rem',
padding: '0',
textAlign: 'left',
});
for (const key of missingFeatures) {
const item = document.createElement('li');
applyStyles(item, {
display: 'flex',
alignItems: 'center',
gap: '0.5rem',
padding: '0.4rem 0.75rem',
background: '#1a1a2e',
borderRadius: '6px',
marginBottom: '0.4rem',
fontFamily: 'monospace',
fontSize: '0.9rem',
color: '#ff6b6b',
});
const mark = document.createElement('span');
mark.textContent = '✗';
mark.setAttribute('aria-hidden', 'true');
const label = document.createElement('span');
label.textContent = FEATURE_LABELS[key] ?? key;
item.appendChild(mark);
item.appendChild(label);
list.appendChild(item);
}
card.appendChild(list);
}
const suggestion = document.createElement('p');
applyStyles(suggestion, { color: '#b0b0c8', fontSize: '0.9rem', lineHeight: '1.5' });
suggestion.textContent = 'Please upgrade to a modern browser such as ';
const browsers = document.createElement('strong');
browsers.textContent = 'Chrome 90+, Firefox 90+, or Safari 14+';
applyStyles(browsers, { color: '#00d9ff' });
suggestion.appendChild(browsers);
suggestion.append('.');
card.appendChild(suggestion);
overlay.appendChild(card);
container.appendChild(overlay);
// Focus the overlay so screen readers announce it immediately
overlay.focus();
return { element: overlay };
}
function applyStyles(el, styles) {
Object.assign(el.style, styles);
}