lib/amd/src/local/reactive/srlogger.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. * Screen reader-only (sr-only) reactive mutations logger class.
  17. *
  18. * This logger can be used by the StateManager to log mutation feedbacks and actions.
  19. * The feedback messages logged by this logger will be rendered in a sr-only, ARIA live region.
  20. *
  21. * @module core/local/reactive/srlogger
  22. * @class SRLogger
  23. * @copyright 2023 Jun Pataleta <jun@moodle.com>
  24. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25. */
  26. import Logger from 'core/local/reactive/logger';
  27. /**
  28. * Logger entry structure.
  29. *
  30. * @typedef {object} LoggerEntry
  31. * @property {string} feedbackMessage Feedback message.
  32. */
  33. /**
  34. * Screen reader-only (sr-only) reactive mutations logger class.
  35. *
  36. * @class SRLogger
  37. */
  38. export default class SRLogger extends Logger {
  39. /**
  40. * The element ID of the ARIA live region where the logger feedback will be rendered.
  41. *
  42. * @type {string}
  43. */
  44. static liveRegionId = 'sr-logger-feedback-container';
  45. /**
  46. * Add a log entry.
  47. * @param {LoggerEntry} entry Log entry.
  48. */
  49. add(entry) {
  50. if (entry.feedbackMessage) {
  51. // Fetch or create an ARIA live region that will serve as the container for the logger feedback.
  52. let loggerFeedback = document.getElementById(SRLogger.liveRegionId);
  53. if (!loggerFeedback) {
  54. loggerFeedback = document.createElement('div');
  55. loggerFeedback.id = SRLogger.liveRegionId;
  56. loggerFeedback.classList.add('sr-only');
  57. loggerFeedback.setAttribute('aria-live', 'polite');
  58. document.body.append(loggerFeedback);
  59. }
  60. // Set the ARIA live region's contents with the feedback.
  61. loggerFeedback.innerHTML = entry.feedbackMessage;
  62. // Clear the feedback message after 4 seconds to avoid the contents from being read out in case the user navigates
  63. // to this region. This is similar to the default timeout of toast messages before disappearing from view.
  64. setTimeout(() => {
  65. loggerFeedback.innerHTML = '';
  66. }, 4000);
  67. }
  68. }
  69. }