diff --git a/amd/build/ui.min.js b/amd/build/ui.min.js index f58268d..f3bd76b 100644 --- a/amd/build/ui.min.js +++ b/amd/build/ui.min.js @@ -5,10 +5,6 @@ define("tiny_c4l/ui",["exports","./common","./modal","core/modal_factory","./com * @module tiny_c4l/ui * @copyright 2022 Marc Català * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later -<<<<<<< HEAD - */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,previewC4L=!0,allowedComponents=[],Contexts=[],langStrings={};_exports.handleAction=async editor=>{userStudent=(0,_options.isStudent)(editor),previewC4L=(0,_options.showPreview)(editor),langStrings=await getAllStrings(),allowedComponents=(0,_options.getallowedComponents)(editor),(0,_variantslib.loadVariantPreferences)().then(displayDialogue(editor))};const displayDialogue=async editor=>{const data=Object.assign({},{}),modal=await _modal_factory.default.create({type:_modal.default.TYPE,templateContext:await getTemplateContext(editor,data),large:!0});previewC4L||editor.targetElm.closest("body").classList.add("c4l-modal-no-preview"),modal.show(),modal.getRoot().on(_modal_events.default.hidden,(()=>{handleModalHidden(editor)}));modal.getRoot()[0].querySelectorAll(".c4l-button-filter").forEach((node=>{node.addEventListener("click",(event=>{handleButtonFilterClick(event,modal)}))})),modal.getRoot()[0].querySelector(".c4l-select-filter").addEventListener("change",(event=>{handleSelectFilterChange(event,modal)}));modal.getRoot()[0].querySelectorAll(".c4lt-dialog-button").forEach((node=>{node.addEventListener("click",(event=>{handleButtonClick(event,editor,modal)})),previewC4L&&(node.addEventListener("mouseenter",(event=>{handleButtonMouseEvent(event,modal,!0)})),node.addEventListener("mouseleave",(event=>{handleButtonMouseEvent(event,modal,!1)})))}));modal.getRoot()[0].querySelectorAll(".c4l-button-variant").forEach((node=>{node.addEventListener("click",(event=>{handleVariantClick(event,modal)})),previewC4L&&(node.addEventListener("mouseenter",(event=>{handleVariantMouseEvent(event,modal,!0)})),node.addEventListener("mouseleave",(event=>{handleVariantMouseEvent(event,modal,!1)})))}))},handleSelectFilterChange=(event,modal)=>{const select=event.target.closest("select");if(select){const currentContext=select.value;if(-1!==Contexts.indexOf(currentContext)){modal.getRoot()[0].querySelectorAll(".c4l-buttons-filters button").forEach((node=>node.classList.remove("c4l-button-filter-enabled")));modal.getRoot()[0].querySelector('.c4l-button-filter[data-filter="'+currentContext+'"]').classList.add("c4l-button-filter-enabled"),showContextButtons(modal,currentContext)}}},handleButtonFilterClick=(event,modal)=>{const button=event.target.closest("button"),currentContext=button.dataset.filter;if(-1!==Contexts.indexOf(currentContext)){modal.getRoot()[0].querySelectorAll(".c4l-buttons-filters button").forEach((node=>node.classList.remove("c4l-button-filter-enabled"))),button.classList.add("c4l-button-filter-enabled");modal.getRoot()[0].querySelector(".c4l-select-filter").selectedIndex=Contexts.indexOf(currentContext),showContextButtons(modal,currentContext)}},handleModalHidden=editor=>{editor.targetElm.closest("body").classList.remove("c4l-modal-no-preview"),(0,_variantslib.saveVariantPreferences)()},handleButtonClick=(event,editor,modal)=>{const selectedButton=event.target.closest("button").dataset.id;if(null!==_components.components&&void 0!==_components.components&&_components.components[selectedButton]){const sel=editor.selection.getContent();let componentCode=_components.components[selectedButton].code;const placeholder=sel.length>0?sel:_components.components[selectedButton].text,timestamp=(new Date).getTime(),randomId=Math.round(1e5*Math.random())+"-"+timestamp,newNode=document.createElement("span");newNode.dataset.id=randomId,newNode.innerHTML=placeholder,componentCode=componentCode.replace("{{PLACEHOLDER}}",newNode.outerHTML);const variants=(0,_variantslib.getVariantsClass)(_components.components[selectedButton].name);variants.length>0?(componentCode=componentCode.replace("{{VARIANTS}}",variants.join(" ")),componentCode=componentCode.replace("{{VARIANTSHTML}}",(0,_variantslib.getVariantsHtml)(_components.components[selectedButton].name))):(componentCode=componentCode.replace("{{VARIANTS}}",""),componentCode=componentCode.replace("{{VARIANTSHTML}}","")),componentCode=applyLangStrings(componentCode),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"]');node&&(show?(previewDefault.classList.toggle("c4l-hidden"),node.classList.toggle("c4l-hidden")):(node.classList.toggle("c4l-hidden"),previewDefault.classList.toggle("c4l-hidden")))},handleVariantMouseEvent=(event,modal,show)=>{const variant=event.target.closest("span"),variantEnabled="on"==variant.dataset.state,button=event.target.closest("button");variantEnabled||updateVariantComponentState(variant,button,modal,show,!1)},handleVariantClick=(event,modal)=>{event.stopPropagation();const variant=event.target.closest("span"),button=event.target.closest("button");updateVariantComponentState(variant,button,modal,!1,!0)},getTemplateContext=async(editor,data)=>Object.assign({},{elementid:editor.id,buttons:await getButtons(editor),filters:await getFilters(),preview:previewC4L},data),getFilters=async()=>{const filters=[],stringValues=await(0,_str.get_strings)(Contexts.map((key=>({key:key,component:_common.component}))));return Contexts.forEach(((context,index)=>{filters.push({name:stringValues[index],type:context,filterClass:0===index?"c4l-button-filter-enabled":""})})),filters},getButtons=editor=>{const buttons=[],sel=editor.selection.getContent();let componentCode="",placeholder="",variants=[];return _components.components.forEach(((component,index)=>{if(!userStudent||userStudent&&allowedComponents.includes(component.name)){if(previewC4L){placeholder=sel.length>0?sel:component.text,componentCode=component.code,componentCode=componentCode.replace("{{PLACEHOLDER}}",placeholder),variants=(0,_variantslib.getVariantsClass)(component.name);const variantsNode=document.createElement("span");variantsNode.dataset.id="variantHTML-"+component.id,variants.length>0?(componentCode=componentCode.replace("{{VARIANTS}}",variants.join(" ")),variantsNode.innerHTML=(0,_variantslib.getVariantsHtml)(component.name),componentCode=componentCode.replace("{{VARIANTSHTML}}",variantsNode.outerHTML)):(componentCode=componentCode.replace("{{VARIANTS}}",""),componentCode=componentCode.replace("{{VARIANTSHTML}}",variantsNode.outerHTML)),componentCode=applyLangStrings(componentCode)}-1===Contexts.indexOf(component.type)&&Contexts.push(component.type),buttons.push({id:index,name:langStrings.get(component.name),type:component.type,imageClass:component.imageClass,classComponent:"c4lv-"+component.name,htmlcode:componentCode,variants:getVariantsState(component.name,component.variants)}),0!==Contexts.indexOf(component.type)&&(buttons[buttons.length-1].imageClass+=" c4l-hidden")}})),buttons},getVariantsState=(component,elements)=>{const variants=[];let variantState="",variantClass="";return elements.length>3&&(elements=elements.slice(0,2)),elements.forEach(((variant,index)=>{(0,_variantslib.variantExists)(component,variant)?(variantState="on",variantClass="on "):(variantState="off",variantClass=""),variantClass+=variant+"-variant-"+variantState,variants.push({id:index,name:variant,state:variantState,imageClass:variantClass,title:langStrings.get(variant)})})),variants},updateVariantComponentState=(variant,button,modal,show,updateHtml)=>{const selectedVariant="c4l-"+variant.dataset.variant+"-variant",selectedButton=button.dataset.id,componentClass=button.dataset.classcomponent,previewComponent=modal.getRoot()[0].querySelector('div[data-id="code-preview-'+selectedButton+'"] .'+componentClass),variantPreview=modal.getRoot()[0].querySelector('span[data-id="variantHTML-'+selectedButton+'"]');let variantsHtml="";previewComponent?updateHtml?("on"==variant.dataset.state?((0,_variantslib.removeVariant)(_components.components[selectedButton].name,variant.dataset.variant),updateVariantButtonState(variant,!1),previewComponent.classList.remove(selectedVariant)):((0,_variantslib.addVariant)(_components.components[selectedButton].name,variant.dataset.variant),updateVariantButtonState(variant,!0),previewComponent.classList.add(selectedVariant)),variantPreview&&(variantPreview.innerHTML=(0,_variantslib.getVariantsHtml)(_components.components[selectedButton].name))):(variantsHtml=(0,_variantslib.getVariantsHtml)(_components.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.components[selectedButton].name,variant.dataset.variant),updateVariantButtonState(variant,!1)):((0,_variantslib.addVariant)(_components.components[selectedButton].name,variant.dataset.variant),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"))},showContextButtons=(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("c4l-hidden"))),hideNodes.forEach((node=>node.classList.add("c4l-hidden")))},applyLangStrings=text=>([...text.matchAll(/{{#(\w+)}}/g)].forEach((strLang=>{text=text.replace("{{#"+strLang[1]+"}}",langStrings.get(strLang[1]))})),text),getAllStrings=async()=>{const keys=[],compRegex=/{{#(\w+)}}/g;_components.components.forEach((element=>{keys.push(element.name),element.variants.forEach((variant=>{-1===keys.indexOf(variant)&&keys.push(variant)})),[...element.code.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,previewC4L=!0,allowedComponents=[],Contexts=[],langStrings={};_exports.handleAction=async editor=>{userStudent=(0,_options.isStudent)(editor),previewC4L=(0,_options.showPreview)(editor),langStrings=await getAllStrings(),allowedComponents=(0,_options.getallowedComponents)(editor),(0,_variantslib.loadVariantPreferences)().then((()=>displayDialogue(editor)))};const displayDialogue=async editor=>{const data=Object.assign({},{}),modal=await _modal_factory.default.create({type:_modal.default.TYPE,templateContext:await getTemplateContext(editor,data),large:!0});previewC4L||editor.targetElm.closest("body").classList.add("c4l-modal-no-preview"),modal.show(),modal.getRoot().on(_modal_events.default.hidden,(()=>{handleModalHidden(editor)}));modal.getRoot()[0].querySelectorAll(".c4l-button-filter").forEach((node=>{node.addEventListener("click",(event=>{handleButtonFilterClick(event,modal)}))})),modal.getRoot()[0].querySelector(".c4l-select-filter").addEventListener("change",(event=>{handleSelectFilterChange(event,modal)}));modal.getRoot()[0].querySelectorAll(".c4lt-dialog-button").forEach((node=>{node.addEventListener("click",(event=>{handleButtonClick(event,editor,modal)})),previewC4L&&(node.addEventListener("mouseenter",(event=>{handleButtonMouseEvent(event,modal,!0)})),node.addEventListener("mouseleave",(event=>{handleButtonMouseEvent(event,modal,!1)})))}));modal.getRoot()[0].querySelectorAll(".c4l-button-variant").forEach((node=>{node.addEventListener("click",(event=>{handleVariantClick(event,modal)})),previewC4L&&(node.addEventListener("mouseenter",(event=>{handleVariantMouseEvent(event,modal,!0)})),node.addEventListener("mouseleave",(event=>{handleVariantMouseEvent(event,modal,!1)})))}))},handleSelectFilterChange=(event,modal)=>{const select=event.target.closest("select");if(select){const currentContext=select.value;if(-1!==Contexts.indexOf(currentContext)){modal.getRoot()[0].querySelectorAll(".c4l-buttons-filters button").forEach((node=>node.classList.remove("c4l-button-filter-enabled")));modal.getRoot()[0].querySelector('.c4l-button-filter[data-filter="'+currentContext+'"]').classList.add("c4l-button-filter-enabled"),showContextButtons(modal,currentContext)}}},handleButtonFilterClick=(event,modal)=>{const button=event.target.closest("button"),currentContext=button.dataset.filter;if(-1!==Contexts.indexOf(currentContext)){modal.getRoot()[0].querySelectorAll(".c4l-buttons-filters button").forEach((node=>node.classList.remove("c4l-button-filter-enabled"))),button.classList.add("c4l-button-filter-enabled");modal.getRoot()[0].querySelector(".c4l-select-filter").selectedIndex=Contexts.indexOf(currentContext),showContextButtons(modal,currentContext)}},handleModalHidden=editor=>{editor.targetElm.closest("body").classList.remove("c4l-modal-no-preview"),(0,_variantslib.saveVariantPreferences)()},handleButtonClick=(event,editor,modal)=>{const selectedButton=event.target.closest("button").dataset.id;if(null!==_components.components&&void 0!==_components.components&&_components.components[selectedButton]){const sel=editor.selection.getContent();let componentCode=_components.components[selectedButton].code;const placeholder=sel.length>0?sel:_components.components[selectedButton].text,randomId=generateRandomID(),newNode=document.createElement("span");newNode.dataset.id=randomId,newNode.innerHTML=placeholder,componentCode=componentCode.replace("{{PLACEHOLDER}}",newNode.outerHTML);const variants=(0,_variantslib.getVariantsClass)(_components.components[selectedButton].name);variants.length>0?(componentCode=componentCode.replace("{{VARIANTS}}",variants.join(" ")),componentCode=componentCode.replace("{{VARIANTSHTML}}",(0,_variantslib.getVariantsHtml)(_components.components[selectedButton].name))):(componentCode=componentCode.replace("{{VARIANTS}}",""),componentCode=componentCode.replace("{{VARIANTSHTML}}","")),componentCode=applyRandomID(componentCode),componentCode=applyLangStrings(componentCode),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"]');node&&(show?(previewDefault.classList.toggle("c4l-hidden"),node.classList.toggle("c4l-hidden")):(node.classList.toggle("c4l-hidden"),previewDefault.classList.toggle("c4l-hidden")))},handleVariantMouseEvent=(event,modal,show)=>{const variant=event.target.closest("span"),variantEnabled="on"==variant.dataset.state,button=event.target.closest("button");variantEnabled||updateVariantComponentState(variant,button,modal,show,!1)},handleVariantClick=(event,modal)=>{event.stopPropagation();const variant=event.target.closest("span"),button=event.target.closest("button");updateVariantComponentState(variant,button,modal,!1,!0)},getTemplateContext=async(editor,data)=>Object.assign({},{elementid:editor.id,buttons:await getButtons(editor),filters:await getFilters(),preview:previewC4L},data),getFilters=async()=>{const filters=[],stringValues=await(0,_str.get_strings)(Contexts.map((key=>({key:key,component:_common.component}))));return Contexts.forEach(((context,index)=>{filters.push({name:stringValues[index],type:context,filterClass:0===index?"c4l-button-filter-enabled":""})})),filters},getButtons=editor=>{const buttons=[],sel=editor.selection.getContent();let componentCode="",placeholder="",variants=[];return _components.components.forEach(((component,index)=>{if(!userStudent||userStudent&&allowedComponents.includes(component.name)){if(previewC4L){placeholder=sel.length>0?sel:component.text,componentCode=component.code,componentCode=componentCode.replace("{{PLACEHOLDER}}",placeholder),variants=(0,_variantslib.getVariantsClass)(component.name);const variantsNode=document.createElement("span");variantsNode.dataset.id="variantHTML-"+component.id,variants.length>0?(componentCode=componentCode.replace("{{VARIANTS}}",variants.join(" ")),variantsNode.innerHTML=(0,_variantslib.getVariantsHtml)(component.name),componentCode=componentCode.replace("{{VARIANTSHTML}}",variantsNode.outerHTML)):(componentCode=componentCode.replace("{{VARIANTS}}",""),componentCode=componentCode.replace("{{VARIANTSHTML}}",variantsNode.outerHTML)),componentCode=applyLangStrings(componentCode)}-1===Contexts.indexOf(component.type)&&Contexts.push(component.type),buttons.push({id:index,name:langStrings.get(component.name),type:component.type,imageClass:component.imageClass,classComponent:"c4lv-"+component.name,htmlcode:componentCode,variants:getVariantsState(component.name,component.variants)}),0!==Contexts.indexOf(component.type)&&(buttons[buttons.length-1].imageClass+=" c4l-hidden")}})),buttons},getVariantsState=(component,elements)=>{const variants=[];let variantState="",variantClass="";return elements.length>3&&(elements=elements.slice(0,2)),elements.forEach(((variant,index)=>{(0,_variantslib.variantExists)(component,variant)?(variantState="on",variantClass="on "):(variantState="off",variantClass=""),variantClass+=variant+"-variant-"+variantState,variants.push({id:index,name:variant,state:variantState,imageClass:variantClass,title:langStrings.get(variant)})})),variants},updateVariantComponentState=(variant,button,modal,show,updateHtml)=>{const selectedVariant="c4l-"+variant.dataset.variant+"-variant",selectedButton=button.dataset.id,componentClass=button.dataset.classcomponent,previewComponent=modal.getRoot()[0].querySelector('div[data-id="code-preview-'+selectedButton+'"] .'+componentClass),variantPreview=modal.getRoot()[0].querySelector('span[data-id="variantHTML-'+selectedButton+'"]');let variantsHtml="";previewComponent?updateHtml?("on"==variant.dataset.state?((0,_variantslib.removeVariant)(_components.components[selectedButton].name,variant.dataset.variant),updateVariantButtonState(variant,!1),previewComponent.classList.remove(selectedVariant)):((0,_variantslib.addVariant)(_components.components[selectedButton].name,variant.dataset.variant),updateVariantButtonState(variant,!0),previewComponent.classList.add(selectedVariant)),variantPreview&&(variantPreview.innerHTML=(0,_variantslib.getVariantsHtml)(_components.components[selectedButton].name))):(variantsHtml=(0,_variantslib.getVariantsHtml)(_components.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.components[selectedButton].name,variant.dataset.variant),updateVariantButtonState(variant,!1)):((0,_variantslib.addVariant)(_components.components[selectedButton].name,variant.dataset.variant),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"))},showContextButtons=(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("c4l-hidden"))),hideNodes.forEach((node=>node.classList.add("c4l-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.components.forEach((element=>{keys.push(element.name),element.variants.forEach((variant=>{-1===keys.indexOf(variant)&&keys.push(variant)})),[...element.code.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]])))}})); ->>>>>>> 52816fc (foo) + */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,previewC4L=!0,allowedComponents=[],Contexts=[],langStrings={};_exports.handleAction=async editor=>{userStudent=(0,_options.isStudent)(editor),previewC4L=(0,_options.showPreview)(editor),langStrings=await getAllStrings(),allowedComponents=(0,_options.getallowedComponents)(editor),(0,_variantslib.loadVariantPreferences)().then(displayDialogue(editor))};const displayDialogue=async editor=>{const data=Object.assign({},{}),modal=await _modal_factory.default.create({type:_modal.default.TYPE,templateContext:await getTemplateContext(editor,data),large:!0});previewC4L||editor.targetElm.closest("body").classList.add("c4l-modal-no-preview"),modal.show(),modal.getRoot().on(_modal_events.default.hidden,(()=>{handleModalHidden(editor)}));modal.getRoot()[0].querySelectorAll(".c4l-button-filter").forEach((node=>{node.addEventListener("click",(event=>{handleButtonFilterClick(event,modal)}))})),modal.getRoot()[0].querySelector(".c4l-select-filter").addEventListener("change",(event=>{handleSelectFilterChange(event,modal)}));modal.getRoot()[0].querySelectorAll(".c4lt-dialog-button").forEach((node=>{node.addEventListener("click",(event=>{handleButtonClick(event,editor,modal)})),previewC4L&&(node.addEventListener("mouseenter",(event=>{handleButtonMouseEvent(event,modal,!0)})),node.addEventListener("mouseleave",(event=>{handleButtonMouseEvent(event,modal,!1)})))}));modal.getRoot()[0].querySelectorAll(".c4l-button-variant").forEach((node=>{node.addEventListener("click",(event=>{handleVariantClick(event,modal)})),previewC4L&&(node.addEventListener("mouseenter",(event=>{handleVariantMouseEvent(event,modal,!0)})),node.addEventListener("mouseleave",(event=>{handleVariantMouseEvent(event,modal,!1)})))}))},handleSelectFilterChange=(event,modal)=>{const select=event.target.closest("select");if(select){const currentContext=select.value;if(-1!==Contexts.indexOf(currentContext)){modal.getRoot()[0].querySelectorAll(".c4l-buttons-filters button").forEach((node=>node.classList.remove("c4l-button-filter-enabled")));modal.getRoot()[0].querySelector('.c4l-button-filter[data-filter="'+currentContext+'"]').classList.add("c4l-button-filter-enabled"),showContextButtons(modal,currentContext)}}},handleButtonFilterClick=(event,modal)=>{const button=event.target.closest("button"),currentContext=button.dataset.filter;if(-1!==Contexts.indexOf(currentContext)){modal.getRoot()[0].querySelectorAll(".c4l-buttons-filters button").forEach((node=>node.classList.remove("c4l-button-filter-enabled"))),button.classList.add("c4l-button-filter-enabled");modal.getRoot()[0].querySelector(".c4l-select-filter").selectedIndex=Contexts.indexOf(currentContext),showContextButtons(modal,currentContext)}},handleModalHidden=editor=>{editor.targetElm.closest("body").classList.remove("c4l-modal-no-preview"),(0,_variantslib.saveVariantPreferences)()},handleButtonClick=(event,editor,modal)=>{const selectedButton=event.target.closest("button").dataset.id;if(null!==_components.components&&void 0!==_components.components&&_components.components[selectedButton]){const sel=editor.selection.getContent();let componentCode=_components.components[selectedButton].code;const placeholder=sel.length>0?sel:_components.components[selectedButton].text,randomId=generateRandomID(),newNode=document.createElement("span");newNode.dataset.id=randomId,newNode.innerHTML=placeholder,componentCode=componentCode.replace("{{PLACEHOLDER}}",newNode.outerHTML);const variants=(0,_variantslib.getVariantsClass)(_components.components[selectedButton].name);variants.length>0?(componentCode=componentCode.replace("{{VARIANTS}}",variants.join(" ")),componentCode=componentCode.replace("{{VARIANTSHTML}}",(0,_variantslib.getVariantsHtml)(_components.components[selectedButton].name))):(componentCode=componentCode.replace("{{VARIANTS}}",""),componentCode=componentCode.replace("{{VARIANTSHTML}}","")),componentCode=applyRandomID(componentCode),componentCode=applyLangStrings(componentCode),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"]');node&&(show?(previewDefault.classList.toggle("c4l-hidden"),node.classList.toggle("c4l-hidden")):(node.classList.toggle("c4l-hidden"),previewDefault.classList.toggle("c4l-hidden")))},handleVariantMouseEvent=(event,modal,show)=>{const variant=event.target.closest("span"),variantEnabled="on"==variant.dataset.state,button=event.target.closest("button");variantEnabled||updateVariantComponentState(variant,button,modal,show,!1)},handleVariantClick=(event,modal)=>{event.stopPropagation();const variant=event.target.closest("span"),button=event.target.closest("button");updateVariantComponentState(variant,button,modal,!1,!0)},getTemplateContext=async(editor,data)=>Object.assign({},{elementid:editor.id,buttons:await getButtons(editor),filters:await getFilters(),preview:previewC4L},data),getFilters=async()=>{const filters=[],stringValues=await(0,_str.get_strings)(Contexts.map((key=>({key:key,component:_common.component}))));return Contexts.forEach(((context,index)=>{filters.push({name:stringValues[index],type:context,filterClass:0===index?"c4l-button-filter-enabled":""})})),filters},getButtons=editor=>{const buttons=[],sel=editor.selection.getContent();let componentCode="",placeholder="",variants=[];return _components.components.forEach(((component,index)=>{if(!userStudent||userStudent&&allowedComponents.includes(component.name)){if(previewC4L){placeholder=sel.length>0?sel:component.text,componentCode=component.code,componentCode=componentCode.replace("{{PLACEHOLDER}}",placeholder),variants=(0,_variantslib.getVariantsClass)(component.name);const variantsNode=document.createElement("span");variantsNode.dataset.id="variantHTML-"+component.id,variants.length>0?(componentCode=componentCode.replace("{{VARIANTS}}",variants.join(" ")),variantsNode.innerHTML=(0,_variantslib.getVariantsHtml)(component.name),componentCode=componentCode.replace("{{VARIANTSHTML}}",variantsNode.outerHTML)):(componentCode=componentCode.replace("{{VARIANTS}}",""),componentCode=componentCode.replace("{{VARIANTSHTML}}",variantsNode.outerHTML)),componentCode=applyLangStrings(componentCode)}-1===Contexts.indexOf(component.type)&&Contexts.push(component.type),buttons.push({id:index,name:langStrings.get(component.name),type:component.type,imageClass:component.imageClass,classComponent:"c4lv-"+component.name,htmlcode:componentCode,variants:getVariantsState(component.name,component.variants)}),0!==Contexts.indexOf(component.type)&&(buttons[buttons.length-1].imageClass+=" c4l-hidden")}})),buttons},getVariantsState=(component,elements)=>{const variants=[];let variantState="",variantClass="";return elements.length>3&&(elements=elements.slice(0,2)),elements.forEach(((variant,index)=>{(0,_variantslib.variantExists)(component,variant)?(variantState="on",variantClass="on "):(variantState="off",variantClass=""),variantClass+=variant+"-variant-"+variantState,variants.push({id:index,name:variant,state:variantState,imageClass:variantClass,title:langStrings.get(variant)})})),variants},updateVariantComponentState=(variant,button,modal,show,updateHtml)=>{const selectedVariant="c4l-"+variant.dataset.variant+"-variant",selectedButton=button.dataset.id,componentClass=button.dataset.classcomponent,previewComponent=modal.getRoot()[0].querySelector('div[data-id="code-preview-'+selectedButton+'"] .'+componentClass),variantPreview=modal.getRoot()[0].querySelector('span[data-id="variantHTML-'+selectedButton+'"]');let variantsHtml="";previewComponent?updateHtml?("on"==variant.dataset.state?((0,_variantslib.removeVariant)(_components.components[selectedButton].name,variant.dataset.variant),updateVariantButtonState(variant,!1),previewComponent.classList.remove(selectedVariant)):((0,_variantslib.addVariant)(_components.components[selectedButton].name,variant.dataset.variant),updateVariantButtonState(variant,!0),previewComponent.classList.add(selectedVariant)),variantPreview&&(variantPreview.innerHTML=(0,_variantslib.getVariantsHtml)(_components.components[selectedButton].name))):(variantsHtml=(0,_variantslib.getVariantsHtml)(_components.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.components[selectedButton].name,variant.dataset.variant),updateVariantButtonState(variant,!1)):((0,_variantslib.addVariant)(_components.components[selectedButton].name,variant.dataset.variant),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"))},showContextButtons=(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("c4l-hidden"))),hideNodes.forEach((node=>node.classList.add("c4l-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.components.forEach((element=>{keys.push(element.name),element.variants.forEach((variant=>{-1===keys.indexOf(variant)&&keys.push(variant)})),[...element.code.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 2fe3295..e8c5c97 100644 --- a/amd/build/ui.min.js.map +++ b/amd/build/ui.min.js.map @@ -1,5 +1 @@ -<<<<<<< HEAD -{"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 C4L UI.\n *\n * @module tiny_c4l/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 C4LModal from './modal';\nimport ModalFactory from 'core/modal_factory';\nimport {components as Components} from './components';\nimport {get_strings as getStrings} from 'core/str';\nimport {\n isStudent,\n getallowedComponents,\n showPreview\n} from './options';\nimport ModalEvents from 'core/modal_events';\nimport {\n addVariant,\n getVariantsClass,\n getVariantHtml,\n getVariantsHtml,\n loadVariantPreferences,\n removeVariant,\n saveVariantPreferences,\n variantExists\n} from './variantslib';\n\nlet userStudent = false;\nlet previewC4L = true;\nlet allowedComponents = [];\nlet Contexts = [];\nlet langStrings = {};\n\n/**\n * Handle action\n *\n * @param {TinyMCE} editor\n */\nexport const handleAction = async(editor) => {\n userStudent = isStudent(editor);\n previewC4L = showPreview(editor);\n langStrings = await getAllStrings();\n allowedComponents = getallowedComponents(editor);\n loadVariantPreferences().then(displayDialogue(editor));\n};\n\n/**\n * Display modal\n *\n * @param {TinyMCE} editor\n */\nconst displayDialogue = async(editor) => {\n const data = Object.assign({}, {});\n\n // Show modal with buttons.\n const modal = await ModalFactory.create({\n type: C4LModal.TYPE,\n templateContext: await getTemplateContext(editor, data),\n large: true,\n });\n\n // Set modal size when no preview.\n if (!previewC4L) {\n editor.targetElm.closest('body').classList.add('c4l-modal-no-preview');\n }\n modal.show();\n\n // Event modal listener.\n modal.getRoot().on(ModalEvents.hidden, () => {\n handleModalHidden(editor);\n });\n\n // Event filters listener.\n const filters = modal.getRoot()[0].querySelectorAll('.c4l-button-filter');\n filters.forEach(node => {\n node.addEventListener('click', (event) => {\n handleButtonFilterClick(event, modal);\n });\n });\n\n modal.getRoot()[0].querySelector('.c4l-select-filter').addEventListener('change', (event) => {\n handleSelectFilterChange(event, modal);\n });\n\n // Event buttons listeners.\n const buttons = modal.getRoot()[0].querySelectorAll('.c4lt-dialog-button');\n buttons.forEach(node => {\n node.addEventListener('click', (event) => {\n handleButtonClick(event, editor, modal);\n });\n if (previewC4L) {\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('.c4l-button-variant');\n variants.forEach(node => {\n node.addEventListener('click', (event) => {\n handleVariantClick(event, modal);\n });\n if (previewC4L) {\n node.addEventListener('mouseenter', (event) => {\n handleVariantMouseEvent(event, modal, true);\n });\n node.addEventListener('mouseleave', (event) => {\n handleVariantMouseEvent(event, modal, false);\n });\n }\n });\n};\n\n/**\n * Handle a change within filter select.\n *\n * @param {MouseEvent} event The change event\n * @param {obj} modal\n */\nconst handleSelectFilterChange = (event, modal) => {\n const select = event.target.closest('select');\n\n if (select) {\n const currentContext = select.value;\n if (Contexts.indexOf(currentContext) !== -1) {\n // Select current button.\n const buttons = modal.getRoot()[0]\n .querySelectorAll('.c4l-buttons-filters button');\n buttons.forEach(node => node.classList.remove('c4l-button-filter-enabled'));\n const button = modal.getRoot()[0]\n .querySelector('.c4l-button-filter[data-filter=\"' + currentContext + '\"]');\n button.classList.add('c4l-button-filter-enabled');\n\n // Show/hide component buttons.\n showContextButtons(modal, currentContext);\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 handleButtonFilterClick = (event, modal) => {\n const button = event.target.closest('button');\n\n const currentContext = button.dataset.filter;\n // Filter button.\n if (Contexts.indexOf(currentContext) !== -1) {\n // Select current button.\n const buttons = modal.getRoot()[0].querySelectorAll('.c4l-buttons-filters button');\n buttons.forEach(node => node.classList.remove('c4l-button-filter-enabled'));\n button.classList.add('c4l-button-filter-enabled');\n\n // Select current option in select.\n const select = modal.getRoot()[0].querySelector('.c4l-select-filter');\n select.selectedIndex = Contexts.indexOf(currentContext);\n\n // Show/hide component buttons.\n showContextButtons(modal, currentContext);\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('c4l-modal-no-preview');\n saveVariantPreferences();\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 = (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 // Create a new node to replace the placeholder.\n const timestamp = new Date().getTime();\n const randomId = Math.round(Math.random() * 100000) + '-' + timestamp;\n const newNode = document.createElement('span');\n newNode.dataset.id = randomId;\n newNode.innerHTML = placeholder;\n componentCode = componentCode.replace('{{PLACEHOLDER}}', newNode.outerHTML);\n\n // Return active variants for current component.\n const variants = getVariantsClass(Components[selectedButton].name);\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 // Apply lang strings.\n componentCode = applyLangStrings(componentCode);\n\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\n if (node) {\n if (show) {\n previewDefault.classList.toggle('c4l-hidden');\n node.classList.toggle('c4l-hidden');\n } else {\n node.classList.toggle('c4l-hidden');\n previewDefault.classList.toggle('c4l-hidden');\n }\n }\n};\n\n/**\n * Handle a mouse events mouseenter/mouseleave in a variant button.\n *\n * @param {MouseEvent} event The mouseenter/mouseleave event\n * @param {obj} modal\n * @param {bool} show\n */\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 updateVariantComponentState(variant, button, modal, false, true);\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 filters: await getFilters(),\n preview: previewC4L,\n }, data);\n};\n\n/**\n * Get the C4L filters for the dialogue.\n *\n * @returns {object} data\n */\nconst getFilters = async() => {\n const filters = [];\n const stringValues = await getStrings(Contexts.map((key) => ({key, component})));\n\n // Iterate over contexts.\n Contexts.forEach((context, index) => {\n filters.push({\n name: stringValues[index],\n type: context,\n filterClass: index === 0 ? 'c4l-button-filter-enabled' : '',\n });\n });\n\n return filters;\n};\n\n/**\n * Get the C4L buttons for the dialogue.\n *\n * @param {Editor} editor\n * @returns {object} buttons\n */\nconst getButtons = (editor) => {\n const buttons = [];\n const sel = editor.selection.getContent();\n let componentCode = '';\n let placeholder = '';\n let variants = [];\n\n // Iterate over components.\n Components.forEach((component, index) => {\n if (!userStudent || (userStudent && allowedComponents.includes(component.name))) {\n if (previewC4L) {\n placeholder = (sel.length > 0 ? sel : component.text);\n componentCode = component.code;\n componentCode = componentCode.replace('{{PLACEHOLDER}}', placeholder);\n // Return active variants for component.\n variants = getVariantsClass(component.name);\n\n // Apply class variants and html to html component.\n const variantsNode = document.createElement('span');\n variantsNode.dataset.id = 'variantHTML-' + component.id;\n if (variants.length > 0) {\n componentCode = componentCode.replace('{{VARIANTS}}', variants.join(' '));\n variantsNode.innerHTML = getVariantsHtml(component.name);\n componentCode = componentCode.replace('{{VARIANTSHTML}}', variantsNode.outerHTML);\n } else {\n componentCode = componentCode.replace('{{VARIANTS}}', '');\n componentCode = componentCode.replace('{{VARIANTSHTML}}', variantsNode.outerHTML);\n }\n\n // Apply lang strings.\n componentCode = applyLangStrings(componentCode);\n }\n\n // Save contexts.\n if (Contexts.indexOf(component.type) === -1) {\n Contexts.push(component.type);\n }\n\n buttons.push({\n id: index,\n name: langStrings.get(component.name),\n type: component.type,\n imageClass: component.imageClass,\n classComponent: 'c4lv-' + component.name,\n htmlcode: componentCode,\n variants: getVariantsState(component.name, component.variants),\n });\n\n // Add class to hide button.\n if (Contexts.indexOf(component.type) !== 0) {\n buttons[buttons.length - 1].imageClass += ' c4l-hidden';\n }\n }\n });\n\n return buttons;\n};\n\n/**\n * Get variants for the dialogue.\n *\n * @param {string} component\n * @param {object} elements\n * @return {object} Variants for a component\n */\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 = 'c4l-' + 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-' + selectedButton + '\"] .' + componentClass);\n const variantPreview = modal.getRoot()[0]\n .querySelector('span[data-id=\"variantHTML-' + selectedButton + '\"]');\n let variantsHtml = '';\n\n if (previewComponent) {\n if (updateHtml) {\n if (variant.dataset.state == 'on') {\n removeVariant(Components[selectedButton].name, variant.dataset.variant);\n updateVariantButtonState(variant, false);\n previewComponent.classList.remove(selectedVariant);\n } else {\n addVariant(Components[selectedButton].name, variant.dataset.variant);\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);\n updateVariantButtonState(variant, false);\n } else {\n addVariant(Components[selectedButton].name, variant.dataset.variant);\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 showContextButtons = (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('c4l-hidden'));\n hideNodes.forEach(node => node.classList.add('c4l-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 = /{{#(\\w+)}}/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 * Get language strings.\n *\n * @return {object} Language strings\n */\nconst getAllStrings = async() => {\n const keys = [];\n const compRegex = /{{#(\\w+)}}/g;\n\n Components.forEach(element => {\n keys.push(element.name);\n element.variants.forEach(variant => {\n if (keys.indexOf(variant) === -1) {\n keys.push(variant);\n }\n });\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\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","previewC4L","allowedComponents","Contexts","langStrings","async","editor","getAllStrings","then","displayDialogue","data","Object","assign","modal","ModalFactory","create","type","C4LModal","TYPE","templateContext","getTemplateContext","large","targetElm","closest","classList","add","show","getRoot","on","ModalEvents","hidden","handleModalHidden","querySelectorAll","forEach","node","addEventListener","event","handleButtonFilterClick","querySelector","handleSelectFilterChange","handleButtonClick","handleButtonMouseEvent","handleVariantClick","handleVariantMouseEvent","select","target","currentContext","value","indexOf","remove","showContextButtons","button","dataset","filter","selectedIndex","selectedButton","id","Components","sel","selection","getContent","componentCode","code","placeholder","length","text","timestamp","Date","getTime","randomId","Math","round","random","newNode","document","createElement","innerHTML","replace","outerHTML","variants","name","join","applyLangStrings","setContent","nodeSel","dom","destroy","focus","previewDefault","toggle","variant","variantEnabled","state","updateVariantComponentState","stopPropagation","elementid","buttons","getButtons","filters","getFilters","preview","stringValues","map","key","component","context","index","push","filterClass","includes","variantsNode","get","imageClass","classComponent","htmlcode","getVariantsState","elements","variantState","variantClass","slice","title","updateHtml","selectedVariant","componentClass","classcomponent","previewComponent","variantPreview","variantsHtml","updateVariantButtonState","activate","showNodes","hideNodes","matchAll","strLang","keys","compRegex","element","Map"],"mappings":"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"} -======= -{"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 C4L UI.\n *\n * @module tiny_c4l/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 C4LModal from './modal';\nimport ModalFactory from 'core/modal_factory';\nimport {components as Components} from './components';\nimport {get_strings as getStrings} from 'core/str';\nimport {\n isStudent,\n getallowedComponents,\n showPreview\n} from './options';\nimport ModalEvents from 'core/modal_events';\nimport {\n addVariant,\n getVariantsClass,\n getVariantHtml,\n getVariantsHtml,\n loadVariantPreferences,\n removeVariant,\n saveVariantPreferences,\n variantExists\n} from './variantslib';\n\nlet userStudent = false;\nlet previewC4L = true;\nlet allowedComponents = [];\nlet Contexts = [];\nlet langStrings = {};\n\n/**\n * Handle action\n *\n * @param {TinyMCE} editor\n */\nexport const handleAction = async(editor) => {\n userStudent = isStudent(editor);\n previewC4L = showPreview(editor);\n langStrings = await getAllStrings();\n allowedComponents = getallowedComponents(editor);\n loadVariantPreferences().then(() => displayDialogue(editor));\n};\n\n/**\n * Display modal\n *\n * @param {TinyMCE} editor\n */\nconst displayDialogue = async(editor) => {\n const data = Object.assign({}, {});\n\n // Show modal with buttons.\n const modal = await ModalFactory.create({\n type: C4LModal.TYPE,\n templateContext: await getTemplateContext(editor, data),\n large: true,\n });\n\n // Set modal size when no preview.\n if (!previewC4L) {\n editor.targetElm.closest('body').classList.add('c4l-modal-no-preview');\n }\n modal.show();\n\n // Event modal listener.\n modal.getRoot().on(ModalEvents.hidden, () => {\n handleModalHidden(editor);\n });\n\n // Event filters listener.\n const filters = modal.getRoot()[0].querySelectorAll('.c4l-button-filter');\n filters.forEach(node => {\n node.addEventListener('click', (event) => {\n handleButtonFilterClick(event, modal);\n });\n });\n\n modal.getRoot()[0].querySelector('.c4l-select-filter').addEventListener('change', (event) => {\n handleSelectFilterChange(event, modal);\n });\n\n // Event buttons listeners.\n const buttons = modal.getRoot()[0].querySelectorAll('.c4lt-dialog-button');\n buttons.forEach(node => {\n node.addEventListener('click', (event) => {\n handleButtonClick(event, editor, modal);\n });\n if (previewC4L) {\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('.c4l-button-variant');\n variants.forEach(node => {\n node.addEventListener('click', (event) => {\n handleVariantClick(event, modal);\n });\n if (previewC4L) {\n node.addEventListener('mouseenter', (event) => {\n handleVariantMouseEvent(event, modal, true);\n });\n node.addEventListener('mouseleave', (event) => {\n handleVariantMouseEvent(event, modal, false);\n });\n }\n });\n};\n\n/**\n * Handle a change within filter select.\n *\n * @param {MouseEvent} event The change event\n * @param {obj} modal\n */\nconst handleSelectFilterChange = (event, modal) => {\n const select = event.target.closest('select');\n\n if (select) {\n const currentContext = select.value;\n if (Contexts.indexOf(currentContext) !== -1) {\n // Select current button.\n const buttons = modal.getRoot()[0]\n .querySelectorAll('.c4l-buttons-filters button');\n buttons.forEach(node => node.classList.remove('c4l-button-filter-enabled'));\n const button = modal.getRoot()[0]\n .querySelector('.c4l-button-filter[data-filter=\"' + currentContext + '\"]');\n button.classList.add('c4l-button-filter-enabled');\n\n // Show/hide component buttons.\n showContextButtons(modal, currentContext);\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 handleButtonFilterClick = (event, modal) => {\n const button = event.target.closest('button');\n\n const currentContext = button.dataset.filter;\n // Filter button.\n if (Contexts.indexOf(currentContext) !== -1) {\n // Select current button.\n const buttons = modal.getRoot()[0].querySelectorAll('.c4l-buttons-filters button');\n buttons.forEach(node => node.classList.remove('c4l-button-filter-enabled'));\n button.classList.add('c4l-button-filter-enabled');\n\n // Select current option in select.\n const select = modal.getRoot()[0].querySelector('.c4l-select-filter');\n select.selectedIndex = Contexts.indexOf(currentContext);\n\n // Show/hide component buttons.\n showContextButtons(modal, currentContext);\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('c4l-modal-no-preview');\n saveVariantPreferences();\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 = (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 // 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 = componentCode.replace('{{PLACEHOLDER}}', newNode.outerHTML);\n\n // Return active variants for current component.\n const variants = getVariantsClass(Components[selectedButton].name);\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 // Apply random IDs.\n componentCode = applyRandomID(componentCode);\n\n // Apply lang strings.\n componentCode = applyLangStrings(componentCode);\n\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\n if (node) {\n if (show) {\n previewDefault.classList.toggle('c4l-hidden');\n node.classList.toggle('c4l-hidden');\n } else {\n node.classList.toggle('c4l-hidden');\n previewDefault.classList.toggle('c4l-hidden');\n }\n }\n};\n\n/**\n * Handle a mouse events mouseenter/mouseleave in a variant button.\n *\n * @param {MouseEvent} event The mouseenter/mouseleave event\n * @param {obj} modal\n * @param {bool} show\n */\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 updateVariantComponentState(variant, button, modal, false, true);\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 filters: await getFilters(),\n preview: previewC4L,\n }, data);\n};\n\n/**\n * Get the C4L filters for the dialogue.\n *\n * @returns {object} data\n */\nconst getFilters = async() => {\n const filters = [];\n const stringValues = await getStrings(Contexts.map((key) => ({key, component})));\n\n // Iterate over contexts.\n Contexts.forEach((context, index) => {\n filters.push({\n name: stringValues[index],\n type: context,\n filterClass: index === 0 ? 'c4l-button-filter-enabled' : '',\n });\n });\n\n return filters;\n};\n\n/**\n * Get the C4L buttons for the dialogue.\n *\n * @param {Editor} editor\n * @returns {object} buttons\n */\nconst getButtons = (editor) => {\n const buttons = [];\n const sel = editor.selection.getContent();\n let componentCode = '';\n let placeholder = '';\n let variants = [];\n\n // Iterate over components.\n Components.forEach((component, index) => {\n if (!userStudent || (userStudent && allowedComponents.includes(component.name))) {\n if (previewC4L) {\n placeholder = (sel.length > 0 ? sel : component.text);\n componentCode = component.code;\n componentCode = componentCode.replace('{{PLACEHOLDER}}', placeholder);\n // Return active variants for component.\n variants = getVariantsClass(component.name);\n\n // Apply class variants and html to html component.\n const variantsNode = document.createElement('span');\n variantsNode.dataset.id = 'variantHTML-' + component.id;\n if (variants.length > 0) {\n componentCode = componentCode.replace('{{VARIANTS}}', variants.join(' '));\n variantsNode.innerHTML = getVariantsHtml(component.name);\n componentCode = componentCode.replace('{{VARIANTSHTML}}', variantsNode.outerHTML);\n } else {\n componentCode = componentCode.replace('{{VARIANTS}}', '');\n componentCode = componentCode.replace('{{VARIANTSHTML}}', variantsNode.outerHTML);\n }\n\n // Apply lang strings.\n componentCode = applyLangStrings(componentCode);\n }\n\n // Save contexts.\n if (Contexts.indexOf(component.type) === -1) {\n Contexts.push(component.type);\n }\n\n buttons.push({\n id: index,\n name: langStrings.get(component.name),\n type: component.type,\n imageClass: component.imageClass,\n classComponent: 'c4lv-' + component.name,\n htmlcode: componentCode,\n variants: getVariantsState(component.name, component.variants),\n });\n\n // Add class to hide button.\n if (Contexts.indexOf(component.type) !== 0) {\n buttons[buttons.length - 1].imageClass += ' c4l-hidden';\n }\n }\n });\n\n return buttons;\n};\n\n/**\n * Get variants for the dialogue.\n *\n * @param {string} component\n * @param {object} elements\n * @return {object} Variants for a component\n */\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 = 'c4l-' + 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-' + selectedButton + '\"] .' + componentClass);\n const variantPreview = modal.getRoot()[0]\n .querySelector('span[data-id=\"variantHTML-' + selectedButton + '\"]');\n let variantsHtml = '';\n\n if (previewComponent) {\n if (updateHtml) {\n if (variant.dataset.state == 'on') {\n removeVariant(Components[selectedButton].name, variant.dataset.variant);\n updateVariantButtonState(variant, false);\n previewComponent.classList.remove(selectedVariant);\n } else {\n addVariant(Components[selectedButton].name, variant.dataset.variant);\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);\n updateVariantButtonState(variant, false);\n } else {\n addVariant(Components[selectedButton].name, variant.dataset.variant);\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 showContextButtons = (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('c4l-hidden'));\n hideNodes.forEach(node => node.classList.add('c4l-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 keys.push(element.name);\n element.variants.forEach(variant => {\n if (keys.indexOf(variant) === -1) {\n keys.push(variant);\n }\n });\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\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","previewC4L","allowedComponents","Contexts","langStrings","async","editor","getAllStrings","then","displayDialogue","data","Object","assign","modal","ModalFactory","create","type","C4LModal","TYPE","templateContext","getTemplateContext","large","targetElm","closest","classList","add","show","getRoot","on","ModalEvents","hidden","handleModalHidden","querySelectorAll","forEach","node","addEventListener","event","handleButtonFilterClick","querySelector","handleSelectFilterChange","handleButtonClick","handleButtonMouseEvent","handleVariantClick","handleVariantMouseEvent","select","target","currentContext","value","indexOf","remove","showContextButtons","button","dataset","filter","selectedIndex","selectedButton","id","Components","sel","selection","getContent","componentCode","code","placeholder","length","text","randomId","generateRandomID","newNode","document","createElement","innerHTML","replace","outerHTML","variants","name","join","applyRandomID","applyLangStrings","setContent","nodeSel","dom","destroy","focus","previewDefault","toggle","variant","variantEnabled","state","updateVariantComponentState","stopPropagation","elementid","buttons","getButtons","filters","getFilters","preview","stringValues","map","key","component","context","index","push","filterClass","includes","variantsNode","get","imageClass","classComponent","htmlcode","getVariantsState","elements","variantState","variantClass","slice","title","updateHtml","selectedVariant","componentClass","classcomponent","previewComponent","variantPreview","variantsHtml","updateVariantButtonState","activate","showNodes","hideNodes","matchAll","strLang","timestamp","Date","getTime","Math","round","random","compRegex","match","keys","element","Map"],"mappings":"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"} ->>>>>>> 52816fc (foo) +{"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 C4L UI.\n *\n * @module tiny_c4l/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 C4LModal from './modal';\nimport ModalFactory from 'core/modal_factory';\nimport {components as Components} from './components';\nimport {get_strings as getStrings} from 'core/str';\nimport {\n isStudent,\n getallowedComponents,\n showPreview\n} from './options';\nimport ModalEvents from 'core/modal_events';\nimport {\n addVariant,\n getVariantsClass,\n getVariantHtml,\n getVariantsHtml,\n loadVariantPreferences,\n removeVariant,\n saveVariantPreferences,\n variantExists\n} from './variantslib';\n\nlet userStudent = false;\nlet previewC4L = true;\nlet allowedComponents = [];\nlet Contexts = [];\nlet langStrings = {};\n\n/**\n * Handle action\n *\n * @param {TinyMCE} editor\n */\nexport const handleAction = async(editor) => {\n userStudent = isStudent(editor);\n previewC4L = showPreview(editor);\n langStrings = await getAllStrings();\n allowedComponents = getallowedComponents(editor);\n loadVariantPreferences().then(displayDialogue(editor));\n};\n\n/**\n * Display modal\n *\n * @param {TinyMCE} editor\n */\nconst displayDialogue = async(editor) => {\n const data = Object.assign({}, {});\n\n // Show modal with buttons.\n const modal = await ModalFactory.create({\n type: C4LModal.TYPE,\n templateContext: await getTemplateContext(editor, data),\n large: true,\n });\n\n // Set modal size when no preview.\n if (!previewC4L) {\n editor.targetElm.closest('body').classList.add('c4l-modal-no-preview');\n }\n modal.show();\n\n // Event modal listener.\n modal.getRoot().on(ModalEvents.hidden, () => {\n handleModalHidden(editor);\n });\n\n // Event filters listener.\n const filters = modal.getRoot()[0].querySelectorAll('.c4l-button-filter');\n filters.forEach(node => {\n node.addEventListener('click', (event) => {\n handleButtonFilterClick(event, modal);\n });\n });\n\n modal.getRoot()[0].querySelector('.c4l-select-filter').addEventListener('change', (event) => {\n handleSelectFilterChange(event, modal);\n });\n\n // Event buttons listeners.\n const buttons = modal.getRoot()[0].querySelectorAll('.c4lt-dialog-button');\n buttons.forEach(node => {\n node.addEventListener('click', (event) => {\n handleButtonClick(event, editor, modal);\n });\n if (previewC4L) {\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('.c4l-button-variant');\n variants.forEach(node => {\n node.addEventListener('click', (event) => {\n handleVariantClick(event, modal);\n });\n if (previewC4L) {\n node.addEventListener('mouseenter', (event) => {\n handleVariantMouseEvent(event, modal, true);\n });\n node.addEventListener('mouseleave', (event) => {\n handleVariantMouseEvent(event, modal, false);\n });\n }\n });\n};\n\n/**\n * Handle a change within filter select.\n *\n * @param {MouseEvent} event The change event\n * @param {obj} modal\n */\nconst handleSelectFilterChange = (event, modal) => {\n const select = event.target.closest('select');\n\n if (select) {\n const currentContext = select.value;\n if (Contexts.indexOf(currentContext) !== -1) {\n // Select current button.\n const buttons = modal.getRoot()[0]\n .querySelectorAll('.c4l-buttons-filters button');\n buttons.forEach(node => node.classList.remove('c4l-button-filter-enabled'));\n const button = modal.getRoot()[0]\n .querySelector('.c4l-button-filter[data-filter=\"' + currentContext + '\"]');\n button.classList.add('c4l-button-filter-enabled');\n\n // Show/hide component buttons.\n showContextButtons(modal, currentContext);\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 handleButtonFilterClick = (event, modal) => {\n const button = event.target.closest('button');\n\n const currentContext = button.dataset.filter;\n // Filter button.\n if (Contexts.indexOf(currentContext) !== -1) {\n // Select current button.\n const buttons = modal.getRoot()[0].querySelectorAll('.c4l-buttons-filters button');\n buttons.forEach(node => node.classList.remove('c4l-button-filter-enabled'));\n button.classList.add('c4l-button-filter-enabled');\n\n // Select current option in select.\n const select = modal.getRoot()[0].querySelector('.c4l-select-filter');\n select.selectedIndex = Contexts.indexOf(currentContext);\n\n // Show/hide component buttons.\n showContextButtons(modal, currentContext);\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('c4l-modal-no-preview');\n saveVariantPreferences();\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 = (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 // 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 = componentCode.replace('{{PLACEHOLDER}}', newNode.outerHTML);\n\n // Return active variants for current component.\n const variants = getVariantsClass(Components[selectedButton].name);\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 // Apply random IDs.\n componentCode = applyRandomID(componentCode);\n\n // Apply lang strings.\n componentCode = applyLangStrings(componentCode);\n\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\n if (node) {\n if (show) {\n previewDefault.classList.toggle('c4l-hidden');\n node.classList.toggle('c4l-hidden');\n } else {\n node.classList.toggle('c4l-hidden');\n previewDefault.classList.toggle('c4l-hidden');\n }\n }\n};\n\n/**\n * Handle a mouse events mouseenter/mouseleave in a variant button.\n *\n * @param {MouseEvent} event The mouseenter/mouseleave event\n * @param {obj} modal\n * @param {bool} show\n */\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 updateVariantComponentState(variant, button, modal, false, true);\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 filters: await getFilters(),\n preview: previewC4L,\n }, data);\n};\n\n/**\n * Get the C4L filters for the dialogue.\n *\n * @returns {object} data\n */\nconst getFilters = async() => {\n const filters = [];\n const stringValues = await getStrings(Contexts.map((key) => ({key, component})));\n\n // Iterate over contexts.\n Contexts.forEach((context, index) => {\n filters.push({\n name: stringValues[index],\n type: context,\n filterClass: index === 0 ? 'c4l-button-filter-enabled' : '',\n });\n });\n\n return filters;\n};\n\n/**\n * Get the C4L buttons for the dialogue.\n *\n * @param {Editor} editor\n * @returns {object} buttons\n */\nconst getButtons = (editor) => {\n const buttons = [];\n const sel = editor.selection.getContent();\n let componentCode = '';\n let placeholder = '';\n let variants = [];\n\n // Iterate over components.\n Components.forEach((component, index) => {\n if (!userStudent || (userStudent && allowedComponents.includes(component.name))) {\n if (previewC4L) {\n placeholder = (sel.length > 0 ? sel : component.text);\n componentCode = component.code;\n componentCode = componentCode.replace('{{PLACEHOLDER}}', placeholder);\n // Return active variants for component.\n variants = getVariantsClass(component.name);\n\n // Apply class variants and html to html component.\n const variantsNode = document.createElement('span');\n variantsNode.dataset.id = 'variantHTML-' + component.id;\n if (variants.length > 0) {\n componentCode = componentCode.replace('{{VARIANTS}}', variants.join(' '));\n variantsNode.innerHTML = getVariantsHtml(component.name);\n componentCode = componentCode.replace('{{VARIANTSHTML}}', variantsNode.outerHTML);\n } else {\n componentCode = componentCode.replace('{{VARIANTS}}', '');\n componentCode = componentCode.replace('{{VARIANTSHTML}}', variantsNode.outerHTML);\n }\n\n // Apply lang strings.\n componentCode = applyLangStrings(componentCode);\n }\n\n // Save contexts.\n if (Contexts.indexOf(component.type) === -1) {\n Contexts.push(component.type);\n }\n\n buttons.push({\n id: index,\n name: langStrings.get(component.name),\n type: component.type,\n imageClass: component.imageClass,\n classComponent: 'c4lv-' + component.name,\n htmlcode: componentCode,\n variants: getVariantsState(component.name, component.variants),\n });\n\n // Add class to hide button.\n if (Contexts.indexOf(component.type) !== 0) {\n buttons[buttons.length - 1].imageClass += ' c4l-hidden';\n }\n }\n });\n\n return buttons;\n};\n\n/**\n * Get variants for the dialogue.\n *\n * @param {string} component\n * @param {object} elements\n * @return {object} Variants for a component\n */\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 = 'c4l-' + 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-' + selectedButton + '\"] .' + componentClass);\n const variantPreview = modal.getRoot()[0]\n .querySelector('span[data-id=\"variantHTML-' + selectedButton + '\"]');\n let variantsHtml = '';\n\n if (previewComponent) {\n if (updateHtml) {\n if (variant.dataset.state == 'on') {\n removeVariant(Components[selectedButton].name, variant.dataset.variant);\n updateVariantButtonState(variant, false);\n previewComponent.classList.remove(selectedVariant);\n } else {\n addVariant(Components[selectedButton].name, variant.dataset.variant);\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);\n updateVariantButtonState(variant, false);\n } else {\n addVariant(Components[selectedButton].name, variant.dataset.variant);\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 showContextButtons = (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('c4l-hidden'));\n hideNodes.forEach(node => node.classList.add('c4l-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 keys.push(element.name);\n element.variants.forEach(variant => {\n if (keys.indexOf(variant) === -1) {\n keys.push(variant);\n }\n });\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\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","previewC4L","allowedComponents","Contexts","langStrings","async","editor","getAllStrings","then","displayDialogue","data","Object","assign","modal","ModalFactory","create","type","C4LModal","TYPE","templateContext","getTemplateContext","large","targetElm","closest","classList","add","show","getRoot","on","ModalEvents","hidden","handleModalHidden","querySelectorAll","forEach","node","addEventListener","event","handleButtonFilterClick","querySelector","handleSelectFilterChange","handleButtonClick","handleButtonMouseEvent","handleVariantClick","handleVariantMouseEvent","select","target","currentContext","value","indexOf","remove","showContextButtons","button","dataset","filter","selectedIndex","selectedButton","id","Components","sel","selection","getContent","componentCode","code","placeholder","length","text","randomId","generateRandomID","newNode","document","createElement","innerHTML","replace","outerHTML","variants","name","join","applyRandomID","applyLangStrings","setContent","nodeSel","dom","destroy","focus","previewDefault","toggle","variant","variantEnabled","state","updateVariantComponentState","stopPropagation","elementid","buttons","getButtons","filters","getFilters","preview","stringValues","map","key","component","context","index","push","filterClass","includes","variantsNode","get","imageClass","classComponent","htmlcode","getVariantsState","elements","variantState","variantClass","slice","title","updateHtml","selectedVariant","componentClass","classcomponent","previewComponent","variantPreview","variantsHtml","updateVariantButtonState","activate","showNodes","hideNodes","matchAll","strLang","timestamp","Date","getTime","Math","round","random","compRegex","match","keys","element","Map"],"mappings":"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"} \ No newline at end of file diff --git a/amd/src/ui.js b/amd/src/ui.js index 60f3df1..fa697a1 100644 --- a/amd/src/ui.js +++ b/amd/src/ui.js @@ -212,8 +212,7 @@ const handleButtonClick = (event, editor, modal) => { const placeholder = (sel.length > 0 ? sel : Components[selectedButton].text); // Create a new node to replace the placeholder. - const timestamp = new Date().getTime(); - const randomId = Math.round(Math.random() * 100000) + '-' + timestamp; + const randomId = generateRandomID(); const newNode = document.createElement('span'); newNode.dataset.id = randomId; newNode.innerHTML = placeholder; @@ -231,6 +230,9 @@ const handleButtonClick = (event, editor, modal) => { componentCode = componentCode.replace('{{VARIANTSHTML}}', ''); } + // Apply random IDs. + componentCode = applyRandomID(componentCode); + // Apply lang strings. componentCode = applyLangStrings(componentCode); @@ -552,6 +554,30 @@ const applyLangStrings = (text) => { return text; }; +/** + * Generates a random string. + * @return {string} A random string + */ +const generateRandomID = () => { + const timestamp = new Date().getTime(); + return 'R' + Math.round(Math.random() * 100000) + '-' + timestamp; +}; + +/** + * Replace all ID tags with a random string. + * @param {String} text + * @return {String} String with all ID tags replaced with a random string. + */ +const applyRandomID = (text) => { + const compRegex = /{{@ID}}/g; + + if (text.match(compRegex)) { + text = text.replace(compRegex, generateRandomID()); + } + + return text; +}; + /** * Get language strings. *