diff --git a/amd/build/commands.min.js b/amd/build/commands.min.js index 946045a..56ae9f3 100644 --- a/amd/build/commands.min.js +++ b/amd/build/commands.min.js @@ -1,3 +1,3 @@ -define("tiny_c4l/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[elementsButtonNameTitle,elementsMenuItemNameTitle,buttonImage]=await Promise.all([(0,_str.get_string)("button_elements",_common.component),(0,_str.get_string)("menuitem_elements",_common.component),(0,_utils.getButtonImage)("icon",_common.component)]);return editor=>{(0,_options.isElementsVisible)(editor)&&(editor.ui.registry.addIcon(_common.icon,buttonImage.html),editor.ui.registry.addButton(_common.elementsButtonName,{icon:_common.icon,tooltip:elementsButtonNameTitle,onAction:()=>(0,_ui.handleAction)(editor)}),editor.ui.registry.addMenuItem(_common.elementsMenuItemName,{icon:_common.icon,text:elementsMenuItemNameTitle,onAction:()=>(0,_ui.handleAction)(editor)}),editor.options.set("content_style",(0,_options.getpreviewCSS)(editor)))}}})); +define("tiny_elements/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[elementsButtonNameTitle,elementsMenuItemNameTitle,buttonImage]=await Promise.all([(0,_str.get_string)("button_elements",_common.component),(0,_str.get_string)("menuitem_elements",_common.component),(0,_utils.getButtonImage)("icon",_common.component)]);return editor=>{(0,_options.isElementsVisible)(editor)&&(editor.ui.registry.addIcon(_common.icon,buttonImage.html),editor.ui.registry.addButton(_common.elementsButtonName,{icon:_common.icon,tooltip:elementsButtonNameTitle,onAction:()=>(0,_ui.handleAction)(editor)}),editor.ui.registry.addMenuItem(_common.elementsMenuItemName,{icon:_common.icon,text:elementsMenuItemNameTitle,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 b8de9ea..de75bac 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 Elements commands.\n *\n * @module tiny_elements/commands\n * @copyright 2022 Marc Català \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 {\n component,\n elementsButtonName,\n elementsMenuItemName,\n icon,\n} from './common';\nimport {\n isElementsVisible,\n getpreviewCSS\n} from './options';\n\nexport const getSetup = async() => {\n const [\n elementsButtonNameTitle,\n elementsMenuItemNameTitle,\n buttonImage,\n ] = await Promise.all([\n getString('button_elements', component),\n getString('menuitem_elements', component),\n getButtonImage('icon', component),\n ]);\n\n return (editor) => {\n if (isElementsVisible(editor)) {\n // Register the Elements Icon.\n editor.ui.registry.addIcon(icon, buttonImage.html);\n\n // Register the Elements Toolbar Button.\n editor.ui.registry.addButton(elementsButtonName, {\n icon,\n tooltip: elementsButtonNameTitle,\n onAction: () => handleAction(editor),\n });\n\n // Add the Elements Menu Item.\n // This allows it to be added to a standard menu, or a context menu.\n editor.ui.registry.addMenuItem(elementsMenuItemName, {\n icon,\n text: elementsMenuItemNameTitle,\n onAction: () => handleAction(editor),\n });\n\n // Inject custom CSS.\n editor.options.set('content_style', getpreviewCSS(editor));\n }\n };\n};\n"],"names":["async","elementsButtonNameTitle","elementsMenuItemNameTitle","buttonImage","Promise","all","component","editor","ui","registry","addIcon","icon","html","addButton","elementsButtonName","tooltip","onAction","addMenuItem","elementsMenuItemName","text","options","set"],"mappings":"4PAqCwBA,gBAEhBC,wBACAC,0BACAC,mBACMC,QAAQC,IAAI,EAClB,mBAAU,kBAAmBC,oBAC7B,mBAAU,oBAAqBA,oBAC/B,yBAAe,OAAQA,4BAGnBC,UACA,8BAAkBA,UAElBA,OAAOC,GAAGC,SAASC,QAAQC,aAAMR,YAAYS,MAG7CL,OAAOC,GAAGC,SAASI,UAAUC,2BAAoB,CAC7CH,KAAAA,aACAI,QAASd,wBACTe,SAAU,KAAM,oBAAaT,UAKjCA,OAAOC,GAAGC,SAASQ,YAAYC,6BAAsB,CACjDP,KAAAA,aACAQ,KAAMjB,0BACNc,SAAU,KAAM,oBAAaT,UAIjCA,OAAOa,QAAQC,IAAI,iBAAiB,0BAAcd"} \ 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 Elements commands.\n *\n * @module tiny_elements/commands\n * @copyright 2022 Marc Català \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 {\n component,\n elementsButtonName,\n elementsMenuItemName,\n icon,\n} from './common';\nimport {isElementsVisible} from './options';\n\nexport const getSetup = async() => {\n const [\n elementsButtonNameTitle,\n elementsMenuItemNameTitle,\n buttonImage,\n ] = await Promise.all([\n getString('button_elements', component),\n getString('menuitem_elements', component),\n getButtonImage('icon', component),\n ]);\n\n return (editor) => {\n if (isElementsVisible(editor)) {\n // Register the Elements Icon.\n editor.ui.registry.addIcon(icon, buttonImage.html);\n\n // Register the Elements Toolbar Button.\n editor.ui.registry.addButton(elementsButtonName, {\n icon,\n tooltip: elementsButtonNameTitle,\n onAction: () => handleAction(editor),\n });\n\n // Add the Elements Menu Item.\n // This allows it to be added to a standard menu, or a context menu.\n editor.ui.registry.addMenuItem(elementsMenuItemName, {\n icon,\n text: elementsMenuItemNameTitle,\n onAction: () => handleAction(editor),\n });\n }\n };\n};\n"],"names":["async","elementsButtonNameTitle","elementsMenuItemNameTitle","buttonImage","Promise","all","component","editor","ui","registry","addIcon","icon","html","addButton","elementsButtonName","tooltip","onAction","addMenuItem","elementsMenuItemName","text"],"mappings":"iQAkCwBA,gBAEhBC,wBACAC,0BACAC,mBACMC,QAAQC,IAAI,EAClB,mBAAU,kBAAmBC,oBAC7B,mBAAU,oBAAqBA,oBAC/B,yBAAe,OAAQA,4BAGnBC,UACA,8BAAkBA,UAElBA,OAAOC,GAAGC,SAASC,QAAQC,aAAMR,YAAYS,MAG7CL,OAAOC,GAAGC,SAASI,UAAUC,2BAAoB,CAC7CH,KAAAA,aACAI,QAASd,wBACTe,SAAU,KAAM,oBAAaT,UAKjCA,OAAOC,GAAGC,SAASQ,YAAYC,6BAAsB,CACjDP,KAAAA,aACAQ,KAAMjB,0BACNc,SAAU,KAAM,oBAAaT"} \ No newline at end of file diff --git a/amd/build/common.min.js b/amd/build/common.min.js index 9547fef..05edcda 100644 --- a/amd/build/common.min.js +++ b/amd/build/common.min.js @@ -1,4 +1,4 @@ -define("tiny_c4l/common",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0; +define("tiny_elements/common",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0; /** * Tiny Elements common. * diff --git a/amd/build/configuration.min.js b/amd/build/configuration.min.js index f751f28..ec25c8e 100644 --- a/amd/build/configuration.min.js +++ b/amd/build/configuration.min.js @@ -1,4 +1,4 @@ -define("tiny_c4l/configuration",["exports","./common","editor_tiny/utils"],(function(_exports,_common,_utils){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.configure=void 0; +define("tiny_elements/configuration",["exports","./common","editor_tiny/utils"],(function(_exports,_common,_utils){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.configure=void 0; /** * Tiny Elements configuration. * diff --git a/amd/build/helper.min.js b/amd/build/helper.min.js index 658bbdc..2fc63c6 100644 --- a/amd/build/helper.min.js +++ b/amd/build/helper.min.js @@ -1,3 +1,3 @@ -define("tiny_c4l/helper",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.findByName=_exports.findById=void 0;_exports.findById=(set,id)=>set.find((element=>void 0!==element&&element.id==id));_exports.findByName=(set,name)=>set.find((element=>void 0!==element&&element.name==name))})); +define("tiny_elements/helper",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.findByName=_exports.findById=void 0;_exports.findById=(set,id)=>set.find((element=>void 0!==element&&element.id==id));_exports.findByName=(set,name)=>set.find((element=>void 0!==element&&element.name==name))})); //# sourceMappingURL=helper.min.js.map \ No newline at end of file diff --git a/amd/build/helper.min.js.map b/amd/build/helper.min.js.map index f6a26ea..2bb62a3 100644 --- a/amd/build/helper.min.js.map +++ b/amd/build/helper.min.js.map @@ -1 +1 @@ -{"version":3,"file":"helper.min.js","sources":["../src/helper.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 * Some helper functions for tiny_elements.\n *\n * @module tiny_elements/helper\n * @copyright 2024 ISB Bayern\n * @author Stefan Hanauska\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nexport const findById = (set, id) => {\n return set.find((element) => element !== undefined && element.id == id);\n};\n\nexport const findByName = (set, name) => {\n return set.find((element) => element !== undefined && element.name == name);\n};"],"names":["set","id","find","element","undefined","name"],"mappings":"gLAwBwB,CAACA,IAAKC,KACnBD,IAAIE,MAAMC,cAAwBC,IAAZD,SAAyBA,QAAQF,IAAMA,yBAG9C,CAACD,IAAKK,OACrBL,IAAIE,MAAMC,cAAwBC,IAAZD,SAAyBA,QAAQE,MAAQA"} \ No newline at end of file +{"version":3,"file":"helper.min.js","sources":["../src/helper.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 * Some helper functions for tiny_elements.\n *\n * @module tiny_elements/helper\n * @copyright 2024 ISB Bayern\n * @author Stefan Hanauska\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nexport const findById = (set, id) => {\n return set.find((element) => element !== undefined && element.id == id);\n};\n\nexport const findByName = (set, name) => {\n return set.find((element) => element !== undefined && element.name == name);\n};"],"names":["set","id","find","element","undefined","name"],"mappings":"qLAwBwB,CAACA,IAAKC,KACnBD,IAAIE,MAAMC,cAAwBC,IAAZD,SAAyBA,QAAQF,IAAMA,yBAG9C,CAACD,IAAKK,OACrBL,IAAIE,MAAMC,cAAwBC,IAAZD,SAAyBA,QAAQE,MAAQA"} \ No newline at end of file diff --git a/amd/build/management.min.js b/amd/build/management.min.js index 0b4da08..a7300d2 100644 --- a/amd/build/management.min.js +++ b/amd/build/management.min.js @@ -1,3 +1,3 @@ -define("tiny_c4l/management",["exports","core/modal","core_form/modalform","core/str","core/notification","core/ajax"],(function(_exports,_modal,_modalform,_str,_notification,_ajax){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=_exports.deleteItem=void 0,_modal=_interopRequireDefault(_modal),_modalform=_interopRequireDefault(_modalform);class PreviewModal extends _modal.default{configure(modalConfig){modalConfig.removeOnClose=!0,modalConfig.large=!0,super.configure(modalConfig)}}_defineProperty(PreviewModal,"TYPE","tiny_elements/management_preview"),_defineProperty(PreviewModal,"TEMPLATE","tiny_elements/management_preview");function showModal(e,id,table){let title;e.preventDefault(),title=0==id?(0,_str.get_string)("additem","tiny_elements"):(0,_str.get_string)("edititem","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_"+table+"_form",args:{id:id},modalConfig:{title:title}});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>function(form){if(!form.elements.id.value){const compcat=document.querySelector(".compcat.active"),currentUrl=new URL(window.location.href);currentUrl.searchParams.set("compcat",compcat.dataset.compcat),window.location.href=currentUrl.toString()}}(modalForm.getFormNode()))),modalForm.show()}_exports.init=async params=>{if(document.getElementById("elements_import").addEventListener("click",(async e=>{!function(e){e.preventDefault();let title=(0,_str.get_string)("import","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_import_form",args:{},modalConfig:{title:title}});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>location.reload())),modalForm.show()}(e)})),document.getElementsByClassName("add").forEach((element=>{element.addEventListener("click",(async e=>{showModal(e,element.dataset.id,element.dataset.table)}))})),document.getElementsByClassName("edit").forEach((element=>{element.addEventListener("click",(async e=>{showModal(e,element.dataset.id,element.dataset.table)}))})),document.getElementsByClassName("delete").forEach((element=>{element.addEventListener("click",(async e=>{!function(e,id,title,table){e.preventDefault(),(0,_notification.deleteCancelPromise)((0,_str.get_string)("delete","tiny_elements",title),(0,_str.get_string)("deletewarning","tiny_elements")).then((async()=>{if(0!==id)try{if(await deleteItem(id,table)){const link=document.querySelector('[data-table="'+table+'"][data-id="'+id+'"]');if(link){link.closest(".item").remove()}}}catch(error){(0,_notification.exception)(error)}})).catch((()=>{}))}(e,element.dataset.id,element.dataset.title,element.dataset.table)}))})),document.getElementsByClassName("preview").forEach((element=>{element.addEventListener("click",(async e=>{!async function(e){e.preventDefault();let preview=e.target.closest(".preview");(await PreviewModal.create({templateContext:{component:preview.dataset.component,flavors:preview.dataset.flavors.trim().split(" "),config:M.cfg}})).show()}(e)}))})),document.getElementsByClassName("compcat").forEach((element=>{element.addEventListener("click",(async e=>{showItems(e,element.dataset.compcat)}))})),document.getElementById("elements_compflavor_button").addEventListener("click",(async e=>{!function(e){e.preventDefault();let title=(0,_str.get_string)("manage","tiny_elements");new _modalform.default({formClass:"tiny_elements\\form\\management_comp_flavor_form",args:{},modalConfig:{title:title}}).show()}(e)})),document.querySelectorAll(".flavor .card-body > .clickingextended, .component .card-body > .clickingextended, .variant .card-body > .clickingextended").forEach((element=>{element.addEventListener("click",(async e=>{e.target.closest(".item").querySelector("a.edit").click()}))})),params.compcatactive){let compcat=document.querySelector('.compcat[data-compcat="'+params.compcatactive+'"]');compcat&&(showItems(!1,params.compcatactive),compcat.classList.add("active"))}};const deleteItem=(id,table)=>(0,_ajax.call)([{methodname:"tiny_elements_delete_item",args:{id:id,table:table}}])[0];function showItems(e,compcat){document.querySelectorAll(".flavor, .component, .variant").forEach((element=>{element.classList.add("hidden")}));let itemsShow=document.getElementsByClassName(compcat),usedFlavors=[];itemsShow.forEach((element=>{if(element.classList.remove("hidden"),void 0!==element.dataset.flavors){let flavors=element.dataset.flavors.split(" ");for(let value of flavors)usedFlavors.includes(value)||0==value.length||usedFlavors.push(value)}}));let flavorstring=usedFlavors.map((item=>".".concat(item))).join(", ");if(flavorstring.length){document.querySelectorAll(flavorstring).forEach((element=>{element.classList.remove("hidden")}))}if(document.getElementsByClassName("addcontainer").forEach((element=>{element.classList.remove("hidden")})),e){document.getElementsByClassName("compcat").forEach((element=>{element.classList.remove("active")})),e.target.closest(".compcat").classList.add("active")}if("found-items"==compcat){let found=document.querySelector('.compcat[data-compcat="found-items"]');if(found.dataset.loneflavors.length){document.querySelectorAll(found.dataset.loneflavors).forEach((element=>{element.classList.remove("hidden")}))}if(found.dataset.lonevariants.length){document.querySelectorAll(found.dataset.lonevariants).forEach((element=>{element.classList.remove("hidden")}))}if(found.dataset.lonecomponents.length){document.querySelectorAll(found.dataset.lonecomponents).forEach((element=>{element.classList.remove("hidden")}))}}}_exports.deleteItem=deleteItem})); +define("tiny_elements/management",["exports","core/modal","core_form/modalform","core/str","core/notification","core/ajax"],(function(_exports,_modal,_modalform,_str,_notification,_ajax){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=_exports.deleteItem=void 0,_modal=_interopRequireDefault(_modal),_modalform=_interopRequireDefault(_modalform);class PreviewModal extends _modal.default{configure(modalConfig){modalConfig.removeOnClose=!0,modalConfig.large=!0,super.configure(modalConfig)}}_defineProperty(PreviewModal,"TYPE","tiny_elements/management_preview"),_defineProperty(PreviewModal,"TEMPLATE","tiny_elements/management_preview");function showModal(e,id,table){let title;e.preventDefault(),title=0==id?(0,_str.get_string)("additem","tiny_elements"):(0,_str.get_string)("edititem","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_"+table+"_form",args:{id:id},modalConfig:{title:title}});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>function(form){if(!form.elements.id.value){const compcat=document.querySelector(".compcat.active"),currentUrl=new URL(window.location.href);currentUrl.searchParams.set("compcat",compcat.dataset.compcat),window.location.href=currentUrl.toString()}}(modalForm.getFormNode()))),modalForm.show()}_exports.init=async params=>{if(document.getElementById("elements_import").addEventListener("click",(async e=>{!function(e){e.preventDefault();let title=(0,_str.get_string)("import","tiny_elements");const modalForm=new _modalform.default({formClass:"tiny_elements\\form\\management_import_form",args:{},modalConfig:{title:title}});modalForm.addEventListener(modalForm.events.FORM_SUBMITTED,(()=>location.reload())),modalForm.show()}(e)})),document.getElementsByClassName("add").forEach((element=>{element.addEventListener("click",(async e=>{showModal(e,element.dataset.id,element.dataset.table)}))})),document.getElementsByClassName("edit").forEach((element=>{element.addEventListener("click",(async e=>{showModal(e,element.dataset.id,element.dataset.table)}))})),document.getElementsByClassName("delete").forEach((element=>{element.addEventListener("click",(async e=>{!function(e,id,title,table){e.preventDefault(),(0,_notification.deleteCancelPromise)((0,_str.get_string)("delete","tiny_elements",title),(0,_str.get_string)("deletewarning","tiny_elements")).then((async()=>{if(0!==id)try{if(await deleteItem(id,table)){const link=document.querySelector('[data-table="'+table+'"][data-id="'+id+'"]');if(link){link.closest(".item").remove()}}}catch(error){(0,_notification.exception)(error)}})).catch((()=>{}))}(e,element.dataset.id,element.dataset.title,element.dataset.table)}))})),document.getElementsByClassName("preview").forEach((element=>{element.addEventListener("click",(async e=>{!async function(e){e.preventDefault();let preview=e.target.closest(".preview");(await PreviewModal.create({templateContext:{component:preview.dataset.component,flavors:preview.dataset.flavors.trim().split(" "),config:M.cfg}})).show()}(e)}))})),document.getElementsByClassName("compcat").forEach((element=>{element.addEventListener("click",(async e=>{showItems(e,element.dataset.compcat)}))})),document.getElementById("elements_compflavor_button").addEventListener("click",(async e=>{!function(e){e.preventDefault();let title=(0,_str.get_string)("manage","tiny_elements");new _modalform.default({formClass:"tiny_elements\\form\\management_comp_flavor_form",args:{},modalConfig:{title:title}}).show()}(e)})),document.querySelectorAll(".flavor .card-body > .clickingextended, .component .card-body > .clickingextended, .variant .card-body > .clickingextended").forEach((element=>{element.addEventListener("click",(async e=>{e.target.closest(".item").querySelector("a.edit").click()}))})),params.compcatactive){let compcat=document.querySelector('.compcat[data-compcat="'+params.compcatactive+'"]');compcat&&(showItems(!1,params.compcatactive),compcat.classList.add("active"))}};const deleteItem=(id,table)=>(0,_ajax.call)([{methodname:"tiny_elements_delete_item",args:{id:id,table:table}}])[0];function showItems(e,compcat){document.querySelectorAll(".flavor, .component, .variant").forEach((element=>{element.classList.add("hidden")}));let itemsShow=document.getElementsByClassName(compcat),usedFlavors=[];itemsShow.forEach((element=>{if(element.classList.remove("hidden"),void 0!==element.dataset.flavors){let flavors=element.dataset.flavors.split(" ");for(let value of flavors)usedFlavors.includes(value)||0==value.length||usedFlavors.push(value)}}));let flavorstring=usedFlavors.map((item=>".".concat(item))).join(", ");if(flavorstring.length){document.querySelectorAll(flavorstring).forEach((element=>{element.classList.remove("hidden")}))}if(document.getElementsByClassName("addcontainer").forEach((element=>{element.classList.remove("hidden")})),e){document.getElementsByClassName("compcat").forEach((element=>{element.classList.remove("active")})),e.target.closest(".compcat").classList.add("active")}if("found-items"==compcat){let found=document.querySelector('.compcat[data-compcat="found-items"]');if(found.dataset.loneflavors.length){document.querySelectorAll(found.dataset.loneflavors).forEach((element=>{element.classList.remove("hidden")}))}if(found.dataset.lonevariants.length){document.querySelectorAll(found.dataset.lonevariants).forEach((element=>{element.classList.remove("hidden")}))}if(found.dataset.lonecomponents.length){document.querySelectorAll(found.dataset.lonecomponents).forEach((element=>{element.classList.remove("hidden")}))}}}_exports.deleteItem=deleteItem})); //# sourceMappingURL=management.min.js.map \ No newline at end of file diff --git a/amd/build/management.min.js.map b/amd/build/management.min.js.map index 10c560d..dece49a 100644 --- a/amd/build/management.min.js.map +++ b/amd/build/management.min.js.map @@ -1 +1 @@ -{"version":3,"file":"management.min.js","sources":["../src/management.js"],"sourcesContent":["import Modal from 'core/modal';\nimport ModalForm from 'core_form/modalform';\nimport {get_string as getString} from 'core/str';\nimport {exception as displayException, deleteCancelPromise} from 'core/notification';\nimport {call as fetchMany} from 'core/ajax';\n\nclass PreviewModal extends Modal {\n static TYPE = \"tiny_elements/management_preview\";\n static TEMPLATE = \"tiny_elements/management_preview\";\n configure(modalConfig) {\n modalConfig.removeOnClose = true;\n modalConfig.large = true;\n super.configure(modalConfig);\n }\n}\n\nexport const init = async(params) => {\n\n // Add listener to import xml files.\n let importxml = document.getElementById('elements_import');\n importxml.addEventListener('click', async(e) => {\n importModal(e);\n });\n\n // Add listener for adding a new item.\n let additem = document.getElementsByClassName('add');\n additem.forEach(element => {\n element.addEventListener('click', async(e) => {\n showModal(e, element.dataset.id, element.dataset.table);\n });\n });\n\n // Add listener to edit items.\n let edititems = document.getElementsByClassName('edit');\n edititems.forEach(element => {\n element.addEventListener('click', async(e) => {\n showModal(e, element.dataset.id, element.dataset.table);\n });\n });\n\n // Add listener to delete items.\n let deleteitems = document.getElementsByClassName('delete');\n deleteitems.forEach(element => {\n element.addEventListener('click', async(e) => {\n deleteModal(e, element.dataset.id, element.dataset.title, element.dataset.table);\n });\n });\n\n // Add listener to preview items.\n let previewitems = document.getElementsByClassName('preview');\n previewitems.forEach(element => {\n element.addEventListener('click', async(e) => {\n previewModal(e);\n });\n });\n\n // Add listener to select compcat to show corresponding items.\n let compcats = document.getElementsByClassName('compcat');\n compcats.forEach(element => {\n element.addEventListener('click', async(e) => {\n showItems(e, element.dataset.compcat);\n });\n });\n\n // Add listener to manage component flavor relation.\n let compflavor = document.getElementById('elements_compflavor_button');\n compflavor.addEventListener('click', async(e) => {\n compflavorModal(e);\n });\n\n // Add image and text to item setting click area.\n let enlargeItems = document.querySelectorAll(\n '.flavor .card-body > .clickingextended, .component .card-body > .clickingextended, .variant .card-body > .clickingextended'\n );\n enlargeItems.forEach(element => {\n element.addEventListener('click', async(e) => {\n let item = e.target.closest('.item');\n item.querySelector('a.edit').click();\n });\n });\n\n // After submitting a new item, reset active compcat.\n if (params.compcatactive) {\n let compcat = document.querySelector('.compcat[data-compcat=\"' + params.compcatactive + '\"]');\n if (compcat) {\n showItems(false, params.compcatactive);\n compcat.classList.add('active');\n }\n }\n};\n\n/**\n * Show dynamic form to add/edit a source.\n * @param {*} e\n * @param {*} id\n * @param {*} table\n */\nfunction showModal(e, id, table) {\n e.preventDefault();\n let title;\n if (id == 0) {\n title = getString('additem', 'tiny_elements');\n } else {\n title = getString('edititem', 'tiny_elements');\n }\n\n const modalForm = new ModalForm({\n // Set formclass, depending on component.\n formClass: \"tiny_elements\\\\form\\\\management_\" + table + \"_form\",\n args: {\n id: id,\n },\n modalConfig: { title: title },\n });\n // Conditional reload page after submit.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => reloadIfNew(modalForm.getFormNode()));\n\n modalForm.show();\n}\n\n/**\n * Show modal to preview css version.\n * @param {*} e\n */\nasync function previewModal(e) {\n e.preventDefault();\n let preview = e.target.closest(\".preview\");\n const modal = await PreviewModal.create({\n templateContext: {\n component: preview.dataset.component,\n flavors: preview.dataset.flavors.trim().split(\" \"),\n config: M.cfg,\n },\n });\n modal.show();\n}\n\n/**\n * Show dynamic form to import xml backups.\n * @param {*} e\n */\nfunction importModal(e) {\n e.preventDefault();\n let title = getString('import', 'tiny_elements');\n\n const modalForm = new ModalForm({\n // Load import form.\n formClass: \"tiny_elements\\\\form\\\\management_import_form\",\n args: {},\n modalConfig: { title: title },\n });\n // Reload page after submit.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => location.reload());\n\n modalForm.show();\n}\n\n/**\n * Load modal to edit icon urls.\n * @param {*} e\n */\nfunction compflavorModal(e) {\n e.preventDefault();\n let title = getString('manage', 'tiny_elements');\n\n const modalForm = new ModalForm({\n // Load import form.\n formClass: \"tiny_elements\\\\form\\\\management_comp_flavor_form\",\n args: {},\n modalConfig: { title: title },\n });\n\n modalForm.show();\n}\n\n/**\n * Show dynamic form to delete a source.\n * @param {*} e\n * @param {*} id\n * @param {*} title\n * @param {*} table\n */\nfunction deleteModal(e, id, title, table) {\n e.preventDefault();\n\n deleteCancelPromise(\n getString('delete', 'tiny_elements', title),\n getString('deletewarning', 'tiny_elements'),\n ).then(async () => {\n if (id !== 0) {\n try {\n const deleted = await deleteItem(id, table);\n if (deleted) {\n const link = document.querySelector('[data-table=\"' + table + '\"][data-id=\"' + id + '\"]');\n if (link) {\n const card = link.closest(\".item\");\n card.remove();\n }\n }\n } catch (error) {\n displayException(error);\n }\n }\n return;\n }).catch(() => {\n return;\n });\n}\n\n/**\n * Delete elements items.\n * @param {*} id\n * @param {*} table\n * @returns {mixed}\n */\nexport const deleteItem = (\n id,\n table,\n) => fetchMany(\n [{\n methodname: 'tiny_elements_delete_item',\n args: {\n id,\n table,\n }\n }])[0];\n\n/**\n * Show items after clicking a compcat.\n * @param {*} e\n * @param {*} compcat\n */\nfunction showItems(e, compcat) {\n // But first hide all items.\n let itemsHide = document.querySelectorAll('.flavor, .component, .variant');\n itemsHide.forEach(element => {\n element.classList.add('hidden');\n });\n\n // Show component and variants with compcat name and read the flavors.\n let itemsShow = document.getElementsByClassName(compcat);\n let usedFlavors = [];\n itemsShow.forEach(element => {\n element.classList.remove('hidden');\n // Get all flavors to show if on compcat element.\n if (typeof element.dataset.flavors !== 'undefined') {\n let flavors = element.dataset.flavors.split(' ');\n for (let value of flavors) {\n if (!usedFlavors.includes(value) && value.length != 0) {\n usedFlavors.push(value);\n }\n }\n }\n });\n\n // Show the flavors.\n let flavorstring = usedFlavors.map(item => `.${item}`).join(', ');\n if (flavorstring.length) {\n let flavorsShow = document.querySelectorAll(flavorstring);\n flavorsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n\n // Show add buttons.\n let addsShow = document.getElementsByClassName('addcontainer');\n addsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n\n // Unmark all and mark clicked compcat.\n if (e) {\n let items = document.getElementsByClassName('compcat');\n items.forEach(element => {\n element.classList.remove('active');\n });\n let item = e.target.closest('.compcat');\n item.classList.add('active');\n }\n\n // Special case, unassigned items, show all items without connection to compcat.\n if (compcat == 'found-items') {\n let found = document.querySelector('.compcat[data-compcat=\"found-items\"]');\n if (found.dataset.loneflavors.length) {\n let flavorsShow = document.querySelectorAll(found.dataset.loneflavors);\n flavorsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n if (found.dataset.lonevariants.length) {\n let variantsShow = document.querySelectorAll(found.dataset.lonevariants);\n variantsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n if (found.dataset.lonecomponents.length) {\n let componentsShow = document.querySelectorAll(found.dataset.lonecomponents);\n componentsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n }\n}\n\n/**\n * Reload for new items.\n * @param {*} form\n */\nfunction reloadIfNew(form) {\n // Newly created element without id?\n if (!form.elements['id'].value) {\n // Reload page with active compcat.\n const compcat = document.querySelector('.compcat.active');\n const currentUrl = new URL(window.location.href);\n currentUrl.searchParams.set('compcat', compcat.dataset.compcat);\n window.location.href = currentUrl.toString();\n }\n}\n"],"names":["PreviewModal","Modal","configure","modalConfig","removeOnClose","large","showModal","e","id","table","title","preventDefault","modalForm","ModalForm","formClass","args","addEventListener","events","FORM_SUBMITTED","form","elements","value","compcat","document","querySelector","currentUrl","URL","window","location","href","searchParams","set","dataset","toString","reloadIfNew","getFormNode","show","async","getElementById","reload","importModal","getElementsByClassName","forEach","element","then","deleteItem","link","closest","remove","error","catch","deleteModal","preview","target","create","templateContext","component","flavors","trim","split","config","M","cfg","previewModal","showItems","compflavorModal","querySelectorAll","click","params","compcatactive","classList","add","methodname","itemsShow","usedFlavors","includes","length","push","flavorstring","map","item","join","found","loneflavors","lonevariants","lonecomponents"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"management.min.js","sources":["../src/management.js"],"sourcesContent":["import Modal from 'core/modal';\nimport ModalForm from 'core_form/modalform';\nimport {get_string as getString} from 'core/str';\nimport {exception as displayException, deleteCancelPromise} from 'core/notification';\nimport {call as fetchMany} from 'core/ajax';\n\nclass PreviewModal extends Modal {\n static TYPE = \"tiny_elements/management_preview\";\n static TEMPLATE = \"tiny_elements/management_preview\";\n configure(modalConfig) {\n modalConfig.removeOnClose = true;\n modalConfig.large = true;\n super.configure(modalConfig);\n }\n}\n\nexport const init = async(params) => {\n\n // Add listener to import xml files.\n let importxml = document.getElementById('elements_import');\n importxml.addEventListener('click', async(e) => {\n importModal(e);\n });\n\n // Add listener for adding a new item.\n let additem = document.getElementsByClassName('add');\n additem.forEach(element => {\n element.addEventListener('click', async(e) => {\n showModal(e, element.dataset.id, element.dataset.table);\n });\n });\n\n // Add listener to edit items.\n let edititems = document.getElementsByClassName('edit');\n edititems.forEach(element => {\n element.addEventListener('click', async(e) => {\n showModal(e, element.dataset.id, element.dataset.table);\n });\n });\n\n // Add listener to delete items.\n let deleteitems = document.getElementsByClassName('delete');\n deleteitems.forEach(element => {\n element.addEventListener('click', async(e) => {\n deleteModal(e, element.dataset.id, element.dataset.title, element.dataset.table);\n });\n });\n\n // Add listener to preview items.\n let previewitems = document.getElementsByClassName('preview');\n previewitems.forEach(element => {\n element.addEventListener('click', async(e) => {\n previewModal(e);\n });\n });\n\n // Add listener to select compcat to show corresponding items.\n let compcats = document.getElementsByClassName('compcat');\n compcats.forEach(element => {\n element.addEventListener('click', async(e) => {\n showItems(e, element.dataset.compcat);\n });\n });\n\n // Add listener to manage component flavor relation.\n let compflavor = document.getElementById('elements_compflavor_button');\n compflavor.addEventListener('click', async(e) => {\n compflavorModal(e);\n });\n\n // Add image and text to item setting click area.\n let enlargeItems = document.querySelectorAll(\n '.flavor .card-body > .clickingextended, .component .card-body > .clickingextended, .variant .card-body > .clickingextended'\n );\n enlargeItems.forEach(element => {\n element.addEventListener('click', async(e) => {\n let item = e.target.closest('.item');\n item.querySelector('a.edit').click();\n });\n });\n\n // After submitting a new item, reset active compcat.\n if (params.compcatactive) {\n let compcat = document.querySelector('.compcat[data-compcat=\"' + params.compcatactive + '\"]');\n if (compcat) {\n showItems(false, params.compcatactive);\n compcat.classList.add('active');\n }\n }\n};\n\n/**\n * Show dynamic form to add/edit a source.\n * @param {*} e\n * @param {*} id\n * @param {*} table\n */\nfunction showModal(e, id, table) {\n e.preventDefault();\n let title;\n if (id == 0) {\n title = getString('additem', 'tiny_elements');\n } else {\n title = getString('edititem', 'tiny_elements');\n }\n\n const modalForm = new ModalForm({\n // Set formclass, depending on component.\n formClass: \"tiny_elements\\\\form\\\\management_\" + table + \"_form\",\n args: {\n id: id,\n },\n modalConfig: { title: title },\n });\n // Conditional reload page after submit.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => reloadIfNew(modalForm.getFormNode()));\n\n modalForm.show();\n}\n\n/**\n * Show modal to preview css version.\n * @param {*} e\n */\nasync function previewModal(e) {\n e.preventDefault();\n let preview = e.target.closest(\".preview\");\n const modal = await PreviewModal.create({\n templateContext: {\n component: preview.dataset.component,\n flavors: preview.dataset.flavors.trim().split(\" \"),\n config: M.cfg,\n },\n });\n modal.show();\n}\n\n/**\n * Show dynamic form to import xml backups.\n * @param {*} e\n */\nfunction importModal(e) {\n e.preventDefault();\n let title = getString('import', 'tiny_elements');\n\n const modalForm = new ModalForm({\n // Load import form.\n formClass: \"tiny_elements\\\\form\\\\management_import_form\",\n args: {},\n modalConfig: { title: title },\n });\n // Reload page after submit.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, () => location.reload());\n\n modalForm.show();\n}\n\n/**\n * Load modal to edit icon urls.\n * @param {*} e\n */\nfunction compflavorModal(e) {\n e.preventDefault();\n let title = getString('manage', 'tiny_elements');\n\n const modalForm = new ModalForm({\n // Load import form.\n formClass: \"tiny_elements\\\\form\\\\management_comp_flavor_form\",\n args: {},\n modalConfig: { title: title },\n });\n\n modalForm.show();\n}\n\n/**\n * Show dynamic form to delete a source.\n * @param {*} e\n * @param {*} id\n * @param {*} title\n * @param {*} table\n */\nfunction deleteModal(e, id, title, table) {\n e.preventDefault();\n\n deleteCancelPromise(\n getString('delete', 'tiny_elements', title),\n getString('deletewarning', 'tiny_elements'),\n ).then(async () => {\n if (id !== 0) {\n try {\n const deleted = await deleteItem(id, table);\n if (deleted) {\n const link = document.querySelector('[data-table=\"' + table + '\"][data-id=\"' + id + '\"]');\n if (link) {\n const card = link.closest(\".item\");\n card.remove();\n }\n }\n } catch (error) {\n displayException(error);\n }\n }\n return;\n }).catch(() => {\n return;\n });\n}\n\n/**\n * Delete elements items.\n * @param {*} id\n * @param {*} table\n * @returns {mixed}\n */\nexport const deleteItem = (\n id,\n table,\n) => fetchMany(\n [{\n methodname: 'tiny_elements_delete_item',\n args: {\n id,\n table,\n }\n }])[0];\n\n/**\n * Show items after clicking a compcat.\n * @param {*} e\n * @param {*} compcat\n */\nfunction showItems(e, compcat) {\n // But first hide all items.\n let itemsHide = document.querySelectorAll('.flavor, .component, .variant');\n itemsHide.forEach(element => {\n element.classList.add('hidden');\n });\n\n // Show component and variants with compcat name and read the flavors.\n let itemsShow = document.getElementsByClassName(compcat);\n let usedFlavors = [];\n itemsShow.forEach(element => {\n element.classList.remove('hidden');\n // Get all flavors to show if on compcat element.\n if (typeof element.dataset.flavors !== 'undefined') {\n let flavors = element.dataset.flavors.split(' ');\n for (let value of flavors) {\n if (!usedFlavors.includes(value) && value.length != 0) {\n usedFlavors.push(value);\n }\n }\n }\n });\n\n // Show the flavors.\n let flavorstring = usedFlavors.map(item => `.${item}`).join(', ');\n if (flavorstring.length) {\n let flavorsShow = document.querySelectorAll(flavorstring);\n flavorsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n\n // Show add buttons.\n let addsShow = document.getElementsByClassName('addcontainer');\n addsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n\n // Unmark all and mark clicked compcat.\n if (e) {\n let items = document.getElementsByClassName('compcat');\n items.forEach(element => {\n element.classList.remove('active');\n });\n let item = e.target.closest('.compcat');\n item.classList.add('active');\n }\n\n // Special case, unassigned items, show all items without connection to compcat.\n if (compcat == 'found-items') {\n let found = document.querySelector('.compcat[data-compcat=\"found-items\"]');\n if (found.dataset.loneflavors.length) {\n let flavorsShow = document.querySelectorAll(found.dataset.loneflavors);\n flavorsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n if (found.dataset.lonevariants.length) {\n let variantsShow = document.querySelectorAll(found.dataset.lonevariants);\n variantsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n if (found.dataset.lonecomponents.length) {\n let componentsShow = document.querySelectorAll(found.dataset.lonecomponents);\n componentsShow.forEach(element => {\n element.classList.remove('hidden');\n });\n }\n }\n}\n\n/**\n * Reload for new items.\n * @param {*} form\n */\nfunction reloadIfNew(form) {\n // Newly created element without id?\n if (!form.elements['id'].value) {\n // Reload page with active compcat.\n const compcat = document.querySelector('.compcat.active');\n const currentUrl = new URL(window.location.href);\n currentUrl.searchParams.set('compcat', compcat.dataset.compcat);\n window.location.href = currentUrl.toString();\n }\n}\n"],"names":["PreviewModal","Modal","configure","modalConfig","removeOnClose","large","showModal","e","id","table","title","preventDefault","modalForm","ModalForm","formClass","args","addEventListener","events","FORM_SUBMITTED","form","elements","value","compcat","document","querySelector","currentUrl","URL","window","location","href","searchParams","set","dataset","toString","reloadIfNew","getFormNode","show","async","getElementById","reload","importModal","getElementsByClassName","forEach","element","then","deleteItem","link","closest","remove","error","catch","deleteModal","preview","target","create","templateContext","component","flavors","trim","split","config","M","cfg","previewModal","showItems","compflavorModal","querySelectorAll","click","params","compcatactive","classList","add","methodname","itemsShow","usedFlavors","includes","length","push","flavorstring","map","item","join","found","loneflavors","lonevariants","lonecomponents"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/modal.min.js b/amd/build/modal.min.js index 055808e..19aa0ca 100644 --- a/amd/build/modal.min.js +++ b/amd/build/modal.min.js @@ -1,3 +1,3 @@ -define("tiny_c4l/modal",["exports","core/modal","core/modal_registry"],(function(_exports,_modal,_modal_registry){var _class;function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_modal=_interopRequireDefault(_modal),_modal_registry=_interopRequireDefault(_modal_registry);const ElementsModal=(_defineProperty(_class=class extends _modal.default{configure(modalConfig){modalConfig.removeOnClose=!0,super.configure(modalConfig)}registerEventListeners(){super.registerEventListeners()}},"TYPE","tiny_elements/modal"),_defineProperty(_class,"TEMPLATE","tiny_elements/modal"),_class);_modal_registry.default.register(ElementsModal.TYPE,ElementsModal,ElementsModal.TEMPLATE);var _default=ElementsModal;return _exports.default=_default,_exports.default})); +define("tiny_elements/modal",["exports","core/modal","core/modal_registry"],(function(_exports,_modal,_modal_registry){var _class;function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_modal=_interopRequireDefault(_modal),_modal_registry=_interopRequireDefault(_modal_registry);const ElementsModal=(_defineProperty(_class=class extends _modal.default{configure(modalConfig){modalConfig.removeOnClose=!0,super.configure(modalConfig)}registerEventListeners(){super.registerEventListeners()}},"TYPE","tiny_elements/modal"),_defineProperty(_class,"TEMPLATE","tiny_elements/modal"),_class);_modal_registry.default.register(ElementsModal.TYPE,ElementsModal,ElementsModal.TEMPLATE);var _default=ElementsModal;return _exports.default=_default,_exports.default})); //# sourceMappingURL=modal.min.js.map \ No newline at end of file diff --git a/amd/build/modal.min.js.map b/amd/build/modal.min.js.map index 98c2d9a..45a1122 100644 --- a/amd/build/modal.min.js.map +++ b/amd/build/modal.min.js.map @@ -1 +1 @@ -{"version":3,"file":"modal.min.js","sources":["../src/modal.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 * Elements Modal for Tiny.\n *\n * @module tiny_elements/modal\n * @copyright 2022 Marc Català \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Modal from 'core/modal';\nimport ModalRegistry from 'core/modal_registry';\n\nconst ElementsModal = class extends Modal {\n static TYPE = 'tiny_elements/modal';\n static TEMPLATE = 'tiny_elements/modal';\n\n configure(modalConfig) {\n // Remove modal from DOM on close.\n modalConfig.removeOnClose = true;\n super.configure(modalConfig);\n }\n\n registerEventListeners() {\n // Call the parent registration.\n super.registerEventListeners();\n }\n};\n\nModalRegistry.register(ElementsModal.TYPE, ElementsModal, ElementsModal.TEMPLATE);\n\nexport default ElementsModal;\n"],"names":["ElementsModal","Modal","configure","modalConfig","removeOnClose","registerEventListeners","register","TYPE","TEMPLATE"],"mappings":"uiBA0BMA,sCAAgB,cAAcC,eAIhCC,UAAUC,aAENA,YAAYC,eAAgB,QACtBF,UAAUC,aAGpBE,+BAEUA,kCAXI,yDACI,uDAcRC,SAASN,cAAcO,KAAMP,cAAeA,cAAcQ,uBAEzDR"} \ No newline at end of file +{"version":3,"file":"modal.min.js","sources":["../src/modal.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 * Elements Modal for Tiny.\n *\n * @module tiny_elements/modal\n * @copyright 2022 Marc Català \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Modal from 'core/modal';\nimport ModalRegistry from 'core/modal_registry';\n\nconst ElementsModal = class extends Modal {\n static TYPE = 'tiny_elements/modal';\n static TEMPLATE = 'tiny_elements/modal';\n\n configure(modalConfig) {\n // Remove modal from DOM on close.\n modalConfig.removeOnClose = true;\n super.configure(modalConfig);\n }\n\n registerEventListeners() {\n // Call the parent registration.\n super.registerEventListeners();\n }\n};\n\nModalRegistry.register(ElementsModal.TYPE, ElementsModal, ElementsModal.TEMPLATE);\n\nexport default ElementsModal;\n"],"names":["ElementsModal","Modal","configure","modalConfig","removeOnClose","registerEventListeners","register","TYPE","TEMPLATE"],"mappings":"4iBA0BMA,sCAAgB,cAAcC,eAIhCC,UAAUC,aAENA,YAAYC,eAAgB,QACtBF,UAAUC,aAGpBE,+BAEUA,kCAXI,yDACI,uDAcRC,SAASN,cAAcO,KAAMP,cAAeA,cAAcQ,uBAEzDR"} \ No newline at end of file diff --git a/amd/build/options.min.js b/amd/build/options.min.js index 71d3f88..dc2e422 100644 --- a/amd/build/options.min.js +++ b/amd/build/options.min.js @@ -1,4 +1,4 @@ -define("tiny_c4l/options",["exports","editor_tiny/options","./common"],(function(_exports,_options,_common){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.showPreview=_exports.register=_exports.isStudent=_exports.isElementsVisible=_exports.getCssUrl=void 0; +define("tiny_elements/options",["exports","editor_tiny/options","./common"],(function(_exports,_options,_common){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.showPreview=_exports.register=_exports.isStudent=_exports.isElementsVisible=_exports.getCssUrl=void 0; /** * Options helper for Elements plugin. * @@ -6,6 +6,6 @@ define("tiny_c4l/options",["exports","editor_tiny/options","./common"],(function * @copyright 2022 Marc Català * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -const isstudentName=(0,_options.getPluginOptionName)(_common.pluginName,"isstudent"),showpreviewName=(0,_options.getPluginOptionName)(_common.pluginName,"showpreview"),viewelementsName=(0,_options.getPluginOptionName)(_common.pluginName,"viewelements"),cssUrlName=(0,_options.getPluginOptionName)(_common.pluginName,"cssurl");_exports.register=editor=>{const registerOption=editor.options.register;registerOption(isstudentName,{processor:"boolean",default:!1}),registerOption(showpreviewName,{processor:"boolean",default:!0}),registerOption(viewelementsName,{processor:"boolean",default:!0}),registerOption(cssUrlName,{processor:"string",default:""})};_exports.isElementsVisible=editor=>editor.options.get(viewelementsName);_exports.isStudent=editor=>editor.options.get(isstudentName);_exports.showPreview=editor=>editor.options.get(showpreviewName);_exports.getCssUrl=editor=>editor.options.get(cssUrlName)})); +const isstudentName=(0,_options.getPluginOptionName)(_common.pluginName,"isstudent"),showpreviewName=(0,_options.getPluginOptionName)(_common.pluginName,"showpreview"),viewElementsName=(0,_options.getPluginOptionName)(_common.pluginName,"viewelements"),cssUrlName=(0,_options.getPluginOptionName)(_common.pluginName,"cssurl");_exports.register=editor=>{const registerOption=editor.options.register;registerOption(isstudentName,{processor:"boolean",default:!1}),registerOption(showpreviewName,{processor:"boolean",default:!0}),registerOption(viewElementsName,{processor:"boolean",default:!0}),registerOption(cssUrlName,{processor:"string",default:""})};_exports.isElementsVisible=editor=>editor.options.get(viewElementsName);_exports.isStudent=editor=>editor.options.get(isstudentName);_exports.showPreview=editor=>editor.options.get(showpreviewName);_exports.getCssUrl=editor=>editor.options.get(cssUrlName)})); //# sourceMappingURL=options.min.js.map \ No newline at end of file diff --git a/amd/build/options.min.js.map b/amd/build/options.min.js.map index e3775fd..edecced 100644 --- a/amd/build/options.min.js.map +++ b/amd/build/options.min.js.map @@ -1 +1 @@ -{"version":3,"file":"options.min.js","sources":["../src/options.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 * Options helper for Elements plugin.\n *\n * @module tiny_elements/options\n * @copyright 2022 Marc Català \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {getPluginOptionName} from 'editor_tiny/options';\nimport {pluginName} from './common';\n\nconst isstudentName = getPluginOptionName(pluginName, 'isstudent');\nconst showpreviewName = getPluginOptionName(pluginName, 'showpreview');\nconst viewelementsName = getPluginOptionName(pluginName, 'viewelements');\nconst cssUrlName = getPluginOptionName(pluginName, 'cssurl');\n\nexport const register = (editor) => {\n const registerOption = editor.options.register;\n\n registerOption(isstudentName, {\n processor: 'boolean',\n \"default\": false,\n });\n\n registerOption(showpreviewName, {\n processor: 'boolean',\n \"default\": true,\n });\n\n registerOption(viewelementsName, {\n processor: 'boolean',\n \"default\": true,\n });\n\n registerOption(cssUrlName, {\n processor: 'string',\n \"default\": '',\n });\n};\n\n/**\n * Get the permissions configuration for the Tiny Elements plugin.\n *\n * @param {TinyMCE} editor\n * @returns {object}\n */\nexport const isElementsVisible = (editor) => editor.options.get(viewelementsName);\n\n/**\n * Get whether user is a student configuration for the Tiny Elements plugin.\n *\n * @param {TinyMCE} editor\n * @returns {object}\n */\nexport const isStudent = (editor) => editor.options.get(isstudentName);\n\n/**\n * Get the preview visibility configuration for the Tiny Elements plugin.\n *\n * @param {TinyMCE} editor\n * @returns {object}\n */\nexport const showPreview = (editor) => editor.options.get(showpreviewName);\n\n/**\n * Get the css url for the Tiny Elements plugin (to be used in the editor).\n * @param {TinyMCE} editor\n * @returns {string}\n */\nexport const getCssUrl = (editor) => editor.options.get(cssUrlName);\n"],"names":["isstudentName","pluginName","showpreviewName","viewelementsName","cssUrlName","editor","registerOption","options","register","processor","get"],"mappings":";;;;;;;;MA0BMA,eAAgB,gCAAoBC,mBAAY,aAChDC,iBAAkB,gCAAoBD,mBAAY,eAClDE,kBAAmB,gCAAoBF,mBAAY,gBACnDG,YAAa,gCAAoBH,mBAAY,4BAE1BI,eACfC,eAAiBD,OAAOE,QAAQC,SAEtCF,eAAeN,cAAe,CAC1BS,UAAW,mBACC,IAGhBH,eAAeJ,gBAAiB,CAC5BO,UAAW,mBACC,IAGhBH,eAAeH,iBAAkB,CAC7BM,UAAW,mBACC,IAGhBH,eAAeF,WAAY,CACvBK,UAAW,iBACC,iCAUcJ,QAAWA,OAAOE,QAAQG,IAAIP,qCAQtCE,QAAWA,OAAOE,QAAQG,IAAIV,oCAQ5BK,QAAWA,OAAOE,QAAQG,IAAIR,oCAOhCG,QAAWA,OAAOE,QAAQG,IAAIN"} \ No newline at end of file +{"version":3,"file":"options.min.js","sources":["../src/options.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 * Options helper for Elements plugin.\n *\n * @module tiny_elements/options\n * @copyright 2022 Marc Català \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {getPluginOptionName} from 'editor_tiny/options';\nimport {pluginName} from './common';\n\nconst isstudentName = getPluginOptionName(pluginName, 'isstudent');\nconst showpreviewName = getPluginOptionName(pluginName, 'showpreview');\nconst viewElementsName = getPluginOptionName(pluginName, 'viewelements');\nconst cssUrlName = getPluginOptionName(pluginName, 'cssurl');\n\nexport const register = (editor) => {\n const registerOption = editor.options.register;\n\n registerOption(isstudentName, {\n processor: 'boolean',\n \"default\": false,\n });\n\n registerOption(showpreviewName, {\n processor: 'boolean',\n \"default\": true,\n });\n\n registerOption(viewElementsName, {\n processor: 'boolean',\n \"default\": true,\n });\n\n registerOption(cssUrlName, {\n processor: 'string',\n \"default\": '',\n });\n};\n\n/**\n * Get the permissions configuration for the Tiny Elements plugin.\n *\n * @param {TinyMCE} editor\n * @returns {object}\n */\nexport const isElementsVisible = (editor) => editor.options.get(viewElementsName);\n\n/**\n * Get whether user is a student configuration for the Tiny Elements plugin.\n *\n * @param {TinyMCE} editor\n * @returns {object}\n */\nexport const isStudent = (editor) => editor.options.get(isstudentName);\n\n/**\n * Get the preview visibility configuration for the Tiny Elements plugin.\n *\n * @param {TinyMCE} editor\n * @returns {object}\n */\nexport const showPreview = (editor) => editor.options.get(showpreviewName);\n\n/**\n * Get the css url for the Tiny Elements plugin (to be used in the editor).\n * @param {TinyMCE} editor\n * @returns {string}\n */\nexport const getCssUrl = (editor) => editor.options.get(cssUrlName);\n"],"names":["isstudentName","pluginName","showpreviewName","viewElementsName","cssUrlName","editor","registerOption","options","register","processor","get"],"mappings":";;;;;;;;MA0BMA,eAAgB,gCAAoBC,mBAAY,aAChDC,iBAAkB,gCAAoBD,mBAAY,eAClDE,kBAAmB,gCAAoBF,mBAAY,gBACnDG,YAAa,gCAAoBH,mBAAY,4BAE1BI,eACfC,eAAiBD,OAAOE,QAAQC,SAEtCF,eAAeN,cAAe,CAC1BS,UAAW,mBACC,IAGhBH,eAAeJ,gBAAiB,CAC5BO,UAAW,mBACC,IAGhBH,eAAeH,iBAAkB,CAC7BM,UAAW,mBACC,IAGhBH,eAAeF,WAAY,CACvBK,UAAW,iBACC,iCAUcJ,QAAWA,OAAOE,QAAQG,IAAIP,qCAQtCE,QAAWA,OAAOE,QAAQG,IAAIV,oCAQ5BK,QAAWA,OAAOE,QAAQG,IAAIR,oCAOhCG,QAAWA,OAAOE,QAAQG,IAAIN"} \ No newline at end of file diff --git a/amd/build/plugin.min.js b/amd/build/plugin.min.js index 2000639..2bee249 100644 --- a/amd/build/plugin.min.js +++ b/amd/build/plugin.min.js @@ -1,4 +1,4 @@ -define("tiny_c4l/plugin",["exports","editor_tiny/loader","editor_tiny/utils","./common","./options","./commands","./configuration"],(function(_exports,_loader,_utils,_common,_options,_commands,Configuration){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,Configuration=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj} +define("tiny_elements/plugin",["exports","editor_tiny/loader","editor_tiny/utils","./common","./options","./commands","./configuration"],(function(_exports,_loader,_utils,_common,_options,_commands,Configuration){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,Configuration=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj} /** * Tiny Elements plugin. * diff --git a/amd/build/preferencelib.min.js b/amd/build/preferencelib.min.js index 7699e0d..56da3e0 100644 --- a/amd/build/preferencelib.min.js +++ b/amd/build/preferencelib.min.js @@ -1,4 +1,4 @@ -define("tiny_c4l/preferencelib",["exports","core/ajax","core/notification"],(function(_exports,_ajax,_notification){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +define("tiny_elements/preferencelib",["exports","core/ajax","core/notification"],(function(_exports,_ajax,_notification){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} /** * Helper for handling user preferences. * diff --git a/amd/build/ui.min.js b/amd/build/ui.min.js index 6f347bf..f4260a6 100644 --- a/amd/build/ui.min.js +++ b/amd/build/ui.min.js @@ -1,10 +1,10 @@ -define("tiny_c4l/ui",["exports","./common","./modal","core/modal_factory","core/str","./options","core/modal_events","./variantslib","./helper","./preferencelib","core/ajax","editor_tiny/options"],(function(_exports,_common,_modal,_modal_factory,_str,_options,_modal_events,_variantslib,_helper,_preferencelib,_ajax,_options2){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +define("tiny_elements/ui",["exports","./common","./modal","core/modal_factory","core/str","./options","core/modal_events","./variantslib","./helper","./preferencelib","core/ajax","editor_tiny/options"],(function(_exports,_common,_modal,_modal_factory,_str,_options,_modal_events,_variantslib,_helper,_preferencelib,_ajax,_options2){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} /** * Tiny Elements UI. * * @module tiny_elements/ui * @copyright 2022 Marc Català * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.handleAction=void 0,_modal=_interopRequireDefault(_modal),_modal_factory=_interopRequireDefault(_modal_factory),_modal_events=_interopRequireDefault(_modal_events);let userStudent=!1,previewElements=!0,components=[],categories=[],flavors=[],variants=[],langStrings={},contextid=1,currentFlavor="",currentFlavorId=0,currentCategoryId=1,lastFlavor=[];_exports.handleAction=async editor=>{contextid=(0,_options2.getContextId)(editor),userStudent=(0,_options.isStudent)(editor);let data=await getElementsData();components=data.components,categories=data.categories,flavors=data.flavors,variants=data.variants,(0,_variantslib.setComponents)(components),(0,_variantslib.setVariants)(variants),(0,_variantslib.setFlavors)(flavors),previewElements=(0,_options.showPreview)(editor),langStrings=await getAllStrings(),currentCategoryId=await(0,_preferencelib.loadPreferences)(_preferencelib.Preferences.category),lastFlavor=await(0,_preferencelib.loadPreferences)(_preferencelib.Preferences.category_flavors),null===lastFlavor&&(lastFlavor=[]);let componentVariants=await(0,_preferencelib.loadPreferences)(_preferencelib.Preferences.component_variants);null===componentVariants&&(componentVariants={}),(0,_variantslib.loadVariantPreferences)(componentVariants),displayDialogue(editor)};const displayDialogue=async editor=>{const data=Object.assign({},{}),templateContext=await getTemplateContext(editor,data),modal=await _modal_factory.default.create({type:_modal.default.TYPE,templateContext:templateContext,large:!0}),modalClass=previewElements?"elements-modal":"elements-modal-no-preview";editor.targetElm.closest("body").classList.add(modalClass),modal.show(),modal.getRoot().on(_modal_events.default.hidden,(()=>{handleModalHidden(editor)}));const soleCategories=modal.getRoot()[0].querySelectorAll(".elements-category.no-flavors");soleCategories.forEach((node=>{node.addEventListener("click",(event=>{handleCategoryClick(event,modal)}))}));const selectCategories=modal.getRoot()[0].querySelectorAll(".elements-category-flavor");selectCategories.forEach((node=>{node.addEventListener("click",(event=>{handleCategoryFlavorClick(event,modal)}))}));modal.getRoot()[0].querySelectorAll(".elementst-dialog-button").forEach((node=>{node.addEventListener("click",(event=>{handleButtonClick(event,editor,modal)})),previewElements&&(node.addEventListener("mouseenter",(event=>{handleButtonMouseEvent(event,modal,!0)})),node.addEventListener("mouseleave",(event=>{handleButtonMouseEvent(event,modal,!1)})))}));if(modal.getRoot()[0].querySelectorAll(".elements-button-variant").forEach((node=>{node.addEventListener("click",(event=>{handleVariantClick(event,modal)}))})),soleCategories.length>0||selectCategories.length>0){let savedCategory=currentCategoryId;soleCategories[0].displayorder>selectCategories[0].displayorder?selectCategories[0].click():soleCategories[0].click(),0!=savedCategory&&(soleCategories.forEach((node=>{node.dataset.categoryid==savedCategory&&node.click()})),selectCategories.forEach((node=>{if(node.dataset.categoryid==savedCategory){let target=modal.getRoot()[0].querySelector('.elements-category-flavor[data-id="'+currentFlavorId+'"]');if(target){handleCategoryFlavorClick({target:target},modal)}}})))}},handleCategoryClick=(event,modal)=>{const link=event.target;currentCategoryId=link.dataset.categoryid;modal.getRoot()[0].querySelectorAll(".nav-link, .dropdown-item").forEach((node=>node.classList.remove("active"))),link.classList.add("active"),showCategoryButtons(modal,currentCategoryId)},handleCategoryFlavorClick=(event,modal)=>{const link=event.target;currentFlavor=link.dataset.flavor,currentFlavorId=link.dataset.id,currentCategoryId=link.dataset.categoryid,lastFlavor[currentCategoryId]=currentFlavorId;modal.getRoot()[0].querySelectorAll(".nav-link, .dropdown-item").forEach((node=>node.classList.remove("active"))),link.classList.add("active");modal.getRoot()[0].querySelector('.nav-link[data-categoryid="'+currentCategoryId+'"]').classList.add("active");modal.getRoot()[0].querySelectorAll(".elements-buttons-preview button").forEach((componentButton=>{if(null!=componentButton.dataset.flavor&&componentButton.classList.remove(componentButton.dataset.flavor),componentButton.classList.add(currentFlavor),componentButton.dataset.flavor=currentFlavor,""!=componentButton.dataset.flavorlist&&!componentButton.dataset.flavorlist.split(",").includes(currentFlavor)||componentButton.dataset.category!=currentCategoryId)componentButton.classList.add("elements-hidden");else if(componentButton.classList.remove("elements-hidden"),""!=componentButton.dataset.flavorlist){let variants=(0,_variantslib.getVariantsClass)(components[componentButton.dataset.id].name,currentFlavor);componentButton.querySelectorAll(".elements-button-variant").forEach((variant=>{-1!=variants.indexOf("elements-"+variant.dataset.variant+"-variant")?updateVariantButtonState(variant,!0):updateVariantButtonState(variant,!1)}))}}))},handleModalHidden=editor=>{editor.targetElm.closest("body").classList.remove("elements-modal-no-preview"),0!=currentCategoryId&&0!=currentFlavorId&&(0,_preferencelib.savePreferences)([{type:_preferencelib.Preferences.category,value:currentCategoryId},{type:_preferencelib.Preferences.category_flavors,value:JSON.stringify(lastFlavor)},{type:_preferencelib.Preferences.component_variants,value:JSON.stringify((0,_variantslib.getVariantPreferences)())}])},updateComponentCode=function(componentCode,selectedButton,placeholder){let flavor=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"";componentCode=componentCode.replace("{{PLACEHOLDER}}",placeholder);const variants=(0,_variantslib.getVariantsClass)(components[selectedButton].name,flavor);return componentCode=variants.length>0?(componentCode=componentCode.replace("{{VARIANTS}}",variants.join(" "))).replace("{{VARIANTSHTML}}",(0,_variantslib.getVariantsHtml)(components[selectedButton].name)):(componentCode=componentCode.replace("{{VARIANTS}}","")).replace("{{VARIANTSHTML}}",""),componentCode=(componentCode=(componentCode=currentFlavor?componentCode.replace("{{FLAVOR}}",currentFlavor):componentCode.replace("{{FLAVOR}}","")).replace("{{COMPONENT}}",components[selectedButton].name)).replace("{{CATEGORY}}",categories[currentCategoryId].name),componentCode=applyRandomID(componentCode),componentCode=applyLangStrings(componentCode)},handleButtonClick=async(event,editor,modal)=>{const selectedButton=event.target.closest("button").dataset.id;if(components[selectedButton]){const sel=editor.selection.getContent();let componentCode=components[selectedButton].code;const placeholder=sel.length>0?sel:components[selectedButton].text;let flavor=components[selectedButton].flavors.length>0?currentFlavor:"";const randomId=generateRandomID(),newNode=document.createElement("span");newNode.dataset.id=randomId,newNode.innerHTML=placeholder,componentCode=updateComponentCode(componentCode,selectedButton,newNode.outerHTML,flavor),editor.selection.setContent(componentCode);const nodeSel=editor.dom.select('span[data-id="'+randomId+'"]');null!=nodeSel&&nodeSel[0]&&editor.selection.select(nodeSel[0]),modal.destroy(),editor.focus()}},handleButtonMouseEvent=(event,modal,show)=>{const selectedButton=event.target.closest("button").dataset.id,node=modal.getRoot()[0].querySelector('div[data-id="code-preview-'+selectedButton+'"]'),previewDefault=modal.getRoot()[0].querySelector('div[data-id="code-preview-default"]');let flavor=components[selectedButton].flavors.length>0?currentFlavor:"";node.innerHTML=updateComponentCode(components[selectedButton].code,selectedButton,components[selectedButton].text,flavor),node&&(show?(previewDefault.classList.toggle("elements-hidden"),node.classList.toggle("elements-hidden")):(node.classList.toggle("elements-hidden"),previewDefault.classList.toggle("elements-hidden")))},handleVariantClick=(event,modal)=>{event.stopPropagation();const variant=event.target.closest("span"),button=event.target.closest("button"),flavor=components[button.dataset.id].flavors.length>0?currentFlavor:"";updateVariantComponentState(variant,button,modal,!1,!0);modal.getRoot()[0].querySelector('div[data-id="code-preview-'+button.dataset.id+'"]').innerHTML=updateComponentCode(components[button.dataset.id].code,button.dataset.id,components[button.dataset.id].text,flavor)},getTemplateContext=async(editor,data)=>Object.assign({},{elementid:editor.id,buttons:await getButtons(editor),categories:await getCategories(),preview:previewElements},data),getCategories=async()=>{const cats=[];return categories.forEach((category=>{let categoryFlavors=getCategoryFlavors(category.id),hasFlavors=hasCategoryFlavors(categoryFlavors);cats.push({categoryid:category.id,name:category.displayname,type:category.id,displayorder:category.displayorder,flavors:categoryFlavors,hasFlavors:hasFlavors,active:""})})),cats.sort(((a,b)=>a.displayorder-b.displayorder)),cats.length>0&&(cats[0].active="active",cats[0].flavors.length>0&&(cats[0].flavors[0].factive="active")),cats},getComponentVariants=component=>{const componentVariants=[];return component.variants.forEach((variant=>{let variantitem=(0,_helper.findByName)(variants,variant);if(void 0!==variantitem){let state=(0,_variantslib.variantExists)(component.name,variantitem.name)?"on":"off";componentVariants.push({id:variantitem.id,name:variantitem.name,state:state,imageClass:variantitem.name+"-variant-"+state,title:langStrings.get(variantitem.name),content:variantitem.content})}})),componentVariants},getCategoryFlavors=categoryId=>{const categoryFlavors=[];return flavors.forEach((flavor=>{(flavor.categories==categoryId||flavor.categories.split(",").includes(categoryId))&&categoryFlavors.push({id:flavor.id,name:flavor.name,displayname:flavor.displayname})})),categoryFlavors},hasCategoryFlavors=value=>Array.isArray(value)&&value.length,getButtons=async editor=>{const buttons=[];editor.selection.getContent();return Object.values(components).forEach((component=>{buttons.push({id:component.id,name:component.displayname,type:component.compcat,imageClass:"elements-"+component.name+"-icon",htmlcode:component.code,variants:getComponentVariants(component),flavorlist:component.flavors.join(","),category:component.compcat})})),buttons.sort(((a,b)=>a.displayorder-b.displayorder)),buttons},getElementsData=async()=>{const data=await(0,_ajax.call)([{methodname:"tiny_elements_get_elements_data",args:{isstudent:userStudent,contextid:contextid}}])[0],indexedComponents=[];data.components.forEach((component=>{indexedComponents[component.id]=component}));const indexedVariants=[];data.variants.forEach((variant=>{indexedVariants[variant.id]=variant}));const indexedCategories=[];return data.categories.forEach((category=>{indexedCategories[category.id]=category})),{components:indexedComponents,variants:indexedVariants,categories:indexedCategories,flavors:data.flavors}},updateVariantComponentState=(variant,button,modal,show,updateHtml)=>{const selectedVariant="elements-"+variant.dataset.variant+"-variant",selectedButton=button.dataset.id,componentClass=button.dataset.classcomponent,previewComponent=modal.getRoot()[0].querySelector('div[data-id="code-preview-'+button.dataset.id+'"] .'+componentClass),variantPreview=modal.getRoot()[0].querySelector('span[data-id="variantHTML-'+button.dataset.id+'"]');let variantsHtml="",hasflavors=components[selectedButton].flavors.length>0;previewComponent?updateHtml?("on"==variant.dataset.state?((0,_variantslib.removeVariant)(components[selectedButton].name,variant.dataset.variant,hasflavors?currentFlavor:""),updateVariantButtonState(variant,!1),previewComponent.classList.remove(selectedVariant)):((0,_variantslib.addVariant)(components[selectedButton].name,variant.dataset.variant,hasflavors?currentFlavor:""),updateVariantButtonState(variant,!0),previewComponent.classList.add(selectedVariant)),variantPreview&&(variantPreview.innerHTML=(0,_variantslib.getVariantsHtml)(components[selectedButton].name))):(variantsHtml=(0,_variantslib.getVariantsHtml)(components[selectedButton].name),show?(previewComponent.classList.add(selectedVariant),variantsHtml+=(0,_variantslib.getVariantHtml)(variant.dataset.variant)):previewComponent.classList.remove(selectedVariant),variantPreview&&(variantPreview.innerHTML=variantsHtml)):"on"==variant.dataset.state?((0,_variantslib.removeVariant)(components[selectedButton].name,variant.dataset.variant,hasflavors?currentFlavor:""),updateVariantButtonState(variant,!1)):((0,_variantslib.addVariant)(components[selectedButton].name,variant.dataset.variant,hasflavors?currentFlavor:""),updateVariantButtonState(variant,!0))},updateVariantButtonState=(variant,activate)=>{activate?(variant.dataset.state="on",variant.classList.remove(variant.dataset.variant+"-variant-off"),variant.classList.add(variant.dataset.variant+"-variant-on"),variant.classList.add("on")):(variant.dataset.state="off",variant.classList.remove(variant.dataset.variant+"-variant-on"),variant.classList.add(variant.dataset.variant+"-variant-off"),variant.classList.remove("on"))},showCategoryButtons=(modal,context)=>{const showNodes=modal.getRoot()[0].querySelectorAll('button[data-type="'+context+'"]'),hideNodes=modal.getRoot()[0].querySelectorAll('button[data-type]:not([data-type="'+context+'"])');showNodes.forEach((node=>node.classList.remove("elements-hidden"))),hideNodes.forEach((node=>node.classList.add("elements-hidden")))},applyLangStrings=text=>([...text.matchAll(/{{#([^}]*)}}/g)].forEach((strLang=>{text=text.replace("{{#"+strLang[1]+"}}",langStrings.get(strLang[1]))})),text),generateRandomID=()=>{const timestamp=(new Date).getTime();return"R"+Math.round(1e5*Math.random())+"-"+timestamp},applyRandomID=text=>{const compRegex=/{{@ID}}/g;return text.match(compRegex)&&(text=text.replace(compRegex,generateRandomID())),text},getAllStrings=async()=>{const keys=[],compRegex=/{{#([^}]*)}}/g;components.forEach((element=>{[...element.code.matchAll(compRegex)].forEach((strLang=>{-1===keys.indexOf(strLang[1])&&keys.push(strLang[1])})),[...element.text.matchAll(compRegex)].forEach((strLang=>{-1===keys.indexOf(strLang[1])&&keys.push(strLang[1])}))}));const stringValues=await(0,_str.get_strings)(keys.map((key=>({key:key,component:_common.component}))));return new Map(keys.map(((key,index)=>[key,stringValues[index]])))}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.handleAction=void 0,_modal=_interopRequireDefault(_modal),_modal_factory=_interopRequireDefault(_modal_factory),_modal_events=_interopRequireDefault(_modal_events);let userStudent=!1,previewElements=!0,components=[],categories=[],flavors=[],variants=[],langStrings={},contextid=1,currentFlavor="",currentFlavorId=0,currentCategoryId=1,lastFlavor=[];_exports.handleAction=async editor=>{contextid=(0,_options2.getContextId)(editor),userStudent=(0,_options.isStudent)(editor);let data=await getElementsData();components=data.components,categories=data.categories,flavors=data.flavors,variants=data.variants,(0,_variantslib.setComponents)(components),(0,_variantslib.setVariants)(variants),(0,_variantslib.setFlavors)(flavors),previewElements=(0,_options.showPreview)(editor),langStrings=await getAllStrings(),currentCategoryId=await(0,_preferencelib.loadPreferences)(_preferencelib.Preferences.category),lastFlavor=await(0,_preferencelib.loadPreferences)(_preferencelib.Preferences.category_flavors),null===lastFlavor&&(lastFlavor=[]);let componentVariants=await(0,_preferencelib.loadPreferences)(_preferencelib.Preferences.component_variants);null===componentVariants&&(componentVariants={}),(0,_variantslib.loadVariantPreferences)(componentVariants),displayDialogue(editor)};const displayDialogue=async editor=>{const data=Object.assign({},{}),templateContext=await getTemplateContext(editor,data),modal=await _modal_factory.default.create({type:_modal.default.TYPE,templateContext:templateContext,large:!0}),modalClass=previewElements?"elements-modal":"elements-modal-no-preview";editor.targetElm.closest("body").classList.add(modalClass),modal.show(),modal.getRoot().on(_modal_events.default.hidden,(()=>{handleModalHidden(editor)}));const soleCategories=modal.getRoot()[0].querySelectorAll(".elements-category.no-flavors");soleCategories.forEach((node=>{node.addEventListener("click",(event=>{handleCategoryClick(event,modal)}))}));const selectCategories=modal.getRoot()[0].querySelectorAll(".elements-category-flavor");selectCategories.forEach((node=>{node.addEventListener("click",(event=>{handleCategoryFlavorClick(event,modal)}))}));modal.getRoot()[0].querySelectorAll(".elementst-dialog-button").forEach((node=>{node.addEventListener("click",(event=>{handleButtonClick(event,editor,modal)})),previewElements&&(node.addEventListener("mouseenter",(event=>{handleButtonMouseEvent(event,modal,!0)})),node.addEventListener("mouseleave",(event=>{handleButtonMouseEvent(event,modal,!1)})))}));if(modal.getRoot()[0].querySelectorAll(".elements-button-variant").forEach((node=>{node.addEventListener("click",(event=>{handleVariantClick(event,modal)}))})),soleCategories.length>0||selectCategories.length>0){let savedCategory=currentCategoryId;soleCategories[0].displayorder>selectCategories[0].displayorder?selectCategories[0].click():soleCategories[0].click(),0!=savedCategory&&(soleCategories.forEach((node=>{node.dataset.categoryid==savedCategory&&node.click()})),selectCategories.forEach((node=>{if(node.dataset.categoryid==savedCategory){let target=modal.getRoot()[0].querySelector('.elements-category-flavor[data-id="'+currentFlavorId+'"]');if(target){handleCategoryFlavorClick({target:target},modal)}}})))}},handleCategoryClick=(event,modal)=>{const link=event.target;currentCategoryId=link.dataset.categoryid;modal.getRoot()[0].querySelectorAll(".nav-link, .dropdown-item").forEach((node=>node.classList.remove("active"))),link.classList.add("active"),showCategoryButtons(modal,currentCategoryId)},handleCategoryFlavorClick=(event,modal)=>{const link=event.target;currentFlavor=link.dataset.flavor,currentFlavorId=link.dataset.id,currentCategoryId=link.dataset.categoryid,lastFlavor[currentCategoryId]=currentFlavorId;modal.getRoot()[0].querySelectorAll(".nav-link, .dropdown-item").forEach((node=>node.classList.remove("active"))),link.classList.add("active");modal.getRoot()[0].querySelector('.nav-link[data-categoryid="'+currentCategoryId+'"]').classList.add("active");modal.getRoot()[0].querySelectorAll(".elements-buttons-preview button").forEach((componentButton=>{if(null!=componentButton.dataset.flavor&&componentButton.classList.remove(componentButton.dataset.flavor),componentButton.classList.add(currentFlavor),componentButton.dataset.flavor=currentFlavor,""!=componentButton.dataset.flavorlist&&!componentButton.dataset.flavorlist.split(",").includes(currentFlavor)||componentButton.dataset.category!=currentCategoryId)componentButton.classList.add("elements-hidden");else if(componentButton.classList.remove("elements-hidden"),""!=componentButton.dataset.flavorlist){let variants=(0,_variantslib.getVariantsClass)(components[componentButton.dataset.id].name,currentFlavor);componentButton.querySelectorAll(".elements-button-variant").forEach((variant=>{updateVariantButtonState(variant,-1!=variants.indexOf(variant.dataset.variantclass))}))}}))},handleModalHidden=editor=>{editor.targetElm.closest("body").classList.remove("elements-modal-no-preview"),0!=currentCategoryId&&0!=currentFlavorId&&(0,_preferencelib.savePreferences)([{type:_preferencelib.Preferences.category,value:currentCategoryId},{type:_preferencelib.Preferences.category_flavors,value:JSON.stringify(lastFlavor)},{type:_preferencelib.Preferences.component_variants,value:JSON.stringify((0,_variantslib.getVariantPreferences)())}])},updateComponentCode=function(componentCode,selectedButton,placeholder){let flavor=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"";componentCode=componentCode.replace("{{PLACEHOLDER}}",placeholder);const variants=(0,_variantslib.getVariantsClass)(components[selectedButton].name,flavor);return componentCode=variants.length>0?(componentCode=componentCode.replace("{{VARIANTS}}",variants.join(" "))).replace("{{VARIANTSHTML}}",(0,_variantslib.getVariantsHtml)(components[selectedButton].name)):(componentCode=componentCode.replace("{{VARIANTS}}","")).replace("{{VARIANTSHTML}}",""),componentCode=(componentCode=(componentCode=currentFlavor?componentCode.replace("{{FLAVOR}}",currentFlavor):componentCode.replace("{{FLAVOR}}","")).replace("{{COMPONENT}}",components[selectedButton].name)).replace("{{CATEGORY}}",categories[currentCategoryId].name),componentCode=applyRandomID(componentCode),componentCode=applyLangStrings(componentCode)},handleButtonClick=async(event,editor,modal)=>{const selectedButton=event.target.closest("button").dataset.id;if(components[selectedButton]){const sel=editor.selection.getContent();let componentCode=components[selectedButton].code;const placeholder=sel.length>0?sel:components[selectedButton].text;let flavor=components[selectedButton].flavors.length>0?currentFlavor:"";const randomId=generateRandomID(),newNode=document.createElement("span");newNode.dataset.id=randomId,newNode.innerHTML=placeholder,componentCode=updateComponentCode(componentCode,selectedButton,newNode.outerHTML,flavor),editor.selection.setContent(componentCode);const nodeSel=editor.dom.select('span[data-id="'+randomId+'"]');null!=nodeSel&&nodeSel[0]&&editor.selection.select(nodeSel[0]),modal.destroy(),editor.focus()}},handleButtonMouseEvent=(event,modal,show)=>{const selectedButton=event.target.closest("button").dataset.id,node=modal.getRoot()[0].querySelector('div[data-id="code-preview-'+selectedButton+'"]'),previewDefault=modal.getRoot()[0].querySelector('div[data-id="code-preview-default"]');let flavor=components[selectedButton].flavors.length>0?currentFlavor:"";node.innerHTML=updateComponentCode(components[selectedButton].code,selectedButton,components[selectedButton].text,flavor),node&&(show?(previewDefault.classList.toggle("elements-hidden"),node.classList.toggle("elements-hidden")):(node.classList.toggle("elements-hidden"),previewDefault.classList.toggle("elements-hidden")))},handleVariantClick=(event,modal)=>{event.stopPropagation();const variant=event.target.closest("span"),button=event.target.closest("button"),flavor=components[button.dataset.id].flavors.length>0?currentFlavor:"";updateVariantComponentState(variant,button,modal,!1,!0);modal.getRoot()[0].querySelector('div[data-id="code-preview-'+button.dataset.id+'"]').innerHTML=updateComponentCode(components[button.dataset.id].code,button.dataset.id,components[button.dataset.id].text,flavor)},getTemplateContext=async(editor,data)=>Object.assign({},{elementid:editor.id,buttons:await getButtons(editor),categories:await getCategories(),preview:previewElements},data),getCategories=async()=>{const cats=[];return categories.forEach((category=>{let categoryFlavors=getCategoryFlavors(category.id),hasFlavors=hasCategoryFlavors(categoryFlavors);cats.push({categoryid:category.id,name:category.displayname,type:category.id,displayorder:category.displayorder,flavors:categoryFlavors,hasFlavors:hasFlavors,active:""})})),cats.sort(((a,b)=>a.displayorder-b.displayorder)),cats.length>0&&(cats[0].active="active",cats[0].flavors.length>0&&(cats[0].flavors[0].factive="active")),cats},getComponentVariants=component=>{const componentVariants=[];return component.variants.forEach((variant=>{let variantitem=(0,_helper.findByName)(variants,variant);if(void 0!==variantitem){let state=(0,_variantslib.variantExists)(component.name,variantitem.name)?"on":"off";componentVariants.push({id:variantitem.id,name:variantitem.name,state:state,imageClass:variantitem.name+"-variant-"+state,variantclass:(variantitem.c4lcompatibility?"c4l":"elements")+"-"+variantitem.name+"-variant",title:langStrings.get(variantitem.name),content:variantitem.content})}})),componentVariants},getCategoryFlavors=categoryId=>{const categoryFlavors=[];return flavors.forEach((flavor=>{(flavor.categories==categoryId||flavor.categories.split(",").includes(categoryId))&&categoryFlavors.push({id:flavor.id,name:flavor.name,displayname:flavor.displayname})})),categoryFlavors},hasCategoryFlavors=value=>Array.isArray(value)&&value.length,getButtons=async editor=>{const buttons=[];editor.selection.getContent();return Object.values(components).forEach((component=>{buttons.push({id:component.id,name:component.displayname,type:component.compcat,imageClass:"elements-"+component.name+"-icon",htmlcode:component.code,variants:getComponentVariants(component),flavorlist:component.flavors.join(","),category:component.compcat})})),buttons.sort(((a,b)=>a.displayorder-b.displayorder)),buttons},getElementsData=async()=>{const data=await(0,_ajax.call)([{methodname:"tiny_elements_get_elements_data",args:{isstudent:userStudent,contextid:contextid}}])[0],indexedComponents=[];data.components.forEach((component=>{indexedComponents[component.id]=component}));const indexedVariants=[];data.variants.forEach((variant=>{indexedVariants[variant.id]=variant}));const indexedCategories=[];return data.categories.forEach((category=>{indexedCategories[category.id]=category})),{components:indexedComponents,variants:indexedVariants,categories:indexedCategories,flavors:data.flavors}},updateVariantComponentState=(variant,button,modal,show,updateHtml)=>{const selectedVariant=variant.dataset.variantclass,selectedButton=button.dataset.id,componentClass=button.dataset.classcomponent,previewComponent=modal.getRoot()[0].querySelector('div[data-id="code-preview-'+button.dataset.id+'"] .'+componentClass),variantPreview=modal.getRoot()[0].querySelector('span[data-id="variantHTML-'+button.dataset.id+'"]');let variantsHtml="",hasflavors=components[selectedButton].flavors.length>0;previewComponent?updateHtml?("on"==variant.dataset.state?((0,_variantslib.removeVariant)(components[selectedButton].name,variant.dataset.variant,hasflavors?currentFlavor:""),updateVariantButtonState(variant,!1),previewComponent.classList.remove(selectedVariant)):((0,_variantslib.addVariant)(components[selectedButton].name,variant.dataset.variant,hasflavors?currentFlavor:""),updateVariantButtonState(variant,!0),previewComponent.classList.add(selectedVariant)),variantPreview&&(variantPreview.innerHTML=(0,_variantslib.getVariantsHtml)(components[selectedButton].name))):(variantsHtml=(0,_variantslib.getVariantsHtml)(components[selectedButton].name),show?(previewComponent.classList.add(selectedVariant),variantsHtml+=(0,_variantslib.getVariantHtml)(variant.dataset.variant)):previewComponent.classList.remove(selectedVariant),variantPreview&&(variantPreview.innerHTML=variantsHtml)):"on"==variant.dataset.state?((0,_variantslib.removeVariant)(components[selectedButton].name,variant.dataset.variant,hasflavors?currentFlavor:""),updateVariantButtonState(variant,!1)):((0,_variantslib.addVariant)(components[selectedButton].name,variant.dataset.variant,hasflavors?currentFlavor:""),updateVariantButtonState(variant,!0))},updateVariantButtonState=(variant,activate)=>{activate?(variant.dataset.state="on",variant.classList.remove(variant.dataset.variant+"-variant-off"),variant.classList.add(variant.dataset.variant+"-variant-on"),variant.classList.add("on")):(variant.dataset.state="off",variant.classList.remove(variant.dataset.variant+"-variant-on"),variant.classList.add(variant.dataset.variant+"-variant-off"),variant.classList.remove("on"))},showCategoryButtons=(modal,context)=>{const showNodes=modal.getRoot()[0].querySelectorAll('button[data-type="'+context+'"]'),hideNodes=modal.getRoot()[0].querySelectorAll('button[data-type]:not([data-type="'+context+'"])');showNodes.forEach((node=>node.classList.remove("elements-hidden"))),hideNodes.forEach((node=>node.classList.add("elements-hidden")))},applyLangStrings=text=>([...text.matchAll(/{{#([^}]*)}}/g)].forEach((strLang=>{text=text.replace("{{#"+strLang[1]+"}}",langStrings.get(strLang[1]))})),text),generateRandomID=()=>{const timestamp=(new Date).getTime();return"R"+Math.round(1e5*Math.random())+"-"+timestamp},applyRandomID=text=>{const compRegex=/{{@ID}}/g;return text.match(compRegex)&&(text=text.replace(compRegex,generateRandomID())),text},getAllStrings=async()=>{const keys=[],compRegex=/{{#([^}]*)}}/g;components.forEach((element=>{[...element.code.matchAll(compRegex)].forEach((strLang=>{-1===keys.indexOf(strLang[1])&&keys.push(strLang[1])})),[...element.text.matchAll(compRegex)].forEach((strLang=>{-1===keys.indexOf(strLang[1])&&keys.push(strLang[1])}))}));const stringValues=await(0,_str.get_strings)(keys.map((key=>({key:key,component:_common.component}))));return new Map(keys.map(((key,index)=>[key,stringValues[index]])))}})); //# 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 b8f78c5..760cc39 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\n/**\n * Tiny Elements UI.\n *\n * @module tiny_elements/ui\n * @copyright 2022 Marc Català \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {component} from './common';\nimport ElementsModal from './modal';\nimport ModalFactory from 'core/modal_factory';\nimport {get_strings as getStrings} from 'core/str';\nimport {\n isStudent,\n showPreview\n} from './options';\nimport ModalEvents from 'core/modal_events';\nimport {\n addVariant,\n getVariantsClass,\n getVariantHtml,\n getVariantPreferences,\n getVariantsHtml,\n loadVariantPreferences,\n removeVariant,\n setFlavors,\n setVariants,\n variantExists,\n setComponents\n} from './variantslib';\nimport {\n findByName\n} from './helper';\nimport {\n savePreferences,\n loadPreferences,\n Preferences\n} from './preferencelib';\nimport {call as fetchMany} from 'core/ajax';\nimport {getContextId} from 'editor_tiny/options';\n\nlet userStudent = false;\n\nlet previewElements = true;\nlet components = [];\nlet categories = [];\nlet flavors = [];\nlet variants = [];\nlet langStrings = {};\nlet contextid = 1;\n\nlet currentFlavor = '';\nlet currentFlavorId = 0;\nlet currentCategoryId = 1;\nlet lastFlavor = [];\n\n/**\n * Handle action\n *\n * @param {TinyMCE} editor\n */\nexport const handleAction = async(editor) => {\n contextid = getContextId(editor);\n userStudent = isStudent(editor);\n let data = await getElementsData();\n components = data.components;\n categories = data.categories;\n flavors = data.flavors;\n variants = data.variants;\n setComponents(components);\n setVariants(variants);\n setFlavors(flavors);\n previewElements = showPreview(editor);\n langStrings = await getAllStrings();\n currentCategoryId = await loadPreferences(Preferences.category);\n lastFlavor = await loadPreferences(Preferences.category_flavors);\n if (lastFlavor === null) {\n lastFlavor = [];\n }\n let componentVariants = await loadPreferences(Preferences.component_variants);\n if (componentVariants === null) {\n componentVariants = {};\n }\n loadVariantPreferences(componentVariants);\n displayDialogue(editor);\n};\n\n/**\n * Display modal\n *\n * @param {TinyMCE} editor\n */\nconst displayDialogue = async(editor) => {\n const data = Object.assign({}, {});\n const templateContext = await getTemplateContext(editor, data);\n // Show modal with buttons.\n const modal = await ModalFactory.create({\n type: ElementsModal.TYPE,\n templateContext: templateContext,\n large: true,\n });\n\n // Choose class to modal.\n const modalClass = previewElements ? 'elements-modal' : 'elements-modal-no-preview';\n\n // Set class to modal.\n editor.targetElm.closest('body').classList.add(modalClass);\n\n modal.show();\n\n // Event modal listener.\n modal.getRoot().on(ModalEvents.hidden, () => {\n handleModalHidden(editor);\n });\n\n // Event listener for categories without flavors.\n const soleCategories = modal.getRoot()[0].querySelectorAll('.elements-category.no-flavors');\n soleCategories.forEach(node => {\n node.addEventListener('click', (event) => {\n handleCategoryClick(event, modal);\n });\n });\n\n // Event listener for categories with flavors.\n const selectCategories = modal.getRoot()[0].querySelectorAll('.elements-category-flavor');\n selectCategories.forEach(node => {\n node.addEventListener('click', (event) => {\n handleCategoryFlavorClick(event, modal);\n });\n });\n\n // Event buttons listeners.\n const buttons = modal.getRoot()[0].querySelectorAll('.elementst-dialog-button');\n buttons.forEach(node => {\n node.addEventListener('click', (event) => {\n handleButtonClick(event, editor, modal);\n });\n if (previewElements) {\n node.addEventListener('mouseenter', (event) => {\n handleButtonMouseEvent(event, modal, true);\n });\n node.addEventListener('mouseleave', (event) => {\n handleButtonMouseEvent(event, modal, false);\n });\n }\n });\n\n // Event variants listeners.\n const variants = modal.getRoot()[0].querySelectorAll('.elements-button-variant');\n variants.forEach(node => {\n node.addEventListener('click', (event) => {\n handleVariantClick(event, modal);\n });\n });\n\n // Select first or saved category.\n if (soleCategories.length > 0 || selectCategories.length > 0) {\n let savedCategory = currentCategoryId;\n if (soleCategories[0].displayorder > selectCategories[0].displayorder ) {\n selectCategories[0].click();\n } else {\n soleCategories[0].click();\n }\n if (savedCategory != 0) {\n soleCategories.forEach((node) => {\n if (node.dataset.categoryid == savedCategory) {\n node.click();\n }\n });\n selectCategories.forEach((node) => {\n if (node.dataset.categoryid == savedCategory) {\n // Simulate click on flavor.\n let target = modal.getRoot()[0].querySelector(\n '.elements-category-flavor[data-id=\"' + currentFlavorId + '\"]',\n );\n if (target) {\n let e = {target: target};\n handleCategoryFlavorClick(e, modal);\n }\n }\n });\n }\n }\n};\n\n/**\n * Handle a click within filter button.\n *\n * @param {MouseEvent} event The change event\n * @param {obj} modal\n */\nconst handleCategoryClick = (event, modal) => {\n const link = event.target;\n currentCategoryId = link.dataset.categoryid;\n\n // Remove active from all and set to selected.\n const links = modal.getRoot()[0].querySelectorAll('.nav-link, .dropdown-item');\n links.forEach(node => node.classList.remove('active'));\n link.classList.add('active');\n\n // Show/hide component buttons.\n showCategoryButtons(modal, currentCategoryId);\n};\n\nconst handleCategoryFlavorClick = (event, modal) => {\n const link = event.target;\n currentFlavor = link.dataset.flavor;\n currentFlavorId = link.dataset.id;\n currentCategoryId = link.dataset.categoryid;\n lastFlavor[currentCategoryId] = currentFlavorId;\n\n // Remove active from all and set to selected.\n const links = modal.getRoot()[0].querySelectorAll('.nav-link, .dropdown-item');\n links.forEach(node => node.classList.remove('active'));\n link.classList.add('active');\n const category = modal.getRoot()[0].querySelector('.nav-link[data-categoryid=\"' + currentCategoryId + '\"]');\n category.classList.add('active');\n\n const componentButtons = modal.getRoot()[0].querySelectorAll('.elements-buttons-preview button');\n componentButtons.forEach(componentButton => {\n // Remove previous flavor.\n if (componentButton.dataset.flavor != undefined) {\n componentButton.classList.remove(componentButton.dataset.flavor);\n }\n componentButton.classList.add(currentFlavor);\n componentButton.dataset.flavor = currentFlavor;\n if (\n (componentButton.dataset.flavorlist == '' || componentButton.dataset.flavorlist.split(',').includes(currentFlavor)) &&\n componentButton.dataset.category == currentCategoryId\n ) {\n componentButton.classList.remove('elements-hidden');\n if (componentButton.dataset.flavorlist != '') {\n let variants = getVariantsClass(components[componentButton.dataset.id].name, currentFlavor);\n let availableVariants = componentButton.querySelectorAll('.elements-button-variant');\n availableVariants.forEach((variant) => {\n if (variants.indexOf('elements-' + variant.dataset.variant + '-variant') != -1) {\n updateVariantButtonState(variant, true);\n } else {\n updateVariantButtonState(variant, false);\n }\n });\n }\n } else {\n componentButton.classList.add('elements-hidden');\n }\n });\n\n};\n\n/**\n * Handle when closing the Modal.\n *\n * @param {obj} editor\n */\nconst handleModalHidden = (editor) => {\n editor.targetElm.closest('body').classList.remove('elements-modal-no-preview');\n if (currentCategoryId != 0 && currentFlavorId != 0) {\n savePreferences([\n {type: Preferences.category, value: currentCategoryId},\n {type: Preferences.category_flavors, value: JSON.stringify(lastFlavor)},\n {type: Preferences.component_variants, value: JSON.stringify(getVariantPreferences())}\n ]);\n }\n};\n\nconst updateComponentCode = (componentCode, selectedButton, placeholder, flavor = '') => {\n componentCode = componentCode.replace('{{PLACEHOLDER}}', placeholder);\n\n // Return active variants for current component.\n const variants = getVariantsClass(components[selectedButton].name, flavor);\n\n // Apply variants to html component.\n if (variants.length > 0) {\n componentCode = componentCode.replace('{{VARIANTS}}', variants.join(' '));\n componentCode = componentCode.replace('{{VARIANTSHTML}}', getVariantsHtml(components[selectedButton].name));\n } else {\n componentCode = componentCode.replace('{{VARIANTS}}', '');\n componentCode = componentCode.replace('{{VARIANTSHTML}}', '');\n }\n\n if (currentFlavor) {\n componentCode = componentCode.replace('{{FLAVOR}}', currentFlavor);\n } else {\n componentCode = componentCode.replace('{{FLAVOR}}', '');\n }\n\n componentCode = componentCode.replace('{{COMPONENT}}', components[selectedButton].name);\n componentCode = componentCode.replace('{{CATEGORY}}', categories[currentCategoryId].name);\n\n // Apply random IDs.\n componentCode = applyRandomID(componentCode);\n\n // Apply lang strings.\n componentCode = applyLangStrings(componentCode);\n\n return componentCode;\n};\n\n/**\n * Handle a click in a component button.\n *\n * @param {MouseEvent} event The click event\n * @param {obj} editor\n * @param {obj} modal\n */\nconst handleButtonClick = async(event, editor, modal) => {\n const selectedButton = event.target.closest('button').dataset.id;\n\n // Component button.\n if (components[selectedButton]) {\n const sel = editor.selection.getContent();\n let componentCode = components[selectedButton].code;\n const placeholder = (sel.length > 0 ? sel : components[selectedButton].text);\n\n let flavor = components[selectedButton].flavors.length > 0 ? currentFlavor : '';\n\n // Create a new node to replace the placeholder.\n const randomId = generateRandomID();\n const newNode = document.createElement('span');\n newNode.dataset.id = randomId;\n newNode.innerHTML = placeholder;\n componentCode = updateComponentCode(componentCode, selectedButton, newNode.outerHTML, flavor);\n // Sets new content.\n editor.selection.setContent(componentCode);\n\n // Select text.\n const nodeSel = editor.dom.select('span[data-id=\"' + randomId + '\"]');\n if (nodeSel?.[0]) {\n editor.selection.select(nodeSel[0]);\n }\n\n modal.destroy();\n editor.focus();\n }\n};\n\n/**\n * Handle a mouse events mouseenter/mouseleave in a component button.\n *\n * @param {MouseEvent} event The click event\n * @param {obj} modal\n * @param {bool} show\n */\nconst handleButtonMouseEvent = (event, modal, show) => {\n const selectedButton = event.target.closest('button').dataset.id;\n const node = modal.getRoot()[0].querySelector('div[data-id=\"code-preview-' + selectedButton + '\"]');\n const previewDefault = modal.getRoot()[0].querySelector('div[data-id=\"code-preview-default\"]');\n let flavor = components[selectedButton].flavors.length > 0 ? currentFlavor : '';\n\n node.innerHTML = updateComponentCode(components[selectedButton].code, selectedButton, components[selectedButton].text, flavor);\n\n if (node) {\n if (show) {\n previewDefault.classList.toggle('elements-hidden');\n node.classList.toggle('elements-hidden');\n } else {\n node.classList.toggle('elements-hidden');\n previewDefault.classList.toggle('elements-hidden');\n }\n }\n};\n\n/**\n * Handle a mouse events mouseenter/mouseleave in a variant button.\n * Not used at the moment.\n *\n * @param {MouseEvent} event The mouseenter/mouseleave event\n * @param {obj} modal\n * @param {bool} show\n */\n// eslint-disable-next-line no-unused-vars\nconst handleVariantMouseEvent = (event, modal, show) => {\n const variant = event.target.closest('span');\n const variantEnabled = variant.dataset.state == 'on';\n const button = event.target.closest('button');\n\n if (!variantEnabled) {\n updateVariantComponentState(variant, button, modal, show, false);\n }\n};\n\n\n/**\n * Handle a mouse event within the variant buttons.\n *\n * @param {MouseEvent} event The mouseenter/mouseleave event\n * @param {obj} modal\n */\nconst handleVariantClick = (event, modal) => {\n event.stopPropagation();\n const variant = event.target.closest('span');\n const button = event.target.closest('button');\n const flavor = components[button.dataset.id].flavors.length > 0 ? currentFlavor : '';\n\n updateVariantComponentState(variant, button, modal, false, true);\n\n const node = modal.getRoot()[0].querySelector('div[data-id=\"code-preview-' + button.dataset.id + '\"]');\n node.innerHTML = updateComponentCode(\n components[button.dataset.id].code,\n button.dataset.id,\n components[button.dataset.id].text,\n flavor\n );\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 = async(editor, data) => {\n return Object.assign({}, {\n elementid: editor.id,\n buttons: await getButtons(editor),\n categories: await getCategories(),\n preview: previewElements,\n }, data);\n};\n\n/**\n * Get the Elements categories for the dialogue.\n *\n * @returns {object} data\n */\nconst getCategories = async() => {\n const cats = [];\n //const stringValues = await getStrings(Contexts.map((key) => ({key, component})));\n // Iterate over contexts.\n categories.forEach((category) => {\n let categoryFlavors = getCategoryFlavors(category.id);\n let hasFlavors = hasCategoryFlavors(categoryFlavors);\n cats.push({\n categoryid: category.id,\n name: category.displayname,\n type: category.id,\n displayorder: category.displayorder,\n flavors: categoryFlavors,\n hasFlavors: hasFlavors,\n active: '',\n });\n });\n // Sort by displayorder and set first to active.\n cats.sort((a, b) => a.displayorder - b.displayorder);\n if (cats.length > 0) {\n cats[0].active = 'active';\n if (cats[0].flavors.length > 0) {\n cats[0].flavors[0].factive = 'active';\n }\n }\n\n return cats;\n};\n\nconst getComponentVariants = (component) => {\n const componentVariants = [];\n component.variants.forEach(variant => {\n let variantitem = findByName(variants, variant);\n if (variantitem !== undefined) {\n let state = variantExists(component.name, variantitem.name) ? 'on' : 'off';\n componentVariants.push({\n id: variantitem.id,\n name: variantitem.name,\n state: state,\n imageClass: variantitem.name + '-variant-' + state,\n title: langStrings.get(variantitem.name),\n content: variantitem.content,\n });\n }\n });\n return componentVariants;\n};\n\nconst getCategoryFlavors = (categoryId) => {\n const categoryFlavors = [];\n flavors.forEach(flavor => {\n if (flavor.categories == categoryId || flavor.categories.split(',').includes(categoryId)) {\n categoryFlavors.push({\n id: flavor.id,\n name: flavor.name,\n displayname: flavor.displayname,\n });\n }\n });\n return categoryFlavors;\n};\n\nconst hasCategoryFlavors = (value) => {\n return Array.isArray(value) && value.length;\n};\n\n/**\n * Get the Elements buttons for the dialogue.\n *\n * @param {Editor} editor\n * @returns {object} buttons\n */\nconst getButtons = async(editor) => {\n const buttons = [];\n // Not used at the moment.\n // eslint-disable-next-line no-unused-vars\n const sel = editor.selection.getContent();\n Object.values(components).forEach(component => {\n buttons.push({\n id: component.id,\n name: component.displayname,\n type: component.compcat,\n imageClass: 'elements-' + component.name + '-icon',\n htmlcode: component.code,\n variants: getComponentVariants(component, variants),\n flavorlist: component.flavors.join(','),\n category: component.compcat,\n });\n });\n buttons.sort((a, b) => a.displayorder - b.displayorder);\n\n return buttons;\n};\n\nconst getElementsData = async() => {\n const data = await fetchMany([{\n methodname: 'tiny_elements_get_elements_data',\n args: {\n isstudent: userStudent,\n contextid: contextid\n },\n }])[0];\n\n // TODO error handling\n const indexedComponents = [];\n data.components.forEach(component => {\n indexedComponents[component.id] = component;\n });\n\n const indexedVariants = [];\n data.variants.forEach(variant => {\n indexedVariants[variant.id] = variant;\n });\n\n const indexedCategories = [];\n data.categories.forEach(category => {\n indexedCategories[category.id] = category;\n });\n\n return {\n components: indexedComponents,\n variants: indexedVariants,\n categories: indexedCategories,\n flavors: data.flavors,\n };\n};\n\n/**\n * Get variants for the dialogue.\n * Not used at the moment.\n *\n * @param {string} component\n * @param {object} elements\n * @return {object} Variants for a component\n */\n// eslint-disable-next-line no-unused-vars\nconst getVariantsState = (component, elements) => {\n const variants = [];\n let variantState = '';\n let variantClass = '';\n\n // Max 3 variants.\n if (elements.length > 3) {\n elements = elements.slice(0, 2);\n }\n\n elements.forEach((variant, index) => {\n if (variantExists(component, variant)) {\n variantState = 'on';\n variantClass = 'on ';\n } else {\n variantState = 'off';\n variantClass = '';\n }\n variantClass += variant + '-variant-' + variantState;\n variants.push({\n id: index,\n name: variant,\n state: variantState,\n imageClass: variantClass,\n title: langStrings.get(variant),\n });\n });\n\n return variants;\n};\n\n/**\n * Update a variant component UI.\n *\n * @param {obj} variant\n * @param {obj} button\n * @param {obj} modal\n * @param {bool} show\n * @param {bool} updateHtml\n */\nconst updateVariantComponentState = (variant, button, modal, show, updateHtml) => {\n const selectedVariant = 'elements-' + variant.dataset.variant + '-variant';\n const selectedButton = button.dataset.id;\n const componentClass = button.dataset.classcomponent;\n const previewComponent = modal.getRoot()[0]\n .querySelector('div[data-id=\"code-preview-' + button.dataset.id + '\"] .' + componentClass);\n const variantPreview = modal.getRoot()[0]\n .querySelector('span[data-id=\"variantHTML-' + button.dataset.id + '\"]');\n let variantsHtml = '';\n let hasflavors = components[selectedButton].flavors.length > 0;\n\n if (previewComponent) {\n if (updateHtml) {\n if (variant.dataset.state == 'on') {\n removeVariant(components[selectedButton].name, variant.dataset.variant, hasflavors ? currentFlavor : '');\n updateVariantButtonState(variant, false);\n previewComponent.classList.remove(selectedVariant);\n } else {\n addVariant(components[selectedButton].name, variant.dataset.variant, hasflavors ? currentFlavor : '');\n updateVariantButtonState(variant, true);\n previewComponent.classList.add(selectedVariant);\n }\n\n // Update variant preview HTML.\n if (variantPreview) {\n variantPreview.innerHTML = getVariantsHtml(components[selectedButton].name);\n }\n } else {\n variantsHtml = getVariantsHtml(components[selectedButton].name);\n if (show) {\n previewComponent.classList.add(selectedVariant);\n variantsHtml += getVariantHtml(variant.dataset.variant);\n } else {\n previewComponent.classList.remove(selectedVariant);\n }\n\n // Update variant preview HTML.\n if (variantPreview) {\n variantPreview.innerHTML = variantsHtml;\n }\n }\n } else {\n // Update variants preferences.\n if (variant.dataset.state == 'on') {\n removeVariant(components[selectedButton].name, variant.dataset.variant, hasflavors ? currentFlavor : '');\n updateVariantButtonState(variant, false);\n } else {\n addVariant(components[selectedButton].name, variant.dataset.variant, hasflavors ? currentFlavor : '');\n updateVariantButtonState(variant, true);\n }\n }\n};\n\n/**\n * Update a variant button UI.\n *\n * @param {obj} variant\n * @param {bool} activate\n */\nconst updateVariantButtonState = (variant, activate) => {\n if (activate) {\n variant.dataset.state = 'on';\n variant.classList.remove(variant.dataset.variant + '-variant-off');\n variant.classList.add(variant.dataset.variant + '-variant-on');\n variant.classList.add('on');\n } else {\n variant.dataset.state = 'off';\n variant.classList.remove(variant.dataset.variant + '-variant-on');\n variant.classList.add(variant.dataset.variant + '-variant-off');\n variant.classList.remove('on');\n }\n};\n\n/**\n * Show/hide buttons depend on selected context.\n *\n * @param {object} modal\n * @param {String} context\n */\nconst showCategoryButtons = (modal, context) => {\n const showNodes = modal.getRoot()[0].querySelectorAll('button[data-type=\"' + context + '\"]');\n const hideNodes = modal.getRoot()[0].querySelectorAll('button[data-type]:not([data-type=\"' + context + '\"])');\n\n showNodes.forEach(node => node.classList.remove('elements-hidden'));\n hideNodes.forEach(node => node.classList.add('elements-hidden'));\n};\n\n/**\n * Replace all localized strings.\n *\n * @param {String} text\n * @return {String} String with lang tags replaced with a localized string.\n */\nconst applyLangStrings = (text) => {\n const compRegex = /{{#([^}]*)}}/g;\n\n [...text.matchAll(compRegex)].forEach(strLang => {\n text = text.replace('{{#' + strLang[1] + '}}', langStrings.get(strLang[1]));\n });\n\n return text;\n};\n\n/**\n * Generates a random string.\n * @return {string} A random string\n */\nconst generateRandomID = () => {\n const timestamp = new Date().getTime();\n return 'R' + Math.round(Math.random() * 100000) + '-' + timestamp;\n};\n\n/**\n * Replace all ID tags with a random string.\n * @param {String} text\n * @return {String} String with all ID tags replaced with a random string.\n */\nconst applyRandomID = (text) => {\n const compRegex = /{{@ID}}/g;\n\n if (text.match(compRegex)) {\n text = text.replace(compRegex, generateRandomID());\n }\n\n return text;\n};\n\n/**\n * Get language strings.\n *\n * @return {object} Language strings\n */\nconst getAllStrings = async() => {\n const keys = [];\n const compRegex = /{{#([^}]*)}}/g;\n\n components.forEach(element => {\n // Get lang strings from components.\n [...element.code.matchAll(compRegex)].forEach(strLang => {\n if (keys.indexOf(strLang[1]) === -1) {\n keys.push(strLang[1]);\n }\n });\n\n // Get lang strings from text placeholders.\n [...element.text.matchAll(compRegex)].forEach(strLang => {\n if (keys.indexOf(strLang[1]) === -1) {\n keys.push(strLang[1]);\n }\n });\n });\n\n const stringValues = await getStrings(keys.map((key) => ({key, component})));\n return new Map(keys.map((key, index) => ([key, stringValues[index]])));\n};\n"],"names":["userStudent","previewElements","components","categories","flavors","variants","langStrings","contextid","currentFlavor","currentFlavorId","currentCategoryId","lastFlavor","async","editor","data","getElementsData","getAllStrings","Preferences","category","category_flavors","componentVariants","component_variants","displayDialogue","Object","assign","templateContext","getTemplateContext","modal","ModalFactory","create","type","ElementsModal","TYPE","large","modalClass","targetElm","closest","classList","add","show","getRoot","on","ModalEvents","hidden","handleModalHidden","soleCategories","querySelectorAll","forEach","node","addEventListener","event","handleCategoryClick","selectCategories","handleCategoryFlavorClick","handleButtonClick","handleButtonMouseEvent","handleVariantClick","length","savedCategory","displayorder","click","dataset","categoryid","target","querySelector","link","remove","showCategoryButtons","flavor","id","componentButton","undefined","flavorlist","split","includes","name","variant","indexOf","updateVariantButtonState","value","JSON","stringify","updateComponentCode","componentCode","selectedButton","placeholder","replace","join","applyRandomID","applyLangStrings","sel","selection","getContent","code","text","randomId","generateRandomID","newNode","document","createElement","innerHTML","outerHTML","setContent","nodeSel","dom","select","destroy","focus","previewDefault","toggle","stopPropagation","button","updateVariantComponentState","elementid","buttons","getButtons","getCategories","preview","cats","categoryFlavors","getCategoryFlavors","hasFlavors","hasCategoryFlavors","push","displayname","active","sort","a","b","factive","getComponentVariants","component","variantitem","state","imageClass","title","get","content","categoryId","Array","isArray","values","compcat","htmlcode","methodname","args","isstudent","indexedComponents","indexedVariants","indexedCategories","updateHtml","selectedVariant","componentClass","classcomponent","previewComponent","variantPreview","variantsHtml","hasflavors","activate","context","showNodes","hideNodes","matchAll","strLang","timestamp","Date","getTime","Math","round","random","compRegex","match","keys","element","stringValues","map","key","Map","index"],"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 Elements UI.\n *\n * @module tiny_elements/ui\n * @copyright 2022 Marc Català \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {component} from './common';\nimport ElementsModal from './modal';\nimport ModalFactory from 'core/modal_factory';\nimport {get_strings as getStrings} from 'core/str';\nimport {\n isStudent,\n showPreview\n} from './options';\nimport ModalEvents from 'core/modal_events';\nimport {\n addVariant,\n getVariantsClass,\n getVariantHtml,\n getVariantPreferences,\n getVariantsHtml,\n loadVariantPreferences,\n removeVariant,\n setFlavors,\n setVariants,\n variantExists,\n setComponents\n} from './variantslib';\nimport {\n findByName\n} from './helper';\nimport {\n savePreferences,\n loadPreferences,\n Preferences\n} from './preferencelib';\nimport {call as fetchMany} from 'core/ajax';\nimport {getContextId} from 'editor_tiny/options';\n\nlet userStudent = false;\n\nlet previewElements = true;\nlet components = [];\nlet categories = [];\nlet flavors = [];\nlet variants = [];\nlet langStrings = {};\nlet contextid = 1;\n\nlet currentFlavor = '';\nlet currentFlavorId = 0;\nlet currentCategoryId = 1;\nlet lastFlavor = [];\n\n/**\n * Handle action\n *\n * @param {TinyMCE} editor\n */\nexport const handleAction = async(editor) => {\n contextid = getContextId(editor);\n userStudent = isStudent(editor);\n let data = await getElementsData();\n components = data.components;\n categories = data.categories;\n flavors = data.flavors;\n variants = data.variants;\n setComponents(components);\n setVariants(variants);\n setFlavors(flavors);\n previewElements = showPreview(editor);\n langStrings = await getAllStrings();\n currentCategoryId = await loadPreferences(Preferences.category);\n lastFlavor = await loadPreferences(Preferences.category_flavors);\n if (lastFlavor === null) {\n lastFlavor = [];\n }\n let componentVariants = await loadPreferences(Preferences.component_variants);\n if (componentVariants === null) {\n componentVariants = {};\n }\n loadVariantPreferences(componentVariants);\n displayDialogue(editor);\n};\n\n/**\n * Display modal\n *\n * @param {TinyMCE} editor\n */\nconst displayDialogue = async(editor) => {\n const data = Object.assign({}, {});\n const templateContext = await getTemplateContext(editor, data);\n // Show modal with buttons.\n const modal = await ModalFactory.create({\n type: ElementsModal.TYPE,\n templateContext: templateContext,\n large: true,\n });\n\n // Choose class to modal.\n const modalClass = previewElements ? 'elements-modal' : 'elements-modal-no-preview';\n\n // Set class to modal.\n editor.targetElm.closest('body').classList.add(modalClass);\n\n modal.show();\n\n // Event modal listener.\n modal.getRoot().on(ModalEvents.hidden, () => {\n handleModalHidden(editor);\n });\n\n // Event listener for categories without flavors.\n const soleCategories = modal.getRoot()[0].querySelectorAll('.elements-category.no-flavors');\n soleCategories.forEach(node => {\n node.addEventListener('click', (event) => {\n handleCategoryClick(event, modal);\n });\n });\n\n // Event listener for categories with flavors.\n const selectCategories = modal.getRoot()[0].querySelectorAll('.elements-category-flavor');\n selectCategories.forEach(node => {\n node.addEventListener('click', (event) => {\n handleCategoryFlavorClick(event, modal);\n });\n });\n\n // Event buttons listeners.\n const buttons = modal.getRoot()[0].querySelectorAll('.elementst-dialog-button');\n buttons.forEach(node => {\n node.addEventListener('click', (event) => {\n handleButtonClick(event, editor, modal);\n });\n if (previewElements) {\n node.addEventListener('mouseenter', (event) => {\n handleButtonMouseEvent(event, modal, true);\n });\n node.addEventListener('mouseleave', (event) => {\n handleButtonMouseEvent(event, modal, false);\n });\n }\n });\n\n // Event variants listeners.\n const variants = modal.getRoot()[0].querySelectorAll('.elements-button-variant');\n variants.forEach(node => {\n node.addEventListener('click', (event) => {\n handleVariantClick(event, modal);\n });\n });\n\n // Select first or saved category.\n if (soleCategories.length > 0 || selectCategories.length > 0) {\n let savedCategory = currentCategoryId;\n if (soleCategories[0].displayorder > selectCategories[0].displayorder ) {\n selectCategories[0].click();\n } else {\n soleCategories[0].click();\n }\n if (savedCategory != 0) {\n soleCategories.forEach((node) => {\n if (node.dataset.categoryid == savedCategory) {\n node.click();\n }\n });\n selectCategories.forEach((node) => {\n if (node.dataset.categoryid == savedCategory) {\n // Simulate click on flavor.\n let target = modal.getRoot()[0].querySelector(\n '.elements-category-flavor[data-id=\"' + currentFlavorId + '\"]',\n );\n if (target) {\n let e = {target: target};\n handleCategoryFlavorClick(e, modal);\n }\n }\n });\n }\n }\n};\n\n/**\n * Handle a click within filter button.\n *\n * @param {MouseEvent} event The change event\n * @param {obj} modal\n */\nconst handleCategoryClick = (event, modal) => {\n const link = event.target;\n currentCategoryId = link.dataset.categoryid;\n\n // Remove active from all and set to selected.\n const links = modal.getRoot()[0].querySelectorAll('.nav-link, .dropdown-item');\n links.forEach(node => node.classList.remove('active'));\n link.classList.add('active');\n\n // Show/hide component buttons.\n showCategoryButtons(modal, currentCategoryId);\n};\n\nconst handleCategoryFlavorClick = (event, modal) => {\n const link = event.target;\n currentFlavor = link.dataset.flavor;\n currentFlavorId = link.dataset.id;\n currentCategoryId = link.dataset.categoryid;\n lastFlavor[currentCategoryId] = currentFlavorId;\n\n // Remove active from all and set to selected.\n const links = modal.getRoot()[0].querySelectorAll('.nav-link, .dropdown-item');\n links.forEach(node => node.classList.remove('active'));\n link.classList.add('active');\n const category = modal.getRoot()[0].querySelector('.nav-link[data-categoryid=\"' + currentCategoryId + '\"]');\n category.classList.add('active');\n\n const componentButtons = modal.getRoot()[0].querySelectorAll('.elements-buttons-preview button');\n componentButtons.forEach(componentButton => {\n // Remove previous flavor.\n if (componentButton.dataset.flavor != undefined) {\n componentButton.classList.remove(componentButton.dataset.flavor);\n }\n componentButton.classList.add(currentFlavor);\n componentButton.dataset.flavor = currentFlavor;\n if (\n (componentButton.dataset.flavorlist == '' || componentButton.dataset.flavorlist.split(',').includes(currentFlavor)) &&\n componentButton.dataset.category == currentCategoryId\n ) {\n componentButton.classList.remove('elements-hidden');\n if (componentButton.dataset.flavorlist != '') {\n let variants = getVariantsClass(components[componentButton.dataset.id].name, currentFlavor);\n let availableVariants = componentButton.querySelectorAll('.elements-button-variant');\n availableVariants.forEach((variant) => {\n updateVariantButtonState(variant, variants.indexOf(variant.dataset.variantclass) != -1);\n });\n }\n } else {\n componentButton.classList.add('elements-hidden');\n }\n });\n\n};\n\n/**\n * Handle when closing the Modal.\n *\n * @param {obj} editor\n */\nconst handleModalHidden = (editor) => {\n editor.targetElm.closest('body').classList.remove('elements-modal-no-preview');\n if (currentCategoryId != 0 && currentFlavorId != 0) {\n savePreferences([\n {type: Preferences.category, value: currentCategoryId},\n {type: Preferences.category_flavors, value: JSON.stringify(lastFlavor)},\n {type: Preferences.component_variants, value: JSON.stringify(getVariantPreferences())}\n ]);\n }\n};\n\nconst updateComponentCode = (componentCode, selectedButton, placeholder, flavor = '') => {\n componentCode = componentCode.replace('{{PLACEHOLDER}}', placeholder);\n\n // Return active variants for current component.\n const variants = getVariantsClass(components[selectedButton].name, flavor);\n\n // Apply variants to html component.\n if (variants.length > 0) {\n componentCode = componentCode.replace('{{VARIANTS}}', variants.join(' '));\n componentCode = componentCode.replace('{{VARIANTSHTML}}', getVariantsHtml(components[selectedButton].name));\n } else {\n componentCode = componentCode.replace('{{VARIANTS}}', '');\n componentCode = componentCode.replace('{{VARIANTSHTML}}', '');\n }\n\n if (currentFlavor) {\n componentCode = componentCode.replace('{{FLAVOR}}', currentFlavor);\n } else {\n componentCode = componentCode.replace('{{FLAVOR}}', '');\n }\n\n componentCode = componentCode.replace('{{COMPONENT}}', components[selectedButton].name);\n componentCode = componentCode.replace('{{CATEGORY}}', categories[currentCategoryId].name);\n\n // Apply random IDs.\n componentCode = applyRandomID(componentCode);\n\n // Apply lang strings.\n componentCode = applyLangStrings(componentCode);\n\n return componentCode;\n};\n\n/**\n * Handle a click in a component button.\n *\n * @param {MouseEvent} event The click event\n * @param {obj} editor\n * @param {obj} modal\n */\nconst handleButtonClick = async(event, editor, modal) => {\n const selectedButton = event.target.closest('button').dataset.id;\n\n // Component button.\n if (components[selectedButton]) {\n const sel = editor.selection.getContent();\n let componentCode = components[selectedButton].code;\n const placeholder = (sel.length > 0 ? sel : components[selectedButton].text);\n\n let flavor = components[selectedButton].flavors.length > 0 ? currentFlavor : '';\n\n // Create a new node to replace the placeholder.\n const randomId = generateRandomID();\n const newNode = document.createElement('span');\n newNode.dataset.id = randomId;\n newNode.innerHTML = placeholder;\n componentCode = updateComponentCode(componentCode, selectedButton, newNode.outerHTML, flavor);\n // Sets new content.\n editor.selection.setContent(componentCode);\n\n // Select text.\n const nodeSel = editor.dom.select('span[data-id=\"' + randomId + '\"]');\n if (nodeSel?.[0]) {\n editor.selection.select(nodeSel[0]);\n }\n\n modal.destroy();\n editor.focus();\n }\n};\n\n/**\n * Handle a mouse events mouseenter/mouseleave in a component button.\n *\n * @param {MouseEvent} event The click event\n * @param {obj} modal\n * @param {bool} show\n */\nconst handleButtonMouseEvent = (event, modal, show) => {\n const selectedButton = event.target.closest('button').dataset.id;\n const node = modal.getRoot()[0].querySelector('div[data-id=\"code-preview-' + selectedButton + '\"]');\n const previewDefault = modal.getRoot()[0].querySelector('div[data-id=\"code-preview-default\"]');\n let flavor = components[selectedButton].flavors.length > 0 ? currentFlavor : '';\n\n node.innerHTML = updateComponentCode(components[selectedButton].code, selectedButton, components[selectedButton].text, flavor);\n\n if (node) {\n if (show) {\n previewDefault.classList.toggle('elements-hidden');\n node.classList.toggle('elements-hidden');\n } else {\n node.classList.toggle('elements-hidden');\n previewDefault.classList.toggle('elements-hidden');\n }\n }\n};\n\n/**\n * Handle a mouse events mouseenter/mouseleave in a variant button.\n * Not used at the moment.\n *\n * @param {MouseEvent} event The mouseenter/mouseleave event\n * @param {obj} modal\n * @param {bool} show\n */\n// eslint-disable-next-line no-unused-vars\nconst handleVariantMouseEvent = (event, modal, show) => {\n const variant = event.target.closest('span');\n const variantEnabled = variant.dataset.state == 'on';\n const button = event.target.closest('button');\n\n if (!variantEnabled) {\n updateVariantComponentState(variant, button, modal, show, false);\n }\n};\n\n\n/**\n * Handle a mouse event within the variant buttons.\n *\n * @param {MouseEvent} event The mouseenter/mouseleave event\n * @param {obj} modal\n */\nconst handleVariantClick = (event, modal) => {\n event.stopPropagation();\n const variant = event.target.closest('span');\n const button = event.target.closest('button');\n const flavor = components[button.dataset.id].flavors.length > 0 ? currentFlavor : '';\n\n updateVariantComponentState(variant, button, modal, false, true);\n\n const node = modal.getRoot()[0].querySelector('div[data-id=\"code-preview-' + button.dataset.id + '\"]');\n node.innerHTML = updateComponentCode(\n components[button.dataset.id].code,\n button.dataset.id,\n components[button.dataset.id].text,\n flavor\n );\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 = async(editor, data) => {\n return Object.assign({}, {\n elementid: editor.id,\n buttons: await getButtons(editor),\n categories: await getCategories(),\n preview: previewElements,\n }, data);\n};\n\n/**\n * Get the Elements categories for the dialogue.\n *\n * @returns {object} data\n */\nconst getCategories = async() => {\n const cats = [];\n //const stringValues = await getStrings(Contexts.map((key) => ({key, component})));\n // Iterate over contexts.\n categories.forEach((category) => {\n let categoryFlavors = getCategoryFlavors(category.id);\n let hasFlavors = hasCategoryFlavors(categoryFlavors);\n cats.push({\n categoryid: category.id,\n name: category.displayname,\n type: category.id,\n displayorder: category.displayorder,\n flavors: categoryFlavors,\n hasFlavors: hasFlavors,\n active: '',\n });\n });\n // Sort by displayorder and set first to active.\n cats.sort((a, b) => a.displayorder - b.displayorder);\n if (cats.length > 0) {\n cats[0].active = 'active';\n if (cats[0].flavors.length > 0) {\n cats[0].flavors[0].factive = 'active';\n }\n }\n\n return cats;\n};\n\nconst getComponentVariants = (component) => {\n const componentVariants = [];\n component.variants.forEach(variant => {\n let variantitem = findByName(variants, variant);\n if (variantitem !== undefined) {\n let state = variantExists(component.name, variantitem.name) ? 'on' : 'off';\n componentVariants.push({\n id: variantitem.id,\n name: variantitem.name,\n state: state,\n imageClass: variantitem.name + '-variant-' + state,\n variantclass: (variantitem.c4lcompatibility ? 'c4l' : 'elements') + '-' + variantitem.name + '-variant',\n title: langStrings.get(variantitem.name),\n content: variantitem.content,\n });\n }\n });\n return componentVariants;\n};\n\nconst getCategoryFlavors = (categoryId) => {\n const categoryFlavors = [];\n flavors.forEach(flavor => {\n if (flavor.categories == categoryId || flavor.categories.split(',').includes(categoryId)) {\n categoryFlavors.push({\n id: flavor.id,\n name: flavor.name,\n displayname: flavor.displayname,\n });\n }\n });\n return categoryFlavors;\n};\n\nconst hasCategoryFlavors = (value) => {\n return Array.isArray(value) && value.length;\n};\n\n/**\n * Get the Elements buttons for the dialogue.\n *\n * @param {Editor} editor\n * @returns {object} buttons\n */\nconst getButtons = async(editor) => {\n const buttons = [];\n // Not used at the moment.\n // eslint-disable-next-line no-unused-vars\n const sel = editor.selection.getContent();\n Object.values(components).forEach(component => {\n buttons.push({\n id: component.id,\n name: component.displayname,\n type: component.compcat,\n imageClass: 'elements-' + component.name + '-icon',\n htmlcode: component.code,\n variants: getComponentVariants(component, variants),\n flavorlist: component.flavors.join(','),\n category: component.compcat,\n });\n });\n buttons.sort((a, b) => a.displayorder - b.displayorder);\n\n return buttons;\n};\n\nconst getElementsData = async() => {\n const data = await fetchMany([{\n methodname: 'tiny_elements_get_elements_data',\n args: {\n isstudent: userStudent,\n contextid: contextid\n },\n }])[0];\n\n // TODO error handling\n const indexedComponents = [];\n data.components.forEach(component => {\n indexedComponents[component.id] = component;\n });\n\n const indexedVariants = [];\n data.variants.forEach(variant => {\n indexedVariants[variant.id] = variant;\n });\n\n const indexedCategories = [];\n data.categories.forEach(category => {\n indexedCategories[category.id] = category;\n });\n\n return {\n components: indexedComponents,\n variants: indexedVariants,\n categories: indexedCategories,\n flavors: data.flavors,\n };\n};\n\n/**\n * Get variants for the dialogue.\n * Not used at the moment.\n *\n * @param {string} component\n * @param {object} elements\n * @return {object} Variants for a component\n */\n// eslint-disable-next-line no-unused-vars\nconst getVariantsState = (component, elements) => {\n const variants = [];\n let variantState = '';\n let variantClass = '';\n\n // Max 3 variants.\n if (elements.length > 3) {\n elements = elements.slice(0, 2);\n }\n\n elements.forEach((variant, index) => {\n if (variantExists(component, variant)) {\n variantState = 'on';\n variantClass = 'on ';\n } else {\n variantState = 'off';\n variantClass = '';\n }\n variantClass += variant + '-variant-' + variantState;\n variants.push({\n id: index,\n name: variant,\n state: variantState,\n imageClass: variantClass,\n title: langStrings.get(variant),\n });\n });\n\n return variants;\n};\n\n/**\n * Update a variant component UI.\n *\n * @param {obj} variant\n * @param {obj} button\n * @param {obj} modal\n * @param {bool} show\n * @param {bool} updateHtml\n */\nconst updateVariantComponentState = (variant, button, modal, show, updateHtml) => {\n const selectedVariant = variant.dataset.variantclass;\n const selectedButton = button.dataset.id;\n const componentClass = button.dataset.classcomponent;\n const previewComponent = modal.getRoot()[0]\n .querySelector('div[data-id=\"code-preview-' + button.dataset.id + '\"] .' + componentClass);\n const variantPreview = modal.getRoot()[0]\n .querySelector('span[data-id=\"variantHTML-' + button.dataset.id + '\"]');\n let variantsHtml = '';\n let hasflavors = components[selectedButton].flavors.length > 0;\n\n if (previewComponent) {\n if (updateHtml) {\n if (variant.dataset.state == 'on') {\n removeVariant(components[selectedButton].name, variant.dataset.variant, hasflavors ? currentFlavor : '');\n updateVariantButtonState(variant, false);\n previewComponent.classList.remove(selectedVariant);\n } else {\n addVariant(components[selectedButton].name, variant.dataset.variant, hasflavors ? currentFlavor : '');\n updateVariantButtonState(variant, true);\n previewComponent.classList.add(selectedVariant);\n }\n\n // Update variant preview HTML.\n if (variantPreview) {\n variantPreview.innerHTML = getVariantsHtml(components[selectedButton].name);\n }\n } else {\n variantsHtml = getVariantsHtml(components[selectedButton].name);\n if (show) {\n previewComponent.classList.add(selectedVariant);\n variantsHtml += getVariantHtml(variant.dataset.variant);\n } else {\n previewComponent.classList.remove(selectedVariant);\n }\n\n // Update variant preview HTML.\n if (variantPreview) {\n variantPreview.innerHTML = variantsHtml;\n }\n }\n } else {\n // Update variants preferences.\n if (variant.dataset.state == 'on') {\n removeVariant(components[selectedButton].name, variant.dataset.variant, hasflavors ? currentFlavor : '');\n updateVariantButtonState(variant, false);\n } else {\n addVariant(components[selectedButton].name, variant.dataset.variant, hasflavors ? currentFlavor : '');\n updateVariantButtonState(variant, true);\n }\n }\n};\n\n/**\n * Update a variant button UI.\n *\n * @param {obj} variant\n * @param {bool} activate\n */\nconst updateVariantButtonState = (variant, activate) => {\n if (activate) {\n variant.dataset.state = 'on';\n variant.classList.remove(variant.dataset.variant + '-variant-off');\n variant.classList.add(variant.dataset.variant + '-variant-on');\n variant.classList.add('on');\n } else {\n variant.dataset.state = 'off';\n variant.classList.remove(variant.dataset.variant + '-variant-on');\n variant.classList.add(variant.dataset.variant + '-variant-off');\n variant.classList.remove('on');\n }\n};\n\n/**\n * Show/hide buttons depend on selected context.\n *\n * @param {object} modal\n * @param {String} context\n */\nconst showCategoryButtons = (modal, context) => {\n const showNodes = modal.getRoot()[0].querySelectorAll('button[data-type=\"' + context + '\"]');\n const hideNodes = modal.getRoot()[0].querySelectorAll('button[data-type]:not([data-type=\"' + context + '\"])');\n\n showNodes.forEach(node => node.classList.remove('elements-hidden'));\n hideNodes.forEach(node => node.classList.add('elements-hidden'));\n};\n\n/**\n * Replace all localized strings.\n *\n * @param {String} text\n * @return {String} String with lang tags replaced with a localized string.\n */\nconst applyLangStrings = (text) => {\n const compRegex = /{{#([^}]*)}}/g;\n\n [...text.matchAll(compRegex)].forEach(strLang => {\n text = text.replace('{{#' + strLang[1] + '}}', langStrings.get(strLang[1]));\n });\n\n return text;\n};\n\n/**\n * Generates a random string.\n * @return {string} A random string\n */\nconst generateRandomID = () => {\n const timestamp = new Date().getTime();\n return 'R' + Math.round(Math.random() * 100000) + '-' + timestamp;\n};\n\n/**\n * Replace all ID tags with a random string.\n * @param {String} text\n * @return {String} String with all ID tags replaced with a random string.\n */\nconst applyRandomID = (text) => {\n const compRegex = /{{@ID}}/g;\n\n if (text.match(compRegex)) {\n text = text.replace(compRegex, generateRandomID());\n }\n\n return text;\n};\n\n/**\n * Get language strings.\n *\n * @return {object} Language strings\n */\nconst getAllStrings = async() => {\n const keys = [];\n const compRegex = /{{#([^}]*)}}/g;\n\n components.forEach(element => {\n // Get lang strings from components.\n [...element.code.matchAll(compRegex)].forEach(strLang => {\n if (keys.indexOf(strLang[1]) === -1) {\n keys.push(strLang[1]);\n }\n });\n\n // Get lang strings from text placeholders.\n [...element.text.matchAll(compRegex)].forEach(strLang => {\n if (keys.indexOf(strLang[1]) === -1) {\n keys.push(strLang[1]);\n }\n });\n });\n\n const stringValues = await getStrings(keys.map((key) => ({key, component})));\n return new Map(keys.map((key, index) => ([key, stringValues[index]])));\n};\n"],"names":["userStudent","previewElements","components","categories","flavors","variants","langStrings","contextid","currentFlavor","currentFlavorId","currentCategoryId","lastFlavor","async","editor","data","getElementsData","getAllStrings","Preferences","category","category_flavors","componentVariants","component_variants","displayDialogue","Object","assign","templateContext","getTemplateContext","modal","ModalFactory","create","type","ElementsModal","TYPE","large","modalClass","targetElm","closest","classList","add","show","getRoot","on","ModalEvents","hidden","handleModalHidden","soleCategories","querySelectorAll","forEach","node","addEventListener","event","handleCategoryClick","selectCategories","handleCategoryFlavorClick","handleButtonClick","handleButtonMouseEvent","handleVariantClick","length","savedCategory","displayorder","click","dataset","categoryid","target","querySelector","link","remove","showCategoryButtons","flavor","id","componentButton","undefined","flavorlist","split","includes","name","variant","updateVariantButtonState","indexOf","variantclass","value","JSON","stringify","updateComponentCode","componentCode","selectedButton","placeholder","replace","join","applyRandomID","applyLangStrings","sel","selection","getContent","code","text","randomId","generateRandomID","newNode","document","createElement","innerHTML","outerHTML","setContent","nodeSel","dom","select","destroy","focus","previewDefault","toggle","stopPropagation","button","updateVariantComponentState","elementid","buttons","getButtons","getCategories","preview","cats","categoryFlavors","getCategoryFlavors","hasFlavors","hasCategoryFlavors","push","displayname","active","sort","a","b","factive","getComponentVariants","component","variantitem","state","imageClass","c4lcompatibility","title","get","content","categoryId","Array","isArray","values","compcat","htmlcode","methodname","args","isstudent","indexedComponents","indexedVariants","indexedCategories","updateHtml","selectedVariant","componentClass","classcomponent","previewComponent","variantPreview","variantsHtml","hasflavors","activate","context","showNodes","hideNodes","matchAll","strLang","timestamp","Date","getTime","Math","round","random","compRegex","match","keys","element","stringValues","map","key","Map","index"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/variantslib.min.js b/amd/build/variantslib.min.js index df5b4b6..497eeff 100644 --- a/amd/build/variantslib.min.js +++ b/amd/build/variantslib.min.js @@ -1,4 +1,4 @@ -define("tiny_c4l/variantslib",["exports","./helper"],(function(_exports,_helper){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.variantExists=_exports.setVariants=_exports.setFlavors=_exports.setComponents=_exports.removeVariant=_exports.loadVariantPreferences=_exports.getVariantsHtml=_exports.getVariantsClass=_exports.getVariantPreferences=_exports.getVariantPreference=_exports.getVariantHtml=_exports.addVariant=void 0; +define("tiny_elements/variantslib",["exports","./helper"],(function(_exports,_helper){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.variantExists=_exports.setVariants=_exports.setFlavors=_exports.setComponents=_exports.removeVariant=_exports.loadVariantPreferences=_exports.getVariantsHtml=_exports.getVariantsClass=_exports.getVariantPreferences=_exports.getVariantPreference=_exports.getVariantHtml=_exports.addVariant=void 0; /** * Variants helper for Elements plugin. * @@ -6,6 +6,6 @@ define("tiny_c4l/variantslib",["exports","./helper"],(function(_exports,_helper) * @copyright 2023 Marc Català * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -let variantPreferences={},VARIANTS=[],COMPONENTS=[],FLAVORS=[];_exports.setFlavors=flavors=>{FLAVORS=flavors};_exports.setVariants=variants=>{VARIANTS=variants};_exports.setComponents=components=>{COMPONENTS=components};_exports.getVariantPreferences=()=>variantPreferences;_exports.loadVariantPreferences=preferences=>{variantPreferences=null!=preferences?preferences:{}};const getVariantPreference=function(component){let flavor=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",componentObj=(0,_helper.findByName)(COMPONENTS,component),flavorObj=(0,_helper.findByName)(FLAVORS,flavor);return void 0===componentObj?[]:""!=flavor||variantPreferences[componentObj.id]?""!=flavor&&void 0===flavorObj?[]:""==flavor||variantPreferences[componentObj.id+"-"+flavorObj.id]?""==flavor?variantPreferences[componentObj.id]:variantPreferences[componentObj.id+"-"+flavorObj.id]:[]:[]};_exports.getVariantPreference=getVariantPreference;const variantExists=function(component,variant){let flavor=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",variantObj=(0,_helper.findByName)(VARIANTS,variant);return-1!==getVariantPreference(component,flavor).indexOf(variantObj.id)};_exports.variantExists=variantExists;_exports.getVariantsClass=function(component){let flavor=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",variants=[];return getVariantPreference(component,flavor).forEach((variant=>{let variantObj=(0,_helper.findById)(VARIANTS,variant);void 0!==variantObj&&variants.push("elements-"+variantObj.name+"-variant")})),variants};_exports.getVariantsHtml=component=>{let variantsHtml="",variantObj={};return(0,_helper.findByName)(COMPONENTS,component).variants.forEach((variant=>{variantObj=(0,_helper.findByName)(VARIANTS,variant),null!=variantObj&&(variantsHtml+=variantObj.content)})),variantsHtml};_exports.getVariantHtml=variant=>{let variantHtml=[],variantObj={};return variantObj=(0,_helper.findByName)(VARIANTS,variant),null!=variantObj&&(variantHtml=variantObj.html),variantHtml};_exports.addVariant=function(component,variant){let flavor=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",componentObj=(0,_helper.findByName)(COMPONENTS,component),variantObj=(0,_helper.findByName)(VARIANTS,variant),flavorObj=(0,_helper.findByName)(FLAVORS,flavor);""==flavor?(variantPreferences[componentObj.id]||(variantPreferences[componentObj.id]=[]),variantExists(component,variant)||variantPreferences[componentObj.id].push(variantObj.id)):(variantPreferences[componentObj.id+"-"+flavorObj.id]||(variantPreferences[componentObj.id+"-"+flavorObj.id]=[]),variantExists(component,variant,flavor)||variantPreferences[componentObj.id+"-"+flavorObj.id].push(variantObj.id))};_exports.removeVariant=function(component,variant){let flavor=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",componentObj=(0,_helper.findByName)(COMPONENTS,component),variantObj=(0,_helper.findByName)(VARIANTS,variant),flavorObj=(0,_helper.findByName)(FLAVORS,flavor);if(""!=flavor){let index=variantPreferences[componentObj.id+"-"+flavorObj.id].indexOf(variantObj.id);-1!==index&&delete variantPreferences[componentObj.id+"-"+flavorObj.id][index],0==variantPreferences[componentObj.id+"-"+flavorObj.id].length&&delete variantPreferences[componentObj.id+"-"+flavorObj.id]}else{let index=variantPreferences[componentObj.id].indexOf(variantObj.id);-1!==index&&delete variantPreferences[componentObj.id][index],0==variantPreferences[componentObj.id].length&&delete variantPreferences[componentObj.id]}}})); +let variantPreferences={},VARIANTS=[],COMPONENTS=[],FLAVORS=[];_exports.setFlavors=flavors=>{FLAVORS=flavors};_exports.setVariants=variants=>{VARIANTS=variants};_exports.setComponents=components=>{COMPONENTS=components};_exports.getVariantPreferences=()=>variantPreferences;_exports.loadVariantPreferences=preferences=>{variantPreferences=null!=preferences?preferences:{}};const getVariantPreference=function(component){let flavor=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",componentObj=(0,_helper.findByName)(COMPONENTS,component),flavorObj=(0,_helper.findByName)(FLAVORS,flavor);return void 0===componentObj?[]:""!=flavor||variantPreferences[componentObj.id]?""!=flavor&&void 0===flavorObj?[]:""==flavor||variantPreferences[componentObj.id+"-"+flavorObj.id]?""==flavor?variantPreferences[componentObj.id]:variantPreferences[componentObj.id+"-"+flavorObj.id]:[]:[]};_exports.getVariantPreference=getVariantPreference;const variantExists=function(component,variant){let flavor=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",variantObj=(0,_helper.findByName)(VARIANTS,variant);return-1!==getVariantPreference(component,flavor).indexOf(variantObj.id)};_exports.variantExists=variantExists;_exports.getVariantsClass=function(component){let flavor=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",variants=[];return getVariantPreference(component,flavor).forEach((variant=>{let variantObj=(0,_helper.findById)(VARIANTS,variant);void 0!==variantObj&&variants.push((variant.c4lcompatibility?"c4l":"elements")+"-"+variantObj.name+"-variant")})),variants};_exports.getVariantsHtml=component=>{let variantsHtml="",variantObj={};return(0,_helper.findByName)(COMPONENTS,component).variants.forEach((variant=>{variantObj=(0,_helper.findByName)(VARIANTS,variant),null!=variantObj&&(variantsHtml+=variantObj.content)})),variantsHtml};_exports.getVariantHtml=variant=>{let variantHtml=[],variantObj={};return variantObj=(0,_helper.findByName)(VARIANTS,variant),null!=variantObj&&(variantHtml=variantObj.html),variantHtml};_exports.addVariant=function(component,variant){let flavor=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",componentObj=(0,_helper.findByName)(COMPONENTS,component),variantObj=(0,_helper.findByName)(VARIANTS,variant),flavorObj=(0,_helper.findByName)(FLAVORS,flavor);""==flavor?(variantPreferences[componentObj.id]||(variantPreferences[componentObj.id]=[]),variantExists(component,variant)||variantPreferences[componentObj.id].push(variantObj.id)):(variantPreferences[componentObj.id+"-"+flavorObj.id]||(variantPreferences[componentObj.id+"-"+flavorObj.id]=[]),variantExists(component,variant,flavor)||variantPreferences[componentObj.id+"-"+flavorObj.id].push(variantObj.id))};_exports.removeVariant=function(component,variant){let flavor=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",componentObj=(0,_helper.findByName)(COMPONENTS,component),variantObj=(0,_helper.findByName)(VARIANTS,variant),flavorObj=(0,_helper.findByName)(FLAVORS,flavor);if(""!=flavor){let index=variantPreferences[componentObj.id+"-"+flavorObj.id].indexOf(variantObj.id);-1!==index&&delete variantPreferences[componentObj.id+"-"+flavorObj.id][index],0==variantPreferences[componentObj.id+"-"+flavorObj.id].length&&delete variantPreferences[componentObj.id+"-"+flavorObj.id]}else{let index=variantPreferences[componentObj.id].indexOf(variantObj.id);-1!==index&&delete variantPreferences[componentObj.id][index],0==variantPreferences[componentObj.id].length&&delete variantPreferences[componentObj.id]}}})); //# sourceMappingURL=variantslib.min.js.map \ No newline at end of file diff --git a/amd/build/variantslib.min.js.map b/amd/build/variantslib.min.js.map index 3d1a250..75c07c9 100644 --- a/amd/build/variantslib.min.js.map +++ b/amd/build/variantslib.min.js.map @@ -1 +1 @@ -{"version":3,"file":"variantslib.min.js","sources":["../src/variantslib.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 * Variants helper for Elements plugin.\n *\n * @module tiny_elements/variantslib\n * @copyright 2023 Marc Català \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {\n findById,\n findByName\n} from './helper';\n\nlet variantPreferences = {};\nlet VARIANTS = [];\nlet COMPONENTS = [];\nlet FLAVORS = [];\n\nexport const setFlavors = (flavors) => {\n FLAVORS = flavors;\n};\n\nexport const setVariants = (variants) => {\n VARIANTS = variants;\n};\n\nexport const setComponents = (components) => {\n COMPONENTS = components;\n};\n\nexport const getVariantPreferences = () => {\n return variantPreferences;\n};\n\n/**\n * Load user preferences.\n * @param {array} preferences\n * @returns {Promise}\n */\nexport const loadVariantPreferences = (preferences) => {\n if (preferences !== undefined && preferences !== null) {\n variantPreferences = preferences;\n } else {\n variantPreferences = {};\n }\n};\n\n/**\n * Get variant preferences for a single component-flavor combination.\n * @param {*} component\n * @param {*} flavor\n * @returns\n */\nexport const getVariantPreference = (component, flavor = '') => {\n let componentObj = findByName(COMPONENTS, component);\n let flavorObj = findByName(FLAVORS, flavor);\n\n if (componentObj === undefined) {\n return [];\n }\n\n if (flavor == '' && !variantPreferences[componentObj.id]) {\n return [];\n }\n\n if (flavor != '' && flavorObj === undefined) {\n return [];\n }\n\n if (flavor != '' && !variantPreferences[componentObj.id + '-' + flavorObj.id]) {\n return [];\n }\n\n if (flavor == '') {\n return variantPreferences[componentObj.id];\n } else {\n return variantPreferences[componentObj.id + '-' + flavorObj.id];\n }\n};\n\n/**\n * Returns whether a variant exists for a component.\n *\n * @param {string} component Component name\n * @param {string} variant Variant name\n * @param {string} flavor Flavor name\n * @returns {bool}\n */\nexport const variantExists = (component, variant, flavor = '') => {\n let variantObj = findByName(VARIANTS, variant);\n return getVariantPreference(component, flavor).indexOf(variantObj.id) !== -1;\n};\n\n/**\n * Returns each variant for a component as a CSS class.\n *\n * @param {string} component Component name\n * @param {string} flavor Flavor name\n * @returns {Array}\n */\nexport const getVariantsClass = (component, flavor = '') => {\n let variants = [];\n getVariantPreference(component, flavor).forEach(variant => {\n let variantObj = findById(VARIANTS, variant);\n if (variantObj !== undefined) {\n variants.push('elements-' + variantObj.name + '-variant');\n }\n });\n\n return variants;\n};\n\n/**\n * Return all HTML variants for a component.\n *\n * @param {string} component Component name\n * @returns {string}\n */\nexport const getVariantsHtml = (component) => {\n let variantsHtml = '';\n let variantObj = {};\n\n let componentObj = findByName(COMPONENTS, component);\n componentObj.variants.forEach(variant => {\n variantObj = findByName(VARIANTS, variant);\n if (variantObj != undefined) {\n variantsHtml += variantObj.content;\n }\n });\n\n return variantsHtml;\n};\n\n/**\n * Return the HTML variant.\n *\n * @param {string} variant Variant name\n * @returns {string}\n */\nexport const getVariantHtml = (variant) => {\n let variantHtml = [];\n let variantObj = {};\n\n variantObj = findByName(VARIANTS, variant);\n if (variantObj != undefined) {\n variantHtml = variantObj.html;\n }\n return variantHtml;\n};\n\n/**\n * Add a variant to variantPreferences\n *\n * @param {string} component Component name\n * @param {string} variant Variant name\n * @param {string} flavor Flavor name\n */\nexport const addVariant = (component, variant, flavor = '') => {\n let componentObj = findByName(COMPONENTS, component);\n let variantObj = findByName(VARIANTS, variant);\n let flavorObj = findByName(FLAVORS, flavor);\n\n if (flavor == '') {\n if (!variantPreferences[componentObj.id]) {\n variantPreferences[componentObj.id] = [];\n }\n if (!variantExists(component, variant)) {\n variantPreferences[componentObj.id].push(variantObj.id);\n }\n } else {\n if (!variantPreferences[componentObj.id + '-' + flavorObj.id]) {\n variantPreferences[componentObj.id + '-' + flavorObj.id] = [];\n }\n if (!variantExists(component, variant, flavor)) {\n variantPreferences[componentObj.id + '-' + flavorObj.id].push(variantObj.id);\n }\n }\n};\n\n/**\n * Remove a variant from variantPreferences\n *\n * @param {string} component Component name\n * @param {string} variant Variant name\n * @param {string} flavor Flavor name\n */\nexport const removeVariant = (component, variant, flavor = '') => {\n let componentObj = findByName(COMPONENTS, component);\n let variantObj = findByName(VARIANTS, variant);\n let flavorObj = findByName(FLAVORS, flavor);\n\n if (flavor != '') {\n let index = variantPreferences[componentObj.id + '-' + flavorObj.id].indexOf(variantObj.id);\n if (index !== -1) {\n delete variantPreferences[componentObj.id + '-' + flavorObj.id][index];\n }\n if (variantPreferences[componentObj.id + '-' + flavorObj.id].length == 0) {\n delete variantPreferences[componentObj.id + '-' + flavorObj.id];\n }\n } else {\n let index = variantPreferences[componentObj.id].indexOf(variantObj.id);\n if (index !== -1) {\n delete variantPreferences[componentObj.id][index];\n }\n if (variantPreferences[componentObj.id].length == 0) {\n delete variantPreferences[componentObj.id];\n }\n }\n};\n"],"names":["variantPreferences","VARIANTS","COMPONENTS","FLAVORS","flavors","variants","components","preferences","getVariantPreference","component","flavor","componentObj","flavorObj","undefined","id","variantExists","variant","variantObj","indexOf","forEach","push","name","variantsHtml","content","variantHtml","html","index","length"],"mappings":";;;;;;;;IA4BIA,mBAAqB,GACrBC,SAAW,GACXC,WAAa,GACbC,QAAU,uBAEaC,UACvBD,QAAUC,8BAGcC,WACxBJ,SAAWI,iCAGeC,aAC1BJ,WAAaI,2CAGoB,IAC1BN,mDAQ4BO,cAE/BP,mBADAO,MAAAA,YACqBA,YAEA,UAUhBC,qBAAuB,SAACC,eAAWC,8DAAS,GACjDC,cAAe,sBAAWT,WAAYO,WACtCG,WAAY,sBAAWT,QAASO,oBAEfG,IAAjBF,aACO,GAGG,IAAVD,QAAiBV,mBAAmBW,aAAaG,IAIvC,IAAVJ,aAA8BG,IAAdD,UACT,GAGG,IAAVF,QAAiBV,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,IAI5D,IAAVJ,OACOV,mBAAmBW,aAAaG,IAEhCd,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,IANrD,GARA,6DA0BFC,cAAgB,SAACN,UAAWO,aAASN,8DAAS,GACnDO,YAAa,sBAAWhB,SAAUe,gBACqC,IAApER,qBAAqBC,UAAWC,QAAQQ,QAAQD,WAAWH,oEAUtC,SAACL,eAAWC,8DAAS,GAC7CL,SAAW,UACfG,qBAAqBC,UAAWC,QAAQS,SAAQH,cACxCC,YAAa,oBAAShB,SAAUe,cACjBH,IAAfI,YACAZ,SAASe,KAAK,YAAcH,WAAWI,KAAO,eAI/ChB,mCASqBI,gBACxBa,aAAe,GACfL,WAAa,UAEE,sBAAWf,WAAYO,WAC7BJ,SAASc,SAAQH,UAC1BC,YAAa,sBAAWhB,SAAUe,SAChBH,MAAdI,aACAK,cAAgBL,WAAWM,YAI5BD,sCASoBN,cACvBQ,YAAc,GACdP,WAAa,UAEjBA,YAAa,sBAAWhB,SAAUe,SAChBH,MAAdI,aACAO,YAAcP,WAAWQ,MAEtBD,iCAUe,SAACf,UAAWO,aAASN,8DAAS,GAChDC,cAAe,sBAAWT,WAAYO,WACtCQ,YAAa,sBAAWhB,SAAUe,SAClCJ,WAAY,sBAAWT,QAASO,QAEtB,IAAVA,QACKV,mBAAmBW,aAAaG,MACjCd,mBAAmBW,aAAaG,IAAM,IAErCC,cAAcN,UAAWO,UAC1BhB,mBAAmBW,aAAaG,IAAIM,KAAKH,WAAWH,MAGnDd,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,MACtDd,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,IAAM,IAE1DC,cAAcN,UAAWO,QAASN,SACnCV,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,IAAIM,KAAKH,WAAWH,6BAYxD,SAACL,UAAWO,aAASN,8DAAS,GACnDC,cAAe,sBAAWT,WAAYO,WACtCQ,YAAa,sBAAWhB,SAAUe,SAClCJ,WAAY,sBAAWT,QAASO,WAEtB,IAAVA,OAAc,KACVgB,MAAQ1B,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,IAAII,QAAQD,WAAWH,KACzE,IAAXY,cACO1B,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,IAAIY,OAEG,GAAnE1B,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,IAAIa,eAClD3B,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,QAE7D,KACCY,MAAQ1B,mBAAmBW,aAAaG,IAAII,QAAQD,WAAWH,KACpD,IAAXY,cACO1B,mBAAmBW,aAAaG,IAAIY,OAEG,GAA9C1B,mBAAmBW,aAAaG,IAAIa,eAC7B3B,mBAAmBW,aAAaG"} \ No newline at end of file +{"version":3,"file":"variantslib.min.js","sources":["../src/variantslib.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 * Variants helper for Elements plugin.\n *\n * @module tiny_elements/variantslib\n * @copyright 2023 Marc Català \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {\n findById,\n findByName\n} from './helper';\n\nlet variantPreferences = {};\nlet VARIANTS = [];\nlet COMPONENTS = [];\nlet FLAVORS = [];\n\nexport const setFlavors = (flavors) => {\n FLAVORS = flavors;\n};\n\nexport const setVariants = (variants) => {\n VARIANTS = variants;\n};\n\nexport const setComponents = (components) => {\n COMPONENTS = components;\n};\n\nexport const getVariantPreferences = () => {\n return variantPreferences;\n};\n\n/**\n * Load user preferences.\n * @param {array} preferences\n * @returns {Promise}\n */\nexport const loadVariantPreferences = (preferences) => {\n if (preferences !== undefined && preferences !== null) {\n variantPreferences = preferences;\n } else {\n variantPreferences = {};\n }\n};\n\n/**\n * Get variant preferences for a single component-flavor combination.\n * @param {*} component\n * @param {*} flavor\n * @returns\n */\nexport const getVariantPreference = (component, flavor = '') => {\n let componentObj = findByName(COMPONENTS, component);\n let flavorObj = findByName(FLAVORS, flavor);\n\n if (componentObj === undefined) {\n return [];\n }\n\n if (flavor == '' && !variantPreferences[componentObj.id]) {\n return [];\n }\n\n if (flavor != '' && flavorObj === undefined) {\n return [];\n }\n\n if (flavor != '' && !variantPreferences[componentObj.id + '-' + flavorObj.id]) {\n return [];\n }\n\n if (flavor == '') {\n return variantPreferences[componentObj.id];\n } else {\n return variantPreferences[componentObj.id + '-' + flavorObj.id];\n }\n};\n\n/**\n * Returns whether a variant exists for a component.\n *\n * @param {string} component Component name\n * @param {string} variant Variant name\n * @param {string} flavor Flavor name\n * @returns {bool}\n */\nexport const variantExists = (component, variant, flavor = '') => {\n let variantObj = findByName(VARIANTS, variant);\n return getVariantPreference(component, flavor).indexOf(variantObj.id) !== -1;\n};\n\n/**\n * Returns each variant for a component as a CSS class.\n *\n * @param {string} component Component name\n * @param {string} flavor Flavor name\n * @returns {Array}\n */\nexport const getVariantsClass = (component, flavor = '') => {\n let variants = [];\n getVariantPreference(component, flavor).forEach(variant => {\n let variantObj = findById(VARIANTS, variant);\n if (variantObj !== undefined) {\n variants.push((variant.c4lcompatibility ? 'c4l' : 'elements') + '-' + variantObj.name + '-variant');\n }\n });\n\n return variants;\n};\n\n/**\n * Return all HTML variants for a component.\n *\n * @param {string} component Component name\n * @returns {string}\n */\nexport const getVariantsHtml = (component) => {\n let variantsHtml = '';\n let variantObj = {};\n\n let componentObj = findByName(COMPONENTS, component);\n componentObj.variants.forEach(variant => {\n variantObj = findByName(VARIANTS, variant);\n if (variantObj != undefined) {\n variantsHtml += variantObj.content;\n }\n });\n\n return variantsHtml;\n};\n\n/**\n * Return the HTML variant.\n *\n * @param {string} variant Variant name\n * @returns {string}\n */\nexport const getVariantHtml = (variant) => {\n let variantHtml = [];\n let variantObj = {};\n\n variantObj = findByName(VARIANTS, variant);\n if (variantObj != undefined) {\n variantHtml = variantObj.html;\n }\n return variantHtml;\n};\n\n/**\n * Add a variant to variantPreferences\n *\n * @param {string} component Component name\n * @param {string} variant Variant name\n * @param {string} flavor Flavor name\n */\nexport const addVariant = (component, variant, flavor = '') => {\n let componentObj = findByName(COMPONENTS, component);\n let variantObj = findByName(VARIANTS, variant);\n let flavorObj = findByName(FLAVORS, flavor);\n\n if (flavor == '') {\n if (!variantPreferences[componentObj.id]) {\n variantPreferences[componentObj.id] = [];\n }\n if (!variantExists(component, variant)) {\n variantPreferences[componentObj.id].push(variantObj.id);\n }\n } else {\n if (!variantPreferences[componentObj.id + '-' + flavorObj.id]) {\n variantPreferences[componentObj.id + '-' + flavorObj.id] = [];\n }\n if (!variantExists(component, variant, flavor)) {\n variantPreferences[componentObj.id + '-' + flavorObj.id].push(variantObj.id);\n }\n }\n};\n\n/**\n * Remove a variant from variantPreferences\n *\n * @param {string} component Component name\n * @param {string} variant Variant name\n * @param {string} flavor Flavor name\n */\nexport const removeVariant = (component, variant, flavor = '') => {\n let componentObj = findByName(COMPONENTS, component);\n let variantObj = findByName(VARIANTS, variant);\n let flavorObj = findByName(FLAVORS, flavor);\n\n if (flavor != '') {\n let index = variantPreferences[componentObj.id + '-' + flavorObj.id].indexOf(variantObj.id);\n if (index !== -1) {\n delete variantPreferences[componentObj.id + '-' + flavorObj.id][index];\n }\n if (variantPreferences[componentObj.id + '-' + flavorObj.id].length == 0) {\n delete variantPreferences[componentObj.id + '-' + flavorObj.id];\n }\n } else {\n let index = variantPreferences[componentObj.id].indexOf(variantObj.id);\n if (index !== -1) {\n delete variantPreferences[componentObj.id][index];\n }\n if (variantPreferences[componentObj.id].length == 0) {\n delete variantPreferences[componentObj.id];\n }\n }\n};\n"],"names":["variantPreferences","VARIANTS","COMPONENTS","FLAVORS","flavors","variants","components","preferences","getVariantPreference","component","flavor","componentObj","flavorObj","undefined","id","variantExists","variant","variantObj","indexOf","forEach","push","c4lcompatibility","name","variantsHtml","content","variantHtml","html","index","length"],"mappings":";;;;;;;;IA4BIA,mBAAqB,GACrBC,SAAW,GACXC,WAAa,GACbC,QAAU,uBAEaC,UACvBD,QAAUC,8BAGcC,WACxBJ,SAAWI,iCAGeC,aAC1BJ,WAAaI,2CAGoB,IAC1BN,mDAQ4BO,cAE/BP,mBADAO,MAAAA,YACqBA,YAEA,UAUhBC,qBAAuB,SAACC,eAAWC,8DAAS,GACjDC,cAAe,sBAAWT,WAAYO,WACtCG,WAAY,sBAAWT,QAASO,oBAEfG,IAAjBF,aACO,GAGG,IAAVD,QAAiBV,mBAAmBW,aAAaG,IAIvC,IAAVJ,aAA8BG,IAAdD,UACT,GAGG,IAAVF,QAAiBV,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,IAI5D,IAAVJ,OACOV,mBAAmBW,aAAaG,IAEhCd,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,IANrD,GARA,6DA0BFC,cAAgB,SAACN,UAAWO,aAASN,8DAAS,GACnDO,YAAa,sBAAWhB,SAAUe,gBACqC,IAApER,qBAAqBC,UAAWC,QAAQQ,QAAQD,WAAWH,oEAUtC,SAACL,eAAWC,8DAAS,GAC7CL,SAAW,UACfG,qBAAqBC,UAAWC,QAAQS,SAAQH,cACxCC,YAAa,oBAAShB,SAAUe,cACjBH,IAAfI,YACAZ,SAASe,MAAMJ,QAAQK,iBAAmB,MAAQ,YAAc,IAAMJ,WAAWK,KAAO,eAIzFjB,mCASqBI,gBACxBc,aAAe,GACfN,WAAa,UAEE,sBAAWf,WAAYO,WAC7BJ,SAASc,SAAQH,UAC1BC,YAAa,sBAAWhB,SAAUe,SAChBH,MAAdI,aACAM,cAAgBN,WAAWO,YAI5BD,sCASoBP,cACvBS,YAAc,GACdR,WAAa,UAEjBA,YAAa,sBAAWhB,SAAUe,SAChBH,MAAdI,aACAQ,YAAcR,WAAWS,MAEtBD,iCAUe,SAAChB,UAAWO,aAASN,8DAAS,GAChDC,cAAe,sBAAWT,WAAYO,WACtCQ,YAAa,sBAAWhB,SAAUe,SAClCJ,WAAY,sBAAWT,QAASO,QAEtB,IAAVA,QACKV,mBAAmBW,aAAaG,MACjCd,mBAAmBW,aAAaG,IAAM,IAErCC,cAAcN,UAAWO,UAC1BhB,mBAAmBW,aAAaG,IAAIM,KAAKH,WAAWH,MAGnDd,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,MACtDd,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,IAAM,IAE1DC,cAAcN,UAAWO,QAASN,SACnCV,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,IAAIM,KAAKH,WAAWH,6BAYxD,SAACL,UAAWO,aAASN,8DAAS,GACnDC,cAAe,sBAAWT,WAAYO,WACtCQ,YAAa,sBAAWhB,SAAUe,SAClCJ,WAAY,sBAAWT,QAASO,WAEtB,IAAVA,OAAc,KACViB,MAAQ3B,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,IAAII,QAAQD,WAAWH,KACzE,IAAXa,cACO3B,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,IAAIa,OAEG,GAAnE3B,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,IAAIc,eAClD5B,mBAAmBW,aAAaG,GAAK,IAAMF,UAAUE,QAE7D,KACCa,MAAQ3B,mBAAmBW,aAAaG,IAAII,QAAQD,WAAWH,KACpD,IAAXa,cACO3B,mBAAmBW,aAAaG,IAAIa,OAEG,GAA9C3B,mBAAmBW,aAAaG,IAAIc,eAC7B5B,mBAAmBW,aAAaG"} \ No newline at end of file diff --git a/amd/src/commands.js b/amd/src/commands.js index e1ee1e9..e23f7c2 100644 --- a/amd/src/commands.js +++ b/amd/src/commands.js @@ -30,10 +30,7 @@ import { elementsMenuItemName, icon, } from './common'; -import { - isElementsVisible, - getpreviewCSS -} from './options'; +import {isElementsVisible} from './options'; export const getSetup = async() => { const [ @@ -65,9 +62,6 @@ export const getSetup = async() => { text: elementsMenuItemNameTitle, onAction: () => handleAction(editor), }); - - // Inject custom CSS. - editor.options.set('content_style', getpreviewCSS(editor)); } }; }; diff --git a/amd/src/components.js b/amd/src/components.js deleted file mode 100644 index 79e5d66..0000000 --- a/amd/src/components.js +++ /dev/null @@ -1,270 +0,0 @@ -// This file is part of Moodle - http://moodle.org/ -// -// Moodle is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Moodle is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Moodle. If not, see . - -/** - * Tiny Elements components. - * - * @module tiny_elements/components - * @copyright 2022 Marc Català - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -const components = [ - { - id: "0", - name: "keyconcept", - type: "contextual", - imageClass: "elements-keyconcept-icon", - code: - '

' + - "{{PLACEHOLDER}}


", - text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tempor odio vel turpis consequat sodales.", - variants: ["full-width"], - }, - { - id: "1", - name: "tip", - type: "contextual", - imageClass: "elements-tip-icon", - code: - `

- {{PLACEHOLDER}}


`, - text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tempor odio vel turpis consequat sodales.", - variants: ["full-width"], - }, - { - id: "2", - name: "reminder", - type: "contextual", - imageClass: "elements-reminder-icon", - code: - `

- {{PLACEHOLDER}}


`, - text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tempor odio vel turpis consequat sodales.", - variants: ["full-width"], - }, - { - id: "3", - name: "quote", - type: "contextual", - imageClass: "elements-quote-icon", - code: - `

-
-

{{PLACEHOLDER}}

-
- {{VARIANTSHTML}} -


`, - text: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus a posuere nibh, eu mollis lacus." + - " Praesent dictum in velit sed dapibus.", - variants: ["full-width", "quote"], - }, - { - id: "4", - name: "dodontcards", - type: "contextual", - imageClass: "elements-dodontcards-icon", - code: - `

-
{{PLACEHOLDER}}
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. - Phasellus a posuere nibh, eu mollis lacus. - Praesent dictum in velit sed dapibus. Orci varius natoque penatibus et magnis dis parturient montes, - nascetur ridiculus mus.


`, - text: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus a posuere nibh, eu mollis lacus." + - " Praesent dictum in velit sed dapibus." + - "Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.", - variants: ["full-width"], - }, - { - id: "5", - name: "readingcontext", - type: "contextual", - imageClass: "elements-readingcontext-icon", - code: - `

-

{{PLACEHOLDER}}

{{VARIANTSHTML}}


`, - text: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus leo, hendrerit ac sem vitae," + - " posuere egestas nisi. Lorem ipsum dolor sit amet. " + - "Phasellus leo, hendrerit ac sem vitae, posuere egestas nisi.", - variants: ["full-width", "quote", "comfort-reading"], - }, - { - id: "6", - name: "example", - type: "contextual", - imageClass: "elements-example-icon", - code: - `

Lorem ipsum dolor sit amet

-

{{PLACEHOLDER}}


`, - text: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit." + - " Phasellus a posuere nibh, eu mollis lacus." + - " Praesent dictum in velit sed dapibus. Orci varius natoque penatibus et magnis dis parturient montes," + - " nascetur ridiculus mus.", - variants: ["full-width"], - }, - { - id: "7", - name: "figure", - type: "contextual", - imageClass: "elements-figure-icon", - code: - `

Lorem ipsum dolor sit amet - {{VARIANTSHTML}}


`, - text: "Consectetur adipiscing elit.", - variants: ["full-width", "caption"], - }, - { - id: "8", - name: "tag", - type: "contextual", - imageClass: "elements-tag-icon", - code: - `

-
{{PLACEHOLDER}}
`, - text: "Lorem ipsum", - variants: ["align-right"], - }, - { - id: "9", - name: "inlinetag", - type: "contextual", - imageClass: "elements-inlinetag-icon", - code: `{{PLACEHOLDER}}`, - text: "Text", - variants: [], - }, - { - id: "10", - name: "attention", - type: "procedural", - imageClass: "elements-attention-icon", - code: - `

- "{{PLACEHOLDER}}


`, - text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tempor odio vel turpis consequat sodales.", - variants: ["full-width"], - }, - { - id: "11", - name: "estimatedtime", - type: "procedural", - imageClass: "elements-estimatedtime-icon", - code: - `

{{PLACEHOLDER}} {{#min}}
`, - text: "15", - variants: ["align-left"], - }, - { - id: "12", - name: "duedate", - type: "procedural", - imageClass: "elements-duedate-icon", - code: - `

{{PLACEHOLDER}}
`, - text: "November 17th", - variants: ["align-left"], - }, - { - id: "13", - name: "proceduralcontext", - type: "procedural", - imageClass: "elements-proceduralcontext-icon", - code: - `

- {{PLACEHOLDER}}


`, - text: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus a posuere nibh, eu mollis lacus." + - " Praesent dictum in velit sed dapibus." + - " Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla quis lorem aliquet," + - " fermentum dolor ac, venenatis turpis.", - variants: ["full-width"], - }, - { - id: "14", - name: "learningoutcomes", - type: "procedural", - imageClass: "elements-learningoutcomes-icon", - code: - `

-
-
{{#learningoutcomes}}
-
  • {{PLACEHOLDER}}
  • Curabitur non nulla sit amet - nisl tempus convallis quis ac lectus. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.
  • -
  • Nulla porttitor accumsan tincidunt. Curabitur aliquet quam id dui posuere blandit. - Curabitur non nulla sit amet nisl tempus convallis quis ac lectus.


`, - text: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut porta, neque id feugiat consectetur, " + - "enim ipsum tincidunt nunc, id suscipit mauris urna sit amet lectus.", - variants: ["full-width", "ordered-list"], - }, - { - id: "15", - name: "gradingvalue", - type: "evaluative", - imageClass: "elements-gradingvalue-icon", - code: - `

{{#gradingvalue}}: {{PLACEHOLDER}}
`, - text: "33.3%", - variants: ["align-left"], - }, - { - id: "16", - name: "expectedfeedback", - type: "evaluative", - imageClass: "elements-expectedfeedback-icon", - code: - `

-

{{PLACEHOLDER}}


`, - text: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus a posuere nibh, eu mollis lacus." + - " Praesent dictum in velit sed dapibus.", - variants: ["full-width"], - }, - { - id: "17", - name: "allpurposecard", - type: "helper", - imageClass: "elements-allpurposecard-icon", - code: - `

{{PLACEHOLDER}}


`, - text: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus a posuere nibh, eu mollis lacus." + - " Praesent dictum in velit sed dapibus." + - " Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.", - variants: ["full-width"], - }, -]; - -export default { - components, -}; diff --git a/amd/src/options.js b/amd/src/options.js index 539503c..fc85756 100644 --- a/amd/src/options.js +++ b/amd/src/options.js @@ -26,7 +26,7 @@ import {pluginName} from './common'; const isstudentName = getPluginOptionName(pluginName, 'isstudent'); const showpreviewName = getPluginOptionName(pluginName, 'showpreview'); -const viewelementsName = getPluginOptionName(pluginName, 'viewelements'); +const viewElementsName = getPluginOptionName(pluginName, 'viewelements'); const cssUrlName = getPluginOptionName(pluginName, 'cssurl'); export const register = (editor) => { @@ -42,7 +42,7 @@ export const register = (editor) => { "default": true, }); - registerOption(viewelementsName, { + registerOption(viewElementsName, { processor: 'boolean', "default": true, }); @@ -59,7 +59,7 @@ export const register = (editor) => { * @param {TinyMCE} editor * @returns {object} */ -export const isElementsVisible = (editor) => editor.options.get(viewelementsName); +export const isElementsVisible = (editor) => editor.options.get(viewElementsName); /** * Get whether user is a student configuration for the Tiny Elements plugin. diff --git a/amd/src/ui.js b/amd/src/ui.js index fbab963..9040160 100644 --- a/amd/src/ui.js +++ b/amd/src/ui.js @@ -248,11 +248,7 @@ const handleCategoryFlavorClick = (event, modal) => { let variants = getVariantsClass(components[componentButton.dataset.id].name, currentFlavor); let availableVariants = componentButton.querySelectorAll('.elements-button-variant'); availableVariants.forEach((variant) => { - if (variants.indexOf('elements-' + variant.dataset.variant + '-variant') != -1) { - updateVariantButtonState(variant, true); - } else { - updateVariantButtonState(variant, false); - } + updateVariantButtonState(variant, variants.indexOf(variant.dataset.variantclass) != -1); }); } } else { @@ -479,6 +475,7 @@ const getComponentVariants = (component) => { name: variantitem.name, state: state, imageClass: variantitem.name + '-variant-' + state, + variantclass: (variantitem.c4lcompatibility ? 'c4l' : 'elements') + '-' + variantitem.name + '-variant', title: langStrings.get(variantitem.name), content: variantitem.content, }); @@ -616,7 +613,7 @@ const getVariantsState = (component, elements) => { * @param {bool} updateHtml */ const updateVariantComponentState = (variant, button, modal, show, updateHtml) => { - const selectedVariant = 'elements-' + variant.dataset.variant + '-variant'; + const selectedVariant = variant.dataset.variantclass; const selectedButton = button.dataset.id; const componentClass = button.dataset.classcomponent; const previewComponent = modal.getRoot()[0] diff --git a/amd/src/variantslib.js b/amd/src/variantslib.js index b10f500..3de69fb 100644 --- a/amd/src/variantslib.js +++ b/amd/src/variantslib.js @@ -118,7 +118,7 @@ export const getVariantsClass = (component, flavor = '') => { getVariantPreference(component, flavor).forEach(variant => { let variantObj = findById(VARIANTS, variant); if (variantObj !== undefined) { - variants.push('elements-' + variantObj.name + '-variant'); + variants.push((variant.c4lcompatibility ? 'c4l' : 'elements') + '-' + variantObj.name + '-variant'); } }); diff --git a/classes/external/get_c4l_data.php b/classes/external/get_c4l_data.php deleted file mode 100644 index d70d470..0000000 --- a/classes/external/get_c4l_data.php +++ /dev/null @@ -1,112 +0,0 @@ -. - -namespace tiny_elements\external; - -use core_external\external_api; -use core_external\external_function_parameters; -use core_external\external_multiple_structure; -use core_external\external_single_structure; -use core_external\external_value; - -/** - * Web service to retrieve all elements data. - * - * @package tiny_elements - * @copyright 2024 ISB Bayern - * @author Stefan Hanauska - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class get_elements_data extends external_api { - /** - * Describes the parameters. - * - * @return external_function_parameters - */ - public static function execute_parameters(): external_function_parameters { - return new external_function_parameters([ - 'contextid' => new external_value(PARAM_INT, 'Context id', VALUE_REQUIRED), - 'isstudent' => new external_value(PARAM_BOOL, 'Only return components for students', VALUE_REQUIRED), - ]); - } - - /** - * Retrieve the categories, components, flavors and variants. - * - * @return array associative array containing the aggregated information for all elements data. - */ - public static function execute(int $contextid, bool $isstudent): array { - // We usually need to call validate_parameters, but we do not have any (yet). - self::validate_parameters(self::execute_parameters(), [ - 'contextid' => $contextid, - 'isstudent' => $isstudent, - ]); - $context = \core\context::instance_by_id($contextid); - self::validate_context($context); - - require_capability('tiny/elements:viewplugin', $context); - - return \tiny_elements\local\utils::get_elements_data($isstudent); - } - - /** - * Describes the return structure of the service. - * - * @return external_multiple_structure the return structure - */ - public static function execute_returns(): external_single_structure { - return new external_single_structure([ - 'categories' => new external_multiple_structure( - new external_single_structure([ - 'id' => new external_value(PARAM_INT, 'the id of the category'), - 'name' => new external_value(PARAM_TEXT, 'the name of the category'), - 'displayname' => new external_value(PARAM_TEXT, 'the display name of the category'), - 'displayorder' => new external_value(PARAM_INT, 'the display order of the category'), - ], 'a component category') - ), - 'components' => new external_multiple_structure( - new external_single_structure([ - 'id' => new external_value(PARAM_INT, 'the id of the component'), - 'name' => new external_value(PARAM_TEXT, 'the name of the component'), - 'displayname' => new external_value(PARAM_TEXT, 'the display name of the component'), - 'compcat' => new external_value(PARAM_INT, 'the id of the component category'), - 'code' => new external_value(PARAM_RAW, 'the code'), - 'text' => new external_value(PARAM_TEXT, 'the text'), - 'variants' => new external_multiple_structure(new external_value(PARAM_TEXT, 'the variants')), - 'flavors' => new external_multiple_structure(new external_value(PARAM_TEXT, 'the flavors')), - 'displayorder' => new external_value(PARAM_INT, 'the display order of the component'), - ], 'a component') - ), - 'flavors' => new external_multiple_structure( - new external_single_structure([ - 'id' => new external_value(PARAM_INT, 'the id of the flavor'), - 'name' => new external_value(PARAM_TEXT, 'the name of the flavor'), - 'displayname' => new external_value(PARAM_TEXT, 'the display name of the flavor'), - 'content' => new external_value(PARAM_RAW, 'the content'), - 'categories' => new external_value(PARAM_TEXT, 'the categories'), - ], 'a component flavor') - ), - 'variants' => new external_multiple_structure( - new external_single_structure([ - 'id' => new external_value(PARAM_INT, 'the id of the variant'), - 'name' => new external_value(PARAM_TEXT, 'the name of the variant'), - 'displayname' => new external_value(PARAM_TEXT, 'the display name of the variant'), - 'content' => new external_value(PARAM_RAW, 'the content'), - ], 'a component variant') - ), - ]); - } -} diff --git a/classes/form/management_import_form.php b/classes/form/management_import_form.php index 38ad62d..cbabca7 100644 --- a/classes/form/management_import_form.php +++ b/classes/form/management_import_form.php @@ -73,32 +73,13 @@ public function process_dynamic_submission(): array { if ($file === null) { throw new \moodle_exception('errorbackupfile', 'tiny_elements'); } + $manager = new \tiny_elements\manager(); + if ($file->get_mimetype() == 'application/zip') { - $fp = get_file_packer('application/zip'); - $fp->extract_to_storage($file, SYSCONTEXTID, 'tiny_elements', 'import', $draftitemid, '/'); - $xmlfile = $fs->get_file(SYSCONTEXTID, 'tiny_elements', 'import', $draftitemid, '/', 'tiny_elements_export.xml'); - if (!$xmlfile) { - throw new \moodle_exception('errorbackupfile', 'tiny_elements'); - } - $xmlcontent = $xmlfile->get_content(); + $manager->import($file); } else { $xmlcontent = $file->get_content(); - } - - $manager = new \tiny_elements\manager(); - $manager->importxml($xmlcontent); - $categories = $DB->get_records('tiny_elements_compcat'); - foreach ($categories as $category) { - $categoryfiles = $fs->get_directory_files( - SYSCONTEXTID, - 'tiny_elements', - 'import', - $draftitemid, - '/' . $category->name . '/', - true, - false - ); - $manager->importfiles($categoryfiles, $category->id, $category->name); + $manager->importxml($xmlcontent); } \tiny_elements\local\utils::purge_css_cache(); diff --git a/classes/form/management_variant_form.php b/classes/form/management_variant_form.php index a2d5852..889bdce 100644 --- a/classes/form/management_variant_form.php +++ b/classes/form/management_variant_form.php @@ -52,5 +52,10 @@ public function definition() { $mform->addElement('url', 'iconurl', get_string('iconurl', 'tiny_elements'), ['size' => '255']); $mform->setType('iconurl', PARAM_URL); + + $mform->addElement('advcheckbox', 'c4lcompatibility', get_string('c4lcompatibility', 'tiny_elements')); + $mform->setType('c4lcompatibility', PARAM_INT); + $mform->setDefault('c4lcompatibility', 0); + $mform->addHelpButton('c4lcompatibility', 'c4lcompatibility', 'tiny_elements'); } } diff --git a/classes/manager.php b/classes/manager.php index 8cd02fb..52ce1ba 100644 --- a/classes/manager.php +++ b/classes/manager.php @@ -48,6 +48,15 @@ class manager { 'compflavor' => 'tiny_elements_comp_flavor', 'compvariant' => 'tiny_elements_comp_variant', ]; + /** @var array Table name aliases for compatibility with tiny_c4l exports. */ + protected static $tablealiases = [ + 'tiny_elements_compcat' => 'tiny_c4l_compcat', + 'tiny_elements_component' => 'tiny_c4l_component', + 'tiny_elements_flavor' => 'tiny_c4l_flavor', + 'tiny_elements_variant' => 'tiny_c4l_variant', + 'tiny_elements_comp_flavor' => 'tiny_c4l_comp_flavor', + 'tiny_elements_comp_variant' => 'tiny_c4l_comp_variant', + ]; /** @var array All tables that are optional. */ protected static $optionaltables = ['tiny_elements_comp_flavor', 'tiny_elements_comp_variant']; @@ -213,13 +222,16 @@ public function importxml(string $xmlcontent): bool { $componentmap = []; foreach (self::$tables as $table) { - if (!isset($xml->$table) && !in_array($table, self::$optionaltables)) { + $aliasname = self::$tablealiases[$table]; + if (!isset($xml->$table) && !isset($xml->$aliasname) && !in_array($table, self::$optionaltables)) { throw new moodle_exception(get_string('error_import_missing_table', 'tiny_elements', $table)); } } $data = []; + $aliases = array_flip(self::$tablealiases); + // Make data usable for further processing. foreach ($xml as $table => $rows) { foreach ($rows as $row) { @@ -227,7 +239,11 @@ public function importxml(string $xmlcontent): bool { foreach ($row as $column => $value) { $obj->$column = (string) $value; } - $data[$table][] = $obj; + if (in_array($table, self::$tables)) { + $data[$table][] = $obj; + } else { + $data[$aliases[$table]][] = $obj; + } } } @@ -449,6 +465,7 @@ public static function import_component_variant(array|object $record, array $com * @return string */ public static function update_pluginfile_tags_bulk(array $categorymap, string $subject): string { + $subject = self::update_c4l_pluginfile_tags($subject); foreach ($categorymap as $oldid => $newid) { $subject = self::update_pluginfile_tags($oldid, $newid, $subject, 'bulk'); } @@ -456,6 +473,18 @@ public static function update_pluginfile_tags_bulk(array $categorymap, string $s return $subject; } + /** + * Rename the pluginfile tags from tiny_c4l to tiny_elements. + * + * @param string $subject + * @return string + */ + public static function update_c4l_pluginfile_tags(string $subject): string { + $oldstring = '@@PLUGINFILE@@/1/tiny_c4l/'; + $newstring = '@@PLUGINFILE@@/1/tiny_elements/'; + return str_replace($oldstring, $newstring, $subject); + } + /** * Update the pluginfile tags in the given subject. * @@ -527,12 +556,15 @@ public function delete_flavor(int $id): void { public function import(stored_file|string $zip, $draftitemid = 0): void { global $DB; - if (file_exists($zip)) { + if ($zip instanceof stored_file || file_exists($zip)) { $fs = get_file_storage(); $fp = get_file_packer('application/zip'); $fp->extract_to_storage($zip, $this->contextid, 'tiny_elements', 'import', $draftitemid, '/'); $manager = new manager(); $xmlfile = $fs->get_file($this->contextid, 'tiny_elements', 'import', $draftitemid, '/', 'tiny_elements_export.xml'); + if (!$xmlfile) { + $xmlfile = $fs->get_file($this->contextid, 'tiny_elements', 'import', $draftitemid, '/', 'tiny_c4l_export.xml'); + } $xmlcontent = $xmlfile->get_content(); $manager->importxml($xmlcontent); $categories = $DB->get_records('tiny_elements_compcat'); diff --git a/classes/plugininfo.php b/classes/plugininfo.php index fac5500..cc4c28a 100644 --- a/classes/plugininfo.php +++ b/classes/plugininfo.php @@ -89,12 +89,6 @@ public static function get_plugin_configuration_for_context( 'tiny_elements_styles.css?rev=' . $rev )->out(); - // Get CSS preview. - $previewcss = $config->custompreviewcss ?? ''; - - // Get custom components. - $customcomponents = self::get_custom_components($config); - return [ 'isstudent' => $isstudent, 'showpreview' => ($showpreview == '1'), diff --git a/db/install.xml b/db/install.xml index 6d72492..cc601f2 100644 --- a/db/install.xml +++ b/db/install.xml @@ -48,6 +48,7 @@ + diff --git a/lang/en/tiny_c4l.php b/lang/en/tiny_c4l.php deleted file mode 100644 index ad5f43f..0000000 --- a/lang/en/tiny_c4l.php +++ /dev/null @@ -1,108 +0,0 @@ -. - -/** - * Plugin Elements strings for language en. - * - * @package tiny_elements - * @category string - * @copyright 2022 Marc Català - * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -$string['additem'] = 'Add item'; -$string['aimedatstudents'] = 'Aimed at Students'; -$string['aimedatstudents_desc'] = 'By default, only selected components will be available for users with student capabilities when using the editor. To change the default setting, just check or uncheck you own preferred selection.'; -$string['allpurposecard'] = 'All-purpose card'; -$string['attention'] = 'Attention'; -$string['button_elements'] = 'Elements'; -$string['elements:manage'] = 'Manage components'; -$string['elements:viewplugin'] = 'View Elements plugin'; -$string['code'] = 'Code'; -$string['code_help'] = 'HTML code to insert. You can use {{VARIANTS}}, {{FLAVOR}} and {{PLACEHOLDER}} as placeholders for variants, flavors and text to be inserted.'; -$string['compcat'] = 'Categories'; -$string['compflavor_icons'] = 'Change button icons for components depending on flavors'; -$string['component_flavor'] = 'Component/flavor'; -$string['componentname'] = 'Component name'; -$string['componentname_help'] = 'Name of the component use for internal use (also as a class name in CSS)'; -$string['components'] = 'Components'; -$string['content'] = 'Content'; -$string['css'] = 'CSS'; -$string['delete'] = 'Delete item "{$a}"'; -$string['deletewarning'] = 'Are you sure you want to delete this item.'; -$string['displayname'] = 'Display name'; -$string['displayname_help'] = 'Name of the component visible to the users'; -$string['displayorder'] = 'Display order'; -$string['dodontcards'] = 'Do/don\'t cards'; -$string['duedate'] = 'Due date'; -$string['edititem'] = 'Edit item'; -$string['enablepreview'] = 'Enable preview'; -$string['enablepreview_desc'] = 'If enabled, a preview is showed when you hover the mouse cursor over each component.'; -$string['error_export'] = 'Error creating export file'; -$string['error_fileimport'] = 'Error importing file "{$a}"'; -$string['error_import_component'] = 'Error importing component "{$a}"'; -$string['error_import_missing_table'] = 'Error while importing xml: missing table "{$a}"'; -$string['errorbackupfile'] = 'Error in backup file'; -$string['errorcompcat'] = '**compcat** cant be empty'; -$string['errordisplayname'] = 'Displayname cant be empty'; -$string['errorname'] = 'Name cant be empty'; -$string['estimatedtime'] = 'Estimated time'; -$string['example'] = 'Example'; -$string['expectedfeedback'] = 'Expected feedback'; -$string['export'] = 'Export'; -$string['figure'] = 'Figure'; -$string['files'] = 'Files'; -$string['flavors'] = 'Flavors'; -$string['foundcompcat'] = 'Unassigned Items'; -$string['gradingvalue'] = 'Grading value'; -$string['helper'] = 'Helper'; -$string['helplinktext'] = 'Elements helper'; -$string['hideforstudents'] = 'Accessible to teachers only in editor'; -$string['iconurl'] = 'Icon URL'; -$string['imageclass'] = 'Imageclass'; -$string['import'] = 'Import'; -$string['inlinetag'] = 'Inline tag'; -$string['js'] = 'JS'; -$string['keyconcept'] = 'Key concept'; -$string['learningoutcomes'] = 'Learning outcomes'; -$string['linktomanagerdesc'] = 'Go to management to change stuff'; -$string['linktomanagername'] = 'Link to management'; -$string['manage'] = 'Manage'; -$string['management'] = 'Management'; -$string['menuitem_elements'] = 'Components for Learning (Elements)'; -$string['min'] = 'min'; -$string['name'] = 'Name'; -$string['notintendedforstudents'] = 'Not intended for Students '; -$string['notintendedforstudents_desc'] = 'By default, evaluative and procedural components are not intended for users with student capabilities to use in the editor. To change the default setting, check the components you would like to make available to the students.'; -$string['pluginname'] = 'Components for Learning (Elements)'; -$string['preview'] = 'Preview'; -$string['previewcss'] = 'Preview CSS'; -$string['previewcsstext'] = 'If everything is correct, the component should be shown in all flavors'; -$string['previewdefault'] = 'Place the pointer on any component to see its preview.'; -$string['privacy:preference:category'] = 'Preferred category'; -$string['privacy:preference:components_flavors'] = 'Preferred flavor for each component'; -$string['privacy:preference:components_variants'] = 'Preferred variants of each component'; -$string['proceduralcontext'] = 'Procedural context'; -$string['quote'] = 'Quote'; -$string['readingcontext'] = 'Reading context'; -$string['reminder'] = 'Reminder'; -$string['tag'] = 'Tag'; -$string['text'] = 'Text'; -$string['tip'] = 'Tip'; -$string['validclassname'] = 'The name has to be a valid css class name. It may only contain letters, numbers and the characters "-" and "_". It must start with a letter or "_". Using only lowercase letters is recommended.'; -$string['variants'] = 'Variants'; diff --git a/pix/c4l_allpurposecard_icon.svg b/pix/c4l_allpurposecard_icon.svg deleted file mode 100644 index f700515..0000000 --- a/pix/c4l_allpurposecard_icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/pix/c4l_attention.svg b/pix/c4l_attention.svg deleted file mode 100644 index 241787f..0000000 --- a/pix/c4l_attention.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/pix/c4l_attention_icon.svg b/pix/c4l_attention_icon.svg deleted file mode 100644 index 4371a4f..0000000 --- a/pix/c4l_attention_icon.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/pix/c4l_customcomponent_icon.svg b/pix/c4l_customcomponent_icon.svg deleted file mode 100644 index 8df1452..0000000 --- a/pix/c4l_customcomponent_icon.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/pix/c4l_docard.svg b/pix/c4l_docard.svg deleted file mode 100644 index 9a82ed4..0000000 --- a/pix/c4l_docard.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/pix/c4l_dodontcards_icon.svg b/pix/c4l_dodontcards_icon.svg deleted file mode 100644 index bfadda0..0000000 --- a/pix/c4l_dodontcards_icon.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/pix/c4l_dontcard.svg b/pix/c4l_dontcard.svg deleted file mode 100644 index e831b3a..0000000 --- a/pix/c4l_dontcard.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/pix/c4l_example_icon.svg b/pix/c4l_example_icon.svg deleted file mode 100644 index f0f3cc6..0000000 --- a/pix/c4l_example_icon.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/pix/c4l_figure_icon.svg b/pix/c4l_figure_icon.svg deleted file mode 100644 index 832d63e..0000000 --- a/pix/c4l_figure_icon.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/pix/c4l_figure_placeholder.svg b/pix/c4l_figure_placeholder.svg deleted file mode 100644 index 92c754e..0000000 --- a/pix/c4l_figure_placeholder.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/pix/c4l_inlinetag_icon.svg b/pix/c4l_inlinetag_icon.svg deleted file mode 100644 index 16b49b4..0000000 --- a/pix/c4l_inlinetag_icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/pix/c4l_learningoutcomes_icon.svg b/pix/c4l_learningoutcomes_icon.svg deleted file mode 100644 index 322607e..0000000 --- a/pix/c4l_learningoutcomes_icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/pix/c4l_learningoutcomes_list_item.svg b/pix/c4l_learningoutcomes_list_item.svg deleted file mode 100644 index 7565a26..0000000 --- a/pix/c4l_learningoutcomes_list_item.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/pix/c4l_learningoutcomes_shadow.svg b/pix/c4l_learningoutcomes_shadow.svg deleted file mode 100644 index 1620474..0000000 --- a/pix/c4l_learningoutcomes_shadow.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/pix/c4l_multipurposecard_icon.svg b/pix/c4l_multipurposecard_icon.svg deleted file mode 100644 index fb9e5fd..0000000 --- a/pix/c4l_multipurposecard_icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/pix/c4l_preview_icon.svg b/pix/c4l_preview_icon.svg deleted file mode 100644 index dcd73a5..0000000 --- a/pix/c4l_preview_icon.svg +++ /dev/null @@ -1,3 +0,0 @@ - -]> \ No newline at end of file diff --git a/pix/c4l_proceduralcontext_icon.svg b/pix/c4l_proceduralcontext_icon.svg deleted file mode 100644 index bcf974c..0000000 --- a/pix/c4l_proceduralcontext_icon.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/pix/c4l_szenario_avatar1_cat_dog_icon.svg b/pix/c4l_szenario_avatar1_cat_dog_icon.svg deleted file mode 100644 index 4f846e4..0000000 --- a/pix/c4l_szenario_avatar1_cat_dog_icon.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/pix/c4l_szenario_avatar1_default_icon.svg b/pix/c4l_szenario_avatar1_default_icon.svg deleted file mode 100644 index 36739b1..0000000 --- a/pix/c4l_szenario_avatar1_default_icon.svg +++ /dev/null @@ -1,351 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pix/c4l_szenario_avatar2_cat_dog_icon.svg b/pix/c4l_szenario_avatar2_cat_dog_icon.svg deleted file mode 100644 index 06575b1..0000000 --- a/pix/c4l_szenario_avatar2_cat_dog_icon.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/pix/c4l_szenario_avatar2_default_icon.svg b/pix/c4l_szenario_avatar2_default_icon.svg deleted file mode 100644 index a3a18ba..0000000 --- a/pix/c4l_szenario_avatar2_default_icon.svg +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pix/c4l_titel_cat_dog_icon.svg b/pix/c4l_titel_cat_dog_icon.svg deleted file mode 100644 index 4f846e4..0000000 --- a/pix/c4l_titel_cat_dog_icon.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/pix/c4l_titel_default_icon.svg b/pix/c4l_titel_default_icon.svg deleted file mode 100644 index 6dca103..0000000 --- a/pix/c4l_titel_default_icon.svg +++ /dev/null @@ -1,410 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pix/noun_project_icons/c4l_duedate.svg b/pix/noun_project_icons/c4l_duedate.svg deleted file mode 100644 index ee6b05a..0000000 --- a/pix/noun_project_icons/c4l_duedate.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/pix/noun_project_icons/c4l_duedate_icon.svg b/pix/noun_project_icons/c4l_duedate_icon.svg deleted file mode 100644 index a609ad2..0000000 --- a/pix/noun_project_icons/c4l_duedate_icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/pix/noun_project_icons/c4l_estimatedtime.svg b/pix/noun_project_icons/c4l_estimatedtime.svg deleted file mode 100644 index 9d0da86..0000000 --- a/pix/noun_project_icons/c4l_estimatedtime.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/pix/noun_project_icons/c4l_estimatedtime_icon.svg b/pix/noun_project_icons/c4l_estimatedtime_icon.svg deleted file mode 100644 index 7fdb559..0000000 --- a/pix/noun_project_icons/c4l_estimatedtime_icon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/pix/noun_project_icons/c4l_expectedfeedback.svg b/pix/noun_project_icons/c4l_expectedfeedback.svg deleted file mode 100644 index fbbe9dc..0000000 --- a/pix/noun_project_icons/c4l_expectedfeedback.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/pix/noun_project_icons/c4l_expectedfeedback_icon.svg b/pix/noun_project_icons/c4l_expectedfeedback_icon.svg deleted file mode 100644 index c542f3e..0000000 --- a/pix/noun_project_icons/c4l_expectedfeedback_icon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/pix/noun_project_icons/c4l_gradingvalue.svg b/pix/noun_project_icons/c4l_gradingvalue.svg deleted file mode 100644 index b6ed1f4..0000000 --- a/pix/noun_project_icons/c4l_gradingvalue.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/pix/noun_project_icons/c4l_gradingvalue_icon.svg b/pix/noun_project_icons/c4l_gradingvalue_icon.svg deleted file mode 100644 index 2c09c7c..0000000 --- a/pix/noun_project_icons/c4l_gradingvalue_icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/pix/noun_project_icons/c4l_keyconcept_icon.svg b/pix/noun_project_icons/c4l_keyconcept_icon.svg deleted file mode 100644 index 2a20f03..0000000 --- a/pix/noun_project_icons/c4l_keyconcept_icon.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/pix/noun_project_icons/c4l_quote_close.svg b/pix/noun_project_icons/c4l_quote_close.svg deleted file mode 100644 index 7528c86..0000000 --- a/pix/noun_project_icons/c4l_quote_close.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/pix/noun_project_icons/c4l_quote_icon.svg b/pix/noun_project_icons/c4l_quote_icon.svg deleted file mode 100644 index eea54c9..0000000 --- a/pix/noun_project_icons/c4l_quote_icon.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/pix/noun_project_icons/c4l_quote_open.svg b/pix/noun_project_icons/c4l_quote_open.svg deleted file mode 100644 index ed75e79..0000000 --- a/pix/noun_project_icons/c4l_quote_open.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/pix/noun_project_icons/c4l_readingcontext_icon.svg b/pix/noun_project_icons/c4l_readingcontext_icon.svg deleted file mode 100644 index de7c8d1..0000000 --- a/pix/noun_project_icons/c4l_readingcontext_icon.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/pix/noun_project_icons/c4l_reminder.svg b/pix/noun_project_icons/c4l_reminder.svg deleted file mode 100644 index 57fe88f..0000000 --- a/pix/noun_project_icons/c4l_reminder.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/pix/noun_project_icons/c4l_reminder_icon.svg b/pix/noun_project_icons/c4l_reminder_icon.svg deleted file mode 100644 index 2d726cc..0000000 --- a/pix/noun_project_icons/c4l_reminder_icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/pix/noun_project_icons/c4l_tag_icon.svg b/pix/noun_project_icons/c4l_tag_icon.svg deleted file mode 100644 index 8b45b55..0000000 --- a/pix/noun_project_icons/c4l_tag_icon.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/pix/noun_project_icons/c4l_tip.svg b/pix/noun_project_icons/c4l_tip.svg deleted file mode 100644 index 2bfcf5f..0000000 --- a/pix/noun_project_icons/c4l_tip.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/pix/noun_project_icons/c4l_tip_icon.svg b/pix/noun_project_icons/c4l_tip_icon.svg deleted file mode 100644 index 0ff94b7..0000000 --- a/pix/noun_project_icons/c4l_tip_icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/pix/variants/align-center-variant-off.svg b/pix/variants/align-center-variant-off.svg deleted file mode 100644 index 6f0f37c..0000000 --- a/pix/variants/align-center-variant-off.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/pix/variants/align-center-variant-on.svg b/pix/variants/align-center-variant-on.svg deleted file mode 100644 index d26ed28..0000000 --- a/pix/variants/align-center-variant-on.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/pix/variants/align-left-variant-off.svg b/pix/variants/align-left-variant-off.svg deleted file mode 100644 index 5d810c2..0000000 --- a/pix/variants/align-left-variant-off.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/pix/variants/align-left-variant-on.svg b/pix/variants/align-left-variant-on.svg deleted file mode 100644 index d0df3d2..0000000 --- a/pix/variants/align-left-variant-on.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/pix/variants/align-right-variant-off.svg b/pix/variants/align-right-variant-off.svg deleted file mode 100644 index 83c1ba9..0000000 --- a/pix/variants/align-right-variant-off.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/pix/variants/align-right-variant-on.svg b/pix/variants/align-right-variant-on.svg deleted file mode 100644 index b455a03..0000000 --- a/pix/variants/align-right-variant-on.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/pix/variants/caption-variant-off.svg b/pix/variants/caption-variant-off.svg deleted file mode 100644 index 74f6349..0000000 --- a/pix/variants/caption-variant-off.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/pix/variants/caption-variant-on.svg b/pix/variants/caption-variant-on.svg deleted file mode 100644 index e436441..0000000 --- a/pix/variants/caption-variant-on.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/pix/variants/comfort-reading-variant-off.svg b/pix/variants/comfort-reading-variant-off.svg deleted file mode 100644 index 9ef8980..0000000 --- a/pix/variants/comfort-reading-variant-off.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/pix/variants/comfort-reading-variant-on.svg b/pix/variants/comfort-reading-variant-on.svg deleted file mode 100644 index 63ffdc1..0000000 --- a/pix/variants/comfort-reading-variant-on.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/pix/variants/dont-card-only-variant-off.svg b/pix/variants/dont-card-only-variant-off.svg deleted file mode 100644 index 4de8ff2..0000000 --- a/pix/variants/dont-card-only-variant-off.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/pix/variants/dont-card-only-variant-on.svg b/pix/variants/dont-card-only-variant-on.svg deleted file mode 100644 index 347b368..0000000 --- a/pix/variants/dont-card-only-variant-on.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/pix/variants/full-width-variant-off.svg b/pix/variants/full-width-variant-off.svg deleted file mode 100644 index 2c05ac2..0000000 --- a/pix/variants/full-width-variant-off.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/pix/variants/full-width-variant-on.svg b/pix/variants/full-width-variant-on.svg deleted file mode 100644 index 944ae43..0000000 --- a/pix/variants/full-width-variant-on.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/pix/variants/ordered-list-variant-off.svg b/pix/variants/ordered-list-variant-off.svg deleted file mode 100644 index 03bf3b1..0000000 --- a/pix/variants/ordered-list-variant-off.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/pix/variants/ordered-list-variant-on.svg b/pix/variants/ordered-list-variant-on.svg deleted file mode 100644 index 5f30528..0000000 --- a/pix/variants/ordered-list-variant-on.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/pix/variants/quote-variant-off.svg b/pix/variants/quote-variant-off.svg deleted file mode 100644 index a177537..0000000 --- a/pix/variants/quote-variant-off.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/pix/variants/quote-variant-on.svg b/pix/variants/quote-variant-on.svg deleted file mode 100644 index 4a6e029..0000000 --- a/pix/variants/quote-variant-on.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/settings.php b/settings.php index 0d40826..b92108e 100644 --- a/settings.php +++ b/settings.php @@ -39,95 +39,13 @@ $default = 1; $setting = new admin_setting_configcheckbox('tiny_elements/enablepreview', $name, $desc, $default); $settings->add($setting); - - // Configure available students' components. - $components = [ - 'keyconcept' => get_string('keyconcept', 'tiny_elements'), - 'tip' => get_string('tip', 'tiny_elements'), - 'reminder' => get_string('reminder', 'tiny_elements'), - 'quote' => get_string('quote', 'tiny_elements'), - 'dodontcards' => get_string('dodontcards', 'tiny_elements'), - 'readingcontext' => get_string('readingcontext', 'tiny_elements'), - 'example' => get_string('example', 'tiny_elements'), - 'figure' => get_string('figure', 'tiny_elements'), - 'tag' => get_string('tag', 'tiny_elements'), - 'inlinetag' => get_string('inlinetag', 'tiny_elements'), - 'attention' => get_string('attention', 'tiny_elements'), - 'allpurposecard' => get_string('allpurposecard', 'tiny_elements'), - ]; - $name = get_string('aimedatstudents', 'tiny_elements'); - $desc = get_string('aimedatstudents_desc', 'tiny_elements'); - $setting = new admin_setting_configmulticheckbox('tiny_elements/aimedatstudents', $name, $desc, $components, $components); - $settings->add($setting); - - - // Configure not intended students' components. - $components = [ - 'estimatedtime' => get_string('estimatedtime', 'tiny_elements'), - 'duedate' => get_string('duedate', 'tiny_elements'), - 'proceduralcontext' => get_string('proceduralcontext', 'tiny_elements'), - 'gradingvalue' => get_string('gradingvalue', 'tiny_elements'), - 'expectedfeedback' => get_string('expectedfeedback', 'tiny_elements'), - 'learningoutcomes' => get_string('learningoutcomes', 'tiny_elements'), - ]; - $name = get_string('notintendedforstudents', 'tiny_elements'); - $desc = get_string('notintendedforstudents_desc', 'tiny_elements'); - $setting = new admin_setting_configmulticheckbox('tiny_elements/notintendedforstudents', $name, $desc, [], $components); - $settings->add($setting); - - // Custom components settings. - $settings->add(new admin_setting_heading('tiny_elements/customcomponents', new lang_string('customcomponents', 'tiny_elements'), '')); - - // Number of custom components. - $name = 'tiny_elements/customcompcount'; - $title = get_string('customcompcount', 'tiny_elements'); - $description = get_string('customcompcountdesc', 'tiny_elements'); - $options = range(0, 12); - $options = array_combine($options, $options); - $setting = new admin_setting_configselect($name, $title, $description, 0, $options); - $setting->set_updatedcallback('purge_all_caches'); - $settings->add($setting); - - - // CSS for preview content inside editor. - $name = 'tiny_elements/custompreviewcss'; - $title = get_string('custompreviewcss', 'tiny_elements'); - $url = new moodle_url('/admin/settings.php', ['section' => 'additionalhtml']); - $link = html_writer::link($url, get_string('additionalhtml', 'tiny_elements'), ['target' => '_blank']); - $description = get_string('custompreviewcssdesc', 'tiny_elements', $link); - $setting = new admin_setting_configtextarea($name, $title, $description, ''); - $settings->add($setting); - - // Images bank. - $fileareaid = 'customimagesbank'; - $name = 'tiny_elements/customimagesbank'; - $title = get_string('customimagesbank', 'tiny_elements'); - $description = get_string('customimagesbankdesc', 'tiny_elements'); - $options = ['accepted_types' => ['image'], 'maxfiles' => -1]; - $setting = new admin_setting_configstoredfile($name, $title, $description, $fileareaid, 0, $options); - $settings->add($setting); - - // If we don't have any custom component yet, set to 0. - if (!$customcompcount = get_config('tiny_elements', 'customcompcount')) { - $customcompcount = 0; - } - - for ($componentindex = 1; $componentindex <= $customcompcount; $componentindex++) { - - // Header. - $name = 'tiny_elements/customcomptitle' . $componentindex; - $title = get_string('customcomptitle', 'tiny_elements', $componentindex); - $title = html_writer::tag('h4', $title); - $setting = new admin_setting_description($name, '', $title); - $settings->add($setting); - - // Add text with link to management as setting. - $settings->add(new \tiny_elements\admin\setting_customtext( - 'tiny_elements/management', - get_string('linktomanagername', 'tiny_elements'), - get_string('linktomanagerdesc', 'tiny_elements', (new moodle_url('/lib/editor/tiny/plugins/elements/management.php'))->out()), - '' - )); - } + + // Add text with link to management as setting. + $settings->add(new \tiny_elements\admin\setting_customtext( + 'tiny_elements/management', + get_string('linktomanagername', 'tiny_elements'), + get_string('linktomanagerdesc', 'tiny_elements', (new moodle_url('/lib/editor/tiny/plugins/elements/management.php'))->out()), + '' + )); } diff --git a/templates/modal.mustache b/templates/modal.mustache index 67a3314..98513f4 100644 --- a/templates/modal.mustache +++ b/templates/modal.mustache @@ -98,6 +98,7 @@ class="elements-button-variant {{imageClass}} {{state}}" data-id="{{id}}" data-variant="{{name}}" + data-variantclass="{{variantclass}}" data-state="{{state}}" data-toggle="tooltip" data-placement="top" diff --git a/tests/tiny_c4l_insert_table_comp_variant_test.php b/tests/tiny_c4l_insert_table_comp_variant_test.php deleted file mode 100644 index e4bf9e9..0000000 --- a/tests/tiny_c4l_insert_table_comp_variant_test.php +++ /dev/null @@ -1,153 +0,0 @@ -. - -/** - * Unit test adding junction table for components and variants. - * - * @package tiny_elements - * @copyright 2024 ISB Bayern, Franziska Hübler - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace tiny_elements; - -/** - * Unit test adding junction table for components and variants. - * - * @package tiny_elements - * @copyright 2024 ISB Bayern, Franziska Hübler - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -final class tiny_elements_insert_table_comp_variant_test extends \advanced_testcase { - /** - * Tests adding junction table for components and variants. - * - * @covers \tiny_elements_insert_comp_variant - */ - public function test_tiny_elements_insert_comp_variant(): void { - global $DB, $CFG; - - require($CFG->dirroot . "/lib/editor/tiny/plugins/elements/db/upgradelib.php"); - - $this->resetAfterTest(); - - // Truncate the tiny_elements_component table to get a white piece of paper. - $DB->delete_records('tiny_elements_component'); - - // Checking that tiny_elements_component table is empty. - $this->assertEmpty($DB->get_records('tiny_elements_component')); - - // Populating tiny_elements_component with data. - - // Insert one element without variant. - $record1 = new \stdClass(); - $record1->name = 'inlinetag'; - $record1->displayname = 'Inline Tag'; - $record1->compcat = 2; - $record1->code = '{{PLACEHOLDER}}'; - $record1->text = 'text'; - $record1->variants = ''; - $record1->displayorder = 0; - $record1->css = '.elements-inlinetag {font-weight: 900;}'; - $record1->js = ''; - $record1->iconurl = ''; - $record1->timecreated = time(); - $record1->timemodified = time() + 1; - $DB->insert_record('tiny_elements_component', $record1); - - // Insert one element with one variant. - $record2 = new \stdClass(); - $record2->name = 'dodontcards'; - $record2->displayname = 'Do/Don’t Cards'; - $record2->compcat = 2; - $record2->code = '

'; - $record2->text = 'Lorem ipsum'; - $record2->variants = 'full-width'; - $record2->displayorder = 0; - $record2->css = '.elements-dodontcards { margin-bottom: 0;}'; - $record2->js = ''; - $record2->iconurl = ''; - $record2->timecreated = time(); - $record2->timemodified = time() + 2; - $DB->insert_record('tiny_elements_component', $record2); - - // Insert one element with two variant. - $record3 = new \stdClass(); - $record3->name = 'quote'; - $record3->displayname = 'Quote'; - $record3->compcat = 2; - $record3->code = '
'; - $record3->text = 'Lorem ipsum'; - $record3->variants = 'full-width,quote'; - $record3->displayorder = 0; - $record3->css = '.elements-quote-body {display: flex;}'; - $record3->js = ''; - $record3->iconurl = '@@PLUGINFILE@@/1/tiny_elements/images/2/noun_project_icons/'; - $record3->timecreated = time(); - $record3->timemodified = time() + 1; - $DB->insert_record('tiny_elements_component', $record3); - - // Insert one element with three variant. - $record4 = new \stdClass(); - $record4->name = 'readingcontext'; - $record4->displayname = 'Readingcontext'; - $record4->compcat = 2; - $record4->code = '
'; - $record4->text = 'Lorem ipsum'; - $record4->variants = 'comfort-reading,full-width,quote'; - $record4->displayorder = 0; - $record4->css = '.elementsv-readingcontext p {font-size: 16px;}'; - $record4->js = ''; - $record4->iconurl = ''; - $record4->timecreated = time(); - $record4->timemodified = time() + 1; - $DB->insert_record('tiny_elements_component', $record4); - - // Check that there are 4 Elements in tiny_elements_component. - $this->assertEquals(4, $DB->count_records('tiny_elements_component')); - - // Check 13 fieldnames in tiny_elements_component. - $compquote = $DB->get_record('tiny_elements_component', ['name' => 'quote']); - $this->assertEquals(13, count((array) $compquote)); - - // Running the migration script. - tiny_elements_insert_comp_variant(); - - // Checking the results. - - // Check that there are still 4 Elements in tiny_elements_component. - $this->assertEquals(4, $DB->count_records('tiny_elements_component')); - - // Check 12 fieldnames in tiny_elements_component (so one field was deleted). - $compquote = $DB->get_record('tiny_elements_component', ['name' => 'quote']); - $this->assertEquals(12, count((array) $compquote)); - - // Check that there are 6 Elements in tiny_elements_comp_variant. - $this->assertEquals(6, $DB->count_records('tiny_elements_comp_variant')); - - // Check data correctness. - $sql = "SELECT cpv.variant - FROM {tiny_elements_comp_variant} cpv - JOIN {tiny_elements_component} cp - ON cpv.component = cp.id - WHERE cp.name = :component"; - - $this->assertCount(0, $DB->get_records_sql($sql, ['component' => 'inlinetag'])); - $this->assertCount(1, $DB->get_records_sql($sql, ['component' => 'dodontcards'])); - $this->assertCount(2, $DB->get_records_sql($sql, ['component' => 'quote'])); - $this->assertCount(3, $DB->get_records_sql($sql, ['component' => 'readingcontext'])); - } -}