diff --git a/amd/build/commands.min.js b/amd/build/commands.min.js index 4d25d2f..6beee03 100644 --- a/amd/build/commands.min.js +++ b/amd/build/commands.min.js @@ -1,3 +1,3 @@ -define("tiny_codepro/commands",["exports","editor_tiny/utils","core/str","./ui","./common","./options"],(function(_exports,_utils,_str,_ui,_common,_options){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.getSetup=void 0;_exports.getSetup=async()=>{const[pluginName,buttonImage]=await Promise.all([(0,_str.get_string)("pluginname",_common.component),(0,_utils.getButtonImage)("icon",_common.component)]);return editor=>{(0,_options.isPluginVisible)(editor)&&(editor.ui.registry.addIcon(_common.icon,buttonImage.html),editor.ui.registry.addButton(_common.component,{icon:_common.icon,tooltip:pluginName,onAction:()=>(0,_ui.handleAction)(editor),enabled:!1,onSetup:api=>{const cb=()=>api.setEnabled(!0);return editor.on("SetContent",cb),()=>editor.off("SetContent",cb)}}),editor.ui.registry.addMenuItem(_common.component,{icon:_common.icon,text:pluginName,onAction:()=>(0,_ui.handleAction)(editor)}))}}})); +define("tiny_codepro/commands",["exports","editor_tiny/utils","core/str","./ui","./common","./options"],(function(_exports,_utils,_str,_ui,_common,_options){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.getSetup=void 0;_exports.getSetup=async()=>{const[pluginName,buttonImage]=await Promise.all([(0,_str.get_string)("pluginname",_common.component),(0,_utils.getButtonImage)("icon",_common.component)]);return editor=>{(0,_options.isPluginVisible)(editor)&&(editor.ui.registry.addIcon(_common.icon,buttonImage.html),editor.ui.registry.addButton(_common.component,{icon:_common.icon,tooltip:pluginName,onAction:()=>(0,_ui.handleAction)(editor)}),editor.ui.registry.addMenuItem(_common.component,{icon:_common.icon,text:pluginName,onAction:()=>(0,_ui.handleAction)(editor)}))}}})); //# sourceMappingURL=commands.min.js.map \ No newline at end of file diff --git a/amd/build/commands.min.js.map b/amd/build/commands.min.js.map index 05a6921..f8bb1ad 100644 --- a/amd/build/commands.min.js.map +++ b/amd/build/commands.min.js.map @@ -1 +1 @@ -{"version":3,"file":"commands.min.js","sources":["../src/commands.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 CodePro plugin.\n *\n * @module tiny_codepro/plugin\n * @copyright 2023 Josep Mulet Pol \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {getButtonImage} from 'editor_tiny/utils';\nimport {get_string as getString} from 'core/str';\nimport {handleAction} from './ui';\nimport {component, icon} from './common';\nimport {isPluginVisible} from './options';\n\nexport const getSetup = async() => {\n const [\n pluginName,\n buttonImage,\n ] = await Promise.all([\n getString('pluginname', component),\n getButtonImage('icon', component),\n ]);\n\n return (editor) => {\n if (!isPluginVisible(editor)) {\n return;\n }\n // Register the Icon.\n editor.ui.registry.addIcon(icon, buttonImage.html);\n\n // Register the Toolbar Button.\n editor.ui.registry.addButton(component, {\n icon,\n tooltip: pluginName,\n onAction: () => handleAction(editor),\n enabled: false,\n onSetup: (api) => {\n const cb = () => api.setEnabled(true);\n editor.on('SetContent', cb);\n return () => editor.off('SetContent', cb);\n }\n });\n\n // Add the Menu Item.\n // This allows it to be added to a standard menu, or a context menu.\n editor.ui.registry.addMenuItem(component, {\n icon,\n text: pluginName,\n onAction: () => handleAction(editor)\n });\n };\n};"],"names":["async","pluginName","buttonImage","Promise","all","component","editor","ui","registry","addIcon","icon","html","addButton","tooltip","onAction","enabled","onSetup","api","cb","setEnabled","on","off","addMenuItem","text"],"mappings":"gQA6BwBA,gBAEhBC,WACAC,mBACMC,QAAQC,IAAI,EAClB,mBAAU,aAAcC,oBACxB,yBAAe,OAAQA,4BAGnBC,UACC,4BAAgBA,UAIrBA,OAAOC,GAAGC,SAASC,QAAQC,aAAMR,YAAYS,MAG7CL,OAAOC,GAAGC,SAASI,UAAUP,kBAAW,CACpCK,KAAAA,aACAG,QAASZ,WACTa,SAAU,KAAM,oBAAaR,QAC7BS,SAAS,EACTC,QAAUC,YACAC,GAAK,IAAMD,IAAIE,YAAW,UAChCb,OAAOc,GAAG,aAAcF,IACjB,IAAMZ,OAAOe,IAAI,aAAcH,OAM9CZ,OAAOC,GAAGC,SAASc,YAAYjB,kBAAW,CACtCK,KAAAA,aACAa,KAAMtB,WACNa,SAAU,KAAM,oBAAaR"} \ No newline at end of file +{"version":3,"file":"commands.min.js","sources":["../src/commands.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 CodePro plugin.\n *\n * @module tiny_codepro/plugin\n * @copyright 2023 Josep Mulet Pol \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {getButtonImage} from 'editor_tiny/utils';\nimport {get_string as getString} from 'core/str';\nimport {handleAction} from './ui';\nimport {component, icon} from './common';\nimport {isPluginVisible} from './options';\n\nexport const getSetup = async() => {\n const [\n pluginName,\n buttonImage,\n ] = await Promise.all([\n getString('pluginname', component),\n getButtonImage('icon', component),\n ]);\n\n return (editor) => {\n if (!isPluginVisible(editor)) {\n return;\n }\n // Register the Icon.\n editor.ui.registry.addIcon(icon, buttonImage.html);\n\n // Register the Toolbar Button.\n editor.ui.registry.addButton(component, {\n icon,\n tooltip: pluginName,\n onAction: () => handleAction(editor)\n });\n\n // Add the Menu Item.\n // This allows it to be added to a standard menu, or a context menu.\n editor.ui.registry.addMenuItem(component, {\n icon,\n text: pluginName,\n onAction: () => handleAction(editor)\n });\n };\n};"],"names":["async","pluginName","buttonImage","Promise","all","component","editor","ui","registry","addIcon","icon","html","addButton","tooltip","onAction","addMenuItem","text"],"mappings":"gQA6BwBA,gBAEhBC,WACAC,mBACMC,QAAQC,IAAI,EAClB,mBAAU,aAAcC,oBACxB,yBAAe,OAAQA,4BAGnBC,UACC,4BAAgBA,UAIrBA,OAAOC,GAAGC,SAASC,QAAQC,aAAMR,YAAYS,MAG7CL,OAAOC,GAAGC,SAASI,UAAUP,kBAAW,CACpCK,KAAAA,aACAG,QAASZ,WACTa,SAAU,KAAM,oBAAaR,UAKjCA,OAAOC,GAAGC,SAASO,YAAYV,kBAAW,CACtCK,KAAAA,aACAM,KAAMf,WACNa,SAAU,KAAM,oBAAaR"} \ No newline at end of file diff --git a/amd/build/plugin.min.js b/amd/build/plugin.min.js index e9ddbf4..57cc166 100644 --- a/amd/build/plugin.min.js +++ b/amd/build/plugin.min.js @@ -5,6 +5,6 @@ define("tiny_codepro/plugin",["exports","editor_tiny/loader","editor_tiny/utils" * @module tiny_codepro/plugin * @copyright 2023 Josep Mulet Pol * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */(Configuration);var _default=new Promise((async resolve=>{const[tinyMCE,pluginMetadata,setupCommands]=await Promise.all([(0,_loader.getTinyMCE)(),(0,_utils.getPluginMetadata)(_common.component,_common.pluginName,"https://github.com/jmulet/moodle-tiny_codepro"),(0,_commands.getSetup)()]);tinyMCE.PluginManager.add(_common.pluginName,(editor=>((0,_options.register)(editor),setupCommands(editor),pluginMetadata))),resolve([_common.pluginName,Configuration])}));return _exports.default=_default,_exports.default})); + */(Configuration);var _default=new Promise((async resolve=>{const[tinyMCE,pluginMetadata,setupCommands]=await Promise.all([(0,_loader.getTinyMCE)(),(0,_utils.getPluginMetadata)(_common.component,_common.pluginName,"https://github.com/jmulet/moodle-tiny_codepro"),(0,_commands.getSetup)()]);tinyMCE.PluginManager.add(_common.pluginName,(editor=>((0,_options.register)(editor),editor.once("SetContent",(()=>{setupCommands(editor)})),pluginMetadata))),resolve([_common.pluginName,Configuration])}));return _exports.default=_default,_exports.default})); //# sourceMappingURL=plugin.min.js.map \ No newline at end of file diff --git a/amd/build/plugin.min.js.map b/amd/build/plugin.min.js.map index 70dbc6b..76fc0e6 100644 --- a/amd/build/plugin.min.js.map +++ b/amd/build/plugin.min.js.map @@ -1 +1 @@ -{"version":3,"file":"plugin.min.js","sources":["../src/plugin.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 CodePro plugin.\n *\n * @module tiny_codepro/plugin\n * @copyright 2023 Josep Mulet Pol \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from './common';\nimport {register as registerOptions} from './options';\nimport {getSetup as getCommandSetup} from './commands';\nimport * as Configuration from './configuration';\n\nconst documentationUrl = 'https://github.com/jmulet/moodle-tiny_codepro';\n\n// Setup the Plugin.\n// eslint-disable-next-line no-async-promise-executor\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n pluginMetadata,\n setupCommands,\n ] = await Promise.all([\n getTinyMCE(),\n getPluginMetadata(component, pluginName, documentationUrl),\n getCommandSetup(),\n ]);\n\n tinyMCE.PluginManager.add(pluginName, (editor) => {\n // Register options.\n registerOptions(editor);\n // Resolve the Plugin and include configuration.\n // Setup commands.\n setupCommands(editor);\n return pluginMetadata;\n });\n resolve([pluginName, Configuration]);\n});\n"],"names":["Promise","async","tinyMCE","pluginMetadata","setupCommands","all","component","pluginName","PluginManager","add","editor","resolve","Configuration"],"mappings":";;;;;;;kCAmCe,IAAIA,SAAQC,MAAAA,gBAEnBC,QACAC,eACAC,qBACMJ,QAAQK,IAAI,EAClB,yBACA,4BAAkBC,kBAAWC,mBAXZ,kDAYjB,0BAGJL,QAAQM,cAAcC,IAAIF,oBAAaG,+BAEnBA,QAGhBN,cAAcM,QACPP,kBAEXQ,QAAQ,CAACJ,mBAAYK"} \ No newline at end of file +{"version":3,"file":"plugin.min.js","sources":["../src/plugin.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 CodePro plugin.\n *\n * @module tiny_codepro/plugin\n * @copyright 2023 Josep Mulet Pol \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {getTinyMCE} from 'editor_tiny/loader';\nimport {getPluginMetadata} from 'editor_tiny/utils';\n\nimport {component, pluginName} from './common';\nimport {register as registerOptions} from './options';\nimport {getSetup as getCommandSetup} from './commands';\nimport * as Configuration from './configuration';\n\nconst documentationUrl = 'https://github.com/jmulet/moodle-tiny_codepro';\n\n// Setup the Plugin.\n// eslint-disable-next-line no-async-promise-executor\nexport default new Promise(async(resolve) => {\n const [\n tinyMCE,\n pluginMetadata,\n setupCommands,\n ] = await Promise.all([\n getTinyMCE(),\n getPluginMetadata(component, pluginName, documentationUrl),\n getCommandSetup(),\n ]);\n\n tinyMCE.PluginManager.add(pluginName, (editor) => {\n // Register options.\n registerOptions(editor);\n // Resolve the Plugin and include configuration.\n // Setup commands (only if the content has been set) to prevent from opening the modal without content.\n editor.once('SetContent', () => {\n setupCommands(editor);\n });\n return pluginMetadata;\n });\n\n resolve([pluginName, Configuration]);\n});\n"],"names":["Promise","async","tinyMCE","pluginMetadata","setupCommands","all","component","pluginName","PluginManager","add","editor","once","resolve","Configuration"],"mappings":";;;;;;;kCAmCe,IAAIA,SAAQC,MAAAA,gBAEnBC,QACAC,eACAC,qBACMJ,QAAQK,IAAI,EAClB,yBACA,4BAAkBC,kBAAWC,mBAXZ,kDAYjB,0BAGJL,QAAQM,cAAcC,IAAIF,oBAAaG,+BAEnBA,QAGhBA,OAAOC,KAAK,cAAc,KACtBP,cAAcM,WAEXP,kBAGXS,QAAQ,CAACL,mBAAYM"} \ No newline at end of file diff --git a/amd/build/ui.min.js b/amd/build/ui.min.js index 584ec4d..bc40221 100644 --- a/amd/build/ui.min.js +++ b/amd/build/ui.min.js @@ -5,6 +5,6 @@ define("tiny_codepro/ui",["exports","./modal","core/modal_events","./preferences * @module tiny_codepro/plugin * @copyright 2023 Josep Mulet Pol * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.handleAction=void 0,_modal_events=(obj=_modal_events)&&obj.__esModule?obj:{default:obj};let modal=null,codeEditorInstance=null;const toggleClasses=function(el,classList){const cl=el.classList;classList.forEach((className=>{cl.toggle(className)}))};_exports.handleAction=async editor=>{null===modal&&await createDialogue();modal.footer.find("button.btn[data-action]").off("click.codepro").on("click.codepro",(evt=>{if(evt.target.classList.contains("btn-primary")){const updatedCode=codeEditorInstance.getValue({source_view:!0});editor.setContent(updatedCode)}modal.hide(),codeEditorInstance.setValue()}));const markerNode=document.createElement("SPAN");markerNode.innerHTML=" ",markerNode.classList.add("CmCaReT");editor.selection.getStart().append(markerNode);let html=editor.getContent({source_view:!0});html=html.replace(/]*)>([^<]*)<\/span>/gm,String.fromCharCode(0)),markerNode.remove(),(0,_preferences.getPref)("prettify")&&(html=codeEditorInstance.prettifyCode(html)),codeEditorInstance.setValue(html),modal.show(),setTimeout((()=>codeEditorInstance.focus()),500)};const createDialogue=async()=>{const data={elementid:Math.random().toString(32).substring(2)};return modal=await(0,_modal.createModal)({templateContext:data}),modal.getRoot().find(".modal-dialog.modal-lg").addClass("tiny_codepro-dlg"),modal.getRoot().off("keydown"),modal.getRoot().on(_modal_events.default.outsideClick,(evt=>{evt.preventDefault()})),modal.body.css("overflow-y","overlay"),modal.header.css("height","61.46px"),modal.header.css("padding","1rem 1rem"),new Promise((resolve=>{require(["tiny_codepro/cm6pro-lazy"],(CodeProEditor=>{const targetElem=modal.body.find(".tiny_codepro-editor-area")[0];codeEditorInstance=new CodeProEditor(targetElem),modal.footer.find("button.btn.btn-light").on("click",(evt=>{evt.preventDefault();const ds=evt.currentTarget.dataset,icon=evt.currentTarget.querySelector("i.fa"),$dlgElem=modal.getRoot().find('[role="document"], [data-region="modal"]');if(ds.fs)"false"===ds.fs?(ds.fs="true",modal.header.hide(),$dlgElem.removeClass("modal-dialog modal-lg modal-dialog-scrollable"),$dlgElem.addClass("tiny_codepro-fullscreen")):(ds.fs="false",modal.header.show(),$dlgElem.removeClass("tiny_codepro-fullscreen"),$dlgElem.addClass("modal-dialog modal-lg modal-dialog-scrollable")),(0,_preferences.setPref)("fs",ds.fs,!0);else if(ds.theme)"light"===ds.theme?(ds.theme="dark",codeEditorInstance.setTheme("dark"),$dlgElem.addClass("tiny_codepro-dark")):(ds.theme="light",codeEditorInstance.setTheme("light"),$dlgElem.removeClass("tiny_codepro-dark")),toggleClasses(icon,["fa-sun-o","fa-moon-o"]),(0,_preferences.setPref)("theme",ds.theme,!0);else if(ds.wrap)"true"===ds.wrap?(ds.wrap=!1,codeEditorInstance.setLineWrapping(!1)):(ds.wrap=!0,codeEditorInstance.setLineWrapping(!0)),(0,_preferences.setPref)("wrap",ds.wrap,!0),toggleClasses(icon,["fa-exchange","fa-long-arrow-right"]);else if(void 0!==ds.prettify)codeEditorInstance.prettify();else if(void 0!==ds.autoPrettify){(0,_preferences.setPref)("prettify",!(0,_preferences.getPref)("prettify",!1),!0);const icon=evt.currentTarget.querySelector("i");toggleClasses(icon,["fa-times","fa-check"])}})),modal.getRoot().on(_modal_events.default.hidden,(()=>{codeEditorInstance.setValue()}));const currentTheme=(0,_preferences.getPref)("theme","light"),currentWrap=(0,_preferences.getPref)("wrap","false"),currentFs=(0,_preferences.getPref)("fs","false"),currentPrettify=(0,_preferences.getPref)("prettify",!1);"light"!==currentTheme&&modal.footer.find("button.btn.btn-light[data-theme]").click(),"true"===currentWrap&&modal.footer.find("button.btn.btn-light[data-wrap]").click(),"true"===currentFs&&modal.footer.find("button.btn.btn-light[data-fs]").click(),currentPrettify&&modal.footer.find("button.btn.btn-light[data-auto-prettify] > i").removeClass("fa-times").addClass("fa-check"),resolve(modal)}))}))}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.handleAction=void 0,_modal_events=(obj=_modal_events)&&obj.__esModule?obj:{default:obj};let modal=null,codeEditorInstance=null;const toggleClasses=function(el,classList){const cl=el.classList;classList.forEach((className=>{cl.toggle(className)}))};let isLoading=!1;_exports.handleAction=async editor=>{var _codeEditorInstance4;if(isLoading)return;null===modal&&(isLoading=!0,modal=await createDialogue(),isLoading=!1);modal.footer.find("button.btn[data-action]").off("click.codepro").on("click.codepro",(evt=>{var _codeEditorInstance2;if(evt.target.classList.contains("btn-primary")){var _codeEditorInstance;const updatedCode=null===(_codeEditorInstance=codeEditorInstance)||void 0===_codeEditorInstance?void 0:_codeEditorInstance.getValue({source_view:!0});editor.setContent(updatedCode??"")}modal.hide(),null===(_codeEditorInstance2=codeEditorInstance)||void 0===_codeEditorInstance2||_codeEditorInstance2.setValue()}));const markerNode=document.createElement("SPAN");markerNode.innerHTML=" ",markerNode.classList.add("CmCaReT");editor.selection.getStart().append(markerNode);let html=editor.getContent({source_view:!0});var _codeEditorInstance3;(html=html.replace(/]*)>([^<]*)<\/span>/gm,String.fromCharCode(0)),markerNode.remove(),(0,_preferences.getPref)("prettify"))&&(html=null===(_codeEditorInstance3=codeEditorInstance)||void 0===_codeEditorInstance3?void 0:_codeEditorInstance3.prettifyCode(html));null===(_codeEditorInstance4=codeEditorInstance)||void 0===_codeEditorInstance4||_codeEditorInstance4.setValue(html),modal.show(),setTimeout((()=>{var _codeEditorInstance5;return null===(_codeEditorInstance5=codeEditorInstance)||void 0===_codeEditorInstance5?void 0:_codeEditorInstance5.focus()}),500)};const createDialogue=async()=>{const data={elementid:Math.random().toString(32).substring(2)},modal=await(0,_modal.createModal)({templateContext:data});modal.getRoot().find(".modal-dialog.modal-lg").addClass("tiny_codepro-dlg"),modal.getRoot().off("keydown"),modal.getRoot().on(_modal_events.default.outsideClick,(evt=>{evt.preventDefault()})),modal.body.css("overflow-y","overlay"),modal.header.css("height","61.46px"),modal.header.css("padding","1rem 1rem");const CodeProEditor=await new Promise((resolve=>{require(["tiny_codepro/cm6pro-lazy"],(CodeProEditor=>{resolve(CodeProEditor)}))})),targetElem=modal.body.find(".tiny_codepro-editor-area")[0];codeEditorInstance=new CodeProEditor(targetElem),modal.footer.find("button.btn.btn-light").on("click",(evt=>{evt.preventDefault();const ds=evt.currentTarget.dataset,icon=evt.currentTarget.querySelector("i.fa"),$dlgElem=modal.getRoot().find('[role="document"], [data-region="modal"]');if(ds.fs)"false"===ds.fs?(ds.fs="true",modal.header.hide(),$dlgElem.removeClass("modal-dialog modal-lg modal-dialog-scrollable"),$dlgElem.addClass("tiny_codepro-fullscreen")):(ds.fs="false",modal.header.show(),$dlgElem.removeClass("tiny_codepro-fullscreen"),$dlgElem.addClass("modal-dialog modal-lg modal-dialog-scrollable")),(0,_preferences.setPref)("fs",ds.fs,!0);else if(ds.theme)"light"===ds.theme?(ds.theme="dark",codeEditorInstance.setTheme("dark"),$dlgElem.addClass("tiny_codepro-dark")):(ds.theme="light",codeEditorInstance.setTheme("light"),$dlgElem.removeClass("tiny_codepro-dark")),toggleClasses(icon,["fa-sun-o","fa-moon-o"]),(0,_preferences.setPref)("theme",ds.theme,!0);else if(ds.wrap){var _codeEditorInstance6,_codeEditorInstance7;if("true"===ds.wrap)ds.wrap=!1,null===(_codeEditorInstance6=codeEditorInstance)||void 0===_codeEditorInstance6||_codeEditorInstance6.setLineWrapping(!1);else ds.wrap=!0,null===(_codeEditorInstance7=codeEditorInstance)||void 0===_codeEditorInstance7||_codeEditorInstance7.setLineWrapping(!0);(0,_preferences.setPref)("wrap",ds.wrap,!0),toggleClasses(icon,["fa-exchange","fa-long-arrow-right"])}else if(void 0!==ds.prettify){var _codeEditorInstance8;null===(_codeEditorInstance8=codeEditorInstance)||void 0===_codeEditorInstance8||_codeEditorInstance8.prettify()}else if(void 0!==ds.autoPrettify){(0,_preferences.setPref)("prettify",!(0,_preferences.getPref)("prettify",!1),!0);const icon=evt.currentTarget.querySelector("i");toggleClasses(icon,["fa-times","fa-check"])}})),modal.getRoot().on(_modal_events.default.hidden,(()=>{var _codeEditorInstance9;null===(_codeEditorInstance9=codeEditorInstance)||void 0===_codeEditorInstance9||_codeEditorInstance9.setValue()}));const currentTheme=(0,_preferences.getPref)("theme","light"),currentWrap=(0,_preferences.getPref)("wrap","false"),currentFs=(0,_preferences.getPref)("fs","false"),currentPrettify=(0,_preferences.getPref)("prettify",!1);return"light"!==currentTheme&&modal.footer.find("button.btn.btn-light[data-theme]").click(),"true"===currentWrap&&modal.footer.find("button.btn.btn-light[data-wrap]").click(),"true"===currentFs&&modal.footer.find("button.btn.btn-light[data-fs]").click(),currentPrettify&&modal.footer.find("button.btn.btn-light[data-auto-prettify] > i").removeClass("fa-times").addClass("fa-check"),modal}})); //# sourceMappingURL=ui.min.js.map \ No newline at end of file diff --git a/amd/build/ui.min.js.map b/amd/build/ui.min.js.map index 476b446..ae115df 100644 --- a/amd/build/ui.min.js.map +++ b/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\nimport {createModal} from \"./modal\";\nimport ModalEvents from 'core/modal_events';\nimport {getPref, setPref} from \"./preferences\";\n\n/**\n * Tiny CodePro plugin.\n *\n * @module tiny_codepro/plugin\n * @copyright 2023 Josep Mulet Pol \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nconst dialogQuery = '[role=\"document\"], [data-region=\"modal\"]';\nlet modal = null;\nlet codeEditorInstance = null;\n\n/**\n * Utility to toggle a class in an HTML element\n * @param {HTMLElement} el - The Element\n * @param {string[]} classList\n */\nconst toggleClasses = function(el, classList) {\n const cl = el.classList;\n classList.forEach(className => {\n cl.toggle(className);\n });\n};\n\n/**\n * Handle action\n * @param {TinyMCE} editor\n */\nexport const handleAction = async(editor) => {\n if (modal === null) {\n await createDialogue();\n }\n\n // Issue, editor var does not get updated\n // Bind save action to the correct editor\n const $btn = modal.footer.find(\"button.btn[data-action]\");\n $btn.off(\"click.codepro\").on(\"click.codepro\", (evt) => {\n if (evt.target.classList.contains(\"btn-primary\")) {\n // eslint-disable-next-line camelcase\n const updatedCode = codeEditorInstance.getValue({source_view: true});\n editor.setContent(updatedCode);\n }\n modal.hide();\n // Delete content\n codeEditorInstance.setValue();\n });\n\n // Insert caret marker and retrieve html code to pass to CodeMirror\n const markerNode = document.createElement(\"SPAN\");\n markerNode.innerHTML = ' ';\n markerNode.classList.add('CmCaReT');\n const currentNode = editor.selection.getStart();\n currentNode.append(markerNode);\n // eslint-disable-next-line camelcase\n let html = editor.getContent({source_view: true});\n html = html.replace(/]*)>([^<]*)<\\/span>/gm, String.fromCharCode(0));\n markerNode.remove();\n\n if (getPref(\"prettify\")) {\n html = codeEditorInstance.prettifyCode(html);\n }\n codeEditorInstance.setValue(html);\n\n modal.show();\n setTimeout(() => codeEditorInstance.focus(), 500);\n};\n\nconst createDialogue = async() => {\n const data = {\n elementid: Math.random().toString(32).substring(2)\n };\n\n // Show modal with buttons.\n modal = await createModal({\n templateContext: data\n });\n\n modal.getRoot().find(\".modal-dialog.modal-lg\").addClass(\"tiny_codepro-dlg\");\n // Disable keyboard events (ESC key) on this modal\n modal.getRoot().off('keydown');\n // Prevent modal from closing on outside clicks\n modal.getRoot().on(ModalEvents.outsideClick, (evt) => {\n evt.preventDefault();\n });\n modal.body.css(\"overflow-y\", \"overlay\");\n // Override styles imposed by body.tox-fullscreen on modals\n modal.header.css('height', '61.46px');\n modal.header.css('padding', '1rem 1rem');\n\n return new Promise((resolve) => {\n // Load cm6 on demand\n require(['tiny_codepro/cm6pro-lazy'], (CodeProEditor) => {\n const targetElem = modal.body.find('.tiny_codepro-editor-area')[0];\n codeEditorInstance = new CodeProEditor(targetElem);\n\n modal.footer.find(\"button.btn.btn-light\").on(\"click\", (evt) => {\n evt.preventDefault();\n const ds = evt.currentTarget.dataset;\n const icon = evt.currentTarget.querySelector(\"i.fa\");\n const $dlgElem = modal.getRoot().find(dialogQuery);\n if (ds.fs) {\n if (ds.fs === \"false\") {\n // Set fullscreen mode\n ds.fs = \"true\";\n modal.header.hide();\n $dlgElem.removeClass(\"modal-dialog modal-lg modal-dialog-scrollable\");\n $dlgElem.addClass(\"tiny_codepro-fullscreen\");\n } else {\n // Set to modal-lg\n ds.fs = \"false\";\n modal.header.show();\n $dlgElem.removeClass(\"tiny_codepro-fullscreen\");\n $dlgElem.addClass(\"modal-dialog modal-lg modal-dialog-scrollable\");\n }\n setPref(\"fs\", ds.fs, true);\n } else if (ds.theme) {\n if (ds.theme === \"light\") {\n ds.theme = \"dark\";\n codeEditorInstance.setTheme(\"dark\");\n $dlgElem.addClass(\"tiny_codepro-dark\");\n } else {\n ds.theme = \"light\";\n codeEditorInstance.setTheme(\"light\");\n $dlgElem.removeClass(\"tiny_codepro-dark\");\n }\n toggleClasses(icon, [\"fa-sun-o\", \"fa-moon-o\"]);\n setPref(\"theme\", ds.theme, true);\n } else if (ds.wrap) {\n if (ds.wrap === \"true\") {\n ds.wrap = false;\n codeEditorInstance.setLineWrapping(false);\n } else {\n ds.wrap = true;\n codeEditorInstance.setLineWrapping(true);\n }\n setPref(\"wrap\", ds.wrap, true);\n toggleClasses(icon, [\"fa-exchange\", \"fa-long-arrow-right\"]);\n } else if (ds.prettify !== undefined) {\n codeEditorInstance.prettify();\n } else if (ds.autoPrettify !== undefined) {\n setPref(\"prettify\", !getPref(\"prettify\", false), true);\n const icon = evt.currentTarget.querySelector(\"i\");\n toggleClasses(icon, [\"fa-times\", \"fa-check\"]);\n }\n });\n\n modal.getRoot().on(ModalEvents.hidden, () => {\n codeEditorInstance.setValue();\n });\n\n // Setting stored preferences\n const currentTheme = getPref(\"theme\", \"light\");\n const currentWrap = getPref(\"wrap\", \"false\");\n const currentFs = getPref(\"fs\", \"false\");\n const currentPrettify = getPref(\"prettify\", false);\n\n if (currentTheme !== \"light\") {\n modal.footer.find(\"button.btn.btn-light[data-theme]\").click();\n }\n if (currentWrap === \"true\") {\n modal.footer.find(\"button.btn.btn-light[data-wrap]\").click();\n }\n if (currentFs === \"true\") {\n modal.footer.find(\"button.btn.btn-light[data-fs]\").click();\n }\n if (currentPrettify) {\n modal.footer.find(\"button.btn.btn-light[data-auto-prettify] > i\")\n .removeClass(\"fa-times\")\n .addClass(\"fa-check\");\n }\n\n resolve(modal);\n });\n });\n};"],"names":["modal","codeEditorInstance","toggleClasses","el","classList","cl","forEach","className","toggle","async","createDialogue","footer","find","off","on","evt","target","contains","updatedCode","getValue","source_view","editor","setContent","hide","setValue","markerNode","document","createElement","innerHTML","add","selection","getStart","append","html","getContent","replace","String","fromCharCode","remove","prettifyCode","show","setTimeout","focus","data","elementid","Math","random","toString","substring","templateContext","getRoot","addClass","ModalEvents","outsideClick","preventDefault","body","css","header","Promise","resolve","require","CodeProEditor","targetElem","ds","currentTarget","dataset","icon","querySelector","$dlgElem","fs","removeClass","theme","setTheme","wrap","setLineWrapping","undefined","prettify","autoPrettify","hidden","currentTheme","currentWrap","currentFs","currentPrettify","click"],"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\nimport {createModal} from \"./modal\";\nimport ModalEvents from 'core/modal_events';\nimport {getPref, setPref} from \"./preferences\";\n\n/**\n * Tiny CodePro plugin.\n *\n * @module tiny_codepro/plugin\n * @copyright 2023 Josep Mulet Pol \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nconst dialogQuery = '[role=\"document\"], [data-region=\"modal\"]';\nlet modal = null;\nlet codeEditorInstance = null;\n\n/**\n * Utility to toggle a class in an HTML element\n * @param {HTMLElement} el - The Element\n * @param {string[]} classList\n */\nconst toggleClasses = function(el, classList) {\n const cl = el.classList;\n classList.forEach(className => {\n cl.toggle(className);\n });\n};\n\nlet isLoading = false;\n/**\n * Handle action\n * @param {TinyMCE} editor\n */\nexport const handleAction = async(editor) => {\n if (isLoading) {\n return;\n }\n if (modal === null) {\n isLoading = true;\n modal = await createDialogue();\n isLoading = false;\n }\n\n // Issue, editor var does not get updated\n // Bind save action to the correct editor\n const $btn = modal.footer.find(\"button.btn[data-action]\");\n $btn.off(\"click.codepro\").on(\"click.codepro\", (evt) => {\n if (evt.target.classList.contains(\"btn-primary\")) {\n // eslint-disable-next-line camelcase\n const updatedCode = codeEditorInstance?.getValue({source_view: true});\n editor.setContent(updatedCode ?? '');\n }\n modal.hide();\n // Delete content\n codeEditorInstance?.setValue();\n });\n\n // Insert caret marker and retrieve html code to pass to CodeMirror\n const markerNode = document.createElement(\"SPAN\");\n markerNode.innerHTML = ' ';\n markerNode.classList.add('CmCaReT');\n const currentNode = editor.selection.getStart();\n currentNode.append(markerNode);\n // eslint-disable-next-line camelcase\n let html = editor.getContent({source_view: true});\n html = html.replace(/]*)>([^<]*)<\\/span>/gm, String.fromCharCode(0));\n markerNode.remove();\n\n if (getPref(\"prettify\")) {\n html = codeEditorInstance?.prettifyCode(html);\n }\n codeEditorInstance?.setValue(html);\n\n modal.show();\n setTimeout(() => codeEditorInstance?.focus(), 500);\n};\n\n/**\n * Loads cm6 on demand (The first load will be delayed a little bit)\n * @returns {Promise}\n */\nconst requireCm6Pro = () => {\n return new Promise((resolve) => {\n require(['tiny_codepro/cm6pro-lazy'], (CodeProEditor) => {\n resolve(CodeProEditor);\n });\n });\n};\n\n/**\n * Returns the modal instance\n * @returns {Promise}\n */\nconst createDialogue = async() => {\n const data = {\n elementid: Math.random().toString(32).substring(2)\n };\n\n // Show modal with buttons.\n const modal = await createModal({\n templateContext: data\n });\n\n modal.getRoot().find(\".modal-dialog.modal-lg\").addClass(\"tiny_codepro-dlg\");\n // Disable keyboard events (ESC key) on this modal\n modal.getRoot().off('keydown');\n // Prevent modal from closing on outside clicks\n modal.getRoot().on(ModalEvents.outsideClick, (evt) => {\n evt.preventDefault();\n });\n modal.body.css(\"overflow-y\", \"overlay\");\n // Override styles imposed by body.tox-fullscreen on modals\n modal.header.css('height', '61.46px');\n modal.header.css('padding', '1rem 1rem');\n\n const CodeProEditor = await requireCm6Pro();\n const targetElem = modal.body.find('.tiny_codepro-editor-area')[0];\n codeEditorInstance = new CodeProEditor(targetElem);\n\n modal.footer.find(\"button.btn.btn-light\").on(\"click\", (evt) => {\n evt.preventDefault();\n const ds = evt.currentTarget.dataset;\n const icon = evt.currentTarget.querySelector(\"i.fa\");\n const $dlgElem = modal.getRoot().find(dialogQuery);\n if (ds.fs) {\n if (ds.fs === \"false\") {\n // Set fullscreen mode\n ds.fs = \"true\";\n modal.header.hide();\n $dlgElem.removeClass(\"modal-dialog modal-lg modal-dialog-scrollable\");\n $dlgElem.addClass(\"tiny_codepro-fullscreen\");\n } else {\n // Set to modal-lg\n ds.fs = \"false\";\n modal.header.show();\n $dlgElem.removeClass(\"tiny_codepro-fullscreen\");\n $dlgElem.addClass(\"modal-dialog modal-lg modal-dialog-scrollable\");\n }\n setPref(\"fs\", ds.fs, true);\n } else if (ds.theme) {\n if (ds.theme === \"light\") {\n ds.theme = \"dark\";\n codeEditorInstance.setTheme(\"dark\");\n $dlgElem.addClass(\"tiny_codepro-dark\");\n } else {\n ds.theme = \"light\";\n codeEditorInstance.setTheme(\"light\");\n $dlgElem.removeClass(\"tiny_codepro-dark\");\n }\n toggleClasses(icon, [\"fa-sun-o\", \"fa-moon-o\"]);\n setPref(\"theme\", ds.theme, true);\n } else if (ds.wrap) {\n if (ds.wrap === \"true\") {\n ds.wrap = false;\n codeEditorInstance?.setLineWrapping(false);\n } else {\n ds.wrap = true;\n codeEditorInstance?.setLineWrapping(true);\n }\n setPref(\"wrap\", ds.wrap, true);\n toggleClasses(icon, [\"fa-exchange\", \"fa-long-arrow-right\"]);\n } else if (ds.prettify !== undefined) {\n codeEditorInstance?.prettify();\n } else if (ds.autoPrettify !== undefined) {\n setPref(\"prettify\", !getPref(\"prettify\", false), true);\n const icon = evt.currentTarget.querySelector(\"i\");\n toggleClasses(icon, [\"fa-times\", \"fa-check\"]);\n }\n });\n\n modal.getRoot().on(ModalEvents.hidden, () => {\n codeEditorInstance?.setValue();\n });\n\n // Setting stored preferences\n const currentTheme = getPref(\"theme\", \"light\");\n const currentWrap = getPref(\"wrap\", \"false\");\n const currentFs = getPref(\"fs\", \"false\");\n const currentPrettify = getPref(\"prettify\", false);\n\n if (currentTheme !== \"light\") {\n modal.footer.find(\"button.btn.btn-light[data-theme]\").click();\n }\n if (currentWrap === \"true\") {\n modal.footer.find(\"button.btn.btn-light[data-wrap]\").click();\n }\n if (currentFs === \"true\") {\n modal.footer.find(\"button.btn.btn-light[data-fs]\").click();\n }\n if (currentPrettify) {\n modal.footer.find(\"button.btn.btn-light[data-auto-prettify] > i\")\n .removeClass(\"fa-times\")\n .addClass(\"fa-check\");\n }\n return modal;\n};"],"names":["modal","codeEditorInstance","toggleClasses","el","classList","cl","forEach","className","toggle","isLoading","async","createDialogue","footer","find","off","on","evt","target","contains","updatedCode","_codeEditorInstance","getValue","source_view","editor","setContent","hide","setValue","markerNode","document","createElement","innerHTML","add","selection","getStart","append","html","getContent","replace","String","fromCharCode","remove","_codeEditorInstance3","prettifyCode","show","setTimeout","_codeEditorInstance5","focus","data","elementid","Math","random","toString","substring","templateContext","getRoot","addClass","ModalEvents","outsideClick","preventDefault","body","css","header","CodeProEditor","Promise","resolve","require","targetElem","ds","currentTarget","dataset","icon","querySelector","$dlgElem","fs","removeClass","theme","setTheme","wrap","setLineWrapping","undefined","prettify","autoPrettify","hidden","currentTheme","currentWrap","currentFs","currentPrettify","click"],"mappings":"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"} \ No newline at end of file diff --git a/amd/src/commands.js b/amd/src/commands.js index b4ff71d..f63fe8f 100644 --- a/amd/src/commands.js +++ b/amd/src/commands.js @@ -47,13 +47,7 @@ export const getSetup = async() => { editor.ui.registry.addButton(component, { icon, tooltip: pluginName, - onAction: () => handleAction(editor), - enabled: false, - onSetup: (api) => { - const cb = () => api.setEnabled(true); - editor.on('SetContent', cb); - return () => editor.off('SetContent', cb); - } + onAction: () => handleAction(editor) }); // Add the Menu Item. diff --git a/amd/src/plugin.js b/amd/src/plugin.js index c2e484b..6894214 100644 --- a/amd/src/plugin.js +++ b/amd/src/plugin.js @@ -48,9 +48,12 @@ export default new Promise(async(resolve) => { // Register options. registerOptions(editor); // Resolve the Plugin and include configuration. - // Setup commands. - setupCommands(editor); + // Setup commands (only if the content has been set) to prevent from opening the modal without content. + editor.once('SetContent', () => { + setupCommands(editor); + }); return pluginMetadata; }); + resolve([pluginName, Configuration]); }); diff --git a/amd/src/ui.js b/amd/src/ui.js index 4814b3b..3b664be 100644 --- a/amd/src/ui.js +++ b/amd/src/ui.js @@ -40,13 +40,19 @@ const toggleClasses = function(el, classList) { }); }; +let isLoading = false; /** * Handle action * @param {TinyMCE} editor */ export const handleAction = async(editor) => { + if (isLoading) { + return; + } if (modal === null) { - await createDialogue(); + isLoading = true; + modal = await createDialogue(); + isLoading = false; } // Issue, editor var does not get updated @@ -55,12 +61,12 @@ export const handleAction = async(editor) => { $btn.off("click.codepro").on("click.codepro", (evt) => { if (evt.target.classList.contains("btn-primary")) { // eslint-disable-next-line camelcase - const updatedCode = codeEditorInstance.getValue({source_view: true}); - editor.setContent(updatedCode); + const updatedCode = codeEditorInstance?.getValue({source_view: true}); + editor.setContent(updatedCode ?? ''); } modal.hide(); // Delete content - codeEditorInstance.setValue(); + codeEditorInstance?.setValue(); }); // Insert caret marker and retrieve html code to pass to CodeMirror @@ -75,21 +81,37 @@ export const handleAction = async(editor) => { markerNode.remove(); if (getPref("prettify")) { - html = codeEditorInstance.prettifyCode(html); + html = codeEditorInstance?.prettifyCode(html); } - codeEditorInstance.setValue(html); + codeEditorInstance?.setValue(html); modal.show(); - setTimeout(() => codeEditorInstance.focus(), 500); + setTimeout(() => codeEditorInstance?.focus(), 500); }; +/** + * Loads cm6 on demand (The first load will be delayed a little bit) + * @returns {Promise} + */ +const requireCm6Pro = () => { + return new Promise((resolve) => { + require(['tiny_codepro/cm6pro-lazy'], (CodeProEditor) => { + resolve(CodeProEditor); + }); + }); +}; + +/** + * Returns the modal instance + * @returns {Promise} + */ const createDialogue = async() => { const data = { elementid: Math.random().toString(32).substring(2) }; // Show modal with buttons. - modal = await createModal({ + const modal = await createModal({ templateContext: data }); @@ -105,89 +127,84 @@ const createDialogue = async() => { modal.header.css('height', '61.46px'); modal.header.css('padding', '1rem 1rem'); - return new Promise((resolve) => { - // Load cm6 on demand - require(['tiny_codepro/cm6pro-lazy'], (CodeProEditor) => { - const targetElem = modal.body.find('.tiny_codepro-editor-area')[0]; - codeEditorInstance = new CodeProEditor(targetElem); - - modal.footer.find("button.btn.btn-light").on("click", (evt) => { - evt.preventDefault(); - const ds = evt.currentTarget.dataset; - const icon = evt.currentTarget.querySelector("i.fa"); - const $dlgElem = modal.getRoot().find(dialogQuery); - if (ds.fs) { - if (ds.fs === "false") { - // Set fullscreen mode - ds.fs = "true"; - modal.header.hide(); - $dlgElem.removeClass("modal-dialog modal-lg modal-dialog-scrollable"); - $dlgElem.addClass("tiny_codepro-fullscreen"); - } else { - // Set to modal-lg - ds.fs = "false"; - modal.header.show(); - $dlgElem.removeClass("tiny_codepro-fullscreen"); - $dlgElem.addClass("modal-dialog modal-lg modal-dialog-scrollable"); - } - setPref("fs", ds.fs, true); - } else if (ds.theme) { - if (ds.theme === "light") { - ds.theme = "dark"; - codeEditorInstance.setTheme("dark"); - $dlgElem.addClass("tiny_codepro-dark"); - } else { - ds.theme = "light"; - codeEditorInstance.setTheme("light"); - $dlgElem.removeClass("tiny_codepro-dark"); - } - toggleClasses(icon, ["fa-sun-o", "fa-moon-o"]); - setPref("theme", ds.theme, true); - } else if (ds.wrap) { - if (ds.wrap === "true") { - ds.wrap = false; - codeEditorInstance.setLineWrapping(false); - } else { - ds.wrap = true; - codeEditorInstance.setLineWrapping(true); - } - setPref("wrap", ds.wrap, true); - toggleClasses(icon, ["fa-exchange", "fa-long-arrow-right"]); - } else if (ds.prettify !== undefined) { - codeEditorInstance.prettify(); - } else if (ds.autoPrettify !== undefined) { - setPref("prettify", !getPref("prettify", false), true); - const icon = evt.currentTarget.querySelector("i"); - toggleClasses(icon, ["fa-times", "fa-check"]); - } - }); - - modal.getRoot().on(ModalEvents.hidden, () => { - codeEditorInstance.setValue(); - }); - - // Setting stored preferences - const currentTheme = getPref("theme", "light"); - const currentWrap = getPref("wrap", "false"); - const currentFs = getPref("fs", "false"); - const currentPrettify = getPref("prettify", false); - - if (currentTheme !== "light") { - modal.footer.find("button.btn.btn-light[data-theme]").click(); - } - if (currentWrap === "true") { - modal.footer.find("button.btn.btn-light[data-wrap]").click(); + const CodeProEditor = await requireCm6Pro(); + const targetElem = modal.body.find('.tiny_codepro-editor-area')[0]; + codeEditorInstance = new CodeProEditor(targetElem); + + modal.footer.find("button.btn.btn-light").on("click", (evt) => { + evt.preventDefault(); + const ds = evt.currentTarget.dataset; + const icon = evt.currentTarget.querySelector("i.fa"); + const $dlgElem = modal.getRoot().find(dialogQuery); + if (ds.fs) { + if (ds.fs === "false") { + // Set fullscreen mode + ds.fs = "true"; + modal.header.hide(); + $dlgElem.removeClass("modal-dialog modal-lg modal-dialog-scrollable"); + $dlgElem.addClass("tiny_codepro-fullscreen"); + } else { + // Set to modal-lg + ds.fs = "false"; + modal.header.show(); + $dlgElem.removeClass("tiny_codepro-fullscreen"); + $dlgElem.addClass("modal-dialog modal-lg modal-dialog-scrollable"); } - if (currentFs === "true") { - modal.footer.find("button.btn.btn-light[data-fs]").click(); + setPref("fs", ds.fs, true); + } else if (ds.theme) { + if (ds.theme === "light") { + ds.theme = "dark"; + codeEditorInstance.setTheme("dark"); + $dlgElem.addClass("tiny_codepro-dark"); + } else { + ds.theme = "light"; + codeEditorInstance.setTheme("light"); + $dlgElem.removeClass("tiny_codepro-dark"); } - if (currentPrettify) { - modal.footer.find("button.btn.btn-light[data-auto-prettify] > i") - .removeClass("fa-times") - .addClass("fa-check"); + toggleClasses(icon, ["fa-sun-o", "fa-moon-o"]); + setPref("theme", ds.theme, true); + } else if (ds.wrap) { + if (ds.wrap === "true") { + ds.wrap = false; + codeEditorInstance?.setLineWrapping(false); + } else { + ds.wrap = true; + codeEditorInstance?.setLineWrapping(true); } + setPref("wrap", ds.wrap, true); + toggleClasses(icon, ["fa-exchange", "fa-long-arrow-right"]); + } else if (ds.prettify !== undefined) { + codeEditorInstance?.prettify(); + } else if (ds.autoPrettify !== undefined) { + setPref("prettify", !getPref("prettify", false), true); + const icon = evt.currentTarget.querySelector("i"); + toggleClasses(icon, ["fa-times", "fa-check"]); + } + }); - resolve(modal); - }); + modal.getRoot().on(ModalEvents.hidden, () => { + codeEditorInstance?.setValue(); }); + + // Setting stored preferences + const currentTheme = getPref("theme", "light"); + const currentWrap = getPref("wrap", "false"); + const currentFs = getPref("fs", "false"); + const currentPrettify = getPref("prettify", false); + + if (currentTheme !== "light") { + modal.footer.find("button.btn.btn-light[data-theme]").click(); + } + if (currentWrap === "true") { + modal.footer.find("button.btn.btn-light[data-wrap]").click(); + } + if (currentFs === "true") { + modal.footer.find("button.btn.btn-light[data-fs]").click(); + } + if (currentPrettify) { + modal.footer.find("button.btn.btn-light[data-auto-prettify] > i") + .removeClass("fa-times") + .addClass("fa-check"); + } + return modal; }; \ No newline at end of file