mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 22:08:20 +01:00
1 line
15 KiB
Plaintext
1 line
15 KiB
Plaintext
{"version":3,"file":"ajax.min.js","sources":["../src/ajax.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Standard Ajax wrapper for Moodle. It calls the central Ajax script,\n * which can call any existing webservice using the current session.\n * In addition, it can batch multiple requests and return multiple responses.\n *\n * @module core/ajax\n * @copyright 2015 Damyon Wiese <damyon@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 2.9\n */\ndefine(['jquery', 'core/config', 'core/log', 'core/url'], function($, config, Log, URL) {\n\n/**\n * A request to be performed.\n *\n * @typedef {object} request\n * @property {string} methodname The remote method to be called\n * @property {object} args The arguments to pass when fetching the remote content\n */\n\n // Keeps track of when the user leaves the page so we know not to show an error.\n var unloading = false;\n\n /**\n * Success handler. Called when the ajax call succeeds. Checks each response and\n * resolves or rejects the deferred from that request.\n *\n * @method requestSuccess\n * @private\n * @param {Object[]} responses Array of responses containing error, exception and data attributes.\n */\n var requestSuccess = function(responses) {\n // Call each of the success handlers.\n var requests = this,\n exception = null,\n i = 0,\n request,\n response,\n nosessionupdate;\n\n if (responses.error) {\n // There was an error with the request as a whole.\n // We need to reject each promise.\n // Unfortunately this may lead to duplicate dialogues, but each Promise must be rejected.\n for (; i < requests.length; i++) {\n request = requests[i];\n request.deferred.reject(responses);\n }\n\n return;\n }\n\n for (i = 0; i < requests.length; i++) {\n request = requests[i];\n\n response = responses[i];\n // We may not have responses for all the requests.\n if (typeof response !== \"undefined\") {\n if (response.error === false) {\n // Call the done handler if it was provided.\n request.deferred.resolve(response.data);\n } else {\n exception = response.exception;\n nosessionupdate = requests[i].nosessionupdate;\n break;\n }\n } else {\n // This is not an expected case.\n exception = new Error('missing response');\n break;\n }\n }\n // Something failed, reject the remaining promises.\n if (exception !== null) {\n // Redirect to the login page.\n if (exception.errorcode === \"servicerequireslogin\" && !nosessionupdate) {\n window.location = URL.relativeUrl(\"/login/index.php\");\n } else {\n requests.forEach(function(request) {\n request.deferred.reject(exception);\n });\n }\n }\n };\n\n /**\n * Fail handler. Called when the ajax call fails. Rejects all deferreds.\n *\n * @method requestFail\n * @private\n * @param {jqXHR} jqXHR The ajax object.\n * @param {string} textStatus The status string.\n * @param {Error|Object} exception The error thrown.\n */\n var requestFail = function(jqXHR, textStatus, exception) {\n // Reject all the promises.\n var requests = this;\n\n var i = 0;\n for (i = 0; i < requests.length; i++) {\n var request = requests[i];\n\n if (unloading) {\n // No need to trigger an error because we are already navigating.\n Log.error(\"Page unloaded.\");\n Log.error(exception);\n } else {\n request.deferred.reject(exception);\n }\n }\n };\n\n return /** @alias module:core/ajax */ {\n // Public variables and functions.\n /**\n * Make a series of ajax requests and return all the responses.\n *\n * @method call\n * @param {request[]} requests Array of requests with each containing methodname and args properties.\n * done and fail callbacks can be set for each element in the array, or the\n * can be attached to the promises returned by this function.\n * @param {Boolean} [async=true] If false this function will not return until the promises are resolved.\n * @param {Boolean} [loginrequired=true] When false this function calls an endpoint which does not use the\n * session.\n * Note: This may only be used with external functions which have been marked as\n * `'loginrequired' => false`\n * @param {Boolean} [nosessionupdate=false] If true, the timemodified for the session will not be updated.\n * @param {Number} [timeout] number of milliseconds to wait for a response. Defaults to no limit.\n * @param {Number} [cachekey] A cache key used to improve browser-side caching.\n * Typically the same `cachekey` is used for all function calls.\n * When the key changes, this causes the URL used to perform the fetch to change, which\n * prevents the existing browser cache from being used.\n * Note: This option is only availbale when `loginrequired` is `false`.\n * See {@link https://tracker.moodle.org/browser/MDL-65794} for more information.\n * @return {Promise[]} The Promises for each of the supplied requests.\n * The order of the Promise matches the order of requests exactly.\n *\n * @example <caption>A simple example that you might find in a repository module</caption>\n *\n * import {call as fetchMany} from 'core/ajax';\n *\n * export const fetchMessages = timeSince => fetchMany([{methodname: 'core_message_get_messages', args: {timeSince}}])[0];\n *\n * export const fetchNotifications = timeSince => fetchMany([{\n * methodname: 'core_message_get_notifications',\n * args: {\n * timeSince,\n * }\n * }])[0];\n *\n * export const fetchSomethingElse = (some, params, here) => fetchMany([{\n * methodname: 'core_get_something_else',\n * args: {\n * some,\n * params,\n * gohere: here,\n * },\n * }])[0];\n *\n * @example <caption>An example of fetching a string using the cachekey parameter</caption>\n * import {call as fetchMany} from 'core/ajax';\n * import * as Notification from 'core/notification';\n *\n * export const performAction = (some, args) => {\n * Promises.all(fetchMany([{methodname: 'core_get_string', args: {\n * stringid: 'do_not_copy',\n * component: 'core',\n * lang: 'en',\n * stringparams: [],\n * }}], true, false, false, undefined, M.cfg.langrev))\n * .then(([doNotCopyString]) => {\n * window.console.log(doNotCopyString);\n * })\n * .catch(Notification.exception);\n * };\n *\n */\n call: function(requests, async, loginrequired, nosessionupdate, timeout, cachekey) {\n $(window).bind('beforeunload', function() {\n unloading = true;\n });\n var ajaxRequestData = [],\n i,\n promises = [],\n methodInfo = [],\n requestInfo = '';\n\n var maxUrlLength = 2000;\n\n if (typeof loginrequired === \"undefined\") {\n loginrequired = true;\n }\n if (typeof async === \"undefined\") {\n async = true;\n }\n if (typeof timeout === 'undefined') {\n timeout = 0;\n }\n if (typeof cachekey === 'undefined') {\n cachekey = null;\n } else {\n cachekey = parseInt(cachekey);\n if (cachekey <= 0) {\n cachekey = null;\n } else if (!cachekey) {\n cachekey = null;\n }\n }\n\n if (typeof nosessionupdate === \"undefined\") {\n nosessionupdate = false;\n }\n for (i = 0; i < requests.length; i++) {\n var request = requests[i];\n ajaxRequestData.push({\n index: i,\n methodname: request.methodname,\n args: request.args\n });\n request.nosessionupdate = nosessionupdate;\n request.deferred = $.Deferred();\n promises.push(request.deferred.promise());\n // Allow setting done and fail handlers as arguments.\n // This is just a shortcut for the calling code.\n if (typeof request.done !== \"undefined\") {\n request.deferred.done(request.done);\n }\n if (typeof request.fail !== \"undefined\") {\n request.deferred.fail(request.fail);\n }\n request.index = i;\n methodInfo.push(request.methodname);\n }\n\n if (methodInfo.length <= 5) {\n requestInfo = methodInfo.sort().join();\n } else {\n requestInfo = methodInfo.length + '-method-calls';\n }\n\n ajaxRequestData = JSON.stringify(ajaxRequestData);\n var settings = {\n type: 'POST',\n context: requests,\n dataType: 'json',\n processData: false,\n async: async,\n contentType: \"application/json\",\n timeout: timeout\n };\n\n var script = 'service.php';\n var url = config.wwwroot + '/lib/ajax/';\n if (!loginrequired) {\n script = 'service-nologin.php';\n url += script + '?info=' + requestInfo;\n if (cachekey) {\n url += '&cachekey=' + cachekey;\n settings.type = 'GET';\n }\n } else {\n url += script + '?sesskey=' + config.sesskey + '&info=' + requestInfo;\n }\n\n if (nosessionupdate) {\n url += '&nosessionupdate=true';\n }\n\n if (settings.type === 'POST') {\n settings.data = ajaxRequestData;\n } else {\n var urlUseGet = url + '&args=' + encodeURIComponent(ajaxRequestData);\n\n if (urlUseGet.length > maxUrlLength) {\n settings.type = 'POST';\n settings.data = ajaxRequestData;\n } else {\n url = urlUseGet;\n }\n }\n\n // Jquery deprecated done and fail with async=false so we need to do this 2 ways.\n if (async) {\n $.ajax(url, settings)\n .done(requestSuccess)\n .fail(requestFail);\n } else {\n settings.success = requestSuccess;\n settings.error = requestFail;\n $.ajax(url, settings);\n }\n\n return promises;\n }\n };\n});\n"],"names":["define","$","config","Log","URL","unloading","requestSuccess","responses","request","response","nosessionupdate","exception","i","error","this","length","deferred","reject","Error","resolve","data","errorcode","forEach","window","location","relativeUrl","requestFail","jqXHR","textStatus","call","requests","async","loginrequired","timeout","cachekey","bind","ajaxRequestData","promises","methodInfo","requestInfo","parseInt","push","index","methodname","args","Deferred","promise","done","fail","sort","join","JSON","stringify","settings","type","context","dataType","processData","contentType","script","url","wwwroot","sesskey","urlUseGet","encodeURIComponent","ajax","success"],"mappings":"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"} |