// SPDX-License-Identifier: AGPL-3.0-or-later /* This file is part of FreedomBox. @licstart The following is the entire license notice for the JavaScript code in this page. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . @licend The above is the entire license notice for the JavaScript code in this page. */ /* * Remove the 'no-js' class from the element. CSS utilizing this can * create different rules when Javascript is available and when it is not. This * functionality was provided by the Modernizr library earlier. */ document.addEventListener('DOMContentLoaded', function (event) { const html = document.querySelector('html'); html.classList.remove('no-js'); html.classList.add('js'); }); /* * Refresh page if marked for refresh. */ document.addEventListener('DOMContentLoaded', function () { const body = document.querySelector('body'); if (body.hasAttribute('data-refresh-page-sec')) { let seconds = body.getAttribute('data-refresh-page-sec'); seconds = parseInt(seconds, 10); if (isNaN(seconds)) return; window.setTimeout(() => { // Refresh the page without resubmitting the POST data. window.location = window.location.href; }, seconds * 1000); } }); /* * Return all submit buttons on the page */ function getSubmitButtons() { return document.querySelectorAll( "form input[type='submit'], form button[type='submit'].toggle-button"); } /* * Disable submit button on click. */ function onSubmitAddProgress(event) { // Using activeElement is not reliable. If the user presses Enter on a text // field, activeElement with be that text field. However, we do safety // checks and fallback to not disabling/animating the submit button, which // is okay. button = document.activeElement; if (!button.classList.contains('btn') || button.classList.contains('btn-link') || button.classList.contains('no-running-status') || button.classList.contains('pull-right') || button.hasAttribute('disabled')) { return; } // Don't disable the submit button immediately as that will prevent the // button from being sent in the HTTP request. Instead schedule disabling // for the next event loop run which will happen after current event is // processed. window.setTimeout(() => { if (button.tagName == "INPUT") { // For push buttons const beforeElement = document.createElement('div'); beforeElement.classList.add('running-status-button-before'); button.classList.forEach(className => { if (className.startsWith('btn-')) { beforeElement.classList.add(className); } }); button.parentNode.insertBefore(beforeElement, button); } else if (button.tagName == "BUTTON") { // For toggle buttons button.classList.toggle('toggle-button--toggled'); } button.classList.add('running-status-button'); // Disable all form submit buttons on the page for (const formbutton of getSubmitButtons()) { if (!(formbutton.classList.contains('btn-link') || formbutton.classList.contains('no-running-status') || formbutton.hasAttribute('disabled'))) { formbutton.classList.add('temporarily-disabled'); formbutton.setAttribute('disabled', 'disabled'); } } }, 0); } document.addEventListener('DOMContentLoaded', function (event) { for (const button of getSubmitButtons()) { // Don't listen for 'click' event on buttons as they are triggered // even when the form is invalid. button.form.addEventListener('submit', onSubmitAddProgress); } }); /* * Clear button disabling on the page. */ function clearButtonDisabling(event) { for (const button of getSubmitButtons()) { button.classList.remove('running-status-button'); if (button.classList.contains('temporarily-disabled')) { button.classList.remove('temporarily-disabled'); button.removeAttribute('disabled'); } } const beforeSelector = ".running-status-button-before"; const beforeElements = document.querySelectorAll(beforeSelector); for (const element of beforeElements) { element.remove(); } }; // When using back/forward browser's bfcache is used and pages won't receive // 'load' events. Instead a 'pageshow' event is available. When a user does // back/forward we want them to be able to submit the forms again. So clear all // the button disabling. window.addEventListener('pageshow', clearButtonDisabling); /* * Select all option for multiple checkboxes. */ document.addEventListener('DOMContentLoaded', function (event) { // Django < 4.0 generates