From e873df6e437af652eff7ceeebe7a6aecac04a1c9 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Sat, 6 Jun 2026 21:35:48 +0545 Subject: [PATCH] refactor(django_nepkit/static/django_nepkit/js): debounce MutationObserver to avoid full scan and only init relevant forms and inputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added debounce and selective detection to limit re‑initialisation to mutations that affect observed elements, improving performance on pages with frequent DOM changes. --- .../django_nepkit/js/nepali-time-init.js | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/django_nepkit/static/django_nepkit/js/nepali-time-init.js b/django_nepkit/static/django_nepkit/js/nepali-time-init.js index 9b3ca51..17bfda2 100644 --- a/django_nepkit/static/django_nepkit/js/nepali-time-init.js +++ b/django_nepkit/static/django_nepkit/js/nepali-time-init.js @@ -72,10 +72,35 @@ initAll(); } + // Re-initialise on DOM mutations so dynamically-injected forms + // (admin inlines, htmx swaps, etc.) get the same treatment. + // Debounced to avoid an O(document) scan on every keystroke, and + // filtered to only scan when a form/select ancestor was added. if (typeof MutationObserver !== 'undefined' && document.body) { - new MutationObserver(function () { initAll(); }).observe(document.body, { - childList: true, - subtree: true, - }); + var debounceTimer = null; + new MutationObserver(function (mutations) { + var needsInit = false; + for (var i = 0; i < mutations.length; i++) { + var added = mutations[i].addedNodes; + for (var j = 0; j < added.length; j++) { + var node = added[j]; + if (node.nodeType !== 1) continue; + if ( + node.matches && ( + node.matches('form') || + node.matches('.nepkit-time-input') || + (node.querySelector && node.querySelector('.nepkit-time-input')) + ) + ) { + needsInit = true; + break; + } + } + if (needsInit) break; + } + if (!needsInit) return; + if (debounceTimer) clearTimeout(debounceTimer); + debounceTimer = setTimeout(function () { initAll(); }, 50); + }).observe(document.body, { childList: true, subtree: true }); } })();