mirror of
https://github.com/zulip/zulip.git
synced 2025-11-02 21:13:36 +00:00
ES and TypeScript modules are strict by default and don’t need this directive. ESLint will remind us to add it to new CommonJS files and remove it from ES and TypeScript modules. Signed-off-by: Anders Kaseorg <anders@zulip.com>
145 lines
4.7 KiB
JavaScript
145 lines
4.7 KiB
JavaScript
"use strict";
|
|
|
|
const pending_requests = [];
|
|
|
|
function add_pending_request(jqXHR) {
|
|
pending_requests.push(jqXHR);
|
|
if (pending_requests.length > 50) {
|
|
blueslip.warn(
|
|
"The length of pending_requests is over 50. Most likely " +
|
|
"they are not being correctly removed.",
|
|
);
|
|
}
|
|
}
|
|
|
|
function remove_pending_request(jqXHR) {
|
|
const pending_request_index = pending_requests.indexOf(jqXHR);
|
|
if (pending_request_index !== -1) {
|
|
pending_requests.splice(pending_request_index, 1);
|
|
}
|
|
}
|
|
|
|
function call(args, idempotent) {
|
|
if (reload_state.is_in_progress() && !args.ignore_reload) {
|
|
// If we're in the process of reloading, most HTTP requests
|
|
// are useless, with exceptions like cleaning up our event
|
|
// queue and blueslip (Which doesn't use channel.js).
|
|
return;
|
|
}
|
|
|
|
// Wrap the error handlers to reload the page if we get a CSRF error
|
|
// (What probably happened is that the user logged out in another tab).
|
|
let orig_error = args.error;
|
|
if (orig_error === undefined) {
|
|
orig_error = function () {};
|
|
}
|
|
args.error = function wrapped_error(xhr, error_type, xhn) {
|
|
remove_pending_request(xhr);
|
|
|
|
if (reload_state.is_in_progress()) {
|
|
// If we're in the process of reloading the browser,
|
|
// there's no point in running the success handler,
|
|
// because all of our state is about to be discarded
|
|
// anyway.
|
|
blueslip.log(`Ignoring ${args.type} ${args.url} error response while reloading`);
|
|
return;
|
|
}
|
|
|
|
if (xhr.status === 403) {
|
|
try {
|
|
if (JSON.parse(xhr.responseText).code === "CSRF_FAILED") {
|
|
reload.initiate({
|
|
immediate: true,
|
|
save_pointer: true,
|
|
save_narrow: true,
|
|
save_compose: true,
|
|
});
|
|
}
|
|
} catch (ex) {
|
|
blueslip.error(
|
|
"Unexpected 403 response from server",
|
|
{xhr: xhr.responseText, args},
|
|
ex.stack,
|
|
);
|
|
}
|
|
}
|
|
return orig_error(xhr, error_type, xhn);
|
|
};
|
|
let orig_success = args.success;
|
|
if (orig_success === undefined) {
|
|
orig_success = function () {};
|
|
}
|
|
args.success = function wrapped_success(data, textStatus, jqXHR) {
|
|
remove_pending_request(jqXHR);
|
|
|
|
if (reload_state.is_in_progress()) {
|
|
// If we're in the process of reloading the browser,
|
|
// there's no point in running the success handler,
|
|
// because all of our state is about to be discarded
|
|
// anyway.
|
|
blueslip.log(`Ignoring ${args.type} ${args.url} response while reloading`);
|
|
return;
|
|
}
|
|
|
|
if (!data && idempotent) {
|
|
// If idempotent, retry
|
|
blueslip.log("Retrying idempotent" + args);
|
|
setTimeout(() => {
|
|
const jqXHR = $.ajax(args);
|
|
add_pending_request(jqXHR);
|
|
}, 0);
|
|
return;
|
|
}
|
|
return orig_success(data, textStatus, jqXHR);
|
|
};
|
|
|
|
const jqXHR = $.ajax(args);
|
|
add_pending_request(jqXHR);
|
|
return jqXHR;
|
|
}
|
|
|
|
exports.get = function (options) {
|
|
const args = {type: "GET", dataType: "json", ...options};
|
|
return call(args, options.idempotent);
|
|
};
|
|
|
|
exports.post = function (options) {
|
|
const args = {type: "POST", dataType: "json", ...options};
|
|
return call(args, options.idempotent);
|
|
};
|
|
|
|
exports.put = function (options) {
|
|
const args = {type: "PUT", dataType: "json", ...options};
|
|
return call(args, options.idempotent);
|
|
};
|
|
|
|
// Not called exports.delete because delete is a reserved word in JS
|
|
exports.del = function (options) {
|
|
const args = {type: "DELETE", dataType: "json", ...options};
|
|
return call(args, options.idempotent);
|
|
};
|
|
|
|
exports.patch = function (options) {
|
|
// Send a PATCH as a POST in order to work around QtWebkit
|
|
// (Linux/Windows desktop app) not supporting PATCH body.
|
|
if (options.processData === false) {
|
|
// If we're submitting a FormData object, we need to add the
|
|
// method this way
|
|
options.data.append("method", "PATCH");
|
|
} else {
|
|
options.data = {...options.data, method: "PATCH"};
|
|
}
|
|
return exports.post(options, options.idempotent);
|
|
};
|
|
|
|
exports.xhr_error_message = function (message, xhr) {
|
|
if (xhr.status.toString().charAt(0) === "4") {
|
|
// Only display the error response for 4XX, where we've crafted
|
|
// a nice response.
|
|
message += ": " + JSON.parse(xhr.responseText).msg;
|
|
}
|
|
return message;
|
|
};
|
|
|
|
window.channel = exports;
|