Changeset - 44c0a9db3247
[Not reviewed]
1 3 0
Ben Sturmfels (bsturmfels) - 4 months ago 2024-05-09 12:15:33
ben@sturm.com.au
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.
4 files changed with 48 insertions and 9453 deletions:
0 comments (0 inline, 0 general)
TODO.md
Show inline comments
 
# 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
conservancy/static/js/jquery-1.7.2.js
Show inline comments
 
deleted file
conservancy/static/js/supporter-page.js
Show inline comments
...
 
@@ -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,46 +32,48 @@ if (window.location.hash === "#renew") {
 

	
 
var formCorrectionNeeded = qs('#form-correction-needed');
 

	
 
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
 
    // enter.  Now we hide those for JavaScript users:
 
    formCorrectionNeeded.classList.add('hidden');
 

	
 
    qsa('form.supporter-form').forEach(function(form) {
 
        var $amountInput = $('input[type=number]', form).first();
 
        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) {
 
function new_amount(amountData, amountInput, amountError) {
 
    var isValid = amountData.newAmount >= amountData.minAmount;
 
    if (amountData.oldAmount === undefined) {
 
        if (isValid) {
 
                    amountError.classList.add('hidden');
 
            hide(amountError);
 
        } else {
 
                    flipClass($amountInput[0], 'valid', 'invalid');
 
                    amountError.classList.remove('hidden');
 
            flipClass(amountInput, 'valid', 'invalid');
 
            show(amountError);
 
        }
 
    } else if (isValid) {
 
                flipClass($amountInput[0], 'invalid', 'valid');
 
        flipClass(amountInput, 'invalid', 'valid');
 
        hide(amountError);
 
    } else if (amountData.oldAmount >= amountData.minAmount) {
 
                flipClass($amountInput[0], 'valid', 'invalid');
 
        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
 
    // enter.  Now we hide those for JavaScript users:
 
    formCorrectionNeeded.classList.add('hidden');
 

	
 
        $amountInput.on('input', function(event) {
 
            event.target.classList.remove('invalid');
 
        }).on('focusout', function(event) {
 
            var amountInput = event.target;
 
    qsa('form.supporter-form').forEach(function(form) {
 
        var amountInput = qs('input[type=number]', form);
 
        var amountError = qs('.supporter-form-input .form-error', form);
 

	
 
        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 () {
conservancy/templates/base_conservancy.html
Show inline comments
...
 
@@ -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>
0 comments (0 inline, 0 general)