Remove remaining jQuery

This avoids every page on the site parsing 250KB of JavaScript.

supporter-page.js isn't the most elegant code, but at least it's a little more
modular now and no longer user jQuery.
This commit is contained in:
Ben Sturmfels 2024-05-09 22:12:35 +10:00
parent 10dfdb617b
commit 44c0a9db32
Signed by: bsturmfels
GPG key ID: 023C05E2C9C068F0
4 changed files with 50 additions and 9455 deletions

View file

@ -1,12 +1,9 @@
# To-do
* ensure appropriate caching headers are used
* remove jQuery
* consider removing `events` and `worldmap` modules
* ask Denver about why so many license files
* serve a 400 in Apache for a hostname we don't explicitly support
* use `<detail>` elements for supporter page hidden sections, rather than
complex jQuery - or consider Alpine.js
* replace `internalNavigate` with inline flexbox layout
* add tests for main pages returning 200
* move `sponsors.py` and `sponsors.html` into `supporters` app
@ -14,6 +11,9 @@
# Done
* use `<detail>` elements for supporter page hidden sections, rather than
complex jQuery
* remove jQuery
* split the template/content files out from `conservancy/static` into their own
`content` directory (avoid mixing static and non-static content)
* remove `ForceCanonicalHostnameMiddleware` by ensuring canonical redirect and

File diff suppressed because it is too large Load diff

View file

@ -7,8 +7,6 @@
"use strict";
var NEW_AMOUNT_EVENT = 'conservancy:newamount';
var flipClass = function(elem, byeClass, hiClass) {
var classList = elem.classList;
classList.remove(byeClass);
@ -26,10 +24,6 @@ var buildAmountData = function(amountInput) {
return amountData;
}
var supportTypeSelector = function(supportTypeHash) {
return $(supportTypeHash + "Selector");
};
/* We've sometimes published links that say #renew instead of #renewal.
Rewrite that to work as intended. */
if (window.location.hash === "#renew") {
@ -38,6 +32,24 @@ if (window.location.hash === "#renew") {
var formCorrectionNeeded = qs('#form-correction-needed');
function new_amount(amountData, amountInput, amountError) {
var isValid = amountData.newAmount >= amountData.minAmount;
if (amountData.oldAmount === undefined) {
if (isValid) {
hide(amountError);
} else {
flipClass(amountInput, 'valid', 'invalid');
show(amountError);
}
} else if (isValid) {
flipClass(amountInput, 'invalid', 'valid');
hide(amountError);
} else if (amountData.oldAmount >= amountData.minAmount) {
flipClass(amountInput, 'valid', 'invalid');
show(amountError);
}
}
function init_sustainer_form_validation () {
// Forms start in "invalid" form, with the errors shown, so that
// non-Javascript users see the errors by default and know what they must
@ -45,39 +57,23 @@ function init_sustainer_form_validation () {
formCorrectionNeeded.classList.add('hidden');
qsa('form.supporter-form').forEach(function(form) {
var $amountInput = $('input[type=number]', form).first();
var amountInput = qs('input[type=number]', form);
var amountError = qs('.supporter-form-input .form-error', form);
var $amountError = $('.form-error', $amountInput.parents('.supporter-form-input'));
$amountError.on(NEW_AMOUNT_EVENT, function(event, amountData) {
var isValid = amountData.newAmount >= amountData.minAmount;
if (amountData.oldAmount === undefined) {
if (isValid) {
amountError.classList.add('hidden');
} else {
flipClass($amountInput[0], 'valid', 'invalid');
amountError.classList.remove('hidden');
}
} else if (isValid) {
flipClass($amountInput[0], 'invalid', 'valid');
hide(amountError);
} else if (amountData.oldAmount >= amountData.minAmount) {
flipClass($amountInput[0], 'valid', 'invalid');
show(amountError);
}
});
$amountInput.on('input', function(event) {
event.target.classList.remove('invalid');
}).on('focusout', function(event) {
var amountInput = event.target;
function amount_change_handler () {
var amountData = buildAmountData(amountInput);
$amountError.trigger(NEW_AMOUNT_EVENT, amountData);
new_amount(amountData, amountInput, amountError);
amountInput.dataset.oldAmount = amountData.newAmount;
}).trigger('focusout');
}
amountInput.addEventListener('input', function() {
amountInput.classList.remove('invalid');
})
amountInput.addEventListener('focusout', amount_change_handler);
amount_change_handler();
form.addEventListener('submit', function(event) {
var amountData = buildAmountData($amountInput[0]);
var amountData = buildAmountData(amountInput);
if (amountData.newAmount >= amountData.minAmount) {
formCorrectionNeeded.classList.add('hidden');
} else {
@ -90,24 +86,28 @@ function init_sustainer_form_validation () {
}
function init_sustainer_type_switching () {
var selectSupportType = function(event) {
var $selectedLink = $(event.target);
$(".supporter-type-selector a").removeClass("supporter-type-selector-selected");
$selectedLink.addClass("supporter-type-selector-selected");
$(".supporter-type-selection").hide();
$(event.target.hash).show();
function selectSupportType(selectedLink) {
qsa(".supporter-type-selector a").forEach(function(el) {
el.classList.remove("supporter-type-selector-selected");
});
selectedLink.classList.add("supporter-type-selector-selected");
qsa(".supporter-type-selection").forEach(function(el) { hide(el); });
let hash = window.location.hash !== '' ? window.location.hash : '#annual';
show(qs(hash));
formCorrectionNeeded.classList.add('hidden');
return false;
};
$(".supporter-type-selector a").bind("click", selectSupportType);
qsa(".supporter-type-selector a").forEach(function(el) {
el.addEventListener("click", () => selectSupportType(el));
});
var selectSupportTypeFromHash = function() {
return supportTypeSelector(window.location.hash).click();
};
$(window).bind("hashchange", selectSupportTypeFromHash);
if (selectSupportTypeFromHash().length === 0) {
supportTypeSelector("#annual").click();
}
let el = qs(window.location.hash !== '' ? window.location.hash + 'Selector' : '#annualSelector');
selectSupportType(el);
window.addEventListener("hashchange", function () {
let el = qs(window.location.hash !== '' ? window.location.hash + 'Selector' : '#annualSelector');
selectSupportType(el);
});
};
function init_expanders () {

View file

@ -15,7 +15,6 @@
<link rel="stylesheet" type="text/css" href="{% static 'css/tachyons.css' %}"/>
<link rel="stylesheet" type="text/css" media="screen" href="{% static 'css/conservancy.css' %}" />
<link rel="stylesheet" type="text/css" media="(min-width: 67em)" href="{% static 'css/conservancy-bigscreen.css' %}" />
<script type="text/javascript" src="{% static 'js/jquery-1.7.2.js' %}" defer></script>
<script type="text/javascript" src="{% static 'js/conservancy.js' %}" defer></script>
{% block head %}{% endblock %}
</head>