{"version":3,"file":"user_date.min.js","sources":["https:\/\/formacion.cordoba-acoge.com\/lib\/amd\/src\/user_date.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 .\n\n\/**\n * Fetch and render dates from timestamps.\n *\n * @module core\/user_date\n * @copyright 2017 Ryan Wyllie \n * @license http:\/\/www.gnu.org\/copyleft\/gpl.html GNU GPL v3 or later\n *\/\ndefine(['jquery', 'core\/ajax', 'core\/sessionstorage', 'core\/config'],\n function($, Ajax, Storage, Config) {\n\n var SECONDS_IN_DAY = 86400;\n\n \/** @var {object} promisesCache Store all promises we've seen so far. *\/\n var promisesCache = {};\n\n \/**\n * Generate a cache key for the given request. The request should\n * have a timestamp and format key.\n *\n * @param {object} request\n * @return {string}\n *\/\n var getKey = function(request) {\n var language = $('html').attr('lang').replace(\/-\/g, '_');\n return 'core_user_date\/' +\n language + '\/' +\n Config.usertimezone + '\/' +\n request.timestamp + '\/' +\n request.format;\n };\n\n \/**\n * Retrieve a transformed date from the browser's storage.\n *\n * @param {string} key\n * @return {string}\n *\/\n var getFromLocalStorage = function(key) {\n return Storage.get(key);\n };\n\n \/**\n * Save the transformed date in the browser's storage.\n *\n * @param {string} key\n * @param {string} value\n *\/\n var addToLocalStorage = function(key, value) {\n Storage.set(key, value);\n };\n\n \/**\n * Check if a key is in the module's cache.\n *\n * @param {string} key\n * @return {bool}\n *\/\n var inPromisesCache = function(key) {\n return (typeof promisesCache[key] !== 'undefined');\n };\n\n \/**\n * Retrieve a promise from the module's cache.\n *\n * @param {string} key\n * @return {object} jQuery promise\n *\/\n var getFromPromisesCache = function(key) {\n return promisesCache[key];\n };\n\n \/**\n * Save the given promise in the module's cache.\n *\n * @param {string} key\n * @param {object} promise\n *\/\n var addToPromisesCache = function(key, promise) {\n promisesCache[key] = promise;\n };\n\n \/**\n * Send a request to the server for each of the required timestamp\n * and format combinations.\n *\n * Resolves the date's deferred with the values returned from the\n * server and saves the value in local storage.\n *\n * @param {array} dates\n * @return {object} jQuery promise\n *\/\n var loadDatesFromServer = function(dates) {\n var args = dates.map(function(data) {\n var fixDay = data.hasOwnProperty('fixday') ? data.fixday : 1;\n var fixHour = data.hasOwnProperty('fixhour') ? data.fixhour : 1;\n return {\n timestamp: data.timestamp,\n format: data.format,\n type: data.type || null,\n fixday: fixDay,\n fixhour: fixHour\n };\n });\n\n var request = {\n methodname: 'core_get_user_dates',\n args: {\n contextid: Config.contextid,\n timestamps: args\n }\n };\n\n return Ajax.call([request], true, true)[0].then(function(results) {\n results.dates.forEach(function(value, index) {\n var date = dates[index];\n var key = getKey(date);\n\n addToLocalStorage(key, value);\n date.deferred.resolve(value);\n });\n return;\n })\n .catch(function(ex) {\n \/\/ If we failed to retrieve the dates then reject the date's\n \/\/ deferred objects to make sure they don't hang.\n dates.forEach(function(date) {\n date.deferred.reject(ex);\n });\n });\n };\n\n \/**\n * Takes an array of request objects and returns a promise that\n * is resolved with an array of formatted dates.\n *\n * The values in the returned array will be ordered the same as\n * the request array.\n *\n * This function will check both the module's static promises cache\n * and the browser's session storage to see if the user dates have\n * already been loaded in order to avoid sending a network request\n * if possible.\n *\n * Only dates not found in either cache will be sent to the server\n * for transforming.\n *\n * A request object must have a timestamp key and a format key and\n * optionally may have a type key.\n *\n * E.g.\n * var request = [\n * {\n * timestamp: 1293876000,\n * format: '%d %B %Y'\n * },\n * {\n * timestamp: 1293876000,\n * format: '%A, %d %B %Y, %I:%M %p',\n * type: 'gregorian',\n * fixday: false,\n * fixhour: false\n * }\n * ];\n *\n * UserDate.get(request).done(function(dates) {\n * console.log(dates[0]); \/\/ prints \"1 January 2011\".\n * console.log(dates[1]); \/\/ prints \"Saturday, 1 January 2011, 10:00 AM\".\n * });\n *\n * @param {array} requests\n * @return {object} jQuery promise\n *\/\n var get = function(requests) {\n var ajaxRequests = [];\n var promises = [];\n\n \/\/ Loop over each of the requested timestamp\/format combos\n \/\/ and add a promise to the promises array for them.\n requests.forEach(function(request) {\n var key = getKey(request);\n\n \/\/ If we've already got a promise then use it.\n if (inPromisesCache(key)) {\n promises.push(getFromPromisesCache(key));\n } else {\n var deferred = $.Deferred();\n var cached = getFromLocalStorage(key);\n\n if (cached) {\n \/\/ If we were able to get the value from session storage\n \/\/ then we can resolve the deferred with that value. No\n \/\/ need to ask the server to transform it for us.\n deferred.resolve(cached);\n } else {\n \/\/ Add this request to the list of ones we need to load\n \/\/ from the server. Include the deferred so that it can\n \/\/ be resolved when the server has responded with the\n \/\/ transformed values.\n request.deferred = deferred;\n ajaxRequests.push(request);\n }\n\n \/\/ Remember this promise for next time so that we can\n \/\/ bail out early if it is requested again.\n addToPromisesCache(key, deferred.promise());\n promises.push(deferred.promise());\n }\n });\n\n \/\/ If we have any requests that we couldn't resolve from the caches\n \/\/ then let's ask the server to get them for us.\n if (ajaxRequests.length) {\n loadDatesFromServer(ajaxRequests);\n }\n\n \/\/ Wait for all of the promises to resolve. Some of them may be waiting\n \/\/ for a response from the server.\n return $.when.apply($, promises).then(function() {\n \/\/ This looks complicated but it's just converting an unknown\n \/\/ length of arguments into an array for the promise to resolve\n \/\/ with.\n return arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments);\n });\n };\n\n\n \/**\n * For a given timestamp get the midnight value in the user's timezone.\n *\n * The calculation is performed relative to the user's midnight timestamp\n * for today to ensure that timezones are preserved.\n *\n * E.g.\n * Input:\n * timestamp: 1514836800 (01\/01\/2018 8pm GMT)(02\/01\/2018 4am GMT+8)\n * midnight: 1514851200 (02\/01\/2018 midnight GMT)\n * Output:\n * 1514764800 (01\/01\/2018 midnight GMT)\n *\n * Input:\n * timestamp: 1514836800 (01\/01\/2018 8pm GMT)(02\/01\/2018 4am GMT+8)\n * midnight: 1514822400 (02\/01\/2018 midnight GMT+8)\n * Output:\n * 1514822400 (02\/01\/2018 midnight GMT+8)\n *\n * @param {Number} timestamp The timestamp to calculate from\n * @param {Number} todayMidnight The user's midnight timestamp\n * @return {Number} The midnight value of the user's timestamp\n *\/\n var getUserMidnightForTimestamp = function(timestamp, todayMidnight) {\n var future = timestamp > todayMidnight;\n var diffSeconds = Math.abs(timestamp - todayMidnight);\n var diffDays = future ? Math.floor(diffSeconds \/ SECONDS_IN_DAY) : Math.ceil(diffSeconds \/ SECONDS_IN_DAY);\n var diffDaysInSeconds = diffDays * SECONDS_IN_DAY;\n \/\/ Is the timestamp in the future or past?\n var dayTimestamp = future ? todayMidnight + diffDaysInSeconds : todayMidnight - diffDaysInSeconds;\n return dayTimestamp;\n };\n\n return {\n get: get,\n getUserMidnightForTimestamp: getUserMidnightForTimestamp\n };\n});\n"],"names":["define","$","Ajax","Storage","Config","promisesCache","getKey","request","attr","replace","usertimezone","timestamp","format","loadDatesFromServer","dates","args","map","data","fixDay","hasOwnProperty","fixday","fixHour","fixhour","type","methodname","contextid","timestamps","call","then","results","forEach","value","index","date","key","set","addToLocalStorage","deferred","resolve","catch","ex","reject","get","requests","ajaxRequests","promises","inPromisesCache","push","getFromPromisesCache","Deferred","cached","getFromLocalStorage","promise","addToPromisesCache","length","when","apply","arguments","Array","getUserMidnightForTimestamp","todayMidnight","future","diffSeconds","Math","abs","diffDaysInSeconds","floor","ceil"],"mappings":";;;;;;;AAsBAA,wBAAO,CAAC,SAAU,YAAa,sBAAuB,gBAC9C,SAASC,EAAGC,KAAMC,QAASC,YAK3BC,cAAgB,GAShBC,OAAS,SAASC,eAEX,kBADQN,EAAE,QAAQO,KAAK,QAAQC,QAAQ,KAAM,KAElC,IACXL,OAAOM,aAAe,IACtBH,QAAQI,UAAY,IACpBJ,QAAQK,QA+DfC,oBAAsB,SAASC,WAC3BC,KAAOD,MAAME,KAAI,SAASC,UACtBC,OAASD,KAAKE,eAAe,UAAYF,KAAKG,OAAS,EACvDC,QAAUJ,KAAKE,eAAe,WAAaF,KAAKK,QAAU,QACvD,CACHX,UAAWM,KAAKN,UAChBC,OAAQK,KAAKL,OACbW,KAAMN,KAAKM,MAAQ,KACnBH,OAAQF,OACRI,QAASD,YAIbd,QAAU,CACViB,WAAY,sBACZT,KAAM,CACFU,UAAWrB,OAAOqB,UAClBC,WAAYX,cAIbb,KAAKyB,KAAK,CAACpB,UAAU,GAAM,GAAM,GAAGqB,MAAK,SAASC,SACrDA,QAAQf,MAAMgB,SAAQ,SAASC,MAAOC,WAC9BC,KAAOnB,MAAMkB,QAnEL,SAASE,IAAKH,OAClC5B,QAAQgC,IAAID,IAAKH,OAqETK,CAFU9B,OAAO2B,MAEMF,OACvBE,KAAKI,SAASC,QAAQP,aAI7BQ,OAAM,SAASC,IAGZ1B,MAAMgB,SAAQ,SAASG,MACnBA,KAAKI,SAASI,OAAOD,iBAqI1B,CACHE,IAxFM,SAASC,cACXC,aAAe,GACfC,SAAW,UAIfF,SAASb,SAAQ,SAASvB,aAClB2B,IAAM5B,OAAOC,YA1HH,SAAS2B,iBACW,IAAvB7B,cAAc6B,KA4HrBY,CAAgBZ,KAChBW,SAASE,KApHM,SAASb,YACzB7B,cAAc6B,KAmHCc,CAAqBd,UAChC,KACCG,SAAWpC,EAAEgD,WACbC,OArJU,SAAShB,YACxB\/B,QAAQuC,IAAIR,KAoJEiB,CAAoBjB,KAE7BgB,OAIAb,SAASC,QAAQY,SAMjB3C,QAAQ8B,SAAWA,SACnBO,aAAaG,KAAKxC,UA1HT,SAAS2B,IAAKkB,SACnC\/C,cAAc6B,KAAOkB,QA8HbC,CAAmBnB,IAAKG,SAASe,WACjCP,SAASE,KAAKV,SAASe,eAM3BR,aAAaU,QACbzC,oBAAoB+B,cAKjB3C,EAAEsD,KAAKC,MAAMvD,EAAG4C,UAAUjB,MAAK,kBAIN,IAArB6B,UAAUH,OAAe,CAACG,UAAU,IAAMC,MAAMF,MAAM,KAAMC,eAwCvEE,4BAZ8B,SAAShD,UAAWiD,mBAC9CC,OAASlD,UAAYiD,cACrBE,YAAcC,KAAKC,IAAIrD,UAAYiD,eAEnCK,kBAnPa,OAkPFJ,OAASE,KAAKG,MAAMJ,YAlPlB,OAkPkDC,KAAKI,KAAKL,YAlP5D,eAqPED,OAASD,cAAgBK,kBAAoBL,cAAgBK"}