diff --git a/lib/editor/tiny/plugins/h5p/amd/build/ui.min.js b/lib/editor/tiny/plugins/h5p/amd/build/ui.min.js index 288d7c71919..9c5fc8242bd 100644 --- a/lib/editor/tiny/plugins/h5p/amd/build/ui.min.js +++ b/lib/editor/tiny/plugins/h5p/amd/build/ui.min.js @@ -1,10 +1,10 @@ -define("tiny_h5p/ui",["exports","editor_tiny/utils","./common","./options","core/config","core/normalise","core/templates","tiny_h5p/modal","core/modal_events","core/modal_factory"],(function(_exports,_utils,_common,_options,_config,_normalise,_templates,_modal,_modal_events,_modal_factory){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +define("tiny_h5p/ui",["exports","editor_tiny/utils","./common","./options","core/config","core/normalise","core/templates","tiny_h5p/modal","core/modal_events","core/modal_factory","core/pending"],(function(_exports,_utils,_common,_options,_config,_normalise,_templates,_modal,_modal_events,_modal_factory,_pending){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} /** * Tiny H5P Content configuration. * * @module tiny_h5p/commands * @copyright 2022 Andrew Lyons * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.handleAction=void 0,_config=_interopRequireDefault(_config),_modal=_interopRequireDefault(_modal),_modal_events=_interopRequireDefault(_modal_events),_modal_factory=_interopRequireDefault(_modal_factory);let openingSelection=null;_exports.handleAction=editor=>{openingSelection=editor.selection.getBookmark(),displayDialogue(editor)};const getTemplateContext=(editor,data)=>{var _permissions$upload,_permissions$embed,_data$url;const permissions=(0,_options.getPermissions)(editor),canUpload=null!==(_permissions$upload=permissions.upload)&&void 0!==_permissions$upload&&_permissions$upload,canEmbed=null!==(_permissions$embed=permissions.embed)&&void 0!==_permissions$embed&&_permissions$embed,canUploadAndEmbed=canUpload&&canEmbed;return Object.assign({},{elementid:editor.id,canUpload:canUpload,canEmbed:canEmbed,canUploadAndEmbed:canUploadAndEmbed,showOptions:!1,fileURL:null!==(_data$url=null==data?void 0:data.url)&&void 0!==_data$url?_data$url:""},data)},isValidUrl=url=>!!new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*").test(url),handleDialogueSubmission=async(editor,modal,data)=>{const form=(0,_normalise.getList)(modal.getRoot())[0].querySelector("form");if(!form)return modal.destroy(),void displayDialogue(editor,Object.assign({},data));const submittedUrl=form.querySelector('input[name="url"]').value,url=((form,submittedUrl,permissions)=>{if(!submittedUrl||!submittedUrl.startsWith(_config.default.wwwroot)&&!isValidUrl(submittedUrl))return null;const url=new URL(submittedUrl);return null!=permissions&&permissions.upload&&form.querySelector('[name="download"]').checked&&url.searchParams.append("export",1),null!=permissions&&permissions.embed&&form.querySelector('[name="embed"]').checked&&url.searchParams.append("embed",1),form.querySelector('[name="copyright"]').checked&&url.searchParams.append("copyright",1),url})(form,submittedUrl,(0,_options.getPermissions)(editor));if(!url)return modal.destroy(),void displayDialogue(editor,Object.assign({},data,{url:submittedUrl,invalidUrl:!0}));const content=await(0,_templates.renderForPromise)("".concat(_common.component,"/content"),{url:url.toString()});editor.selection.moveToBookmark(openingSelection),editor.execCommand("mceInsertContent",!1,content.html),editor.selection.moveToBookmark(openingSelection)},getCurrentH5PData=currentH5P=>{const data={};let url;try{url=new URL(currentH5P.textContent)}catch(error){return data}return url.searchParams.has("export")&&(data.download=!0,data.showOptions=!0,url.searchParams.delete("export")),url.searchParams.has("embed")&&(data.embed=!0,data.showOptions=!0,url.searchParams.delete("embed")),url.searchParams.has("copyright")&&(data.copyright=!0,data.showOptions=!0,url.searchParams.delete("copyright")),data.url=url.toString(),data},displayDialogue=async function(editor){let data=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const selection=editor.selection.getNode(),currentH5P=selection.closest(".h5p-placeholder");currentH5P&&Object.assign(data,getCurrentH5PData(currentH5P));const modal=await _modal_factory.default.create({type:_modal.default.TYPE,templateContext:getTemplateContext(editor,data),large:!0});modal.show();const $root=modal.getRoot(),root=$root[0];$root.on(_modal_events.default.save,((event,modal)=>{handleDialogueSubmission(editor,modal,data)})),root.addEventListener("click",(e=>{e.target.closest('[data-target="filepicker"]')&&(0,_utils.displayFilepicker)(editor,"h5p").then((params=>{if(""!==params.url){root.querySelector('form input[name="url"]').value=params.url}return params})).catch()}))}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.handleAction=void 0,_config=_interopRequireDefault(_config),_modal=_interopRequireDefault(_modal),_modal_events=_interopRequireDefault(_modal_events),_modal_factory=_interopRequireDefault(_modal_factory),_pending=_interopRequireDefault(_pending);let openingSelection=null;_exports.handleAction=editor=>{openingSelection=editor.selection.getBookmark(),displayDialogue(editor)};const getTemplateContext=(editor,data)=>{var _permissions$upload,_permissions$embed,_data$url;const permissions=(0,_options.getPermissions)(editor),canUpload=null!==(_permissions$upload=permissions.upload)&&void 0!==_permissions$upload&&_permissions$upload,canEmbed=null!==(_permissions$embed=permissions.embed)&&void 0!==_permissions$embed&&_permissions$embed,canUploadAndEmbed=canUpload&&canEmbed;return Object.assign({},{elementid:editor.id,canUpload:canUpload,canEmbed:canEmbed,canUploadAndEmbed:canUploadAndEmbed,showOptions:!1,fileURL:null!==(_data$url=null==data?void 0:data.url)&&void 0!==_data$url?_data$url:""},data)},isValidUrl=url=>!!new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*").test(url),handleDialogueSubmission=async(editor,modal,data)=>{const pendingPromise=new _pending.default("tiny_h5p:handleDialogueSubmission"),form=(0,_normalise.getList)(modal.getRoot())[0].querySelector("form");if(!form)return modal.destroy(),displayDialogue(editor,Object.assign({},data)),void pendingPromise.resolve();const submittedUrl=form.querySelector('input[name="url"]').value,url=((form,submittedUrl,permissions)=>{if(!submittedUrl||!submittedUrl.startsWith(_config.default.wwwroot)&&!isValidUrl(submittedUrl))return null;const url=new URL(submittedUrl);return null!=permissions&&permissions.upload&&form.querySelector('[name="download"]').checked&&url.searchParams.append("export",1),null!=permissions&&permissions.embed&&form.querySelector('[name="embed"]').checked&&url.searchParams.append("embed",1),form.querySelector('[name="copyright"]').checked&&url.searchParams.append("copyright",1),url})(form,submittedUrl,(0,_options.getPermissions)(editor));if(!url)return modal.destroy(),displayDialogue(editor,Object.assign({},data,{url:submittedUrl,invalidUrl:!0})),void pendingPromise.resolve();const content=await(0,_templates.renderForPromise)("".concat(_common.component,"/content"),{url:url.toString()});editor.selection.moveToBookmark(openingSelection),editor.execCommand("mceInsertContent",!1,content.html),editor.selection.moveToBookmark(openingSelection),pendingPromise.resolve()},getCurrentH5PData=currentH5P=>{const data={};let url;try{url=new URL(currentH5P.textContent)}catch(error){return data}return url.searchParams.has("export")&&(data.download=!0,data.showOptions=!0,url.searchParams.delete("export")),url.searchParams.has("embed")&&(data.embed=!0,data.showOptions=!0,url.searchParams.delete("embed")),url.searchParams.has("copyright")&&(data.copyright=!0,data.showOptions=!0,url.searchParams.delete("copyright")),data.url=url.toString(),data},displayDialogue=async function(editor){let data=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const selection=editor.selection.getNode(),currentH5P=selection.closest(".h5p-placeholder");currentH5P&&Object.assign(data,getCurrentH5PData(currentH5P));const modal=await _modal_factory.default.create({type:_modal.default.TYPE,templateContext:getTemplateContext(editor,data),large:!0});modal.show();const $root=modal.getRoot(),root=$root[0];$root.on(_modal_events.default.save,((event,modal)=>{handleDialogueSubmission(editor,modal,data)})),root.addEventListener("click",(e=>{e.target.closest('[data-target="filepicker"]')&&(0,_utils.displayFilepicker)(editor,"h5p").then((params=>{if(""!==params.url){root.querySelector('form input[name="url"]').value=params.url}return params})).catch()}))}})); //# sourceMappingURL=ui.min.js.map \ No newline at end of file diff --git a/lib/editor/tiny/plugins/h5p/amd/build/ui.min.js.map b/lib/editor/tiny/plugins/h5p/amd/build/ui.min.js.map index da85c184c7d..d38d37740fc 100644 --- a/lib/editor/tiny/plugins/h5p/amd/build/ui.min.js.map +++ b/lib/editor/tiny/plugins/h5p/amd/build/ui.min.js.map @@ -1 +1 @@ -{"version":3,"file":"ui.min.js","sources":["../src/ui.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\n/**\n * Tiny H5P Content configuration.\n *\n * @module tiny_h5p/commands\n * @copyright 2022 Andrew Lyons \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {displayFilepicker} from 'editor_tiny/utils';\nimport {component} from './common';\nimport {getPermissions} from './options';\n\nimport Config from 'core/config';\nimport {getList} from 'core/normalise';\nimport {renderForPromise} from 'core/templates';\nimport Modal from 'tiny_h5p/modal';\nimport ModalEvents from 'core/modal_events';\nimport ModalFactory from 'core/modal_factory';\n\nlet openingSelection = null;\n\nexport const handleAction = (editor) => {\n openingSelection = editor.selection.getBookmark();\n displayDialogue(editor);\n};\n\n/**\n * Get the template context for the dialogue.\n *\n * @param {Editor} editor\n * @param {object} data\n * @returns {object} data\n */\nconst getTemplateContext = (editor, data) => {\n const permissions = getPermissions(editor);\n\n const canUpload = permissions.upload ?? false;\n const canEmbed = permissions.embed ?? false;\n const canUploadAndEmbed = canUpload && canEmbed;\n\n return Object.assign({}, {\n elementid: editor.id,\n canUpload,\n canEmbed,\n canUploadAndEmbed,\n showOptions: false,\n fileURL: data?.url ?? '',\n }, data);\n};\n\n/**\n * Get the URL from the submitted form.\n *\n * @param {FormNode} form\n * @param {string} submittedUrl\n * @param {object} permissions\n * @returns {URL|null}\n */\nconst getUrlFromSubmission = (form, submittedUrl, permissions) => {\n if (!submittedUrl || (!submittedUrl.startsWith(Config.wwwroot) && !isValidUrl(submittedUrl))) {\n return null;\n }\n\n // Generate a URL Object for the submitted URL.\n const url = new URL(submittedUrl);\n\n if (permissions?.upload) {\n if (form.querySelector('[name=\"download\"]').checked) {\n url.searchParams.append('export', 1);\n }\n }\n\n if (permissions?.embed) {\n if (form.querySelector('[name=\"embed\"]').checked) {\n url.searchParams.append('embed', 1);\n }\n }\n if (form.querySelector('[name=\"copyright\"]').checked) {\n url.searchParams.append('copyright', 1);\n }\n\n return url;\n};\n\n/**\n * Verify if this could be a h5p URL.\n *\n * @param {string} url Url to verify\n * @return {boolean} whether this is a valid URL.\n */\nconst isValidUrl = (url) => {\n const pattern = new RegExp('^(https?:\\\\/\\\\/)?' + // Protocol.\n '((([a-z\\\\d]([a-z\\\\d-]*[a-z\\\\d])*)\\\\.)+[a-z]{2,}|' + // Domain name.\n '((\\\\d{1,3}\\\\.){3}\\\\d{1,3}))' + // OR ip (v4) address.\n '(\\\\:\\\\d+)?(\\\\/[-a-z\\\\d%_.~+]*)*'); // Port and path.\n return !!pattern.test(url);\n};\n\nconst handleDialogueSubmission = async(editor, modal, data) => {\n const form = getList(modal.getRoot())[0].querySelector('form');\n if (!form) {\n // The form couldn't be found, which is weird.\n // This should not happen.\n // Display the dialogue again.\n modal.destroy();\n displayDialogue(editor, Object.assign({}, data));\n return;\n }\n\n // Get the URL from the submitted form.\n const submittedUrl = form.querySelector('input[name=\"url\"]').value;\n const url = getUrlFromSubmission(form, submittedUrl, getPermissions(editor));\n\n if (!url) {\n // The URL is invalid.\n // Fill it in and represent the dialogue with an error.\n modal.destroy();\n displayDialogue(editor, Object.assign({}, data, {\n url: submittedUrl,\n invalidUrl: true,\n }));\n return;\n }\n\n\n const content = await renderForPromise(`${component}/content`, {\n url: url.toString(),\n });\n\n editor.selection.moveToBookmark(openingSelection);\n editor.execCommand('mceInsertContent', false, content.html);\n editor.selection.moveToBookmark(openingSelection);\n};\n\nconst getCurrentH5PData = (currentH5P) => {\n const data = {};\n let url;\n try {\n url = new URL(currentH5P.textContent);\n } catch (error) {\n return data;\n }\n\n if (url.searchParams.has('export')) {\n data.download = true;\n data.showOptions = true;\n url.searchParams.delete('export');\n }\n\n if (url.searchParams.has('embed')) {\n data.embed = true;\n data.showOptions = true;\n url.searchParams.delete('embed');\n }\n\n if (url.searchParams.has('copyright')) {\n data.copyright = true;\n data.showOptions = true;\n url.searchParams.delete('copyright');\n }\n\n data.url = url.toString();\n\n return data;\n};\n\nconst displayDialogue = async(editor, data = {}) => {\n const selection = editor.selection.getNode();\n const currentH5P = selection.closest('.h5p-placeholder');\n if (currentH5P) {\n Object.assign(data, getCurrentH5PData(currentH5P));\n }\n\n const modal = await ModalFactory.create({\n type: Modal.TYPE,\n templateContext: getTemplateContext(editor, data),\n large: true,\n });\n modal.show();\n\n const $root = modal.getRoot();\n const root = $root[0];\n $root.on(ModalEvents.save, (event, modal) => {\n handleDialogueSubmission(editor, modal, data);\n });\n\n root.addEventListener('click', (e) => {\n const filepickerButton = e.target.closest('[data-target=\"filepicker\"]');\n if (filepickerButton) {\n displayFilepicker(editor, 'h5p').then((params) => {\n if (params.url !== '') {\n const input = root.querySelector('form input[name=\"url\"]');\n input.value = params.url;\n }\n return params;\n })\n .catch();\n }\n });\n};\n"],"names":["openingSelection","editor","selection","getBookmark","displayDialogue","getTemplateContext","data","permissions","canUpload","upload","canEmbed","embed","canUploadAndEmbed","Object","assign","elementid","id","showOptions","fileURL","url","isValidUrl","RegExp","test","handleDialogueSubmission","async","modal","form","getRoot","querySelector","destroy","submittedUrl","value","startsWith","Config","wwwroot","URL","checked","searchParams","append","getUrlFromSubmission","invalidUrl","content","component","toString","moveToBookmark","execCommand","html","getCurrentH5PData","currentH5P","textContent","error","has","download","delete","copyright","getNode","closest","ModalFactory","create","type","Modal","TYPE","templateContext","large","show","$root","root","on","ModalEvents","save","event","addEventListener","e","target","then","params","catch"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"ui.min.js","sources":["../src/ui.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\n/**\n * Tiny H5P Content configuration.\n *\n * @module tiny_h5p/commands\n * @copyright 2022 Andrew Lyons \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {displayFilepicker} from 'editor_tiny/utils';\nimport {component} from './common';\nimport {getPermissions} from './options';\n\nimport Config from 'core/config';\nimport {getList} from 'core/normalise';\nimport {renderForPromise} from 'core/templates';\nimport Modal from 'tiny_h5p/modal';\nimport ModalEvents from 'core/modal_events';\nimport ModalFactory from 'core/modal_factory';\nimport Pending from 'core/pending';\n\nlet openingSelection = null;\n\nexport const handleAction = (editor) => {\n openingSelection = editor.selection.getBookmark();\n displayDialogue(editor);\n};\n\n/**\n * Get the template context for the dialogue.\n *\n * @param {Editor} editor\n * @param {object} data\n * @returns {object} data\n */\nconst getTemplateContext = (editor, data) => {\n const permissions = getPermissions(editor);\n\n const canUpload = permissions.upload ?? false;\n const canEmbed = permissions.embed ?? false;\n const canUploadAndEmbed = canUpload && canEmbed;\n\n return Object.assign({}, {\n elementid: editor.id,\n canUpload,\n canEmbed,\n canUploadAndEmbed,\n showOptions: false,\n fileURL: data?.url ?? '',\n }, data);\n};\n\n/**\n * Get the URL from the submitted form.\n *\n * @param {FormNode} form\n * @param {string} submittedUrl\n * @param {object} permissions\n * @returns {URL|null}\n */\nconst getUrlFromSubmission = (form, submittedUrl, permissions) => {\n if (!submittedUrl || (!submittedUrl.startsWith(Config.wwwroot) && !isValidUrl(submittedUrl))) {\n return null;\n }\n\n // Generate a URL Object for the submitted URL.\n const url = new URL(submittedUrl);\n\n if (permissions?.upload) {\n if (form.querySelector('[name=\"download\"]').checked) {\n url.searchParams.append('export', 1);\n }\n }\n\n if (permissions?.embed) {\n if (form.querySelector('[name=\"embed\"]').checked) {\n url.searchParams.append('embed', 1);\n }\n }\n if (form.querySelector('[name=\"copyright\"]').checked) {\n url.searchParams.append('copyright', 1);\n }\n\n return url;\n};\n\n/**\n * Verify if this could be a h5p URL.\n *\n * @param {string} url Url to verify\n * @return {boolean} whether this is a valid URL.\n */\nconst isValidUrl = (url) => {\n const pattern = new RegExp('^(https?:\\\\/\\\\/)?' + // Protocol.\n '((([a-z\\\\d]([a-z\\\\d-]*[a-z\\\\d])*)\\\\.)+[a-z]{2,}|' + // Domain name.\n '((\\\\d{1,3}\\\\.){3}\\\\d{1,3}))' + // OR ip (v4) address.\n '(\\\\:\\\\d+)?(\\\\/[-a-z\\\\d%_.~+]*)*'); // Port and path.\n return !!pattern.test(url);\n};\n\nconst handleDialogueSubmission = async(editor, modal, data) => {\n const pendingPromise = new Pending('tiny_h5p:handleDialogueSubmission');\n\n const form = getList(modal.getRoot())[0].querySelector('form');\n if (!form) {\n // The form couldn't be found, which is weird.\n // This should not happen.\n // Display the dialogue again.\n modal.destroy();\n displayDialogue(editor, Object.assign({}, data));\n pendingPromise.resolve();\n return;\n }\n\n // Get the URL from the submitted form.\n const submittedUrl = form.querySelector('input[name=\"url\"]').value;\n const url = getUrlFromSubmission(form, submittedUrl, getPermissions(editor));\n\n if (!url) {\n // The URL is invalid.\n // Fill it in and represent the dialogue with an error.\n modal.destroy();\n displayDialogue(editor, Object.assign({}, data, {\n url: submittedUrl,\n invalidUrl: true,\n }));\n pendingPromise.resolve();\n return;\n }\n\n const content = await renderForPromise(`${component}/content`, {\n url: url.toString(),\n });\n\n editor.selection.moveToBookmark(openingSelection);\n editor.execCommand('mceInsertContent', false, content.html);\n editor.selection.moveToBookmark(openingSelection);\n pendingPromise.resolve();\n};\n\nconst getCurrentH5PData = (currentH5P) => {\n const data = {};\n let url;\n try {\n url = new URL(currentH5P.textContent);\n } catch (error) {\n return data;\n }\n\n if (url.searchParams.has('export')) {\n data.download = true;\n data.showOptions = true;\n url.searchParams.delete('export');\n }\n\n if (url.searchParams.has('embed')) {\n data.embed = true;\n data.showOptions = true;\n url.searchParams.delete('embed');\n }\n\n if (url.searchParams.has('copyright')) {\n data.copyright = true;\n data.showOptions = true;\n url.searchParams.delete('copyright');\n }\n\n data.url = url.toString();\n\n return data;\n};\n\nconst displayDialogue = async(editor, data = {}) => {\n const selection = editor.selection.getNode();\n const currentH5P = selection.closest('.h5p-placeholder');\n if (currentH5P) {\n Object.assign(data, getCurrentH5PData(currentH5P));\n }\n\n const modal = await ModalFactory.create({\n type: Modal.TYPE,\n templateContext: getTemplateContext(editor, data),\n large: true,\n });\n modal.show();\n\n const $root = modal.getRoot();\n const root = $root[0];\n $root.on(ModalEvents.save, (event, modal) => {\n handleDialogueSubmission(editor, modal, data);\n });\n\n root.addEventListener('click', (e) => {\n const filepickerButton = e.target.closest('[data-target=\"filepicker\"]');\n if (filepickerButton) {\n displayFilepicker(editor, 'h5p').then((params) => {\n if (params.url !== '') {\n const input = root.querySelector('form input[name=\"url\"]');\n input.value = params.url;\n }\n return params;\n })\n .catch();\n }\n });\n};\n"],"names":["openingSelection","editor","selection","getBookmark","displayDialogue","getTemplateContext","data","permissions","canUpload","upload","canEmbed","embed","canUploadAndEmbed","Object","assign","elementid","id","showOptions","fileURL","url","isValidUrl","RegExp","test","handleDialogueSubmission","async","modal","pendingPromise","Pending","form","getRoot","querySelector","destroy","resolve","submittedUrl","value","startsWith","Config","wwwroot","URL","checked","searchParams","append","getUrlFromSubmission","invalidUrl","content","component","toString","moveToBookmark","execCommand","html","getCurrentH5PData","currentH5P","textContent","error","has","download","delete","copyright","getNode","closest","ModalFactory","create","type","Modal","TYPE","templateContext","large","show","$root","root","on","ModalEvents","save","event","addEventListener","e","target","then","params","catch"],"mappings":";;;;;;;gUAmCIA,iBAAmB,2BAEMC,SACzBD,iBAAmBC,OAAOC,UAAUC,cACpCC,gBAAgBH,eAUdI,mBAAqB,CAACJ,OAAQK,mEAC1BC,aAAc,2BAAeN,QAE7BO,sCAAYD,YAAYE,2DACxBC,oCAAWH,YAAYI,wDACvBC,kBAAoBJ,WAAaE,gBAEhCG,OAAOC,OAAO,GAAI,CACrBC,UAAWd,OAAOe,GAClBR,UAAAA,UACAE,SAAAA,SACAE,kBAAAA,kBACAK,aAAa,EACbC,0BAASZ,MAAAA,YAAAA,KAAMa,mCAAO,IACvBb,OA2CDc,WAAcD,OACA,IAAIE,OAAO,+HAIVC,KAAKH,KAGpBI,yBAA2BC,MAAMvB,OAAQwB,MAAOnB,cAC5CoB,eAAiB,IAAIC,iBAAQ,qCAE7BC,MAAO,sBAAQH,MAAMI,WAAW,GAAGC,cAAc,YAClDF,YAIDH,MAAMM,UACN3B,gBAAgBH,OAAQY,OAAOC,OAAO,GAAIR,YAC1CoB,eAAeM,gBAKbC,aAAeL,KAAKE,cAAc,qBAAqBI,MACvDf,IAxDmB,EAACS,KAAMK,aAAc1B,mBACzC0B,eAAkBA,aAAaE,WAAWC,gBAAOC,WAAajB,WAAWa,qBACnE,WAILd,IAAM,IAAImB,IAAIL,qBAEhB1B,MAAAA,aAAAA,YAAaE,QACTmB,KAAKE,cAAc,qBAAqBS,SACxCpB,IAAIqB,aAAaC,OAAO,SAAU,GAItClC,MAAAA,aAAAA,YAAaI,OACTiB,KAAKE,cAAc,kBAAkBS,SACrCpB,IAAIqB,aAAaC,OAAO,QAAS,GAGrCb,KAAKE,cAAc,sBAAsBS,SACzCpB,IAAIqB,aAAaC,OAAO,YAAa,GAGlCtB,KAiCKuB,CAAqBd,KAAMK,cAAc,2BAAehC,aAE/DkB,WAGDM,MAAMM,UACN3B,gBAAgBH,OAAQY,OAAOC,OAAO,GAAIR,KAAM,CAC5Ca,IAAKc,aACLU,YAAY,UAEhBjB,eAAeM,gBAIbY,cAAgB,yCAAoBC,8BAAqB,CAC3D1B,IAAKA,IAAI2B,aAGb7C,OAAOC,UAAU6C,eAAe/C,kBAChCC,OAAO+C,YAAY,oBAAoB,EAAOJ,QAAQK,MACtDhD,OAAOC,UAAU6C,eAAe/C,kBAChC0B,eAAeM,WAGbkB,kBAAqBC,mBACjB7C,KAAO,OACTa,QAEAA,IAAM,IAAImB,IAAIa,WAAWC,aAC3B,MAAOC,cACE/C,YAGPa,IAAIqB,aAAac,IAAI,YACrBhD,KAAKiD,UAAW,EAChBjD,KAAKW,aAAc,EACnBE,IAAIqB,aAAagB,OAAO,WAGxBrC,IAAIqB,aAAac,IAAI,WACrBhD,KAAKK,OAAQ,EACbL,KAAKW,aAAc,EACnBE,IAAIqB,aAAagB,OAAO,UAGxBrC,IAAIqB,aAAac,IAAI,eACrBhD,KAAKmD,WAAY,EACjBnD,KAAKW,aAAc,EACnBE,IAAIqB,aAAagB,OAAO,cAG5BlD,KAAKa,IAAMA,IAAI2B,WAERxC,MAGLF,gBAAkBoB,eAAMvB,YAAQK,4DAAO,SACnCJ,UAAYD,OAAOC,UAAUwD,UAC7BP,WAAajD,UAAUyD,QAAQ,oBACjCR,YACAtC,OAAOC,OAAOR,KAAM4C,kBAAkBC,mBAGpC1B,YAAcmC,uBAAaC,OAAO,CACpCC,KAAMC,eAAMC,KACZC,gBAAiB5D,mBAAmBJ,OAAQK,MAC5C4D,OAAO,IAEXzC,MAAM0C,aAEAC,MAAQ3C,MAAMI,UACdwC,KAAOD,MAAM,GACnBA,MAAME,GAAGC,sBAAYC,MAAM,CAACC,MAAOhD,SAC/BF,yBAAyBtB,OAAQwB,MAAOnB,SAG5C+D,KAAKK,iBAAiB,SAAUC,IACHA,EAAEC,OAAOjB,QAAQ,4DAEpB1D,OAAQ,OAAO4E,MAAMC,YAChB,KAAfA,OAAO3D,IAAY,CACLkD,KAAKvC,cAAc,0BAC3BI,MAAQ4C,OAAO3D,WAElB2D,UAENC"} \ No newline at end of file diff --git a/lib/editor/tiny/plugins/h5p/amd/src/ui.js b/lib/editor/tiny/plugins/h5p/amd/src/ui.js index badb7d42b03..c34e7751167 100644 --- a/lib/editor/tiny/plugins/h5p/amd/src/ui.js +++ b/lib/editor/tiny/plugins/h5p/amd/src/ui.js @@ -31,6 +31,7 @@ import {renderForPromise} from 'core/templates'; import Modal from 'tiny_h5p/modal'; import ModalEvents from 'core/modal_events'; import ModalFactory from 'core/modal_factory'; +import Pending from 'core/pending'; let openingSelection = null; @@ -112,6 +113,8 @@ const isValidUrl = (url) => { }; const handleDialogueSubmission = async(editor, modal, data) => { + const pendingPromise = new Pending('tiny_h5p:handleDialogueSubmission'); + const form = getList(modal.getRoot())[0].querySelector('form'); if (!form) { // The form couldn't be found, which is weird. @@ -119,6 +122,7 @@ const handleDialogueSubmission = async(editor, modal, data) => { // Display the dialogue again. modal.destroy(); displayDialogue(editor, Object.assign({}, data)); + pendingPromise.resolve(); return; } @@ -134,10 +138,10 @@ const handleDialogueSubmission = async(editor, modal, data) => { url: submittedUrl, invalidUrl: true, })); + pendingPromise.resolve(); return; } - const content = await renderForPromise(`${component}/content`, { url: url.toString(), }); @@ -145,6 +149,7 @@ const handleDialogueSubmission = async(editor, modal, data) => { editor.selection.moveToBookmark(openingSelection); editor.execCommand('mceInsertContent', false, content.html); editor.selection.moveToBookmark(openingSelection); + pendingPromise.resolve(); }; const getCurrentH5PData = (currentH5P) => {