(function() { if (window.location.pathname !== '/challenges') return; function injectSubmissionBoxes(config) { const enabledCategories = config.categories || []; // Find all category headers const headers = document.querySelectorAll('.category-header'); headers.forEach(header => { const catName = header.textContent.trim(); // 1. Check if category is enabled // 2. Check if we already injected a box (to prevent infinite loops) const alreadyInjected = header.nextElementSibling && header.nextElementSibling.classList.contains('custom-cat-sub-box'); if (enabledCategories.includes(catName) && !alreadyInjected) { const div = document.createElement('div'); div.className = "custom-cat-sub-box input-group mt-2 mb-4 p-3 bg-light border rounded"; div.style.maxWidth = "500px"; // Keep it tidy div.innerHTML = `
`; header.after(div); // Submission logic div.querySelector('button').onclick = function() { const btn = this; const input = document.getElementById(`in-${catName.replace(/\s+/g, '-')}`); const val = input.value.trim(); if (!val) return; btn.disabled = true; const params = new URLSearchParams({ submission: val, category: catName, nonce: init.csrfNonce }); fetch('/category_submit', { method: 'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: params }) .then(r => r.json()) .then(data => { alert(data.message); if (data.success) { location.reload(); // Refresh to show the checkmark on the challenge } btn.disabled = false; }) .catch(() => { alert("Error submitting flag."); btn.disabled = false; }); }; } }); } // Initialize the plugin fetch('/category_submit/config') .then(r => r.json()) .then(config => { // Run once on load injectSubmissionBoxes(config); // Observe the challenge board for changes (e.g. category filtering/loading) // We use a debounce timer to avoid the "Loading Forever" infinite loop let timeout; const observer = new MutationObserver(() => { clearTimeout(timeout); timeout = setTimeout(() => { // Temporarily disconnect to avoid observing our own changes observer.disconnect(); injectSubmissionBoxes(config); // Re-observe after injection observer.observe(document.body, { childList: true, subtree: true }); }, 200); }); observer.observe(document.body, { childList: true, subtree: true }); }) .catch(err => console.error("Could not load category submission config", err)); })();