diff --git a/lib/editor/tiny/amd/build/uploader.min.js b/lib/editor/tiny/amd/build/uploader.min.js index a219e8a6a08..0c6115c4468 100644 --- a/lib/editor/tiny/amd/build/uploader.min.js +++ b/lib/editor/tiny/amd/build/uploader.min.js @@ -1,3 +1,3 @@ -define("editor_tiny/uploader",["exports","core_form/events","editor_tiny/options"],(function(_exports,_events,_options){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0;return _exports.default=(editor,filePickerType,blob,fileName,progress)=>new Promise(((resolve,reject)=>{var _options$savepath;(0,_events.notifyUploadStarted)(editor.targetElm.id);const xhr=new XMLHttpRequest;xhr.upload.addEventListener("progress",(e=>{progress(e.loaded/e.total*100)})),xhr.addEventListener("load",(()=>{if(403===xhr.status)return void reject({message:"HTTP error: ".concat(xhr.status),remove:!0});if(xhr.status<200||xhr.status>=300)return void reject("HTTP Error: ".concat(xhr.status));const response=JSON.parse(xhr.responseText);if(!response)return void reject("Invalid JSON: ".concat(xhr.responseText));let location;if((0,_events.notifyUploadCompleted)(editor.targetElm.id),response.url?location=response.url:response.event&&"fileexists"===response.event&&response.newfile&&(location=response.newfile.url),location&&"string"==typeof location)return void resolve(location);const errorString=xhr.responseText,cleanedErrorString=errorString.replace(/\\/g,"");let output="";try{output=JSON.parse(cleanedErrorString)}catch(error){output=errorString}reject(output)})),xhr.addEventListener("error",(()=>{reject({message:"Upload failed due to an XHR transport error. Code: ".concat(xhr.status),remove:!0})}));const formData=new FormData,options=(0,_options.getFilePicker)(editor,filePickerType);formData.append("repo_upload_file",blob,fileName),formData.append("itemid",options.itemid),Object.values(options.repositories).some((repository=>"upload"===repository.type&&(formData.append("repo_id",repository.id),!0))),formData.append("env",options.env),formData.append("sesskey",M.cfg.sesskey),formData.append("client_id",options.client_id),formData.append("savepath",null!==(_options$savepath=options.savepath)&&void 0!==_options$savepath?_options$savepath:"/"),formData.append("ctx_id",options.context.id);const acceptedTypes=options.accepted_types;Array.isArray(acceptedTypes)?acceptedTypes.forEach((function(type){formData.append("accepted_types[]",type)})):formData.append("accepted_types[]",acceptedTypes),xhr.open("POST","".concat(M.cfg.wwwroot,"/repository/repository_ajax.php?action=upload"),!0),xhr.send(formData)})),_exports.default})); +define("editor_tiny/uploader",["exports","core_form/events","editor_tiny/options"],(function(_exports,_events,_options){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0;return _exports.default=(editor,filePickerType,blob,fileName,progress)=>new Promise(((resolve,reject)=>{var _options$savepath;(0,_events.notifyUploadStarted)(editor.targetElm.id);const xhr=new XMLHttpRequest;xhr.upload.addEventListener("progress",(e=>{progress(e.loaded/e.total*100)})),xhr.addEventListener("load",(()=>{if(403===xhr.status)return void reject({message:"HTTP error: ".concat(xhr.status),remove:!0});if(xhr.status<200||xhr.status>=300)return void reject("HTTP Error: ".concat(xhr.status));const response=JSON.parse(xhr.responseText);if(!response)return void reject("Invalid JSON: ".concat(xhr.responseText));let location;if((0,_events.notifyUploadCompleted)(editor.targetElm.id),response.url?location=response.url:response.event&&"fileexists"===response.event&&response.newfile&&(location=response.newfile.url),location&&"string"==typeof location)return void resolve(location);const errorString=xhr.responseText;let output="";try{output=JSON.parse(errorString)}catch(error){output=errorString}reject(output)})),xhr.addEventListener("error",(()=>{reject({message:"Upload failed due to an XHR transport error. Code: ".concat(xhr.status),remove:!0})}));const formData=new FormData,options=(0,_options.getFilePicker)(editor,filePickerType);formData.append("repo_upload_file",blob,fileName),formData.append("itemid",options.itemid),Object.values(options.repositories).some((repository=>"upload"===repository.type&&(formData.append("repo_id",repository.id),!0))),formData.append("env",options.env),formData.append("sesskey",M.cfg.sesskey),formData.append("client_id",options.client_id),formData.append("savepath",null!==(_options$savepath=options.savepath)&&void 0!==_options$savepath?_options$savepath:"/"),formData.append("ctx_id",options.context.id);const acceptedTypes=options.accepted_types;Array.isArray(acceptedTypes)?acceptedTypes.forEach((function(type){formData.append("accepted_types[]",type)})):formData.append("accepted_types[]",acceptedTypes),xhr.open("POST","".concat(M.cfg.wwwroot,"/repository/repository_ajax.php?action=upload"),!0),xhr.send(formData)})),_exports.default})); //# sourceMappingURL=uploader.min.js.map \ No newline at end of file diff --git a/lib/editor/tiny/amd/build/uploader.min.js.map b/lib/editor/tiny/amd/build/uploader.min.js.map index 9eb3e989c15..91628aa2f63 100644 --- a/lib/editor/tiny/amd/build/uploader.min.js.map +++ b/lib/editor/tiny/amd/build/uploader.min.js.map @@ -1 +1 @@ -{"version":3,"file":"uploader.min.js","sources":["../src/uploader.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 Media plugin for Moodle.\n *\n * @module editor_tiny/uploader\n * @copyright 2022 Andrew Lyons \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {\n notifyUploadStarted,\n notifyUploadCompleted,\n} from 'core_form/events';\nimport {getFilePicker} from 'editor_tiny/options';\n\n// This image uploader is based on advice given at:\n// https://www.tiny.cloud/docs/tinymce/6/upload-images/\nexport default (editor, filePickerType, blob, fileName, progress) => new Promise((resolve, reject) => {\n notifyUploadStarted(editor.targetElm.id);\n\n const xhr = new XMLHttpRequest();\n\n // Add the progress handler.\n xhr.upload.addEventListener('progress', (e) => {\n progress(e.loaded / e.total * 100);\n });\n\n xhr.addEventListener('load', () => {\n if (xhr.status === 403) {\n reject({\n message: `HTTP error: ${xhr.status}`,\n remove: true,\n });\n return;\n }\n\n if (xhr.status < 200 || xhr.status >= 300) {\n reject(`HTTP Error: ${xhr.status}`);\n return;\n }\n\n const response = JSON.parse(xhr.responseText);\n\n if (!response) {\n reject(`Invalid JSON: ${xhr.responseText}`);\n return;\n }\n\n notifyUploadCompleted(editor.targetElm.id);\n\n let location;\n if (response.url) {\n location = response.url;\n } else if (response.event && response.event === 'fileexists' && response.newfile) {\n // A file with this name is already in use here - rename to avoid conflict.\n // Chances are, it's a different image (stored in a different folder on the user's computer).\n // If the user wants to reuse an existing image, they can copy/paste it within the editor.\n location = response.newfile.url;\n }\n\n if (location && typeof location === 'string') {\n resolve(location);\n return;\n }\n\n const errorString = xhr.responseText;\n // Remove backslashes and escape characters in the stack trace.\n const cleanedErrorString = errorString.replace(/\\\\/g, '');\n // Try to parse the cleaned string into a JSON object.\n let output = '';\n try {\n output = JSON.parse(cleanedErrorString);\n } catch (error) {\n // If the JSON parsing process returns an error, then it returns the original.\n output = errorString;\n }\n\n reject(output);\n });\n\n xhr.addEventListener('error', () => {\n reject({\n message: `Upload failed due to an XHR transport error. Code: ${xhr.status}`,\n remove: true,\n });\n });\n\n const formData = new FormData();\n const options = getFilePicker(editor, filePickerType);\n\n formData.append('repo_upload_file', blob, fileName);\n formData.append('itemid', options.itemid);\n Object.values(options.repositories).some((repository) => {\n if (repository.type === 'upload') {\n formData.append('repo_id', repository.id);\n return true;\n }\n return false;\n });\n\n formData.append('env', options.env);\n formData.append('sesskey', M.cfg.sesskey);\n formData.append('client_id', options.client_id);\n formData.append('savepath', options.savepath ?? '/');\n formData.append('ctx_id', options.context.id);\n\n // Accepted types can be either a string or an array, but an array is\n // expected in the processing script, so make sure we are sending an array.\n const acceptedTypes = options.accepted_types;\n if (Array.isArray(acceptedTypes)) {\n acceptedTypes.forEach(function(type) {\n formData.append('accepted_types[]', type);\n });\n } else {\n formData.append('accepted_types[]', acceptedTypes);\n }\n\n xhr.open('POST', `${M.cfg.wwwroot}/repository/repository_ajax.php?action=upload`, true);\n xhr.send(formData);\n});\n"],"names":["editor","filePickerType","blob","fileName","progress","Promise","resolve","reject","targetElm","id","xhr","XMLHttpRequest","upload","addEventListener","e","loaded","total","status","message","remove","response","JSON","parse","responseText","location","url","event","newfile","errorString","cleanedErrorString","replace","output","error","formData","FormData","options","append","itemid","Object","values","repositories","some","repository","type","env","M","cfg","sesskey","client_id","savepath","context","acceptedTypes","accepted_types","Array","isArray","forEach","open","wwwroot","send"],"mappings":"gOA8Be,CAACA,OAAQC,eAAgBC,KAAMC,SAAUC,WAAa,IAAIC,SAAQ,CAACC,QAASC,gEACnEP,OAAOQ,UAAUC,UAE/BC,IAAM,IAAIC,eAGhBD,IAAIE,OAAOC,iBAAiB,YAAaC,IACrCV,SAASU,EAAEC,OAASD,EAAEE,MAAQ,QAGlCN,IAAIG,iBAAiB,QAAQ,QACN,MAAfH,IAAIO,mBACJV,OAAO,CACHW,8BAAwBR,IAAIO,QAC5BE,QAAQ,OAKZT,IAAIO,OAAS,KAAOP,IAAIO,QAAU,gBAClCV,6BAAsBG,IAAIO,eAIxBG,SAAWC,KAAKC,MAAMZ,IAAIa,kBAE3BH,qBACDb,+BAAwBG,IAAIa,mBAM5BC,8CAFkBxB,OAAOQ,UAAUC,IAGnCW,SAASK,IACTD,SAAWJ,SAASK,IACbL,SAASM,OAA4B,eAAnBN,SAASM,OAA0BN,SAASO,UAIrEH,SAAWJ,SAASO,QAAQF,KAG5BD,UAAgC,iBAAbA,qBACnBlB,QAAQkB,gBAINI,YAAclB,IAAIa,aAElBM,mBAAqBD,YAAYE,QAAQ,MAAO,QAElDC,OAAS,OAETA,OAASV,KAAKC,MAAMO,oBACtB,MAAOG,OAELD,OAASH,YAGbrB,OAAOwB,WAGXrB,IAAIG,iBAAiB,SAAS,KAC1BN,OAAO,CACHW,qEAA+DR,IAAIO,QACnEE,QAAQ,aAIVc,SAAW,IAAIC,SACfC,SAAU,0BAAcnC,OAAQC,gBAEtCgC,SAASG,OAAO,mBAAoBlC,KAAMC,UAC1C8B,SAASG,OAAO,SAAUD,QAAQE,QAClCC,OAAOC,OAAOJ,QAAQK,cAAcC,MAAMC,YACd,WAApBA,WAAWC,OACXV,SAASG,OAAO,UAAWM,WAAWjC,KAC/B,KAKfwB,SAASG,OAAO,MAAOD,QAAQS,KAC/BX,SAASG,OAAO,UAAWS,EAAEC,IAAIC,SACjCd,SAASG,OAAO,YAAaD,QAAQa,WACrCf,SAASG,OAAO,qCAAYD,QAAQc,wDAAY,KAChDhB,SAASG,OAAO,SAAUD,QAAQe,QAAQzC,UAIpC0C,cAAgBhB,QAAQiB,eAC1BC,MAAMC,QAAQH,eACdA,cAAcI,SAAQ,SAASZ,MACzBV,SAASG,OAAO,mBAAoBO,SAG1CV,SAASG,OAAO,mBAAoBe,eAGxCzC,IAAI8C,KAAK,iBAAWX,EAAEC,IAAIW,0DAAwD,GAClF/C,IAAIgD,KAAKzB"} \ No newline at end of file +{"version":3,"file":"uploader.min.js","sources":["../src/uploader.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 Media plugin for Moodle.\n *\n * @module editor_tiny/uploader\n * @copyright 2022 Andrew Lyons \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {\n notifyUploadStarted,\n notifyUploadCompleted,\n} from 'core_form/events';\nimport {getFilePicker} from 'editor_tiny/options';\n\n// This image uploader is based on advice given at:\n// https://www.tiny.cloud/docs/tinymce/6/upload-images/\nexport default (editor, filePickerType, blob, fileName, progress) => new Promise((resolve, reject) => {\n notifyUploadStarted(editor.targetElm.id);\n\n const xhr = new XMLHttpRequest();\n\n // Add the progress handler.\n xhr.upload.addEventListener('progress', (e) => {\n progress(e.loaded / e.total * 100);\n });\n\n xhr.addEventListener('load', () => {\n if (xhr.status === 403) {\n reject({\n message: `HTTP error: ${xhr.status}`,\n remove: true,\n });\n return;\n }\n\n if (xhr.status < 200 || xhr.status >= 300) {\n reject(`HTTP Error: ${xhr.status}`);\n return;\n }\n\n const response = JSON.parse(xhr.responseText);\n\n if (!response) {\n reject(`Invalid JSON: ${xhr.responseText}`);\n return;\n }\n\n notifyUploadCompleted(editor.targetElm.id);\n\n let location;\n if (response.url) {\n location = response.url;\n } else if (response.event && response.event === 'fileexists' && response.newfile) {\n // A file with this name is already in use here - rename to avoid conflict.\n // Chances are, it's a different image (stored in a different folder on the user's computer).\n // If the user wants to reuse an existing image, they can copy/paste it within the editor.\n location = response.newfile.url;\n }\n\n if (location && typeof location === 'string') {\n resolve(location);\n return;\n }\n\n // Try to parse the error response into a JSON object.\n const errorString = xhr.responseText;\n let output = '';\n try {\n output = JSON.parse(errorString);\n } catch (error) {\n // If the JSON parsing process returns an error, then it returns the original.\n output = errorString;\n }\n\n reject(output);\n });\n\n xhr.addEventListener('error', () => {\n reject({\n message: `Upload failed due to an XHR transport error. Code: ${xhr.status}`,\n remove: true,\n });\n });\n\n const formData = new FormData();\n const options = getFilePicker(editor, filePickerType);\n\n formData.append('repo_upload_file', blob, fileName);\n formData.append('itemid', options.itemid);\n Object.values(options.repositories).some((repository) => {\n if (repository.type === 'upload') {\n formData.append('repo_id', repository.id);\n return true;\n }\n return false;\n });\n\n formData.append('env', options.env);\n formData.append('sesskey', M.cfg.sesskey);\n formData.append('client_id', options.client_id);\n formData.append('savepath', options.savepath ?? '/');\n formData.append('ctx_id', options.context.id);\n\n // Accepted types can be either a string or an array, but an array is\n // expected in the processing script, so make sure we are sending an array.\n const acceptedTypes = options.accepted_types;\n if (Array.isArray(acceptedTypes)) {\n acceptedTypes.forEach(function(type) {\n formData.append('accepted_types[]', type);\n });\n } else {\n formData.append('accepted_types[]', acceptedTypes);\n }\n\n xhr.open('POST', `${M.cfg.wwwroot}/repository/repository_ajax.php?action=upload`, true);\n xhr.send(formData);\n});\n"],"names":["editor","filePickerType","blob","fileName","progress","Promise","resolve","reject","targetElm","id","xhr","XMLHttpRequest","upload","addEventListener","e","loaded","total","status","message","remove","response","JSON","parse","responseText","location","url","event","newfile","errorString","output","error","formData","FormData","options","append","itemid","Object","values","repositories","some","repository","type","env","M","cfg","sesskey","client_id","savepath","context","acceptedTypes","accepted_types","Array","isArray","forEach","open","wwwroot","send"],"mappings":"gOA8Be,CAACA,OAAQC,eAAgBC,KAAMC,SAAUC,WAAa,IAAIC,SAAQ,CAACC,QAASC,gEACnEP,OAAOQ,UAAUC,UAE/BC,IAAM,IAAIC,eAGhBD,IAAIE,OAAOC,iBAAiB,YAAaC,IACrCV,SAASU,EAAEC,OAASD,EAAEE,MAAQ,QAGlCN,IAAIG,iBAAiB,QAAQ,QACN,MAAfH,IAAIO,mBACJV,OAAO,CACHW,8BAAwBR,IAAIO,QAC5BE,QAAQ,OAKZT,IAAIO,OAAS,KAAOP,IAAIO,QAAU,gBAClCV,6BAAsBG,IAAIO,eAIxBG,SAAWC,KAAKC,MAAMZ,IAAIa,kBAE3BH,qBACDb,+BAAwBG,IAAIa,mBAM5BC,8CAFkBxB,OAAOQ,UAAUC,IAGnCW,SAASK,IACTD,SAAWJ,SAASK,IACbL,SAASM,OAA4B,eAAnBN,SAASM,OAA0BN,SAASO,UAIrEH,SAAWJ,SAASO,QAAQF,KAG5BD,UAAgC,iBAAbA,qBACnBlB,QAAQkB,gBAKNI,YAAclB,IAAIa,iBACpBM,OAAS,OAETA,OAASR,KAAKC,MAAMM,aACtB,MAAOE,OAELD,OAASD,YAGbrB,OAAOsB,WAGXnB,IAAIG,iBAAiB,SAAS,KAC1BN,OAAO,CACHW,qEAA+DR,IAAIO,QACnEE,QAAQ,aAIVY,SAAW,IAAIC,SACfC,SAAU,0BAAcjC,OAAQC,gBAEtC8B,SAASG,OAAO,mBAAoBhC,KAAMC,UAC1C4B,SAASG,OAAO,SAAUD,QAAQE,QAClCC,OAAOC,OAAOJ,QAAQK,cAAcC,MAAMC,YACd,WAApBA,WAAWC,OACXV,SAASG,OAAO,UAAWM,WAAW/B,KAC/B,KAKfsB,SAASG,OAAO,MAAOD,QAAQS,KAC/BX,SAASG,OAAO,UAAWS,EAAEC,IAAIC,SACjCd,SAASG,OAAO,YAAaD,QAAQa,WACrCf,SAASG,OAAO,qCAAYD,QAAQc,wDAAY,KAChDhB,SAASG,OAAO,SAAUD,QAAQe,QAAQvC,UAIpCwC,cAAgBhB,QAAQiB,eAC1BC,MAAMC,QAAQH,eACdA,cAAcI,SAAQ,SAASZ,MACzBV,SAASG,OAAO,mBAAoBO,SAG1CV,SAASG,OAAO,mBAAoBe,eAGxCvC,IAAI4C,KAAK,iBAAWX,EAAEC,IAAIW,0DAAwD,GAClF7C,IAAI8C,KAAKzB"} \ No newline at end of file diff --git a/lib/editor/tiny/amd/src/uploader.js b/lib/editor/tiny/amd/src/uploader.js index 71ae3d71a9d..4f11d80bb3e 100644 --- a/lib/editor/tiny/amd/src/uploader.js +++ b/lib/editor/tiny/amd/src/uploader.js @@ -76,13 +76,11 @@ export default (editor, filePickerType, blob, fileName, progress) => new Promise return; } + // Try to parse the error response into a JSON object. const errorString = xhr.responseText; - // Remove backslashes and escape characters in the stack trace. - const cleanedErrorString = errorString.replace(/\\/g, ''); - // Try to parse the cleaned string into a JSON object. let output = ''; try { - output = JSON.parse(cleanedErrorString); + output = JSON.parse(errorString); } catch (error) { // If the JSON parsing process returns an error, then it returns the original. output = errorString;