From 30de24f054a9b0a4d4792439fb5d32742f527c5b Mon Sep 17 00:00:00 2001 From: Younes ENNAJI Date: Sun, 1 Mar 2026 20:11:07 +0000 Subject: [PATCH] fix: add null checks and error handling to docs JS controllers clipboard_controller.js: - Check if clipboard API is available before using - Handle clipboard write promise rejection - Show error icon on failure prev-next_controller.js: - Guard against missing navigation element - Guard against missing span element in links anchor_controller.js: - Guard against missing ul element --- docs/assets/js/controllers/anchor_controller.js | 6 ++++++ .../js/controllers/clipboard_controller.js | 16 +++++++++++++--- .../js/controllers/prev-next_controller.js | 10 ++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/docs/assets/js/controllers/anchor_controller.js b/docs/assets/js/controllers/anchor_controller.js index 550a96aa..d7e3c4a8 100644 --- a/docs/assets/js/controllers/anchor_controller.js +++ b/docs/assets/js/controllers/anchor_controller.js @@ -15,6 +15,12 @@ export default class extends Controller { createAnchorNavigation() { const ul = this.container.querySelector('ul') + + // Guard against missing ul element + if (!ul) { + return + } + const anchors = document.querySelectorAll('#main-article h3, #main-article h2, #main-article a.anchor') if (anchors.length === 0) { diff --git a/docs/assets/js/controllers/clipboard_controller.js b/docs/assets/js/controllers/clipboard_controller.js index 8f7f4303..83bc019b 100644 --- a/docs/assets/js/controllers/clipboard_controller.js +++ b/docs/assets/js/controllers/clipboard_controller.js @@ -20,7 +20,7 @@ export default class extends Controller { parent.append(button) - button.addEventListener('click', () => { + button.addEventListener('click', async () => { let code = codeBlock.textContent.trim() if (code.startsWith('#')) { const parts = code.split('\n') @@ -28,9 +28,19 @@ export default class extends Controller { code = parts.join('\n') } - window.navigator.clipboard.writeText(code) + // Check if clipboard API is available + if (!window.navigator?.clipboard?.writeText) { + console.warn('Clipboard API not available') + return + } - button.innerHTML = '' + try { + await window.navigator.clipboard.writeText(code) + button.innerHTML = '' + } catch (error) { + console.error('Failed to copy to clipboard:', error) + button.innerHTML = '' + } setTimeout(() => { button.innerHTML = icon diff --git a/docs/assets/js/controllers/prev-next_controller.js b/docs/assets/js/controllers/prev-next_controller.js index aa803adb..3e1363c3 100644 --- a/docs/assets/js/controllers/prev-next_controller.js +++ b/docs/assets/js/controllers/prev-next_controller.js @@ -4,6 +4,12 @@ export default class extends Controller { connect() { const prevNext = document.querySelectorAll('.prev-next') const navigation = document.getElementById('main-navigation') + + // Guard against missing navigation element + if (!navigation) { + return + } + const navigationLinks = navigation.querySelectorAll('a') let previous @@ -15,6 +21,10 @@ export default class extends Controller { links.forEach((link) => { const label = link.querySelector('span') + // Guard against missing span element + if (!label) { + return + } label.innerHTML = originalLink.innerHTML.replace(/\d+\. /, '').replace(/<(\S*?)[^>]*>.*?<\/\1>|<.*?\/>/, '') link.href = originalLink.href link.classList.remove('hidden')