From 68db1b9ee03be9c6ea521d7797e3ef465d527303 Mon Sep 17 00:00:00 2001 From: Joseph Nuthalapati Date: Tue, 17 Dec 2024 22:38:27 +0530 Subject: [PATCH] ui: Replace use of jQuery with plain JavaScript sunil: - Add explicit dependency on libjs-jquery in janus even though another dependency brings it in. - Fix looking for elements before DOMContentLoaded is fired. Since most of the scripts are added at the end of the page, it might work now, but doing this properly after DOMContentLoaded allows us to relocate the scripts to the header of the page and add 'defer' attribute on them. - Fix issue with IPv6 method getting selected as 'dchp' in networks.js. - Don't focus on the first element in the form after the page loads. This is bad for accessibility. - Fix issue with setting the readonly/required states of IPv4/IPv6 fields on page load. - Password fields can now be changed to text fields and vice versa without a problem. Simplify. - Fix incorrect repetition of code setting 'show' class in onInvalidEvent(). - Prefer exception getting raised instead of functionality silently failing when expected elements are not found. - Use 'const' instead of 'var' wherever possible. - Prefer .closest() to get to ancestors instead of .parentNode; - Don't CSS transitions when showing an element, 'transition' CSS property does not work on 'display' property. Instead they have to implemented on 'height', 'opacity', etc. - Minor styling changes. Consistent casing. Use arrow styled functions. Signed-off-by: Joseph Nuthalapati Signed-off-by: Sunil Mohan Adapa Reviewed-by: Sunil Mohan Adapa --- .../modules/dynamicdns/static/dynamicdns.js | 72 +++++----- plinth/modules/ejabberd/static/ejabberd.js | 23 ++-- plinth/modules/janus/__init__.py | 6 +- .../matrixsynapse/static/matrixsynapse.js | 23 ++-- plinth/modules/mediawiki/static/mediawiki.js | 21 +-- plinth/modules/networks/static/networks.js | 125 ++++++++++-------- plinth/modules/snapshot/static/snapshot.js | 19 +-- plinth/modules/tor/static/tor.js | 54 +++++--- plinth/modules/torproxy/static/torproxy.js | 22 ++- plinth/templates/base.html | 3 - 10 files changed, 209 insertions(+), 159 deletions(-) diff --git a/plinth/modules/dynamicdns/static/dynamicdns.js b/plinth/modules/dynamicdns/static/dynamicdns.js index 7ee0bcbb0..73d3435d4 100644 --- a/plinth/modules/dynamicdns/static/dynamicdns.js +++ b/plinth/modules/dynamicdns/static/dynamicdns.js @@ -22,58 +22,60 @@ * in this page. */ -(function($) { - var NOIP = 'https://:@dynupdate.no-ip.com/nic/update?' + +document.addEventListener('DOMContentLoaded', () => { + const NOIP = 'https://:@dynupdate.no-ip.com/nic/update?' + 'hostname='; - var FREEDNS = 'https://freedns.afraid.org/dynamic/update.php?' + + const FREEDNS = 'https://freedns.afraid.org/dynamic/update.php?' + '_YOURAPIKEYHERE_'; - $('#id_service_type').change(function() { - set_mode(); + document.getElementById('id_service_type').addEventListener('change', () => { + setMode(); - var service_type = $("#id_service_type").val(); - if (service_type == "noip.com") { - $('#id_update_url').val(NOIP); - } else if (service_type == "freedns.afraid.org") { - $('#id_update_url').val(FREEDNS); + const service_type = document.getElementById('id_service_type').value; + if (service_type === "noip.com") { + document.getElementById('id_update_url').value = NOIP; + } else if (service_type === "freedns.afraid.org") { + document.getElementById('id_update_url').value = FREEDNS; } else { // GnuDIP and other - $('#id_update_url').val(''); + document.getElementById('id_update_url').value = ''; } }); - $('#id_show_password').change(function() { - if ($('#id_show_password').prop('checked')) { - $('#id_password').prop('type', 'text'); + document.getElementById('id_show_password').addEventListener('change', () => { + if (document.getElementById('id_show_password').checked) { + document.getElementById('id_password').type = 'text'; } else { - $('#id_password').prop('type', 'password'); + document.getElementById('id_password').type = 'password'; } }); - function set_mode() { - var service_type = $("#id_service_type").val(); - if (service_type == "gnudip") { - set_gnudip_mode(); + function setMode() { + const service_type = document.getElementById('id_service_type').value; + if (service_type === "gnudip") { + setGnudipMode(); } else { - set_update_url_mode(); + setUpdateUrlMode(); } } - function set_gnudip_mode() { - $('.form-group').show(); - $('#id_update_url').closest('.form-group').hide(); - $('#id_disable_ssl_cert_check').closest('.form-group').hide(); - $('#id_use_http_basic_auth').closest('.form-group').hide(); - $('#id_use_ipv6').closest('.form-group').hide(); - $('#id_server').closest('.form-group').show(); + function setGnudipMode() { + document.querySelectorAll('.form-group').forEach((element) => { + element.style.display = 'block'; + }); + document.getElementById('id_update_url').closest('.form-group').style.display = 'none'; + document.getElementById('id_disable_ssl_cert_check').closest('.form-group').style.display = 'none'; + document.getElementById('id_use_http_basic_auth').closest('.form-group').style.display = 'none'; + document.getElementById('id_use_ipv6').closest('.form-group').style.display = 'none'; + document.getElementById('id_server').closest('.form-group').style.display = 'block'; } - function set_update_url_mode() { - $('#id_update_url').closest('.form-group').show(); - $('#id_disable_ssl_cert_check').closest('.form-group').show(); - $('#id_use_http_basic_auth').closest('.form-group').show(); - $('#id_use_ipv6').closest('.form-group').show(); - $('#id_server').closest('.form-group').hide(); + function setUpdateUrlMode() { + document.getElementById('id_update_url').closest('.form-group').style.display = 'block'; + document.getElementById('id_disable_ssl_cert_check').closest('.form-group').style.display = 'block'; + document.getElementById('id_use_http_basic_auth').closest('.form-group').style.display = 'block'; + document.getElementById('id_use_ipv6').closest('.form-group').style.display = 'block'; + document.getElementById('id_server').closest('.form-group').style.display = 'none'; } - set_mode(); -})(jQuery); + setMode(); +}); diff --git a/plinth/modules/ejabberd/static/ejabberd.js b/plinth/modules/ejabberd/static/ejabberd.js index 6822a474e..7e16492cd 100644 --- a/plinth/modules/ejabberd/static/ejabberd.js +++ b/plinth/modules/ejabberd/static/ejabberd.js @@ -22,14 +22,21 @@ * in this page. */ -jQuery(function($) { - $('#id_enable_managed_turn').change(function() { - if($(this).prop('checked')) { - $('#id_turn_uris').closest('.form-group').hide(); - $('#id_shared_secret').closest('.form-group').hide(); +document.addEventListener('DOMContentLoaded', () => { + const enableManagedTurn = document.getElementById('id_enable_managed_turn'); + const turnUrisGroup = document.getElementById('id_turn_uris').closest('.form-group'); + const sharedSecretGroup = document.getElementById('id_shared_secret').closest('.form-group'); + + function toggleVisibility() { + if (enableManagedTurn.checked) { + turnUrisGroup.style.display = 'none'; + sharedSecretGroup.style.display = 'none'; } else { - $('#id_turn_uris').closest('.form-group').show(); - $('#id_shared_secret').closest('.form-group').show(); + turnUrisGroup.style.display = ''; + sharedSecretGroup.style.display = ''; } - }).change(); + } + + enableManagedTurn.addEventListener('change', toggleVisibility); + toggleVisibility(); }); diff --git a/plinth/modules/janus/__init__.py b/plinth/modules/janus/__init__.py index f1e6ae8e1..9d2cceaa4 100644 --- a/plinth/modules/janus/__init__.py +++ b/plinth/modules/janus/__init__.py @@ -59,9 +59,9 @@ class JanusApp(app_module.App): self.add(shortcut) packages = Packages('packages-janus', [ - 'janus', 'libjs-bootbox', 'libjs-bootstrap', 'libjs-bootswatch', - 'libjs-janus-gateway', 'libjs-jquery-blockui', 'libjs-spin.js', - 'libjs-toastr', 'libjs-webrtc-adapter' + 'janus', 'libjs-jquery', 'libjs-bootbox', 'libjs-bootstrap', + 'libjs-bootswatch', 'libjs-janus-gateway', 'libjs-jquery-blockui', + 'libjs-spin.js', 'libjs-toastr', 'libjs-webrtc-adapter' ]) self.add(packages) diff --git a/plinth/modules/matrixsynapse/static/matrixsynapse.js b/plinth/modules/matrixsynapse/static/matrixsynapse.js index 6822a474e..0d0f7eabe 100644 --- a/plinth/modules/matrixsynapse/static/matrixsynapse.js +++ b/plinth/modules/matrixsynapse/static/matrixsynapse.js @@ -22,14 +22,21 @@ * in this page. */ -jQuery(function($) { - $('#id_enable_managed_turn').change(function() { - if($(this).prop('checked')) { - $('#id_turn_uris').closest('.form-group').hide(); - $('#id_shared_secret').closest('.form-group').hide(); +document.addEventListener('DOMContentLoaded', () => { + const enableManagedTurnCheckbox = document.getElementById('id_enable_managed_turn'); + const turnUrisFormGroup = document.getElementById('id_turn_uris').closest('.form-group'); + const sharedSecretFormGroup = document.getElementById('id_shared_secret').closest('.form-group'); + + function toggleFormGroups() { + if (enableManagedTurnCheckbox.checked) { + turnUrisFormGroup.style.display = 'none'; + sharedSecretFormGroup.style.display = 'none'; } else { - $('#id_turn_uris').closest('.form-group').show(); - $('#id_shared_secret').closest('.form-group').show(); + turnUrisFormGroup.style.display = ''; + sharedSecretFormGroup.style.display = ''; } - }).change(); + } + + enableManagedTurnCheckbox.addEventListener('change', toggleFormGroups); + toggleFormGroups(); }); diff --git a/plinth/modules/mediawiki/static/mediawiki.js b/plinth/modules/mediawiki/static/mediawiki.js index be0303b6d..8d868cca5 100644 --- a/plinth/modules/mediawiki/static/mediawiki.js +++ b/plinth/modules/mediawiki/static/mediawiki.js @@ -22,18 +22,19 @@ * in this page. */ -(function($) { - $('#id_enable_public_registrations').click(function() { - var checkedState = $(this).prop("checked"); - if (checkedState) { - $('#id_enable_private_mode').prop('checked', false); +document.addEventListener('DOMContentLoaded', () => { + const enablePublicRegistrations = document.getElementById('id_enable_public_registrations'); + const enablePrivateMode = document.getElementById('id_enable_private_mode'); + + enablePublicRegistrations.addEventListener('click', () => { + if (enablePublicRegistrations.checked) { + enablePrivateMode.checked = false; } }); - $('#id_enable_private_mode').click(function() { - var checkedState = $(this).prop("checked"); - if (checkedState) { - $('#id_enable_public_registrations').prop('checked', false); + enablePrivateMode.addEventListener('click', () => { + if (enablePrivateMode.checked) { + enablePublicRegistrations.checked = false; } }); -})(jQuery); +}); diff --git a/plinth/modules/networks/static/networks.js b/plinth/modules/networks/static/networks.js index af2260051..6b0ec2b96 100644 --- a/plinth/modules/networks/static/networks.js +++ b/plinth/modules/networks/static/networks.js @@ -22,81 +22,94 @@ * in this page. */ -jQuery(function($) { +document.addEventListener('DOMContentLoaded', () => { - function ip_required(required, ip_version, fields) { - var prefix = '#id_' + ip_version + '_'; + function ipRequired(required, ipVersion, fields) { + const prefix = 'id_' + ipVersion + '_'; for (var i = 0; i < fields.length; i++) { - $(prefix + fields[i]).prop("required", required); - } - } - - function ip_readonly(readonly, ip_version, fields) { - var prefix = '#id_' + ip_version + '_'; - for (var i = 0; i < fields.length; i++) { - $(prefix + fields[i]).prop("readOnly", readonly); - if (readonly) { - $(prefix + fields[i]).val(""); - $(prefix + fields[i]).prop("required", false); + const element = document.getElementById(prefix + fields[i]); + if (element) { + element.required = required; } } } - function on_ipv4_method_change() { - var selected = $("input[name=ipv4_method]:checked"); - if (selected.prop("value") == "manual") { - ip_required(true, 'ipv4', ['address']); - ip_readonly(false, 'ipv4', ['address', 'netmask', 'gateway', + function ipReadOnly(readOnly, ipVersion, fields) { + const prefix = 'id_' + ipVersion + '_'; + for (var i = 0; i < fields.length; i++) { + const element = document.getElementById(prefix + fields[i]); + if (element) { + element.readOnly = readOnly; + if (readOnly) { + element.value = ""; + element.required = false; + } + } + } + } + + function onIpv4MethodChange() { + const selected = document.querySelector("input[name=ipv4_method]:checked"); + if (selected && selected.value === "manual") { + ipRequired(true, 'ipv4', ['address']); + ipReadOnly(false, 'ipv4', ['address', 'netmask', 'gateway', 'dns', 'second_dns' ]); - } else if (selected.prop("value") == "shared") { - ip_required(false, 'ipv4', ['address']); - ip_readonly(false, 'ipv4', ['address', 'netmask']); - ip_readonly(true, 'ipv4', ['gateway', 'dns', 'second_dns']); - } else if (selected.prop("value") == "auto") { - ip_readonly(true, 'ipv4', ['address', 'netmask', 'gateway']); - ip_readonly(false, 'ipv4', ['dns', 'second_dns']); + } else if (selected && selected.value === "shared") { + ipRequired(false, 'ipv4', ['address']); + ipReadOnly(false, 'ipv4', ['address', 'netmask']); + ipReadOnly(true, 'ipv4', ['gateway', 'dns', 'second_dns']); + } else if (selected && selected.value === "auto") { + ipReadOnly(true, 'ipv4', ['address', 'netmask', 'gateway']); + ipReadOnly(false, 'ipv4', ['dns', 'second_dns']); } else { - ip_readonly(true, 'ipv4', ['address', 'netmask', 'gateway', + ipReadOnly(true, 'ipv4', ['address', 'netmask', 'gateway', 'dns', 'second_dns' ]); } } - function on_ipv6_method_change() { - var selected = $("input[name=ipv6_method]:checked"); - if (selected.prop("value") == "manual") { - ip_required(true, 'ipv6', ['address', 'prefix']); - ip_readonly(false, 'ipv6', ['address', 'prefix', 'gateway', + function onIpv6MethodChange() { + const selected = document.querySelector("input[name=ipv6_method]:checked"); + if (selected && selected.value === "manual") { + ipRequired(true, 'ipv6', ['address', 'prefix']); + ipReadOnly(false, 'ipv6', ['address', 'prefix', 'gateway', 'dns', 'second_dns' ]); - } else if (selected.prop("value") == "auto" || - $("#id_ipv6_method").prop("value") == "dhcp") { - ip_readonly(true, 'ipv6', ['address', 'prefix', 'gateway']); - ip_readonly(false, 'ipv6', ['dns', 'second_dns']); + } else if (selected && (selected.value === "auto" || + selected.value === "dhcp")) { + ipReadOnly(true, 'ipv6', ['address', 'prefix', 'gateway']); + ipReadOnly(false, 'ipv6', ['dns', 'second_dns']); } else { - ip_readonly(true, 'ipv6', ['address', 'prefix', 'gateway', + ipReadOnly(true, 'ipv6', ['address', 'prefix', 'gateway', 'dns', 'second_dns' ]); } } - $("#id_name").focus(); - - $("input[name=ipv4_method]").change(on_ipv4_method_change).change(); - $("input[name=ipv6_method]").change(on_ipv6_method_change).change(); - - $('#id_show_password').change(function() { - // Changing type attribute from password to text is prevented by - // most browsers. Making a new form field works. - new_type = 'password'; - if ($('#id_show_password').prop('checked')) - new_type = 'text'; - - $('#id_password').replaceWith( - $('#id_password').clone().attr('type', new_type)); + document.querySelectorAll("input[name=ipv4_method]").forEach(element => { + element.addEventListener('change', onIpv4MethodChange); }); + document.querySelectorAll("input[name=ipv6_method]").forEach(element => { + element.addEventListener('change', onIpv6MethodChange); + }); + + onIpv4MethodChange(); + onIpv6MethodChange(); + + const showPasswordElement = document.getElementById('id_show_password'); + if (showPasswordElement) { + showPasswordElement.addEventListener('change', () => { + // Changing type attribute from password to text is prevented by + // most browsers. Making a new form field works. + var newType = 'password'; + if (showPasswordElement.checked) { + newType = 'text'; + } + document.getElementById('id_password').type = newType; + }); + } }); // When there are validation errors on form elements, expand their parent @@ -104,14 +117,14 @@ jQuery(function($) { // can be show by the browser. document.addEventListener('DOMContentLoaded', event => { const selector = '.form-connection input, .form-connection select'; - const input_elements = document.querySelectorAll(selector); - input_elements.forEach(input => - input.addEventListener('invalid', on_invalid_event) + const inputElements = document.querySelectorAll(selector); + inputElements.forEach(input => + input.addEventListener('invalid', onInvalidEvent) ); }); -function on_invalid_event(event) { - const element = event.target; +function onInvalidEvent(event) { + const element = event.currentTarget; const parent = element.closest('.collapse'); // Don't use .collapse(). Instead, expand all the sections with errors. parent.classList.add('show'); diff --git a/plinth/modules/snapshot/static/snapshot.js b/plinth/modules/snapshot/static/snapshot.js index d82d67f3d..c388af8e8 100644 --- a/plinth/modules/snapshot/static/snapshot.js +++ b/plinth/modules/snapshot/static/snapshot.js @@ -22,12 +22,15 @@ * in this page. */ -(function($) { - $("#select-all").click(function() { - var checkedState = this.checked; - checkboxes = document.getElementsByName('snapshot_list'); - jQuery.each(checkboxes, function(i, checkbox) { - checkbox.checked = checkedState; +document.addEventListener('DOMContentLoaded', () => { + const selectAllCheckbox = document.getElementById('select-all'); + if (selectAllCheckbox) { + selectAllCheckbox.addEventListener('click', (event) => { + const checkedState = event.currentTarget.checked; + const checkboxes = document.getElementsByName('snapshot_list'); + checkboxes.forEach(checkbox => { + checkbox.checked = checkedState; + }); }); - }); -})(jQuery); + } +}); diff --git a/plinth/modules/tor/static/tor.js b/plinth/modules/tor/static/tor.js index b4ccad53c..927ccfda4 100644 --- a/plinth/modules/tor/static/tor.js +++ b/plinth/modules/tor/static/tor.js @@ -22,26 +22,38 @@ * in this page. */ -(function($) { - $('#id_tor-relay_enabled').change(function() { - var bridge = $('#id_tor-bridge_relay_enabled'); - var disable = !$('#id_tor-relay_enabled').prop('checked'); - bridge.prop('disabled', disable); - if (disable) { - $('#id_tor-bridge_relay_enabled').prop('checked', false); - } - }).change(); +document.addEventListener('DOMContentLoaded', () => { + const relayEnabled = document.getElementById('id_tor-relay_enabled'); + const bridgeRelay = document.getElementById('id_tor-bridge_relay_enabled'); + const useUpstreamBridges = document.getElementById('id_tor-use_upstream_bridges'); + const upstreamBridgesField = document.getElementById('id_tor-upstream_bridges') + .closest('.form-group'); - $('#id_tor-use_upstream_bridges').change(function() { - if ($('#id_tor-use_upstream_bridges').prop('checked')) { - $('#id_tor-upstream_bridges').parent().parent().show('slow'); - $('#id_tor-relay_enabled').prop('checked', false) - .prop('disabled', true); - $('#id_tor-bridge_relay_enabled').prop('checked', false) - .prop('disabled', true); - } else { - $('#id_tor-upstream_bridges').parent().parent().hide('slow'); - $('#id_tor-relay_enabled').prop('disabled', false); + function handleRelayChange() { + const disable = !relayEnabled.checked; + bridgeRelay.disabled = disable; + if (disable) { + bridgeRelay.checked = false; } - }).change(); -})(jQuery); + } + + function handleUseUpstreamBridgesChange() { + if (useUpstreamBridges.checked) { + upstreamBridgesField.style.display = ''; + relayEnabled.checked = false; + relayEnabled.disabled = true; + bridgeRelay.checked = false; + bridgeRelay.disabled = true; + } else { + upstreamBridgesField.style.display = 'none'; + relayEnabled.disabled = false; + } + } + + relayEnabled.addEventListener('change', handleRelayChange); + useUpstreamBridges.addEventListener('change', handleUseUpstreamBridgesChange); + + // Initial state + handleRelayChange(); + handleUseUpstreamBridgesChange(); +}); diff --git a/plinth/modules/torproxy/static/torproxy.js b/plinth/modules/torproxy/static/torproxy.js index 3469c5a88..43343f626 100644 --- a/plinth/modules/torproxy/static/torproxy.js +++ b/plinth/modules/torproxy/static/torproxy.js @@ -22,12 +22,20 @@ * in this page. */ -(function($) { - $('#id_torproxy-use_upstream_bridges').change(function() { - if ($('#id_torproxy-use_upstream_bridges').prop('checked')) { - $('#id_torproxy-upstream_bridges').parent().parent().show('slow'); +document.addEventListener('DOMContentLoaded', () => { + const useUpstreamBridges = document.getElementById('id_torproxy-use_upstream_bridges'); + const upstreamBridges = document.getElementById('id_torproxy-upstream_bridges'); + + function handleUseUpstreamBridgesChange() { + if (useUpstreamBridges.checked) { + upstreamBridges.closest('.form-group').style.display = ''; } else { - $('#id_torproxy-upstream_bridges').parent().parent().hide('slow'); + upstreamBridges.closest('.form-group').style.display = 'none'; } - }).change(); -})(jQuery); + } + + useUpstreamBridges.addEventListener('change', handleUseUpstreamBridgesChange); + + // Initial state + handleUseUpstreamBridgesChange(); +}); diff --git a/plinth/templates/base.html b/plinth/templates/base.html index 4d19a4f3f..813a476e5 100644 --- a/plinth/templates/base.html +++ b/plinth/templates/base.html @@ -58,9 +58,6 @@ {% endif %} - - -