Skip to content

Commit

Permalink
unify JavaScript handling of form submissions
Browse files Browse the repository at this point in the history
- drop the `js-submit` class and merge the two separate `submit` event handlers into one
  - it's now easy to run custom functions both before and after a form submission
    - however, the after functions may not be called if the server responds to the form submission with an error
  - the unified function's source code is commented
  - the unified function sends debugging messages to the console
  - form inputs are no longer disabled during submission, because it was complicating the JavaScript code
    - CSS is used instead to gray out the entire form and disable mouse events, but keyboard events aren't be disabled
  - the submission feedback overlay is back, for forms making slow requests before submitting
- replace most uses of `jQuery.ajax()` with `fetch()`, simplifying the `Liberapay.error()` function and removing the need for the `Liberapay.getCookie()` function
  - all forms are now required to include an anti-CSRF token, whereas previously the forms that required JavaScript didn't need to contain the token as it would be taken from the cookies anyway
  - since we no longer need the `csrf_token` cookie to be accessible from JavaScript, mark it as `httponly`
  • Loading branch information
Changaco committed Jul 1, 2024
1 parent ae49ccd commit 71d06cd
Show file tree
Hide file tree
Showing 23 changed files with 328 additions and 264 deletions.
14 changes: 8 additions & 6 deletions error.spt
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,13 @@ user_agent = request.headers.get(b'User-Agent')
% endif
% endblock
[----------------------------------------] application/json via json_dump
{ "error_code": code
, "error_message_short": msg
, "error_message_long": err
, "error_id": sentry_ident
, "error_location": error_location
}
{
"error_code": code,
"error_id": sentry_ident,
"error_location": error_location,
"error_message_long": err,
"error_message_short": msg,
"html_template": getattr(response, 'html_template', None),
}
[----------------------------------------] text/plain
{{err or msg}}
45 changes: 11 additions & 34 deletions js/10-base.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,4 @@
Liberapay.getCookie = function(key) {
var o = new RegExp("(?:^|; ?)" + escape(key) + "=([^;]+)").exec(document.cookie);
if (!o) return null;
var value = o[1];
if (value.charAt(0) === '"') value = value.slice(1, -1);
return unescape(value);
}

Liberapay.init = function() {
// https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
jQuery.ajaxSetup({
beforeSend: function(xhr, settings) {
var safeMethod = (/^(GET|HEAD|OPTIONS|TRACE)$/.test(settings.type));
if (!safeMethod && !settings.crossDomain) {
// We have to avoid httponly on the csrf_token cookie because of this.
xhr.setRequestHeader("X-CSRF-TOKEN", Liberapay.getCookie('csrf_token'));
}
}
});

Liberapay.forms.jsSubmit();

var success_re = /([?&])success=[^&]*/;
Expand Down Expand Up @@ -129,31 +110,27 @@ Liberapay.init = function() {

$(function(){ Liberapay.init(); });

Liberapay.error = function(jqXHR, textStatus, errorThrown) {
var msg = null;
if (jqXHR.responseText > "") {
try {
msg = JSON.parse(jqXHR.responseText).error_message_long;
} catch(exc) {}
}
if (typeof msg != "string" || msg.length == 0) {
msg = "An error occurred (" + (errorThrown || textStatus || jqXHR.status) + ").\n" +
Liberapay.error = function(exc) {
console.error(exc);
var msg = "An error occurred (" + exc + ").\n" +
"Please contact support@liberapay.com if the problem persists.";
}
Liberapay.notification(msg, 'error', -1);
}

Liberapay.wrap = function(f) {
return function() {
return async function() {
try {
return f.apply(this, arguments);
} catch (e) {
console.log(e);
Liberapay.notification(e, 'error', -1);
return await f.apply(this, arguments);
} catch (exc) {
Liberapay.error(exc);
}
}
};

Liberapay.get_object_by_name = function(name) {
return name.split('.').reduce(function(o, k) {return o[k]}, window);
}

Liberapay.jsonml = function(jsonml) {
var node = document.createElement(jsonml[0]);

Expand Down
16 changes: 9 additions & 7 deletions js/charts.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,21 @@ Liberapay.charts.init = function() {
}

Liberapay.charts.load = function(url, $container) {
jQuery.get(url, function(series) {
$(function() {
Liberapay.charts.make(series, $container);
});
}).fail(Liberapay.error);
fetch(url).then(function(response) {
response.json().then(function(series) {
$(function() {
Liberapay.charts.make(series, $container);
});
}).catch(Liberapay.error);
}).catch(Liberapay.error);
}

Liberapay.charts.make = function(series, $container) {
if (series.length) {
$('.chart-wrapper').show();
} else {
if (!!$container.data('msg-empty')) {
$container.append($('<span>').text(' '+$container.data('msg-empty')));
if ($container.attr('data-msg-empty')) {
$container.append($('<span>').text(' '+$container.attr('data-msg-empty')));
}
return;
}
Expand Down
Loading

0 comments on commit 71d06cd

Please sign in to comment.