course/amd/src/downloadcontent.js

  1. // This file is part of Moodle - http://moodle.org/
  2. //
  3. // Moodle is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation, either version 3 of the License, or
  6. // (at your option) any later version.
  7. //
  8. // Moodle is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  15. /**
  16. * Functions related to downloading course content.
  17. *
  18. * @module core_course/downloadcontent
  19. * @copyright 2020 Michael Hawkins <michaelh@moodle.com>
  20. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  21. */
  22. import Config from 'core/config';
  23. import CustomEvents from 'core/custom_interaction_events';
  24. import * as ModalFactory from 'core/modal_factory';
  25. import jQuery from 'jquery';
  26. import Pending from 'core/pending';
  27. import {enter, space} from 'core/key_codes';
  28. /**
  29. * Set up listener to trigger the download course content modal.
  30. *
  31. * @return {void}
  32. */
  33. export const init = () => {
  34. const pendingPromise = new Pending();
  35. // Add event listeners for click and enter/space keys.
  36. jQuery('[data-downloadcourse]').on('click keydown', (e) => {
  37. if (e.type === 'click' || e.which === enter || e.which === space) {
  38. e.preventDefault();
  39. displayDownloadConfirmation(e.currentTarget);
  40. }
  41. });
  42. pendingPromise.resolve();
  43. };
  44. /**
  45. * Display the download course content modal.
  46. *
  47. * @method displayDownloadConfirmation
  48. * @param {Object} downloadModalTrigger The DOM element that triggered the download modal.
  49. * @return {void}
  50. */
  51. const displayDownloadConfirmation = (downloadModalTrigger) => {
  52. ModalFactory.create({
  53. title: downloadModalTrigger.dataset.downloadTitle,
  54. type: ModalFactory.types.SAVE_CANCEL,
  55. body: `<p>${downloadModalTrigger.dataset.downloadBody}</p>`,
  56. buttons: {
  57. save: downloadModalTrigger.dataset.downloadButtonText
  58. },
  59. templateContext: {
  60. classes: 'downloadcoursecontentmodal'
  61. }
  62. })
  63. .then(modal => {
  64. // Display the modal.
  65. modal.show();
  66. const saveButton = document.querySelector('.modal .downloadcoursecontentmodal [data-action="save"]');
  67. const cancelButton = document.querySelector('.modal .downloadcoursecontentmodal [data-action="cancel"]');
  68. const modalContainer = document.querySelector('.modal[data-region="modal-container"]');
  69. // Create listener to trigger the download when the "Download" button is pressed.
  70. jQuery(saveButton).on(CustomEvents.events.activate, (e) => downloadContent(e, downloadModalTrigger, modal));
  71. // Create listener to destroy the modal when closing modal by cancelling.
  72. jQuery(cancelButton).on(CustomEvents.events.activate, () => {
  73. modal.destroy();
  74. });
  75. // Create listener to destroy the modal when closing modal by clicking outside of it.
  76. if (modalContainer.querySelector('.downloadcoursecontentmodal')) {
  77. jQuery(modalContainer).on(CustomEvents.events.activate, () => {
  78. modal.destroy();
  79. });
  80. }
  81. });
  82. };
  83. /**
  84. * Trigger downloading of course content.
  85. *
  86. * @method downloadContent
  87. * @param {Event} e The event triggering the download.
  88. * @param {Object} downloadModalTrigger The DOM element that triggered the download modal.
  89. * @param {Object} modal The modal object.
  90. * @return {void}
  91. */
  92. const downloadContent = (e, downloadModalTrigger, modal) => {
  93. e.preventDefault();
  94. // Create a form to submit the file download request, so we can avoid sending sesskey over GET.
  95. const downloadForm = document.createElement('form');
  96. downloadForm.action = downloadModalTrigger.dataset.downloadLink;
  97. downloadForm.method = 'POST';
  98. // Open download in a new tab, so current course view is not disrupted.
  99. downloadForm.target = '_blank';
  100. const downloadSesskey = document.createElement('input');
  101. downloadSesskey.name = 'sesskey';
  102. downloadSesskey.value = Config.sesskey;
  103. downloadForm.appendChild(downloadSesskey);
  104. downloadForm.style.display = 'none';
  105. document.body.appendChild(downloadForm);
  106. downloadForm.submit();
  107. document.body.removeChild(downloadForm);
  108. // Destroy the modal to prevent duplicates if reopened later.
  109. modal.destroy();
  110. };