mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 14:27:22 +01:00
1 line
15 KiB
Plaintext
1 line
15 KiB
Plaintext
{"version":3,"file":"paged_content_pages.min.js","sources":["../src/paged_content_pages.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 * Javascript for showing/hiding pages of content.\n *\n * @module core/paged_content_pages\n * @copyright 2018 Ryan Wyllie <ryan@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(\n [\n 'jquery',\n 'core/templates',\n 'core/notification',\n 'core/pubsub',\n 'core/paged_content_events',\n 'core/pending',\n ],\n function(\n $,\n Templates,\n Notification,\n PubSub,\n PagedContentEvents,\n Pending\n ) {\n\n var SELECTORS = {\n ROOT: '[data-region=\"page-container\"]',\n PAGE_REGION: '[data-region=\"paged-content-page\"]',\n ACTIVE_PAGE_REGION: '[data-region=\"paged-content-page\"].active'\n };\n\n var TEMPLATES = {\n PAGING_CONTENT_ITEM: 'core/paged_content_page',\n LOADING: 'core/overlay_loading'\n };\n\n var PRELOADING_GRACE_PERIOD = 300;\n\n /**\n * Find a page by the number.\n *\n * @param {object} root The root element.\n * @param {Number} pageNumber The number of the page to be found.\n * @returns {jQuery} The page.\n */\n var findPage = function(root, pageNumber) {\n return root.find('[data-page=\"' + pageNumber + '\"]');\n };\n\n /**\n * Show the loading spinner until the returned deferred is resolved by the\n * calling code.\n *\n * The loading spinner is only rendered after a short grace period to avoid\n * having it flash up briefly in the interface.\n *\n * @param {object} root The root element.\n * @returns {promise} The page.\n */\n var startLoading = function(root) {\n var deferred = $.Deferred();\n root.attr('aria-busy', true);\n\n var pendingPromise = new Pending('core/paged_content_pages:startLoading');\n\n Templates.render(TEMPLATES.LOADING, {visible: true})\n .then(function(html) {\n var loadingSpinner = $(html);\n // Put this in a timer to give the calling code 300 milliseconds\n // to render the content before we show the loading spinner. This\n // helps prevent a loading icon flicker on close to instant\n // rendering.\n var timerId = setTimeout(function() {\n root.css('position', 'relative');\n loadingSpinner.appendTo(root);\n }, PRELOADING_GRACE_PERIOD);\n\n deferred.always(function() {\n clearTimeout(timerId);\n // Remove the loading spinner when our deferred is resolved\n // by the calling code.\n loadingSpinner.remove();\n root.css('position', '');\n root.removeAttr('aria-busy');\n\n pendingPromise.resolve();\n return;\n });\n\n return;\n })\n .fail(Notification.exception);\n\n return deferred;\n };\n\n /**\n * Render the result of the page promise in a paged content page.\n *\n * This function returns a promise that is resolved with the new paged content\n * page.\n *\n * @param {object} root The root element.\n * @param {promise} pagePromise The promise resolved with HTML and JS to render in the page.\n * @param {Number} pageNumber The page number.\n * @returns {promise} The page.\n */\n var renderPagePromise = function(root, pagePromise, pageNumber) {\n var deferred = $.Deferred();\n pagePromise.then(function(html, pageJS) {\n pageJS = pageJS || '';\n // When we get the contents to be rendered we can pass it in as the\n // content for a new page.\n Templates.render(TEMPLATES.PAGING_CONTENT_ITEM, {\n page: pageNumber,\n content: html\n })\n .then(function(html) {\n // Make sure the JS we got from the page promise is being added\n // to the page when we render the page.\n Templates.appendNodeContents(root, html, pageJS);\n var page = findPage(root, pageNumber);\n deferred.resolve(page);\n return;\n })\n .fail(function(exception) {\n deferred.reject(exception);\n })\n .fail(Notification.exception);\n\n return;\n })\n .fail(function(exception) {\n deferred.reject(exception);\n return;\n })\n .fail(Notification.exception);\n\n return deferred.promise();\n };\n\n /**\n * Make one or more pages visible based on the SHOW_PAGES event. The show\n * pages event provides data containing which pages should be shown as well\n * as the limit and offset values for loading the items for each of those pages.\n *\n * The renderPagesContentCallback is provided this list of data to know which\n * pages to load. E.g. the data to load 2 pages might look like:\n * [\n * {\n * pageNumber: 1,\n * limit: 5,\n * offset: 0\n * },\n * {\n * pageNumber: 2,\n * limit: 5,\n * offset: 5\n * }\n * ]\n *\n * The renderPagesContentCallback should return an array of promises, one for\n * each page in the pages data, that is resolved with the HTML and JS for that page.\n *\n * If the renderPagesContentCallback is not provided then it is assumed that\n * all pages have been rendered prior to initialising this module.\n *\n * This function triggers the PAGES_SHOWN event after the pages have been rendered.\n *\n * @param {object} root The root element.\n * @param {Number} pagesData The data for which pages need to be visible.\n * @param {string} id A unique id for this instance.\n * @param {function} renderPagesContentCallback Render pages content.\n */\n var showPages = function(root, pagesData, id, renderPagesContentCallback) {\n var pendingPromise = new Pending('core/paged_content_pages:showPages');\n var existingPages = [];\n var newPageData = [];\n var newPagesPromise = $.Deferred();\n var shownewpage = true;\n // Check which of the pages being requests have previously been rendered\n // so that we only ask for new pages to be rendered by the callback.\n pagesData.forEach(function(pageData) {\n var pageNumber = pageData.pageNumber;\n var existingPage = findPage(root, pageNumber);\n if (existingPage.length) {\n existingPages.push(existingPage);\n } else {\n newPageData.push(pageData);\n }\n });\n\n if (newPageData.length && typeof renderPagesContentCallback === 'function') {\n // If we have pages we haven't previously seen then ask the client code\n // to render them for us by calling the callback.\n var promises = renderPagesContentCallback(newPageData, {\n allItemsLoaded: function(lastPageNumber) {\n PubSub.publish(id + PagedContentEvents.ALL_ITEMS_LOADED, lastPageNumber);\n }\n });\n // After the client has finished rendering each of the pages being asked\n // for then begin our rendering process to put that content into paged\n // content pages.\n var renderPagePromises = promises.map(function(promise, index) {\n // Create our promise for when our rendering will be completed.\n return renderPagePromise(root, promise, newPageData[index].pageNumber);\n });\n // After each of our rendering promises have been completed then we can\n // give all of the new pages to the next bit of code for handling.\n $.when.apply($, renderPagePromises)\n .then(function() {\n var newPages = Array.prototype.slice.call(arguments);\n // Resolve the promise with the list of newly rendered pages.\n newPagesPromise.resolve(newPages);\n return;\n })\n .fail(function(exception) {\n newPagesPromise.reject(exception);\n return;\n })\n .fail(Notification.exception);\n } else {\n // If there aren't any pages to load then immediately resolve the promise.\n newPagesPromise.resolve([]);\n }\n\n var loadingPromise = startLoading(root);\n newPagesPromise.then(function(newPages) {\n // Once all of the new pages have been created then add them to any\n // existing pages we have.\n var pagesToShow = existingPages.concat(newPages);\n // Hide all existing pages.\n root.find(SELECTORS.PAGE_REGION).addClass('hidden');\n // Show each of the pages that were requested.;\n pagesToShow.forEach(function(page) {\n if (shownewpage) {\n page.removeClass('hidden');\n }\n });\n\n return;\n })\n .then(function() {\n // Let everything else know we've displayed the pages.\n PubSub.publish(id + PagedContentEvents.PAGES_SHOWN, pagesData);\n return;\n })\n .fail(Notification.exception)\n .always(function() {\n loadingPromise.resolve();\n pendingPromise.resolve();\n })\n .catch();\n };\n\n /**\n * Initialise the module to listen for SHOW_PAGES events and render the\n * appropriate pages using the provided renderPagesContentCallback function.\n *\n * The renderPagesContentCallback is provided a list of data to know which\n * pages to load.\n * E.g. the data to load 2 pages might look like:\n * [\n * {\n * pageNumber: 1,\n * limit: 5,\n * offset: 0\n * },\n * {\n * pageNumber: 2,\n * limit: 5,\n * offset: 5\n * }\n * ]\n *\n * The renderPagesContentCallback should return an array of promises, one for\n * each page in the pages data, that is resolved with the HTML and JS for that page.\n *\n * If the renderPagesContentCallback is not provided then it is assumed that\n * all pages have been rendered prior to initialising this module.\n *\n * The event element is the element to listen for the paged content events on.\n *\n * @param {object} root The root element.\n * @param {string} id A unique id for this instance.\n * @param {function} renderPagesContentCallback Render pages content.\n */\n var init = function(root, id, renderPagesContentCallback) {\n root = $(root);\n\n PubSub.subscribe(id + PagedContentEvents.SHOW_PAGES, function(pagesData) {\n showPages(root, pagesData, id, renderPagesContentCallback);\n });\n\n PubSub.subscribe(id + PagedContentEvents.SET_ITEMS_PER_PAGE_LIMIT, function() {\n // If the items per page limit was changed then we need to clear our content\n // the load new values based on the new limit.\n root.empty();\n });\n };\n\n return {\n init: init,\n rootSelector: SELECTORS.ROOT,\n };\n});\n"],"names":["define","$","Templates","Notification","PubSub","PagedContentEvents","Pending","SELECTORS","TEMPLATES","findPage","root","pageNumber","find","showPages","pagesData","id","renderPagesContentCallback","pendingPromise","existingPages","newPageData","newPagesPromise","Deferred","forEach","pageData","existingPage","length","push","renderPagePromises","allItemsLoaded","lastPageNumber","publish","ALL_ITEMS_LOADED","map","promise","index","pagePromise","deferred","then","html","pageJS","render","page","content","appendNodeContents","resolve","fail","exception","reject","renderPagePromise","when","apply","newPages","Array","prototype","slice","call","arguments","loadingPromise","attr","visible","loadingSpinner","timerId","setTimeout","css","appendTo","always","clearTimeout","remove","removeAttr","startLoading","pagesToShow","concat","addClass","removeClass","PAGES_SHOWN","catch","init","subscribe","SHOW_PAGES","SET_ITEMS_PER_PAGE_LIMIT","empty","rootSelector"],"mappings":"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"} |