mirror of
https://github.com/moodle/moodle.git
synced 2025-08-08 10:26:40 +02:00
MDL-81825 theme_boost: Refactor .sr-only usages for BS5
- Add .visually-hidden to the Boostratp 5 bridge SCSS file - Replace .sr-only occurrences with .visually-hidden - Replace .dropzone-sr-only-focusable with .dropzone-visually-hidden-focusable for consistency
This commit is contained in:
parent
0888a6d324
commit
f9abc562f5
220 changed files with 469 additions and 439 deletions
2
lib/amd/build/copy_to_clipboard.min.js
vendored
2
lib/amd/build/copy_to_clipboard.min.js
vendored
|
@ -26,6 +26,6 @@ define("core/copy_to_clipboard",["core/str","core/toast","core/prefetch"],(funct
|
|||
* Copy to clipboard
|
||||
* </button>
|
||||
*/
|
||||
const copyNodeContentToClipboard=(copyButton,copyTarget)=>(copyTarget.select(),document.execCommand("copy")?(displaySuccessToast(copyButton),!0):(displayFailureToast(),!1)),displaySuccessToast=copyButton=>getSuccessText(copyButton).then((successMessage=>(0,_toast.add)(successMessage,{}))),displayFailureToast=()=>getFailureText().then((message=>(0,_toast.add)(message,{type:"warning"}))),getFailureText=()=>(0,_str.getString)("unabletocopytoclipboard","core"),getSuccessText=copyButton=>copyButton.dataset.clipboardSuccessMessage?Promise.resolve(copyButton.dataset.clipboardSuccessMessage):(0,_str.getString)("textcopiedtoclipboard","core"),getTextFromContainer=container=>container.value?container.value:container.innerText?container.innerText:null;let loaded=!1;loaded||((0,_prefetch.prefetchStrings)("core",["textcopiedtoclipboard","unabletocopytoclipboard"]),document.addEventListener("click",(e=>{const copyButton=e.target.closest('[data-action="copytoclipboard"]');if(!copyButton)return;if(!copyButton.dataset.clipboardTarget)return;const copyTarget=document.querySelector(copyButton.dataset.clipboardTarget);if(!copyTarget)return;e.preventDefault();const textToCopy=getTextFromContainer(copyTarget);if(textToCopy)if(navigator.clipboard)navigator.clipboard.writeText(textToCopy).then((()=>displaySuccessToast(copyButton))).catch();else if(copyTarget instanceof HTMLInputElement||copyTarget instanceof HTMLTextAreaElement)copyTarget.focus(),copyNodeContentToClipboard(copyButton,copyTarget)&©Button.focus();else{const copyRegion=document.createElement("textarea");copyRegion.value=textToCopy,copyRegion.classList.add("sr-only"),document.body.appendChild(copyRegion),copyNodeContentToClipboard(copyButton,copyRegion),copyRegion.remove(),copyButton.focus()}else displayFailureToast()})),loaded=!0)}));
|
||||
const copyNodeContentToClipboard=(copyButton,copyTarget)=>(copyTarget.select(),document.execCommand("copy")?(displaySuccessToast(copyButton),!0):(displayFailureToast(),!1)),displaySuccessToast=copyButton=>getSuccessText(copyButton).then((successMessage=>(0,_toast.add)(successMessage,{}))),displayFailureToast=()=>getFailureText().then((message=>(0,_toast.add)(message,{type:"warning"}))),getFailureText=()=>(0,_str.getString)("unabletocopytoclipboard","core"),getSuccessText=copyButton=>copyButton.dataset.clipboardSuccessMessage?Promise.resolve(copyButton.dataset.clipboardSuccessMessage):(0,_str.getString)("textcopiedtoclipboard","core"),getTextFromContainer=container=>container.value?container.value:container.innerText?container.innerText:null;let loaded=!1;loaded||((0,_prefetch.prefetchStrings)("core",["textcopiedtoclipboard","unabletocopytoclipboard"]),document.addEventListener("click",(e=>{const copyButton=e.target.closest('[data-action="copytoclipboard"]');if(!copyButton)return;if(!copyButton.dataset.clipboardTarget)return;const copyTarget=document.querySelector(copyButton.dataset.clipboardTarget);if(!copyTarget)return;e.preventDefault();const textToCopy=getTextFromContainer(copyTarget);if(textToCopy)if(navigator.clipboard)navigator.clipboard.writeText(textToCopy).then((()=>displaySuccessToast(copyButton))).catch();else if(copyTarget instanceof HTMLInputElement||copyTarget instanceof HTMLTextAreaElement)copyTarget.focus(),copyNodeContentToClipboard(copyButton,copyTarget)&©Button.focus();else{const copyRegion=document.createElement("textarea");copyRegion.value=textToCopy,copyRegion.classList.add("visually-hidden"),document.body.appendChild(copyRegion),copyNodeContentToClipboard(copyButton,copyRegion),copyRegion.remove(),copyButton.focus()}else displayFailureToast()})),loaded=!0)}));
|
||||
|
||||
//# sourceMappingURL=copy_to_clipboard.min.js.map
|
File diff suppressed because one or more lines are too long
2
lib/amd/build/datafilter/filtertype.min.js
vendored
2
lib/amd/build/datafilter/filtertype.min.js
vendored
|
@ -5,6 +5,6 @@ define("core/datafilter/filtertype",["exports","core/form-autocomplete","core/da
|
|||
* @module core/datafilter/filtertype
|
||||
* @copyright 2020 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_formAutocomplete=_interopRequireDefault(_formAutocomplete),_selectors=_interopRequireDefault(_selectors),_notification=_interopRequireDefault(_notification);return _exports.default=class{constructor(filterType,rootNode,initialValues){this.filterType=filterType,this.rootNode=rootNode,this.addValueSelector(initialValues).then((()=>{const filterRoot=this.filterRoot;return filterRoot&&filterRoot.querySelector(_selectors.default.data.required)&&filterRoot.querySelector(_selectors.default.filter.actions.remove).remove(),filterRoot})).catch(_notification.default.exception)}tearDown(){}get placeholder(){return(0,_str.getString)("placeholdertypeorselect","core")}get showSuggestions(){return!0}async addValueSelector(){let initialValues=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];const filterValueNode=this.getFilterValueNode(),sourceDataNode=this.getSourceDataForFilter();if(!sourceDataNode)throw new Error("No source data for filter.");filterValueNode.innerHTML=sourceDataNode.outerHTML;const dataSource=filterValueNode.querySelector("select");dataSource.id="filter-value-"+dataSource.getAttribute("data-field-name");const filterValueLabel=document.createElement("label");return filterValueLabel.setAttribute("for",dataSource.id),filterValueLabel.classList.add("sr-only"),filterValueLabel.innerText=dataSource.getAttribute("data-field-title"),filterValueNode.appendChild(filterValueLabel),initialValues.forEach((filterValue=>{let selectedOption=dataSource.querySelector('option[value="'.concat(filterValue,'"]'));selectedOption?selectedOption.selected=!0:this.showSuggestions||(selectedOption=document.createElement("option"),selectedOption.value=filterValue,selectedOption.innerHTML=filterValue,selectedOption.selected=!0,dataSource.append(selectedOption))})),_formAutocomplete.default.enhance(dataSource,"1"==dataSource.dataset.allowCustom,null,await this.placeholder,!1,this.showSuggestions,null,!dataSource.multiple,{items:"core/datafilter/autocomplete_selection_items",layout:"core/datafilter/autocomplete_layout",selection:"core/datafilter/autocomplete_selection"})}get filterRoot(){return this.rootNode.querySelector(_selectors.default.filter.byName(this.filterType))}getSourceDataForFilter(){return this.rootNode.querySelector(_selectors.default.filterset.regions.datasource).querySelector(_selectors.default.data.fields.byName(this.filterType))}getFilterValueNode(){return this.filterRoot.querySelector(_selectors.default.filter.regions.values)}get name(){return this.filterType}get jointype(){return parseInt(this.filterRoot.querySelector(_selectors.default.filter.fields.join).value,10)}get rawValues(){const filterValueSelect=this.getFilterValueNode().querySelector("select");return Object.values((select=filterValueSelect,select.querySelectorAll(":checked"))).map((option=>option.value));var select}get values(){return this.rawValues.map((option=>parseInt(option,10)))}get filterOptions(){return[]}get filterValue(){return{name:this.name,jointype:this.jointype,values:this.values,filteroptions:this.filterOptions}}},_exports.default}));
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_formAutocomplete=_interopRequireDefault(_formAutocomplete),_selectors=_interopRequireDefault(_selectors),_notification=_interopRequireDefault(_notification);return _exports.default=class{constructor(filterType,rootNode,initialValues){this.filterType=filterType,this.rootNode=rootNode,this.addValueSelector(initialValues).then((()=>{const filterRoot=this.filterRoot;return filterRoot&&filterRoot.querySelector(_selectors.default.data.required)&&filterRoot.querySelector(_selectors.default.filter.actions.remove).remove(),filterRoot})).catch(_notification.default.exception)}tearDown(){}get placeholder(){return(0,_str.getString)("placeholdertypeorselect","core")}get showSuggestions(){return!0}async addValueSelector(){let initialValues=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];const filterValueNode=this.getFilterValueNode(),sourceDataNode=this.getSourceDataForFilter();if(!sourceDataNode)throw new Error("No source data for filter.");filterValueNode.innerHTML=sourceDataNode.outerHTML;const dataSource=filterValueNode.querySelector("select");dataSource.id="filter-value-"+dataSource.getAttribute("data-field-name");const filterValueLabel=document.createElement("label");return filterValueLabel.setAttribute("for",dataSource.id),filterValueLabel.classList.add("visually-hidden"),filterValueLabel.innerText=dataSource.getAttribute("data-field-title"),filterValueNode.appendChild(filterValueLabel),initialValues.forEach((filterValue=>{let selectedOption=dataSource.querySelector('option[value="'.concat(filterValue,'"]'));selectedOption?selectedOption.selected=!0:this.showSuggestions||(selectedOption=document.createElement("option"),selectedOption.value=filterValue,selectedOption.innerHTML=filterValue,selectedOption.selected=!0,dataSource.append(selectedOption))})),_formAutocomplete.default.enhance(dataSource,"1"==dataSource.dataset.allowCustom,null,await this.placeholder,!1,this.showSuggestions,null,!dataSource.multiple,{items:"core/datafilter/autocomplete_selection_items",layout:"core/datafilter/autocomplete_layout",selection:"core/datafilter/autocomplete_selection"})}get filterRoot(){return this.rootNode.querySelector(_selectors.default.filter.byName(this.filterType))}getSourceDataForFilter(){return this.rootNode.querySelector(_selectors.default.filterset.regions.datasource).querySelector(_selectors.default.data.fields.byName(this.filterType))}getFilterValueNode(){return this.filterRoot.querySelector(_selectors.default.filter.regions.values)}get name(){return this.filterType}get jointype(){return parseInt(this.filterRoot.querySelector(_selectors.default.filter.fields.join).value,10)}get rawValues(){const filterValueSelect=this.getFilterValueNode().querySelector("select");return Object.values((select=filterValueSelect,select.querySelectorAll(":checked"))).map((option=>option.value));var select}get values(){return this.rawValues.map((option=>parseInt(option,10)))}get filterOptions(){return[]}get filterValue(){return{name:this.name,jointype:this.jointype,values:this.values,filteroptions:this.filterOptions}}},_exports.default}));
|
||||
|
||||
//# sourceMappingURL=filtertype.min.js.map
|
File diff suppressed because one or more lines are too long
2
lib/amd/build/dropzone.min.js
vendored
2
lib/amd/build/dropzone.min.js
vendored
|
@ -1,3 +1,3 @@
|
|||
define("core/dropzone",["exports","core/str","core/log","core/prefetch","core/templates"],(function(_exports,_str,_log,_prefetch,_templates){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_log=_interopRequireDefault(_log),_templates=_interopRequireDefault(_templates);var _default=class{constructor(dropZoneElement,fileTypes,callback){_defineProperty(this,"dropZoneElement",void 0),_defineProperty(this,"fileTypes",void 0),_defineProperty(this,"callback",void 0),_defineProperty(this,"dropZoneLabel",""),(0,_prefetch.prefetchString)("core","addfilesdrop"),this.dropZoneElement=dropZoneElement,this.fileTypes=fileTypes,this.callback=callback}init(){return this.dropZoneElement.addEventListener("dragover",(e=>{const dropZone=this.getDropZoneFromEvent(e);dropZone&&(e.preventDefault(),dropZone.classList.add("dragover"))})),this.dropZoneElement.addEventListener("dragleave",(e=>{const dropZone=this.getDropZoneFromEvent(e);dropZone&&(e.preventDefault(),dropZone.classList.remove("dragover"))})),this.dropZoneElement.addEventListener("drop",(e=>{const dropZone=this.getDropZoneFromEvent(e);dropZone&&(e.preventDefault(),dropZone.classList.remove("dragover"),this.callback(e.dataTransfer.files))})),this.dropZoneElement.addEventListener("click",(e=>{this.getDropZoneContainerFromEvent(e)&&this.getFileElementFromEvent(e).click()})),this.dropZoneElement.addEventListener("click",(e=>{e.target.closest(".dropzone-sr-only-focusable")&&this.getFileElementFromEvent(e).click()})),this.dropZoneElement.addEventListener("change",(e=>{const fileInput=this.getFileElementFromEvent(e);fileInput&&(e.preventDefault(),this.callback(fileInput.files))})),this.renderDropZone(this.dropZoneElement,this.fileTypes),_log.default.info("Dropzone has been initialized!"),this}getDropZoneFromEvent(e){return e.target.closest(".dropzone")}getDropZoneContainerFromEvent(e){return e.target.closest(".dropzone-container")}getFileElementFromEvent(e){return e.target.closest(".dropzone-container").querySelector(".drop-zone-fileinput")}setLabel(label){this.dropZoneLabel=label}getLabel(){return this.dropZoneLabel}async renderDropZone(dropZoneElement,fileTypes){this.getLabel()||this.setLabel(await(0,_str.getString)("addfilesdrop","core"));const dropZoneLabel=this.getLabel();dropZoneElement.innerHTML=await _templates.default.render("core/dropzone",{label:dropZoneLabel,filetypes:fileTypes})}};return _exports.default=_default,_exports.default}));
|
||||
define("core/dropzone",["exports","core/str","core/log","core/prefetch","core/templates"],(function(_exports,_str,_log,_prefetch,_templates){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_log=_interopRequireDefault(_log),_templates=_interopRequireDefault(_templates);var _default=class{constructor(dropZoneElement,fileTypes,callback){_defineProperty(this,"dropZoneElement",void 0),_defineProperty(this,"fileTypes",void 0),_defineProperty(this,"callback",void 0),_defineProperty(this,"dropZoneLabel",""),(0,_prefetch.prefetchString)("core","addfilesdrop"),this.dropZoneElement=dropZoneElement,this.fileTypes=fileTypes,this.callback=callback}init(){return this.dropZoneElement.addEventListener("dragover",(e=>{const dropZone=this.getDropZoneFromEvent(e);dropZone&&(e.preventDefault(),dropZone.classList.add("dragover"))})),this.dropZoneElement.addEventListener("dragleave",(e=>{const dropZone=this.getDropZoneFromEvent(e);dropZone&&(e.preventDefault(),dropZone.classList.remove("dragover"))})),this.dropZoneElement.addEventListener("drop",(e=>{const dropZone=this.getDropZoneFromEvent(e);dropZone&&(e.preventDefault(),dropZone.classList.remove("dragover"),this.callback(e.dataTransfer.files))})),this.dropZoneElement.addEventListener("click",(e=>{this.getDropZoneContainerFromEvent(e)&&this.getFileElementFromEvent(e).click()})),this.dropZoneElement.addEventListener("click",(e=>{e.target.closest(".dropzone-visually-hidden-focusable")&&this.getFileElementFromEvent(e).click()})),this.dropZoneElement.addEventListener("change",(e=>{const fileInput=this.getFileElementFromEvent(e);fileInput&&(e.preventDefault(),this.callback(fileInput.files))})),this.renderDropZone(this.dropZoneElement,this.fileTypes),_log.default.info("Dropzone has been initialized!"),this}getDropZoneFromEvent(e){return e.target.closest(".dropzone")}getDropZoneContainerFromEvent(e){return e.target.closest(".dropzone-container")}getFileElementFromEvent(e){return e.target.closest(".dropzone-container").querySelector(".drop-zone-fileinput")}setLabel(label){this.dropZoneLabel=label}getLabel(){return this.dropZoneLabel}async renderDropZone(dropZoneElement,fileTypes){this.getLabel()||this.setLabel(await(0,_str.getString)("addfilesdrop","core"));const dropZoneLabel=this.getLabel();dropZoneElement.innerHTML=await _templates.default.render("core/dropzone",{label:dropZoneLabel,filetypes:fileTypes})}};return _exports.default=_default,_exports.default}));
|
||||
|
||||
//# sourceMappingURL=dropzone.min.js.map
|
File diff suppressed because one or more lines are too long
2
lib/amd/build/local/reactive/srlogger.min.js
vendored
2
lib/amd/build/local/reactive/srlogger.min.js
vendored
|
@ -1,3 +1,3 @@
|
|||
define("core/local/reactive/srlogger",["exports","core/local/reactive/logger"],(function(_exports,_logger){var obj;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_logger=(obj=_logger)&&obj.__esModule?obj:{default:obj};class SRLogger extends _logger.default{add(entry){if(entry.feedbackMessage){let loggerFeedback=document.getElementById(SRLogger.liveRegionId);loggerFeedback||(loggerFeedback=document.createElement("div"),loggerFeedback.id=SRLogger.liveRegionId,loggerFeedback.classList.add("sr-only"),loggerFeedback.setAttribute("aria-live","polite"),document.body.append(loggerFeedback)),loggerFeedback.innerHTML=entry.feedbackMessage,setTimeout((()=>{loggerFeedback.innerHTML=""}),4e3)}}}return _exports.default=SRLogger,function(obj,key,value){key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value}(SRLogger,"liveRegionId","sr-logger-feedback-container"),_exports.default}));
|
||||
define("core/local/reactive/srlogger",["exports","core/local/reactive/logger"],(function(_exports,_logger){var obj;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_logger=(obj=_logger)&&obj.__esModule?obj:{default:obj};class SRLogger extends _logger.default{add(entry){if(entry.feedbackMessage){let loggerFeedback=document.getElementById(SRLogger.liveRegionId);loggerFeedback||(loggerFeedback=document.createElement("div"),loggerFeedback.id=SRLogger.liveRegionId,loggerFeedback.classList.add("visually-hidden"),loggerFeedback.setAttribute("aria-live","polite"),document.body.append(loggerFeedback)),loggerFeedback.innerHTML=entry.feedbackMessage,setTimeout((()=>{loggerFeedback.innerHTML=""}),4e3)}}}return _exports.default=SRLogger,function(obj,key,value){key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value}(SRLogger,"liveRegionId","sr-logger-feedback-container"),_exports.default}));
|
||||
|
||||
//# sourceMappingURL=srlogger.min.js.map
|
|
@ -1 +1 @@
|
|||
{"version":3,"file":"srlogger.min.js","sources":["../../../src/local/reactive/srlogger.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 * Screen reader-only (sr-only) reactive mutations logger class.\n *\n * This logger can be used by the StateManager to log mutation feedbacks and actions.\n * The feedback messages logged by this logger will be rendered in a sr-only, ARIA live region.\n *\n * @module core/local/reactive/srlogger\n * @class SRLogger\n * @copyright 2023 Jun Pataleta <jun@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Logger from 'core/local/reactive/logger';\n\n/**\n * Logger entry structure.\n *\n * @typedef {object} LoggerEntry\n * @property {string} feedbackMessage Feedback message.\n */\n\n/**\n * Screen reader-only (sr-only) reactive mutations logger class.\n *\n * @class SRLogger\n */\nexport default class SRLogger extends Logger {\n /**\n * The element ID of the ARIA live region where the logger feedback will be rendered.\n *\n * @type {string}\n */\n static liveRegionId = 'sr-logger-feedback-container';\n\n /**\n * Add a log entry.\n * @param {LoggerEntry} entry Log entry.\n */\n add(entry) {\n if (entry.feedbackMessage) {\n // Fetch or create an ARIA live region that will serve as the container for the logger feedback.\n let loggerFeedback = document.getElementById(SRLogger.liveRegionId);\n if (!loggerFeedback) {\n loggerFeedback = document.createElement('div');\n loggerFeedback.id = SRLogger.liveRegionId;\n loggerFeedback.classList.add('sr-only');\n loggerFeedback.setAttribute('aria-live', 'polite');\n document.body.append(loggerFeedback);\n }\n // Set the ARIA live region's contents with the feedback.\n loggerFeedback.innerHTML = entry.feedbackMessage;\n\n // Clear the feedback message after 4 seconds to avoid the contents from being read out in case the user navigates\n // to this region. This is similar to the default timeout of toast messages before disappearing from view.\n setTimeout(() => {\n loggerFeedback.innerHTML = '';\n }, 4000);\n }\n }\n}\n"],"names":["SRLogger","Logger","add","entry","feedbackMessage","loggerFeedback","document","getElementById","liveRegionId","createElement","id","classList","setAttribute","body","append","innerHTML","setTimeout"],"mappings":"iQAyCqBA,iBAAiBC,gBAYlCC,IAAIC,UACIA,MAAMC,gBAAiB,KAEnBC,eAAiBC,SAASC,eAAeP,SAASQ,cACjDH,iBACDA,eAAiBC,SAASG,cAAc,OACxCJ,eAAeK,GAAKV,SAASQ,aAC7BH,eAAeM,UAAUT,IAAI,WAC7BG,eAAeO,aAAa,YAAa,UACzCN,SAASO,KAAKC,OAAOT,iBAGzBA,eAAeU,UAAYZ,MAAMC,gBAIjCY,YAAW,KACPX,eAAeU,UAAY,KAC5B,kLA9BMf,wBAMK"}
|
||||
{"version":3,"file":"srlogger.min.js","sources":["../../../src/local/reactive/srlogger.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 * Screen reader-only (visually-hidden) reactive mutations logger class.\n *\n * This logger can be used by the StateManager to log mutation feedbacks and actions.\n * The feedback messages logged by this logger will be rendered in a visually-hidden, ARIA live region.\n *\n * @module core/local/reactive/srlogger\n * @class SRLogger\n * @copyright 2023 Jun Pataleta <jun@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Logger from 'core/local/reactive/logger';\n\n/**\n * Logger entry structure.\n *\n * @typedef {object} LoggerEntry\n * @property {string} feedbackMessage Feedback message.\n */\n\n/**\n * Screen reader-only (visually-hidden) reactive mutations logger class.\n *\n * @class SRLogger\n */\nexport default class SRLogger extends Logger {\n /**\n * The element ID of the ARIA live region where the logger feedback will be rendered.\n *\n * @type {string}\n */\n static liveRegionId = 'sr-logger-feedback-container';\n\n /**\n * Add a log entry.\n * @param {LoggerEntry} entry Log entry.\n */\n add(entry) {\n if (entry.feedbackMessage) {\n // Fetch or create an ARIA live region that will serve as the container for the logger feedback.\n let loggerFeedback = document.getElementById(SRLogger.liveRegionId);\n if (!loggerFeedback) {\n loggerFeedback = document.createElement('div');\n loggerFeedback.id = SRLogger.liveRegionId;\n loggerFeedback.classList.add('visually-hidden');\n loggerFeedback.setAttribute('aria-live', 'polite');\n document.body.append(loggerFeedback);\n }\n // Set the ARIA live region's contents with the feedback.\n loggerFeedback.innerHTML = entry.feedbackMessage;\n\n // Clear the feedback message after 4 seconds to avoid the contents from being read out in case the user navigates\n // to this region. This is similar to the default timeout of toast messages before disappearing from view.\n setTimeout(() => {\n loggerFeedback.innerHTML = '';\n }, 4000);\n }\n }\n}\n"],"names":["SRLogger","Logger","add","entry","feedbackMessage","loggerFeedback","document","getElementById","liveRegionId","createElement","id","classList","setAttribute","body","append","innerHTML","setTimeout"],"mappings":"iQAyCqBA,iBAAiBC,gBAYlCC,IAAIC,UACIA,MAAMC,gBAAiB,KAEnBC,eAAiBC,SAASC,eAAeP,SAASQ,cACjDH,iBACDA,eAAiBC,SAASG,cAAc,OACxCJ,eAAeK,GAAKV,SAASQ,aAC7BH,eAAeM,UAAUT,IAAI,mBAC7BG,eAAeO,aAAa,YAAa,UACzCN,SAASO,KAAKC,OAAOT,iBAGzBA,eAAeU,UAAYZ,MAAMC,gBAIjCY,YAAW,KACPX,eAAeU,UAAY,KAC5B,kLA9BMf,wBAMK"}
|
|
@ -101,11 +101,11 @@ const addEventListeners = () => {
|
|||
// This copyTarget is not an input, or text area so cannot be used with the execCommand('copy') command.
|
||||
// To work around this we create a new textarea and copy that.
|
||||
// This textarea must be part of the DOM and must be visible.
|
||||
// We (ab)use the sr-only tag to ensure that it is considered visible to the browser, whilst being
|
||||
// We (ab)use the visually-hidden tag to ensure that it is considered visible to the browser, whilst being
|
||||
// hidden from view by the user.
|
||||
const copyRegion = document.createElement('textarea');
|
||||
copyRegion.value = textToCopy;
|
||||
copyRegion.classList.add('sr-only');
|
||||
copyRegion.classList.add('visually-hidden');
|
||||
document.body.appendChild(copyRegion);
|
||||
|
||||
copyNodeContentToClipboard(copyButton, copyRegion);
|
||||
|
|
|
@ -109,7 +109,7 @@ export default class {
|
|||
// Create a hidden label for the filter value.
|
||||
const filterValueLabel = document.createElement('label');
|
||||
filterValueLabel.setAttribute('for', dataSource.id);
|
||||
filterValueLabel.classList.add('sr-only');
|
||||
filterValueLabel.classList.add('visually-hidden');
|
||||
filterValueLabel.innerText = dataSource.getAttribute('data-field-title');
|
||||
|
||||
// Append this label to the filter value container.
|
||||
|
|
|
@ -111,7 +111,7 @@ const DropZone = class {
|
|||
this.getFileElementFromEvent(e).click();
|
||||
});
|
||||
this.dropZoneElement.addEventListener('click', (e) => {
|
||||
const dropZoneLabel = e.target.closest('.dropzone-sr-only-focusable');
|
||||
const dropZoneLabel = e.target.closest('.dropzone-visually-hidden-focusable');
|
||||
if (!dropZoneLabel) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Screen reader-only (sr-only) reactive mutations logger class.
|
||||
* Screen reader-only (visually-hidden) reactive mutations logger class.
|
||||
*
|
||||
* This logger can be used by the StateManager to log mutation feedbacks and actions.
|
||||
* The feedback messages logged by this logger will be rendered in a sr-only, ARIA live region.
|
||||
* The feedback messages logged by this logger will be rendered in a visually-hidden, ARIA live region.
|
||||
*
|
||||
* @module core/local/reactive/srlogger
|
||||
* @class SRLogger
|
||||
|
@ -35,7 +35,7 @@ import Logger from 'core/local/reactive/logger';
|
|||
*/
|
||||
|
||||
/**
|
||||
* Screen reader-only (sr-only) reactive mutations logger class.
|
||||
* Screen reader-only (visually-hidden) reactive mutations logger class.
|
||||
*
|
||||
* @class SRLogger
|
||||
*/
|
||||
|
@ -58,7 +58,7 @@ export default class SRLogger extends Logger {
|
|||
if (!loggerFeedback) {
|
||||
loggerFeedback = document.createElement('div');
|
||||
loggerFeedback.id = SRLogger.liveRegionId;
|
||||
loggerFeedback.classList.add('sr-only');
|
||||
loggerFeedback.classList.add('visually-hidden');
|
||||
loggerFeedback.setAttribute('aria-live', 'polite');
|
||||
document.body.append(loggerFeedback);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue