Proyectos de Subversion Moodle

Rev

Autoría | Ultima modificación | Ver Log |

{"version":3,"file":"user_date.min.js","sources":["../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 <http://www.gnu.org/licenses/>.\n\n/**\n * Fetch and render dates from timestamps.\n *\n * @module     core/user_date\n * @copyright  2017 Ryan Wyllie <ryan@moodle.com>\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        return 'core_user_date/' +\n               Config.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","language","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,eACX,kBACAH,OAAOI,SAAW,IAClBJ,OAAOK,aAAe,IACtBF,QAAQG,UAAY,IACpBH,QAAQI,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,YAIbb,QAAU,CACVgB,WAAY,sBACZT,KAAM,CACFU,UAAWpB,OAAOoB,UAClBC,WAAYX,cAIbZ,KAAKwB,KAAK,CAACnB,UAAU,GAAM,GAAM,GAAGoB,MAAK,SAASC,SACrDA,QAAQf,MAAMgB,SAAQ,SAASC,MAAOC,WAC9BC,KAAOnB,MAAMkB,QAnEL,SAASE,IAAKH,OAClC3B,QAAQ+B,IAAID,IAAKH,OAqETK,CAFU7B,OAAO0B,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,SAAStB,aAClB0B,IAAM3B,OAAOC,YA1HH,SAAS0B,iBACW,IAAvB5B,cAAc4B,KA4HrBY,CAAgBZ,KAChBW,SAASE,KApHM,SAASb,YACzB5B,cAAc4B,KAmHCc,CAAqBd,UAChC,KACCG,SAAWnC,EAAE+C,WACbC,OArJU,SAAShB,YACxB9B,QAAQsC,IAAIR,KAoJEiB,CAAoBjB,KAE7BgB,OAIAb,SAASC,QAAQY,SAMjB1C,QAAQ6B,SAAWA,SACnBO,aAAaG,KAAKvC,UA1HT,SAAS0B,IAAKkB,SACnC9C,cAAc4B,KAAOkB,QA8HbC,CAAmBnB,IAAKG,SAASe,WACjCP,SAASE,KAAKV,SAASe,eAM3BR,aAAaU,QACbzC,oBAAoB+B,cAKjB1C,EAAEqD,KAAKC,MAAMtD,EAAG2C,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,kBAlPa,OAiPFJ,OAASE,KAAKG,MAAMJ,YAjPlB,OAiPkDC,KAAKI,KAAKL,YAjP5D,eAoPED,OAASD,cAAgBK,kBAAoBL,cAAgBK"}