|
6 | 6 | var isEmbedded = false; |
7 | 7 | var isOpen = false; |
8 | 8 | var triggersBound = false; |
| 9 | + var initialized = false; |
| 10 | + var pendingOpen = false; |
| 11 | + var openedAt = 0; |
| 12 | + var OPEN_GUARD_MS = 350; |
9 | 13 |
|
10 | 14 | function $(sel, root) { |
11 | 15 | return (root || document).querySelector(sel); |
|
193 | 197 | } |
194 | 198 | } |
195 | 199 |
|
| 200 | + function isPaletteVisible() { |
| 201 | + return !!(palette && palette.classList.contains('is-visible')); |
| 202 | + } |
| 203 | + |
196 | 204 | function open(query) { |
197 | | - if (!palette) return; |
| 205 | + if (!palette) { |
| 206 | + pendingOpen = true; |
| 207 | + return; |
| 208 | + } |
198 | 209 | if (isEmbedded) { |
199 | 210 | if (input) { |
200 | 211 | input.focus(); |
201 | 212 | runSearch(query || input.value || ''); |
202 | 213 | } |
203 | 214 | return; |
204 | 215 | } |
205 | | - if (isOpen) return; |
| 216 | + if (isOpen && isPaletteVisible()) { |
| 217 | + close({ force: true }); |
| 218 | + return; |
| 219 | + } |
206 | 220 |
|
207 | 221 | closeMobileMenu(); |
208 | 222 | isOpen = true; |
| 223 | + openedAt = Date.now(); |
209 | 224 | palette.removeAttribute('hidden'); |
210 | 225 | palette.hidden = false; |
211 | 226 | palette.setAttribute('aria-hidden', 'false'); |
212 | 227 | document.body.classList.add('search-palette-open'); |
213 | | - requestAnimationFrame(function () { |
214 | | - palette.classList.add('is-visible'); |
215 | | - }); |
| 228 | + palette.classList.add('is-visible'); |
216 | 229 | if (input) { |
217 | 230 | input.value = query || ''; |
218 | 231 | input.focus(); |
219 | 232 | runSearch(input.value); |
220 | 233 | } |
221 | 234 | } |
222 | 235 |
|
223 | | - function close() { |
| 236 | + function close(opts) { |
224 | 237 | if (!palette || !isOpen || isEmbedded) return; |
| 238 | + if (!(opts && opts.force) && Date.now() - openedAt < OPEN_GUARD_MS) return; |
225 | 239 | isOpen = false; |
226 | 240 | palette.classList.remove('is-visible'); |
227 | 241 | palette.setAttribute('aria-hidden', 'true'); |
|
238 | 252 | var nodes = getInteractives(); |
239 | 253 | if (activeIndex >= 0 && nodes[activeIndex]) { |
240 | 254 | nodes[activeIndex].click(); |
241 | | - close(); |
| 255 | + close({ force: true }); |
242 | 256 | } |
243 | 257 | } |
244 | 258 |
|
|
262 | 276 | if (openBtn) { |
263 | 277 | e.preventDefault(); |
264 | 278 | e.stopPropagation(); |
265 | | - open(''); |
| 279 | + if (isOpen && isPaletteVisible()) { |
| 280 | + close({ force: true }); |
| 281 | + } else { |
| 282 | + open(''); |
| 283 | + } |
266 | 284 | return; |
267 | 285 | } |
268 | 286 | if (e.target.closest('[data-search-close]')) { |
|
309 | 327 | openSelected(); |
310 | 328 | } else if (e.key === 'Escape') { |
311 | 329 | e.preventDefault(); |
312 | | - close(); |
| 330 | + close({ force: true }); |
313 | 331 | } |
314 | 332 | }); |
315 | 333 | } |
316 | 334 | } |
317 | 335 |
|
318 | 336 | function init() { |
| 337 | + if (initialized) return true; |
319 | 338 | if (!window.CFD_SEARCH || !window.CFD_SEARCH.data) { |
320 | 339 | return false; |
321 | 340 | } |
|
324 | 343 | if (!palette) { |
325 | 344 | return false; |
326 | 345 | } |
| 346 | + initialized = true; |
327 | 347 |
|
328 | 348 | backdrop = $('.search-palette__backdrop', palette); |
329 | 349 | dialog = $('.search-palette__dialog', palette); |
|
343 | 363 | document.addEventListener('keydown', function (e) { |
344 | 364 | if ((e.metaKey || e.ctrlKey) && e.key === 'k') { |
345 | 365 | e.preventDefault(); |
346 | | - if (isOpen && !isEmbedded) close(); |
| 366 | + if (isOpen && !isEmbedded) close({ force: true }); |
347 | 367 | else open(''); |
348 | 368 | return; |
349 | 369 | } |
350 | | - if (e.key === 'Escape' && isOpen && !isEmbedded) close(); |
| 370 | + if (e.key === 'Escape' && isOpen && !isEmbedded) close({ force: true }); |
351 | 371 | }); |
352 | 372 |
|
353 | 373 | if (isEmbedded) { |
|
364 | 384 | } |
365 | 385 |
|
366 | 386 | window.cfdSearchPalette = { open: open, close: close }; |
| 387 | + if (pendingOpen) { |
| 388 | + pendingOpen = false; |
| 389 | + open(''); |
| 390 | + } |
367 | 391 | return true; |
368 | 392 | } |
369 | 393 |
|
|
0 commit comments