diff --git a/lib/editor/tiny/amd/build/utils.min.js b/lib/editor/tiny/amd/build/utils.min.js
index 72b0759cdf581..ee38363d7635b 100644
--- a/lib/editor/tiny/amd/build/utils.min.js
+++ b/lib/editor/tiny/amd/build/utils.min.js
@@ -1,3 +1,3 @@
-define("editor_tiny/utils",["exports","core/templates","./options","core/str"],(function(_exports,_templates,_options,_str){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.updateEditorState=_exports.removeToolbarButtons=_exports.removeToolbarButton=_exports.removeSubmenuItem=_exports.removeMenubarItems=_exports.removeMenubarItem=_exports.getPluginMetadata=_exports.getImagePath=_exports.getDocumentationLink=_exports.getButtonImage=_exports.ensureEditorIsValid=_exports.displayFilepicker=_exports.addToolbarSection=_exports.addToolbarButtons=_exports.addToolbarButton=_exports.addQuickbarsToolbarItem=_exports.addMenubarItem=_exports.addContextmenuItem=void 0;const getImagePath=function(identifier){let component=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"editor_tiny";return Promise.resolve(M.util.image_url(identifier,component))};_exports.getImagePath=getImagePath;_exports.getButtonImage=async function(identifier){let component=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"editor_tiny";return(0,_templates.renderForPromise)("editor_tiny/toolbar_button",{image:await getImagePath(identifier,component)})};_exports.displayFilepicker=(editor,filetype)=>new Promise(((resolve,reject)=>{const configuration=(0,_options.getFilePicker)(editor,filetype);if(configuration){const options={...configuration,formcallback:resolve};M.core_filepicker.show(Y,options)}else reject("Unknown filetype ".concat(filetype))}));_exports.addToolbarButton=function(toolbar,section,button){let after=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;if(!toolbar)return[{name:section,items:[button]}];const mutatedToolbar=JSON.parse(JSON.stringify(toolbar));return mutatedToolbar.map((item=>{if(item.name===section)if(after){let index=item.items.findIndex((value=>value==after));-1!==index&&item.items.splice(index+1,0,button)}else item.items.push(button);return item}))};_exports.addToolbarButtons=(toolbar,section,buttons)=>{if(!toolbar)return[{name:section,items:buttons}];return JSON.parse(JSON.stringify(toolbar)).map((item=>(item.name===section&&buttons.forEach((button=>item.items.push(button))),item)))};_exports.addToolbarSection=function(toolbar,name,relativeTo){let append=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];const newSection={name:name,items:[]},sectionInserted=toolbar.some(((section,index)=>section.name===relativeTo&&(append?toolbar.splice(index+1,0,newSection):toolbar.splice(index,0,newSection),!0)));return sectionInserted||(append?toolbar.push(newSection):toolbar.unshift(newSection)),toolbar};_exports.addMenubarItem=function(menubar,section,menuitem){let after=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;if(!menubar){({})[section]={title:section,items:menuitem}}const mutatedMenubar=JSON.parse(JSON.stringify(menubar));return Array.from(Object.entries(mutatedMenubar)).forEach((_ref=>{let[name,menu]=_ref;if(name===section)if(after){let index=menu.items.indexOf(after);-1!==index&&(index+=after.length,menu.items=menu.items.slice(0,index)+" ".concat(menuitem)+menu.items.slice(index))}else menu.items="".concat(menu.items," ").concat(menuitem)})),mutatedMenubar};_exports.addContextmenuItem=function(contextmenu){const contextmenuItems=(null!=contextmenu?contextmenu:"").split(" ");for(var _len=arguments.length,menuitems=new Array(_len>1?_len-1:0),_key=1;_key<_len;_key++)menuitems[_key-1]=arguments[_key];return contextmenuItems.concat(menuitems).filter((item=>""!==item)).join(" ")};_exports.addQuickbarsToolbarItem=function(quicktoolbar){const quicktoolbarItems=(null!=quicktoolbar?quicktoolbar:"").split(" ");for(var _len2=arguments.length,toolbaritems=new Array(_len2>1?_len2-1:0),_key2=1;_key2<_len2;_key2++)toolbaritems[_key2-1]=arguments[_key2];return quicktoolbarItems.concat(toolbaritems).filter((item=>""!==item)).join(" ")};const getDocumentationLink=pluginName=>"https://docs.moodle.org/en/editor_tiny/".concat(pluginName);_exports.getDocumentationLink=getDocumentationLink;_exports.getPluginMetadata=async function(component,pluginName){let url=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;const name=await(0,_str.getString)("helplinktext",component);return{getMetadata:()=>({name:name,url:null!=url?url:getDocumentationLink(pluginName)})}};_exports.ensureEditorIsValid=editor=>editor.getElement().isConnected?editor:null;_exports.removeToolbarButton=(toolbar,section,button)=>{if(!toolbar)return[{name:section,items:[button]}];return JSON.parse(JSON.stringify(toolbar)).map((item=>(item.name===section&&item.items.splice(item.items.indexOf(button),1),item)))};_exports.removeToolbarButtons=(toolbar,section,buttons)=>{if(!toolbar)return[{name:section,items:buttons}];return JSON.parse(JSON.stringify(toolbar)).map((item=>(item.name===section&&buttons.forEach((button=>item.items.splice(item.items.indexOf(button),1))),item)))};_exports.removeSubmenuItem=async(editor,section,submenuitem)=>{const menuItems=editor.ui.registry.getAll().menuItems[section],submenuitemtitle=await(0,_str.getString)(submenuitem,"editor_tiny");menuItems&&editor.ui.registry.addNestedMenuItem(section,{text:menuItems.text,getSubmenuItems:()=>{let newSubmenu=[];return menuItems.getSubmenuItems().forEach((item=>{item.text.trim()!=submenuitemtitle&&newSubmenu.push(item)})),newSubmenu}})};_exports.removeMenubarItem=(menubar,section,menuitem)=>(menubar[section].items=menubar[section].items.replace(menuitem,""),menubar);_exports.removeMenubarItems=(menubar,section,menuitems)=>{const regexPattern=new RegExp(menuitems.join("|"),"ig");return menubar[section].items=menubar[section].items.replace(regexPattern,""),menubar};_exports.updateEditorState=(editor,target)=>{target.hasAttribute("readonly")?editor.mode.set("readonly"):editor.mode.set("design")}}));
+define("editor_tiny/utils",["exports","core/templates","./options","core/str"],(function(_exports,_templates,_options,_str){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.updateEditorState=_exports.removeToolbarButtons=_exports.removeToolbarButton=_exports.removeSubmenuItem=_exports.removeMenubarItems=_exports.removeMenubarItem=_exports.getPluginMetadata=_exports.getImagePath=_exports.getDocumentationLink=_exports.getButtonImage=_exports.ensureEditorIsValid=_exports.displayFilepicker=_exports.addToolbarSection=_exports.addToolbarButtons=_exports.addToolbarButton=_exports.addQuickbarsToolbarItem=_exports.addMenubarItem=_exports.addContextmenuItem=void 0;const getImagePath=function(identifier){let component=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"editor_tiny";return Promise.resolve(M.util.image_url(identifier,component))};_exports.getImagePath=getImagePath;_exports.getButtonImage=async function(identifier){let component=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"editor_tiny";return(0,_templates.renderForPromise)("editor_tiny/toolbar_button",{image:await getImagePath(identifier,component)})};_exports.displayFilepicker=(editor,filetype)=>new Promise(((resolve,reject)=>{const configuration=(0,_options.getFilePicker)(editor,filetype);if(configuration){const options={...configuration,formcallback:resolve};M.core_filepicker.show(Y,options)}else reject("Unknown filetype ".concat(filetype))}));_exports.addToolbarButton=function(toolbar,section,button){let after=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;if(!toolbar)return[{name:section,items:[button]}];const mutatedToolbar=JSON.parse(JSON.stringify(toolbar));return mutatedToolbar.map((item=>{if(item.name===section)if(after){let index=item.items.findIndex((value=>value==after));-1!==index&&item.items.splice(index+1,0,button)}else item.items.push(button);return item}))};_exports.addToolbarButtons=(toolbar,section,buttons)=>{if(!toolbar)return[{name:section,items:buttons}];return JSON.parse(JSON.stringify(toolbar)).map((item=>(item.name===section&&buttons.forEach((button=>item.items.push(button))),item)))};_exports.addToolbarSection=function(toolbar,name,relativeTo){let append=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];const newSection={name:name,items:[]},sectionInserted=toolbar.some(((section,index)=>section.name===relativeTo&&(append?toolbar.splice(index+1,0,newSection):toolbar.splice(index,0,newSection),!0)));return sectionInserted||(append?toolbar.push(newSection):toolbar.unshift(newSection)),toolbar};_exports.addMenubarItem=function(menubar,section,menuitem){let after=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;if(!menubar){({})[section]={title:section,items:menuitem}}const mutatedMenubar=JSON.parse(JSON.stringify(menubar));return Array.from(Object.entries(mutatedMenubar)).forEach((_ref=>{let[name,menu]=_ref;if(name===section)if(after){let index=menu.items.indexOf(after);-1!==index&&(index+=after.length,menu.items=menu.items.slice(0,index)+" ".concat(menuitem)+menu.items.slice(index))}else menu.items="".concat(menu.items," ").concat(menuitem)})),mutatedMenubar};_exports.addContextmenuItem=function(contextmenu){const contextmenuItems=(contextmenu||"").split(" ");for(var _len=arguments.length,menuitems=new Array(_len>1?_len-1:0),_key=1;_key<_len;_key++)menuitems[_key-1]=arguments[_key];return contextmenuItems.concat(menuitems).filter((item=>""!==item)).join(" ")};_exports.addQuickbarsToolbarItem=function(quicktoolbar){const quicktoolbarItems=(quicktoolbar||"").split(" ");for(var _len2=arguments.length,toolbaritems=new Array(_len2>1?_len2-1:0),_key2=1;_key2<_len2;_key2++)toolbaritems[_key2-1]=arguments[_key2];return quicktoolbarItems.concat(toolbaritems).filter((item=>""!==item)).join(" ")};const getDocumentationLink=pluginName=>"https://docs.moodle.org/en/editor_tiny/".concat(pluginName);_exports.getDocumentationLink=getDocumentationLink;_exports.getPluginMetadata=async function(component,pluginName){let url=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;const name=await(0,_str.getString)("helplinktext",component);return{getMetadata:()=>({name:name,url:null!=url?url:getDocumentationLink(pluginName)})}};_exports.ensureEditorIsValid=editor=>editor.getElement().isConnected?editor:null;_exports.removeToolbarButton=(toolbar,section,button)=>{if(!toolbar)return[{name:section,items:[button]}];return JSON.parse(JSON.stringify(toolbar)).map((item=>(item.name===section&&item.items.splice(item.items.indexOf(button),1),item)))};_exports.removeToolbarButtons=(toolbar,section,buttons)=>{if(!toolbar)return[{name:section,items:buttons}];return JSON.parse(JSON.stringify(toolbar)).map((item=>(item.name===section&&buttons.forEach((button=>item.items.splice(item.items.indexOf(button),1))),item)))};_exports.removeSubmenuItem=async(editor,section,submenuitem)=>{const menuItems=editor.ui.registry.getAll().menuItems[section],submenuitemtitle=await(0,_str.getString)(submenuitem,"editor_tiny");menuItems&&editor.ui.registry.addNestedMenuItem(section,{text:menuItems.text,getSubmenuItems:()=>{let newSubmenu=[];return menuItems.getSubmenuItems().forEach((item=>{item.text.trim()!=submenuitemtitle&&newSubmenu.push(item)})),newSubmenu}})};_exports.removeMenubarItem=(menubar,section,menuitem)=>(menubar[section].items=menubar[section].items.replace(menuitem,""),menubar);_exports.removeMenubarItems=(menubar,section,menuitems)=>{const regexPattern=new RegExp(menuitems.join("|"),"ig");return menubar[section].items=menubar[section].items.replace(regexPattern,""),menubar};_exports.updateEditorState=(editor,target)=>{target.hasAttribute("readonly")?editor.mode.set("readonly"):editor.mode.set("design")}}));
//# sourceMappingURL=utils.min.js.map
\ No newline at end of file
diff --git a/lib/editor/tiny/amd/build/utils.min.js.map b/lib/editor/tiny/amd/build/utils.min.js.map
index 8a3bf96a9658e..38fe4a48825dc 100644
--- a/lib/editor/tiny/amd/build/utils.min.js.map
+++ b/lib/editor/tiny/amd/build/utils.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"utils.min.js","sources":["../src/utils.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 .\n\nimport {renderForPromise} from 'core/templates';\nimport {getFilePicker} from './options';\nimport {getString} from 'core/str';\n\n/**\n * Get the image path for the specified image.\n *\n * @param {string} identifier The name of the image\n * @param {string} component The component name\n * @return {string} The image URL path\n */\nexport const getImagePath = (identifier, component = 'editor_tiny') => Promise.resolve(M.util.image_url(identifier, component));\n\nexport const getButtonImage = async(identifier, component = 'editor_tiny') => renderForPromise('editor_tiny/toolbar_button', {\n image: await getImagePath(identifier, component),\n});\n\n/**\n * Helper to display a filepicker and return a Promise.\n *\n * The Promise will resolve when a file is selected, or reject if the file type is not found.\n *\n * @param {TinyMCE} editor\n * @param {string} filetype\n * @returns {Promise