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 <njoseph@riseup.net>
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
Joseph Nuthalapati 2024-12-17 22:38:27 +05:30 committed by Sunil Mohan Adapa
parent 7ea06bd635
commit 68db1b9ee0
No known key found for this signature in database
GPG Key ID: 43EA1CFF0AA7C5F2
10 changed files with 209 additions and 159 deletions

View File

@ -22,58 +22,60 @@
* in this page.
*/
(function($) {
var NOIP = 'https://<User>:<Pass>@dynupdate.no-ip.com/nic/update?' +
document.addEventListener('DOMContentLoaded', () => {
const NOIP = 'https://<User>:<Pass>@dynupdate.no-ip.com/nic/update?' +
'hostname=<Domain>';
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();
});

View File

@ -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();
});

View File

@ -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)

View File

@ -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();
});

View File

@ -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);
});

View File

@ -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');

View File

@ -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);
}
});

View File

@ -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();
});

View File

@ -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();
});

View File

@ -58,9 +58,6 @@
<link rel="stylesheet" href="{% static user_css %}"/>
{% endif %}
<!-- Local link to system jQuery -->
<!-- TODO Deferring jQuery is causing scripts to be loaded before jQuery is available -->
<script type="text/javascript" src="{% static '/javascript/jquery/jquery.min.js' %}"></script>
<!-- Local link to system Bootstrap JS -->
<script type="text/javascript" src="{% static '/javascript/popper.js/umd/popper.js' %}" defer></script>
<script type="text/javascript" src="{% static 'theme/js/fix.js' %}" defer></script>