|
7 | 7 | <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='8' fill='%230f172a'/%3E%3Cpath fill='%23facc15' d='M16 4l3.4 7 7.6.7-5.8 5.2 1.8 7.6-7-4.2-7 4.2 1.8-7.6-5.8-5.2 7.6-.7z'/%3E%3C/svg%3E" /> |
8 | 8 | <link rel="stylesheet" href="/static/styles.css" /> |
9 | 9 | <link rel="stylesheet" href="https://aladin.cds.unistra.fr/AladinLite/api/v3/latest/aladin.min.css" /> |
| 10 | + <script src="https://aladin.cds.unistra.fr/AladinLite/api/v3/latest/aladin.js"></script> |
10 | 11 | </head> |
11 | 12 | <body> |
12 | 13 | <div id="aladin-lite-div" aria-label="Interactive FITS viewer"></div> |
|
57 | 58 | </p> |
58 | 59 | <p class="notice hidden" id="aladin-error" role="alert"></p> |
59 | 60 | </aside> |
60 | | - <script type="module"> |
61 | | - import { A } from 'https://aladin.cds.unistra.fr/AladinLite/api/v3/latest/aladin.min.js'; |
| 61 | + <script> |
| 62 | + const { A } = window; |
| 63 | + if (!A) { |
| 64 | + console.error('Aladin Lite library failed to load.'); |
| 65 | + } |
62 | 66 |
|
63 | 67 | const statusMessage = document.getElementById('status-message'); |
64 | 68 | const errorBox = document.getElementById('aladin-error'); |
|
145 | 149 | const label = options.label || deriveLabel(source); |
146 | 150 |
|
147 | 151 | clearError(); |
| 152 | + statusMessage.textContent = `Loading ${label}…`; |
148 | 153 | const loadTimeout = window.setTimeout(() => { |
149 | 154 | if (requestId !== currentRequestId) { |
150 | 155 | return; |
|
153 | 158 | showError('The FITS file is taking longer than expected to respond. Please try again or use a different source.'); |
154 | 159 | }, options.timeout ?? 20000); |
155 | 160 |
|
156 | | - const clearLoadState = () => { |
| 161 | + let finished = false; |
| 162 | + |
| 163 | + const finish = () => { |
| 164 | + if (finished) { |
| 165 | + return; |
| 166 | + } |
| 167 | + finished = true; |
157 | 168 | window.clearTimeout(loadTimeout); |
| 169 | + if (typeof options.onCleanup === 'function') { |
| 170 | + try { |
| 171 | + options.onCleanup(); |
| 172 | + } catch (cleanupError) { |
| 173 | + console.warn('Cleanup callback failed', cleanupError); |
| 174 | + } |
| 175 | + } |
158 | 176 | }; |
159 | 177 |
|
160 | 178 | const handleSuccess = (ra, dec, fov, image) => { |
161 | 179 | if (requestId !== currentRequestId) { |
162 | 180 | return; |
163 | 181 | } |
164 | | - clearLoadState(); |
| 182 | + finish(); |
165 | 183 | configureImage(image, options.colormap); |
166 | 184 | focusOnImage(ra, dec, fov); |
167 | 185 | updateStatus(label, fov); |
|
171 | 189 | if (requestId !== currentRequestId) { |
172 | 190 | return; |
173 | 191 | } |
174 | | - clearLoadState(); |
| 192 | + finish(); |
175 | 193 | console.error('Failed to load FITS data', error); |
176 | 194 | showError('Unable to load the FITS data. Please verify the file or URL and try again.'); |
177 | 195 | }; |
178 | 196 |
|
179 | 197 | try { |
180 | 198 | const result = aladinInstance.displayFITS(source, options.params || {}, handleSuccess, handleError); |
181 | 199 | if (result && typeof result.then === 'function') { |
182 | | - result.catch(handleError).finally(clearLoadState); |
| 200 | + result.catch(handleError).finally(finish); |
183 | 201 | } |
184 | 202 | } catch (error) { |
185 | 203 | handleError(error); |
|
191 | 209 | if (!file) { |
192 | 210 | return; |
193 | 211 | } |
194 | | - loadFits(file, { label: `Local file: ${file.name}` }); |
| 212 | + const objectUrl = URL.createObjectURL(file); |
| 213 | + loadFits(objectUrl, { |
| 214 | + label: `Local file: ${file.name}`, |
| 215 | + onCleanup: () => URL.revokeObjectURL(objectUrl) |
| 216 | + }); |
195 | 217 | event.target.value = ''; |
196 | 218 | } |
197 | 219 |
|
|
220 | 242 | } |
221 | 243 |
|
222 | 244 | async function initialiseViewer() { |
| 245 | + if (!A) { |
| 246 | + showError('Aladin Lite could not be loaded. Please check your connection and refresh the page.'); |
| 247 | + return; |
| 248 | + } |
223 | 249 | try { |
224 | 250 | await A.init; |
225 | 251 | aladinInstance = await A.aladin('#aladin-lite-div', { |
|
0 commit comments