diff --git a/README.md b/README.md index 6fb5732..eea9ee1 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ Download zip package, extract the onetopic folder and upload this folder into co ### 2024050905: * New tab styles editor when editing each section. +* Select icon by tab and tab state. +* New background option by section. ### 2024050904: * New "sectionname" parameter to navigate to a tab directly using its name. diff --git a/amd/build/onetopicbackground.min.js b/amd/build/onetopicbackground.min.js new file mode 100644 index 0000000..d10cd6f --- /dev/null +++ b/amd/build/onetopicbackground.min.js @@ -0,0 +1,10 @@ +define("format_onetopic/onetopicbackground",["exports","jquery","core/modal_factory","core/modal_save_cancel","core/modal_events"],(function(_exports,_jquery,_modal_factory,_modal_save_cancel,_modal_events){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +/** + * Onetopic background selector. + * + * @module format_onetopic/onetopicbackground + * @copyright 2021 David Herney Bernal - cirano + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=_interopRequireDefault(_jquery),_modal_factory=_interopRequireDefault(_modal_factory),_modal_save_cancel=_interopRequireDefault(_modal_save_cancel),_modal_events=_interopRequireDefault(_modal_events);_exports.init=controlid=>{var $controlinput=(0,_jquery.default)("#"+controlid),$control=$controlinput.parent(".backgroundpicker"),$controlwindow=$control.find(".backgroundpickerwindow"),$controlbutton=$control.find(".backgroundpickerselector"),$colorpickerinput=$controlwindow.find('input.form-control[type="text"]'),title=$controlwindow.attr("title"),buttons=[];buttons.save=$controlwindow.data("savelabel");_modal_factory.default.create({title:title,body:$controlwindow,type:_modal_save_cancel.default.TYPE,large:!0,buttons:buttons}).done((function(modal){modal.getBody().append($controlwindow),$control.data("modal",modal),function(modal){modal.getRoot().on(_modal_events.default.cancel,(()=>{modal.hide()})),modal.getRoot().on(_modal_events.default.save,(()=>{var newcolor=$colorpickerinput.val(),val=$controlinput.val(),color=readColor(val);color?val=val.replace(color,newcolor):""===val.trim()?val=newcolor:val+=" "+newcolor,$controlinput.val(val),modal.hide()}))}(modal)})),$controlbutton.on("click",(function(e){e.preventDefault(),$controlwindow.removeClass("hidden");var currentval=$controlinput.val(),color=readColor(currentval);$colorpickerinput.val(color),$control.data("modal").show()}))};var readColor=function(text){var regexcolor=new RegExp(/#[0-9a-fA-F]{6}/.source+/|#[0-9a-fA-F]{3}/.source+/|rgba?\(\s*([0-9]{1,3}\s*,\s*){2}[0-9]{1,3}\s*(,\s*[0-9.]+\s*)?\)/.source+/|hsla?\(\s*([0-9]{1,3}\s*,\s*){2}[0-9]{1,3}\s*(,\s*[0-9.]+\s*)?\)/.source),color=text.match(regexcolor);return color&&(color=color[0]),color}})); + +//# sourceMappingURL=onetopicbackground.min.js.map \ No newline at end of file diff --git a/amd/build/onetopicbackground.min.js.map b/amd/build/onetopicbackground.min.js.map new file mode 100644 index 0000000..b158520 --- /dev/null +++ b/amd/build/onetopicbackground.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"onetopicbackground.min.js","sources":["../src/onetopicbackground.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 * Onetopic background selector.\n *\n * @module format_onetopic/onetopicbackground\n * @copyright 2021 David Herney Bernal - cirano\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport $ from 'jquery';\nimport ModalFactory from 'core/modal_factory';\nimport ModalSaveCancel from 'core/modal_save_cancel';\nimport ModalEvents from 'core/modal_events';\n\n/**\n * Component initialization.\n *\n * @method init\n * @param {String} controlid The control id.\n */\nexport const init = (controlid) => {\n\n var $controlinput = $('#' + controlid);\n var $control = $controlinput.parent('.backgroundpicker');\n var $controlwindow = $control.find('.backgroundpickerwindow');\n var $controlbutton = $control.find('.backgroundpickerselector');\n var $colorpickerinput = $controlwindow.find('input.form-control[type=\"text\"]');\n\n // Initialize the modal window.\n var title = $controlwindow.attr('title');\n var buttons = [];\n buttons['save'] = $controlwindow.data('savelabel');\n\n var setEvents = function(modal) {\n modal.getRoot().on(ModalEvents.cancel, () => {\n modal.hide();\n });\n\n modal.getRoot().on(ModalEvents.save, () => {\n var newcolor = $colorpickerinput.val();\n var val = $controlinput.val();\n var color = readColor(val);\n if (color) {\n val = val.replace(color, newcolor);\n } else if (val.trim() === '') {\n val = newcolor;\n } else {\n val += ' ' + newcolor;\n }\n $controlinput.val(val);\n modal.hide();\n });\n };\n\n ModalFactory.create({\n 'title': title,\n 'body': $controlwindow,\n 'type': ModalSaveCancel.TYPE,\n 'large': true,\n 'buttons': buttons\n })\n .done(function(modal) {\n var $modalBody = modal.getBody();\n $modalBody.append($controlwindow);\n $control.data('modal', modal);\n setEvents(modal);\n });\n\n // Color picker control.\n $controlbutton.on('click', function(e) {\n e.preventDefault();\n $controlwindow.removeClass('hidden');\n var currentval = $controlinput.val();\n\n var color = readColor(currentval);\n\n $colorpickerinput.val(color);\n $control.data('modal').show();\n });\n\n};\n\n/**\n * Extracts the first color from a text string. Recognizes hexadecimal, rgba and hsla.\n *\n * @param {string} text\n * @returns\n */\nvar readColor = function(text) {\n var regexcolor = new RegExp(\n /#[0-9a-fA-F]{6}/.source\n + /|#[0-9a-fA-F]{3}/.source\n + /|rgba?\\(\\s*([0-9]{1,3}\\s*,\\s*){2}[0-9]{1,3}\\s*(,\\s*[0-9.]+\\s*)?\\)/.source\n + /|hsla?\\(\\s*([0-9]{1,3}\\s*,\\s*){2}[0-9]{1,3}\\s*(,\\s*[0-9.]+\\s*)?\\)/.source);\n\n var color = text.match(regexcolor);\n if (color) {\n color = color[0];\n }\n\n return color;\n};\n"],"names":["controlid","$controlinput","$control","parent","$controlwindow","find","$controlbutton","$colorpickerinput","title","attr","buttons","data","create","ModalSaveCancel","TYPE","done","modal","getBody","append","getRoot","on","ModalEvents","cancel","hide","save","newcolor","val","color","readColor","replace","trim","setEvents","e","preventDefault","removeClass","currentval","show","text","regexcolor","RegExp","source","match"],"mappings":";;;;;;;gTAiCqBA,gBAEbC,eAAgB,mBAAE,IAAMD,WACxBE,SAAWD,cAAcE,OAAO,qBAChCC,eAAiBF,SAASG,KAAK,2BAC/BC,eAAiBJ,SAASG,KAAK,6BAC/BE,kBAAoBH,eAAeC,KAAK,mCAGxCG,MAAQJ,eAAeK,KAAK,SAC5BC,QAAU,GACdA,QAAO,KAAWN,eAAeO,KAAK,oCAuBzBC,OAAO,OACPJ,WACDJ,oBACAS,2BAAgBC,YACf,UACEJ,UAEdK,MAAK,SAASC,OACMA,MAAMC,UACZC,OAAOd,gBAClBF,SAASS,KAAK,QAASK,OA/BX,SAASA,OACrBA,MAAMG,UAAUC,GAAGC,sBAAYC,QAAQ,KACnCN,MAAMO,UAGVP,MAAMG,UAAUC,GAAGC,sBAAYG,MAAM,SAC7BC,SAAWlB,kBAAkBmB,MAC7BA,IAAMzB,cAAcyB,MACpBC,MAAQC,UAAUF,KAClBC,MACAD,IAAMA,IAAIG,QAAQF,MAAOF,UACH,KAAfC,IAAII,OACXJ,IAAMD,SAENC,KAAO,IAAMD,SAEjBxB,cAAcyB,IAAIA,KAClBV,MAAMO,UAeVQ,CAAUf,UAIdV,eAAec,GAAG,SAAS,SAASY,GAChCA,EAAEC,iBACF7B,eAAe8B,YAAY,cACvBC,WAAalC,cAAcyB,MAE3BC,MAAQC,UAAUO,YAEtB5B,kBAAkBmB,IAAIC,OACtBzB,SAASS,KAAK,SAASyB,eAW3BR,UAAY,SAASS,UACjBC,WAAa,IAAIC,OACjB,kBAAkBC,OAChB,mBAAmBA,OACnB,oEAAoEA,OACpE,oEAAoEA,QAEtEb,MAAQU,KAAKI,MAAMH,mBACnBX,QACAA,MAAQA,MAAM,IAGXA"} \ No newline at end of file diff --git a/amd/build/tabstyles.min.js b/amd/build/tabstyles.min.js index e52a0c1..4ea45cb 100644 --- a/amd/build/tabstyles.min.js +++ b/amd/build/tabstyles.min.js @@ -5,6 +5,6 @@ define("format_onetopic/tabstyles",["exports","jquery","core/modal_factory"],(fu * @module format_onetopic/tabstyles * @copyright 2021 David Herney Bernal - cirano * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=_interopRequireDefault(_jquery),_modal_factory=_interopRequireDefault(_modal_factory);var $tabstyles=null,$styleswindow=null,currenttype="default",globalstyles={},$inputtosave=null;_exports.init=()=>{if($tabstyles=(0,_jquery.default)("#onetopic-tabstyles"),$inputtosave=$tabstyles.find("textarea.savecontrol"),$styleswindow=(0,_jquery.default)("#onetopic-styleswindow"),(0,_jquery.default)("#onetopic-tabstyles .tpl-tabdefault .tabicon").each((function(){var $tabicon=(0,_jquery.default)(this);$tabicon.append(''),$tabicon.append('')})),(0,_jquery.default)("#onetopic-tabstyles .tpl-tabactive .tabicon").each((function(){var $tabicon=(0,_jquery.default)(this);$tabicon.append(''),$tabicon.append('')})),(0,_jquery.default)("#onetopic-tabstyles .tpl-tabparent .tabicon").each((function(){var $tabicon=(0,_jquery.default)(this);$tabicon.append(''),$tabicon.append(''),$tabicon.append('')})),(0,_jquery.default)("#onetopic-tabstyles .tpl-tabchildindex .tabicon").each((function(){var $tabicon=(0,_jquery.default)(this);$tabicon.append(''),$tabicon.append(''),$tabicon.append(''),$tabicon.append('')})),(0,_jquery.default)("#onetopic-tabstyles .tpl-tabchild .tabicon").each((function(){var $tabicon=(0,_jquery.default)(this);$tabicon.append(''),$tabicon.append(''),$tabicon.append('')})),(0,_jquery.default)("#onetopic-tabstyles .tpl-tabhighlighted .tabicon").each((function(){var $tabicon=(0,_jquery.default)(this);$tabicon.append(''),$tabicon.append(''),$tabicon.append('')})),(0,_jquery.default)("#onetopic-tabstyles .tpl-tabdisabled .tabicon").each((function(){(0,_jquery.default)(this).append('')})),(0,_jquery.default)("#onetopic-tabstyles .tabicon").each((function(){(0,_jquery.default)(this).removeClass("hidden")})),""!==$inputtosave.val().trim()){try{null===(globalstyles=JSON.parse($inputtosave.val()))&&(globalstyles={})}catch(e){console.error(e),globalstyles={}}applyStyles()}var $colorpicker=$styleswindow.find(".colorpicker"),$setcolor=$colorpicker.find('[data-action="setcolor"]'),$colorpickerinput=$colorpicker.find("input");$styleswindow.find('[data-control="colorpicker"]').on("click",(function(){var $node=(0,_jquery.default)(this);$colorpicker.show(),$colorpickerinput.val($node.val()),$setcolor.data("target",$node)})).on("change",(function(){var $node=(0,_jquery.default)(this),color=$node.val().trim();$node.css("background-color",color)})),$setcolor.on("click",(function(e){e.preventDefault(),$colorpicker.hide(),$setcolor.data("target").val($colorpickerinput.val()).trigger("change")})),$colorpicker.find('[data-action="cancel"]').on("click",(function(){$colorpicker.hide()}));var title=$styleswindow.data("title");_modal_factory.default.create({title:title,body:""}).done((function(modal){var $modalBody=modal.getBody();$styleswindow.show(),$modalBody.append($styleswindow),$styleswindow.data("modal",modal)})),$styleswindow.find('[data-action="cancelstyles"]').on("click",(function(){$styleswindow.data("modal").hide()})),$styleswindow.find('[data-action="setstyles"]').on("click",(function(){var modal=$styleswindow.data("modal"),newstyles={};$styleswindow.find("[data-style]").each((function(){var $node=(0,_jquery.default)(this),key=$node.data("style"),value=$node.val();""!==value&&(newstyles[key]=value)})),globalstyles[currenttype]=newstyles,$inputtosave.val(JSON.stringify(globalstyles)),applyStyles(),modal.hide()}));["default","active","parent","highlighted","disabled","hover","childs","childindex"].forEach((type=>{(0,_jquery.default)("#onetopic-tabstyles #tabstyleset"+type).on("click",(function(e){e.preventDefault(),showStylesWindow(type)}))})),(0,_jquery.default)("#onetopic-tabstyles #tabstyleclear").on("click",(function(e){e.preventDefault(),globalstyles={},$inputtosave.val(""),applyStyles()})),(0,_jquery.default)("#tabstylesdisplay").on("click",(function(e){e.preventDefault(),$tabstyles.toggleClass("hidden")})),(0,_jquery.default)("#onetopic-styleswindow .onetopic-selecticon").each((function(){var $selecticon=(0,_jquery.default)(this);$selecticon.find("button").on("click",(function(e){e.preventDefault(),$selecticon.find(".listicons").removeClass("hidden")})),$selecticon.find(".listicons span").on("click",(function(e){e.preventDefault();var $icon=(0,_jquery.default)(this);$selecticon.find(".iconselected").html($icon.html()),$selecticon.find('[data-style="tabicon"]').val($icon.data("value")),$selecticon.find(".listicons").addClass("hidden")})),$selecticon.find('[data-style="tabicon"]').on("change",(function(){var $node=(0,_jquery.default)(this);if(""!==$node.val()){var $icon=$selecticon.find('.listicons span[data-value="'+$node.val()+'"]');$icon.length>0&&$selecticon.find(".iconselected").html($icon.html())}else $selecticon.find(".iconselected").html("")}))}))};var showStylesWindow=function(type){if(currenttype=type,$styleswindow.find("[data-style]").each((function(){var $node=(0,_jquery.default)(this);$node.is('input[type="text"]')||$node.is('input[type="hidden"]')?($node.val(""),$node.trigger("change")):$node.is("select")&&$node.find("option").first().prop("selected",!0)})),void 0!==globalstyles[type]){var currentstyles=globalstyles[type];Object.entries(currentstyles).forEach((_ref=>{let[key,value]=_ref;$styleswindow.find('[data-style="'+key+'"]').val(value),$styleswindow.find('[data-control="colorpicker"]').trigger("change"),$styleswindow.find('[data-style="tabicon"]').trigger("change")}))}$styleswindow.data("modal").show()},applyStyles=function(){var withunits=["font-size","line-height","margin","padding","border-width","border-radius"],csscontent="";Object.entries(globalstyles).forEach((_ref2=>{let[type,styles]=_ref2;switch(type){case"active":csscontent+="#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item a.nav-link.active, ",csscontent+="#onetopic-tabstyles .nav-tabs a.nav-link.active, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs a.nav-link.active, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic a.nav-link.active";break;case"parent":csscontent+="#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item.haschilds a.nav-link, ",csscontent+="#onetopic-tabstyles .nav-tabs .nav-item.haschilds a.nav-link";break;case"highlighted":csscontent+="#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item.marker a.nav-link, ",csscontent+="#onetopic-tabstyles .nav-tabs .nav-item.marker a.nav-link, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.marker a.nav-link, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic.marker a.nav-link";break;case"disabled":csscontent+="#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item.disabled a.nav-link, ",csscontent+="#onetopic-tabstyles .nav-tabs .nav-item.disabled a.nav-link, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.disabled a.nav-link, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic.disabled a.nav-link";break;case"hover":csscontent+="#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item a.nav-link:hover, ",csscontent+="#onetopic-tabstyles .nav-tabs .nav-item a.nav-link:hover, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item a.nav-link:hover, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic a.nav-link:hover";break;case"childs":csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic a.nav-link";break;case"childindex":csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic.tab_initial a.nav-link";break;default:csscontent+="#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item a.nav-link, ",csscontent+="#onetopic-tabstyles .nav-tabs a.nav-link"}csscontent+="{";var units=[],stylesarray=Object.entries(styles);stylesarray.forEach((_ref3=>{let[key,value]=_ref3;if(0===key.indexOf("unit-"))key=key.replace("unit-",""),units[key]=value;else if("tabicon"==key&&""!==value){console.log(value);var icon=(0,_jquery.default)('#onetopic-styleswindow .listicons span[data-value="'+value+'"]').html();console.log(icon),(0,_jquery.default)("#onetopic-tabstyles .tabicon-"+type).html(icon).removeClass("hidden")}})),stylesarray.forEach((_ref4=>{let[key,value]=_ref4;0!==key.indexOf("unit-")&&"tabicon"!=key&&(void 0!==units[key]?value+=units[key]:-1!==withunits.indexOf(key)&&(value+="px"),csscontent+="others"==key?value+";":key+":"+value+";")})),csscontent+="}"}));var $stylecontainer=$tabstyles.find("style");$stylecontainer.length>0&&$stylecontainer.remove(),$stylecontainer=(0,_jquery.default)('"),$tabstyles.append($stylecontainer)}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=_interopRequireDefault(_jquery),_modal_factory=_interopRequireDefault(_modal_factory);var $tabstyles=null,$styleswindow=null,currenttype="default",globalstyles={},$inputtosave=null;_exports.init=()=>{if($tabstyles=(0,_jquery.default)("#onetopic-tabstyles"),$inputtosave=$tabstyles.find("textarea.savecontrol"),$styleswindow=(0,_jquery.default)("#onetopic-styleswindow"),(0,_jquery.default)("#onetopic-tabstyles .tpl-tabdefault .tabicon").each((function(){var $tabicon=(0,_jquery.default)(this);$tabicon.append(''),$tabicon.append('')})),(0,_jquery.default)("#onetopic-tabstyles .tpl-tabactive .tabicon").each((function(){var $tabicon=(0,_jquery.default)(this);$tabicon.append(''),$tabicon.append('')})),(0,_jquery.default)("#onetopic-tabstyles .tpl-tabparent .tabicon").each((function(){var $tabicon=(0,_jquery.default)(this);$tabicon.append(''),$tabicon.append(''),$tabicon.append('')})),(0,_jquery.default)("#onetopic-tabstyles .tpl-tabchildindex .tabicon").each((function(){var $tabicon=(0,_jquery.default)(this);$tabicon.append(''),$tabicon.append(''),$tabicon.append(''),$tabicon.append('')})),(0,_jquery.default)("#onetopic-tabstyles .tpl-tabchild .tabicon").each((function(){var $tabicon=(0,_jquery.default)(this);$tabicon.append(''),$tabicon.append(''),$tabicon.append('')})),(0,_jquery.default)("#onetopic-tabstyles .tpl-tabhighlighted .tabicon").each((function(){var $tabicon=(0,_jquery.default)(this);$tabicon.append(''),$tabicon.append(''),$tabicon.append('')})),(0,_jquery.default)("#onetopic-tabstyles .tpl-tabdisabled .tabicon").each((function(){(0,_jquery.default)(this).append('')})),(0,_jquery.default)("#onetopic-tabstyles .tabicon").each((function(){(0,_jquery.default)(this).removeClass("hidden")})),""!==$inputtosave.val().trim()){try{null===(globalstyles=JSON.parse($inputtosave.val()))&&(globalstyles={})}catch(e){console.error(e),globalstyles={}}applyStyles()}var $colorpicker=$styleswindow.find(".colorpicker"),$setcolor=$colorpicker.find('[data-action="setcolor"]'),$colorpickerinput=$colorpicker.find("input");$styleswindow.find('[data-control="colorpicker"]').on("click",(function(){var $node=(0,_jquery.default)(this);$colorpicker.show(),$colorpickerinput.val($node.val()),$setcolor.data("target",$node)})).on("change",(function(){var $node=(0,_jquery.default)(this),color=$node.val().trim();$node.css("background-color",color)})),$setcolor.on("click",(function(e){e.preventDefault(),$colorpicker.hide(),$setcolor.data("target").val($colorpickerinput.val()).trigger("change")})),$colorpicker.find('[data-action="cancel"]').on("click",(function(){$colorpicker.hide()}));var title=$styleswindow.data("title");_modal_factory.default.create({title:title,body:""}).done((function(modal){var $modalBody=modal.getBody();$styleswindow.show(),$modalBody.append($styleswindow),$styleswindow.data("modal",modal)})),$styleswindow.find('[data-action="cancelstyles"]').on("click",(function(){$styleswindow.data("modal").hide()})),$styleswindow.find('[data-action="setstyles"]').on("click",(function(){var modal=$styleswindow.data("modal"),newstyles={};$styleswindow.find("[data-style]").each((function(){var $node=(0,_jquery.default)(this),key=$node.data("style"),value=$node.val();""!==value&&(newstyles[key]=value)})),globalstyles[currenttype]=newstyles,$inputtosave.val(JSON.stringify(globalstyles)),applyStyles(),modal.hide()}));["default","active","parent","highlighted","disabled","hover","childs","childindex"].forEach((type=>{(0,_jquery.default)("#onetopic-tabstyles #tabstyleset"+type).on("click",(function(e){e.preventDefault(),showStylesWindow(type)}))})),(0,_jquery.default)("#onetopic-tabstyles #tabstyleclear").on("click",(function(e){e.preventDefault(),globalstyles={},$inputtosave.val(""),applyStyles()})),(0,_jquery.default)("#tabstylesdisplay").on("click",(function(e){e.preventDefault(),$tabstyles.toggleClass("hidden")})),(0,_jquery.default)("#onetopic-styleswindow .onetopic-selecticon").each((function(){var $selecticon=(0,_jquery.default)(this);$selecticon.find("button").on("click",(function(e){e.preventDefault(),$selecticon.find(".listicons").removeClass("hidden")})),$selecticon.find(".listicons span").on("click",(function(e){e.preventDefault();var $icon=(0,_jquery.default)(this);$selecticon.find(".iconselected").html($icon.html()),$selecticon.find('[data-style="tabicon"]').val($icon.data("value")),$selecticon.find(".listicons").addClass("hidden")})),$selecticon.find('[data-style="tabicon"]').on("change",(function(){var $node=(0,_jquery.default)(this);if(""!==$node.val()){var $icon=$selecticon.find('.listicons span[data-value="'+$node.val()+'"]');$icon.length>0&&$selecticon.find(".iconselected").html($icon.html())}else $selecticon.find(".iconselected").html("")}))}))};var showStylesWindow=function(type){if(currenttype=type,$styleswindow.find("[data-style]").each((function(){var $node=(0,_jquery.default)(this);$node.is('input[type="text"]')||$node.is('input[type="hidden"]')?($node.val(""),$node.trigger("change")):$node.is("select")&&$node.find("option").first().prop("selected",!0)})),void 0!==globalstyles[type]){var currentstyles=globalstyles[type];Object.entries(currentstyles).forEach((_ref=>{let[key,value]=_ref;$styleswindow.find('[data-style="'+key+'"]').val(value),$styleswindow.find('[data-control="colorpicker"]').trigger("change"),$styleswindow.find('[data-style="tabicon"]').trigger("change")}))}$styleswindow.data("modal").show()},applyStyles=function(){var withunits=["font-size","line-height","margin","padding","border-width","border-radius"],csscontent="";Object.entries(globalstyles).forEach((_ref2=>{let[type,styles]=_ref2;switch(type){case"active":csscontent+="#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item a.nav-link.active, ",csscontent+="#onetopic-tabstyles .nav-tabs a.nav-link.active, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs a.nav-link.active, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic a.nav-link.active";break;case"parent":csscontent+="#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item.haschilds a.nav-link, ",csscontent+="#onetopic-tabstyles .nav-tabs .nav-item.haschilds a.nav-link";break;case"highlighted":csscontent+="#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item.marker a.nav-link, ",csscontent+="#onetopic-tabstyles .nav-tabs .nav-item.marker a.nav-link, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.marker a.nav-link, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic.marker a.nav-link";break;case"disabled":csscontent+="#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item.disabled a.nav-link, ",csscontent+="#onetopic-tabstyles .nav-tabs .nav-item.disabled a.nav-link, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.disabled a.nav-link, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic.disabled a.nav-link";break;case"hover":csscontent+="#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item a.nav-link:hover, ",csscontent+="#onetopic-tabstyles .nav-tabs .nav-item a.nav-link:hover, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item a.nav-link:hover, ",csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic a.nav-link:hover";break;case"childs":csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic a.nav-link";break;case"childindex":csscontent+="#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic.tab_initial a.nav-link";break;default:csscontent+="#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item a.nav-link, ",csscontent+="#onetopic-tabstyles .nav-tabs a.nav-link"}csscontent+="{";var units=[],stylesarray=Object.entries(styles);stylesarray.forEach((_ref3=>{let[key,value]=_ref3;if(0===key.indexOf("unit-"))key=key.replace("unit-",""),units[key]=value;else if("tabicon"==key&&""!==value){var icon=(0,_jquery.default)('#onetopic-styleswindow .listicons span[data-value="'+value+'"]').html();(0,_jquery.default)("#onetopic-tabstyles .tabicon-"+type).html(icon).removeClass("hidden")}})),stylesarray.forEach((_ref4=>{let[key,value]=_ref4;0!==key.indexOf("unit-")&&"tabicon"!=key&&(void 0!==units[key]?value+=units[key]:-1!==withunits.indexOf(key)&&(value+="px"),csscontent+="others"==key?value+";":key+":"+value+";")})),csscontent+="}"}));var $stylecontainer=$tabstyles.find("style");$stylecontainer.length>0&&$stylecontainer.remove(),$stylecontainer=(0,_jquery.default)('"),$tabstyles.append($stylecontainer)}})); //# sourceMappingURL=tabstyles.min.js.map \ No newline at end of file diff --git a/amd/build/tabstyles.min.js.map b/amd/build/tabstyles.min.js.map index 790756d..230b11b 100644 --- a/amd/build/tabstyles.min.js.map +++ b/amd/build/tabstyles.min.js.map @@ -1 +1 @@ -{"version":3,"file":"tabstyles.min.js","sources":["../src/tabstyles.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 * Tab editor in site settings.\n *\n * @module format_onetopic/tabstyles\n * @copyright 2021 David Herney Bernal - cirano\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport $ from 'jquery';\nimport ModalFactory from 'core/modal_factory';\n\nvar $tabstyles = null;\nvar $styleswindow = null;\nvar currenttype = 'default';\nvar globalstyles = {};\nvar $inputtosave = null;\n\n/**\n * Component initialization.\n *\n * @method init\n */\nexport const init = () => {\n\n $tabstyles = $('#onetopic-tabstyles');\n $inputtosave = $tabstyles.find('textarea.savecontrol');\n $styleswindow = $('#onetopic-styleswindow');\n\n // Define the tab icons.\n $('#onetopic-tabstyles .tpl-tabdefault .tabicon').each(function() {\n var $tabicon = $(this);\n $tabicon.append('');\n $tabicon.append('');\n });\n\n $('#onetopic-tabstyles .tpl-tabactive .tabicon').each(function() {\n var $tabicon = $(this);\n $tabicon.append('');\n $tabicon.append('');\n });\n\n $('#onetopic-tabstyles .tpl-tabparent .tabicon').each(function() {\n var $tabicon = $(this);\n $tabicon.append('');\n $tabicon.append('');\n $tabicon.append('');\n });\n\n $('#onetopic-tabstyles .tpl-tabchildindex .tabicon').each(function() {\n var $tabicon = $(this);\n $tabicon.append('');\n $tabicon.append('');\n $tabicon.append('');\n $tabicon.append('');\n });\n\n $('#onetopic-tabstyles .tpl-tabchild .tabicon').each(function() {\n var $tabicon = $(this);\n $tabicon.append('');\n $tabicon.append('');\n $tabicon.append('');\n });\n\n $('#onetopic-tabstyles .tpl-tabhighlighted .tabicon').each(function() {\n var $tabicon = $(this);\n $tabicon.append('');\n $tabicon.append('');\n $tabicon.append('');\n });\n\n $('#onetopic-tabstyles .tpl-tabdisabled .tabicon').each(function() {\n var $tabicon = $(this);\n $tabicon.append('');\n });\n\n $('#onetopic-tabstyles .tabicon').each(function() {\n $(this).removeClass('hidden');\n });\n // End of Define the tab icons.\n\n if ($inputtosave.val().trim() !== '') {\n\n try {\n globalstyles = JSON.parse($inputtosave.val());\n\n if (globalstyles === null) {\n globalstyles = {};\n }\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(e);\n globalstyles = {};\n }\n\n applyStyles();\n }\n\n var $colorpicker = $styleswindow.find('.colorpicker');\n var $setcolor = $colorpicker.find('[data-action=\"setcolor\"]');\n var $colorpickerinput = $colorpicker.find('input');\n\n // Color picker control.\n $styleswindow.find('[data-control=\"colorpicker\"]').on('click', function() {\n var $node = $(this);\n\n $colorpicker.show();\n $colorpickerinput.val($node.val());\n $setcolor.data('target', $node);\n }).on('change', function() {\n var $node = $(this);\n var color = $node.val().trim();\n\n $node.css('background-color', color);\n });\n\n $setcolor.on('click', function(e) {\n e.preventDefault();\n\n $colorpicker.hide();\n $setcolor.data('target').val($colorpickerinput.val()).trigger('change');\n });\n\n $colorpicker.find('[data-action=\"cancel\"]').on('click', function() {\n $colorpicker.hide();\n });\n\n var title = $styleswindow.data('title');\n\n // Initialize the modal window.\n ModalFactory.create({\n 'title': title,\n 'body': ''\n }).done(function(modal) {\n var $modalBody = modal.getBody();\n $styleswindow.show();\n $modalBody.append($styleswindow);\n $styleswindow.data('modal', modal);\n });\n\n // Save the styles.\n $styleswindow.find('[data-action=\"cancelstyles\"]').on('click', function() {\n $styleswindow.data('modal').hide();\n });\n\n $styleswindow.find('[data-action=\"setstyles\"]').on('click', function() {\n var modal = $styleswindow.data('modal');\n var newstyles = {};\n\n $styleswindow.find('[data-style]').each(function() {\n var $node = $(this);\n var key = $node.data('style');\n var value = $node.val();\n\n if (value !== '') {\n newstyles[key] = value;\n }\n });\n\n globalstyles[currenttype] = newstyles;\n $inputtosave.val(JSON.stringify(globalstyles));\n applyStyles();\n\n modal.hide();\n });\n\n var types = ['default', 'active', 'parent', 'highlighted', 'disabled', 'hover', 'childs', 'childindex'];\n types.forEach(type => {\n $('#onetopic-tabstyles #tabstyleset' + type).on('click', function(e) {\n e.preventDefault();\n showStylesWindow(type);\n });\n });\n\n $('#onetopic-tabstyles #tabstyleclear').on('click', function(e) {\n e.preventDefault();\n globalstyles = {};\n $inputtosave.val('');\n applyStyles();\n });\n\n $('#tabstylesdisplay').on('click', function(e) {\n e.preventDefault();\n $tabstyles.toggleClass('hidden');\n });\n\n $('#onetopic-styleswindow .onetopic-selecticon').each(function() {\n var $selecticon = $(this);\n $selecticon.find('button').on('click', function(e) {\n e.preventDefault();\n $selecticon.find('.listicons').removeClass('hidden');\n });\n\n $selecticon.find('.listicons span').on('click', function(e) {\n e.preventDefault();\n var $icon = $(this);\n $selecticon.find('.iconselected').html($icon.html());\n $selecticon.find('[data-style=\"tabicon\"]').val($icon.data('value'));\n $selecticon.find('.listicons').addClass('hidden');\n });\n\n $selecticon.find('[data-style=\"tabicon\"]').on('change', function() {\n var $node = $(this);\n\n if ($node.val() === '') {\n $selecticon.find('.iconselected').html('');\n return;\n }\n\n var $icon = $selecticon.find('.listicons span[data-value=\"' + $node.val() + '\"]');\n\n if ($icon.length > 0) {\n $selecticon.find('.iconselected').html($icon.html());\n }\n });\n });\n\n};\n\n/**\n * Show the styles window.\n *\n * @param {string} type\n */\nvar showStylesWindow = function(type) {\n\n currenttype = type;\n $styleswindow.find('[data-style]').each(function() {\n var $node = $(this);\n\n if ($node.is('input[type=\"text\"]') || $node.is('input[type=\"hidden\"]')) {\n $node.val('');\n $node.trigger('change');\n } else if ($node.is('select')) {\n $node.find('option').first().prop('selected', true);\n }\n });\n\n if (globalstyles[type] !== undefined) {\n var currentstyles = globalstyles[type];\n\n Object.entries(currentstyles).forEach(([key, value]) => {\n $styleswindow.find('[data-style=\"' + key + '\"]').val(value);\n\n // Apply the color.\n $styleswindow.find('[data-control=\"colorpicker\"]').trigger('change');\n\n // Change the icon.\n $styleswindow.find('[data-style=\"tabicon\"]').trigger('change');\n });\n }\n\n $styleswindow.data('modal').show();\n\n};\n\n/**\n * Apply the styles to the tabs for check current visualization.\n */\nvar applyStyles = function() {\n\n var withunits = ['font-size', 'line-height', 'margin', 'padding', 'border-width', 'border-radius'];\n var csscontent = '';\n\n Object.entries(globalstyles).forEach(([type, styles]) => {\n\n switch (type) {\n case 'active':\n csscontent += '#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item a.nav-link.active, ';\n csscontent += '#onetopic-tabstyles .nav-tabs a.nav-link.active, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs a.nav-link.active, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic a.nav-link.active';\n break;\n case 'parent':\n csscontent += '#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item.haschilds a.nav-link, ';\n csscontent += '#onetopic-tabstyles .nav-tabs .nav-item.haschilds a.nav-link';\n break;\n case 'highlighted':\n csscontent += '#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item.marker a.nav-link, ';\n csscontent += '#onetopic-tabstyles .nav-tabs .nav-item.marker a.nav-link, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.marker a.nav-link, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic.marker a.nav-link';\n break;\n case 'disabled':\n csscontent += '#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item.disabled a.nav-link, ';\n csscontent += '#onetopic-tabstyles .nav-tabs .nav-item.disabled a.nav-link, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.disabled a.nav-link, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic.disabled a.nav-link';\n break;\n case 'hover':\n csscontent += '#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item a.nav-link:hover, ';\n csscontent += '#onetopic-tabstyles .nav-tabs .nav-item a.nav-link:hover, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item a.nav-link:hover, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic a.nav-link:hover';\n break;\n case 'childs':\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic a.nav-link';\n break;\n case 'childindex':\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic.tab_initial a.nav-link';\n break;\n default:\n csscontent += '#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item a.nav-link, ';\n csscontent += '#onetopic-tabstyles .nav-tabs a.nav-link';\n }\n\n csscontent += '{';\n var units = [];\n var stylesarray = Object.entries(styles);\n\n // Check if exist units for some rules.\n stylesarray.forEach(([key, value]) => {\n // Check if the key start with the units prefix.\n if (key.indexOf('unit-') === 0) {\n\n // Remove the prefix.\n key = key.replace('unit-', '');\n units[key] = value;\n } else if (key == 'tabicon') {\n if (value !== '') {\n console.log(value);\n var icon = $('#onetopic-styleswindow .listicons span[data-value=\"' + value + '\"]').html();\n console.log(icon);\n $('#onetopic-tabstyles .tabicon-' + type).html(icon).removeClass('hidden');\n }\n }\n });\n\n stylesarray.forEach(([key, value]) => {\n\n // Exclude the tab icons and units rules.\n if (key.indexOf('unit-') === 0) {\n return;\n } else if (key == 'tabicon') {\n return;\n }\n\n // If exist a unit for the rule, apply it.\n if (units[key] !== undefined) {\n value = value + units[key];\n } else if (withunits.indexOf(key) !== -1) {\n // If the rule need units, apply px by default.\n value = value + 'px';\n }\n\n if (key == 'others') {\n csscontent += value + ';';\n } else {\n csscontent += key + ':' + value + ';';\n }\n });\n csscontent += '}';\n });\n\n var $stylecontainer = $tabstyles.find('style');\n\n if ($stylecontainer.length > 0) {\n $stylecontainer.remove();\n }\n\n $stylecontainer = $('');\n $tabstyles.append($stylecontainer);\n\n};\n"],"names":["$tabstyles","$styleswindow","currenttype","globalstyles","$inputtosave","find","each","$tabicon","this","append","removeClass","val","trim","JSON","parse","e","console","error","applyStyles","$colorpicker","$setcolor","$colorpickerinput","on","$node","show","data","color","css","preventDefault","hide","trigger","title","create","done","modal","$modalBody","getBody","newstyles","key","value","stringify","forEach","type","showStylesWindow","toggleClass","$selecticon","$icon","html","addClass","length","is","first","prop","undefined","currentstyles","Object","entries","_ref","withunits","csscontent","_ref2","styles","units","stylesarray","_ref3","indexOf","replace","log","icon","_ref4","$stylecontainer","remove"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"tabstyles.min.js","sources":["../src/tabstyles.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 * Tab editor in site settings.\n *\n * @module format_onetopic/tabstyles\n * @copyright 2021 David Herney Bernal - cirano\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport $ from 'jquery';\nimport ModalFactory from 'core/modal_factory';\n\nvar $tabstyles = null;\nvar $styleswindow = null;\nvar currenttype = 'default';\nvar globalstyles = {};\nvar $inputtosave = null;\n\n/**\n * Component initialization.\n *\n * @method init\n */\nexport const init = () => {\n\n $tabstyles = $('#onetopic-tabstyles');\n $inputtosave = $tabstyles.find('textarea.savecontrol');\n $styleswindow = $('#onetopic-styleswindow');\n\n // Define the tab icons.\n $('#onetopic-tabstyles .tpl-tabdefault .tabicon').each(function() {\n var $tabicon = $(this);\n $tabicon.append('');\n $tabicon.append('');\n });\n\n $('#onetopic-tabstyles .tpl-tabactive .tabicon').each(function() {\n var $tabicon = $(this);\n $tabicon.append('');\n $tabicon.append('');\n });\n\n $('#onetopic-tabstyles .tpl-tabparent .tabicon').each(function() {\n var $tabicon = $(this);\n $tabicon.append('');\n $tabicon.append('');\n $tabicon.append('');\n });\n\n $('#onetopic-tabstyles .tpl-tabchildindex .tabicon').each(function() {\n var $tabicon = $(this);\n $tabicon.append('');\n $tabicon.append('');\n $tabicon.append('');\n $tabicon.append('');\n });\n\n $('#onetopic-tabstyles .tpl-tabchild .tabicon').each(function() {\n var $tabicon = $(this);\n $tabicon.append('');\n $tabicon.append('');\n $tabicon.append('');\n });\n\n $('#onetopic-tabstyles .tpl-tabhighlighted .tabicon').each(function() {\n var $tabicon = $(this);\n $tabicon.append('');\n $tabicon.append('');\n $tabicon.append('');\n });\n\n $('#onetopic-tabstyles .tpl-tabdisabled .tabicon').each(function() {\n var $tabicon = $(this);\n $tabicon.append('');\n });\n\n $('#onetopic-tabstyles .tabicon').each(function() {\n $(this).removeClass('hidden');\n });\n // End of Define the tab icons.\n\n if ($inputtosave.val().trim() !== '') {\n\n try {\n globalstyles = JSON.parse($inputtosave.val());\n\n if (globalstyles === null) {\n globalstyles = {};\n }\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(e);\n globalstyles = {};\n }\n\n applyStyles();\n }\n\n var $colorpicker = $styleswindow.find('.colorpicker');\n var $setcolor = $colorpicker.find('[data-action=\"setcolor\"]');\n var $colorpickerinput = $colorpicker.find('input');\n\n // Color picker control.\n $styleswindow.find('[data-control=\"colorpicker\"]').on('click', function() {\n var $node = $(this);\n\n $colorpicker.show();\n $colorpickerinput.val($node.val());\n $setcolor.data('target', $node);\n }).on('change', function() {\n var $node = $(this);\n var color = $node.val().trim();\n\n $node.css('background-color', color);\n });\n\n $setcolor.on('click', function(e) {\n e.preventDefault();\n\n $colorpicker.hide();\n $setcolor.data('target').val($colorpickerinput.val()).trigger('change');\n });\n\n $colorpicker.find('[data-action=\"cancel\"]').on('click', function() {\n $colorpicker.hide();\n });\n\n var title = $styleswindow.data('title');\n\n // Initialize the modal window.\n ModalFactory.create({\n 'title': title,\n 'body': ''\n }).done(function(modal) {\n var $modalBody = modal.getBody();\n $styleswindow.show();\n $modalBody.append($styleswindow);\n $styleswindow.data('modal', modal);\n });\n\n // Save the styles.\n $styleswindow.find('[data-action=\"cancelstyles\"]').on('click', function() {\n $styleswindow.data('modal').hide();\n });\n\n $styleswindow.find('[data-action=\"setstyles\"]').on('click', function() {\n var modal = $styleswindow.data('modal');\n var newstyles = {};\n\n $styleswindow.find('[data-style]').each(function() {\n var $node = $(this);\n var key = $node.data('style');\n var value = $node.val();\n\n if (value !== '') {\n newstyles[key] = value;\n }\n });\n\n globalstyles[currenttype] = newstyles;\n $inputtosave.val(JSON.stringify(globalstyles));\n applyStyles();\n\n modal.hide();\n });\n\n var types = ['default', 'active', 'parent', 'highlighted', 'disabled', 'hover', 'childs', 'childindex'];\n types.forEach(type => {\n $('#onetopic-tabstyles #tabstyleset' + type).on('click', function(e) {\n e.preventDefault();\n showStylesWindow(type);\n });\n });\n\n $('#onetopic-tabstyles #tabstyleclear').on('click', function(e) {\n e.preventDefault();\n globalstyles = {};\n $inputtosave.val('');\n applyStyles();\n });\n\n $('#tabstylesdisplay').on('click', function(e) {\n e.preventDefault();\n $tabstyles.toggleClass('hidden');\n });\n\n $('#onetopic-styleswindow .onetopic-selecticon').each(function() {\n var $selecticon = $(this);\n $selecticon.find('button').on('click', function(e) {\n e.preventDefault();\n $selecticon.find('.listicons').removeClass('hidden');\n });\n\n $selecticon.find('.listicons span').on('click', function(e) {\n e.preventDefault();\n var $icon = $(this);\n $selecticon.find('.iconselected').html($icon.html());\n $selecticon.find('[data-style=\"tabicon\"]').val($icon.data('value'));\n $selecticon.find('.listicons').addClass('hidden');\n });\n\n $selecticon.find('[data-style=\"tabicon\"]').on('change', function() {\n var $node = $(this);\n\n if ($node.val() === '') {\n $selecticon.find('.iconselected').html('');\n return;\n }\n\n var $icon = $selecticon.find('.listicons span[data-value=\"' + $node.val() + '\"]');\n\n if ($icon.length > 0) {\n $selecticon.find('.iconselected').html($icon.html());\n }\n });\n });\n\n};\n\n/**\n * Show the styles window.\n *\n * @param {string} type\n */\nvar showStylesWindow = function(type) {\n\n currenttype = type;\n $styleswindow.find('[data-style]').each(function() {\n var $node = $(this);\n\n if ($node.is('input[type=\"text\"]') || $node.is('input[type=\"hidden\"]')) {\n $node.val('');\n $node.trigger('change');\n } else if ($node.is('select')) {\n $node.find('option').first().prop('selected', true);\n }\n });\n\n if (globalstyles[type] !== undefined) {\n var currentstyles = globalstyles[type];\n\n Object.entries(currentstyles).forEach(([key, value]) => {\n $styleswindow.find('[data-style=\"' + key + '\"]').val(value);\n\n // Apply the color.\n $styleswindow.find('[data-control=\"colorpicker\"]').trigger('change');\n\n // Change the icon.\n $styleswindow.find('[data-style=\"tabicon\"]').trigger('change');\n });\n }\n\n $styleswindow.data('modal').show();\n\n};\n\n/**\n * Apply the styles to the tabs for check current visualization.\n */\nvar applyStyles = function() {\n\n var withunits = ['font-size', 'line-height', 'margin', 'padding', 'border-width', 'border-radius'];\n var csscontent = '';\n\n Object.entries(globalstyles).forEach(([type, styles]) => {\n\n switch (type) {\n case 'active':\n csscontent += '#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item a.nav-link.active, ';\n csscontent += '#onetopic-tabstyles .nav-tabs a.nav-link.active, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs a.nav-link.active, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic a.nav-link.active';\n break;\n case 'parent':\n csscontent += '#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item.haschilds a.nav-link, ';\n csscontent += '#onetopic-tabstyles .nav-tabs .nav-item.haschilds a.nav-link';\n break;\n case 'highlighted':\n csscontent += '#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item.marker a.nav-link, ';\n csscontent += '#onetopic-tabstyles .nav-tabs .nav-item.marker a.nav-link, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.marker a.nav-link, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic.marker a.nav-link';\n break;\n case 'disabled':\n csscontent += '#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item.disabled a.nav-link, ';\n csscontent += '#onetopic-tabstyles .nav-tabs .nav-item.disabled a.nav-link, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.disabled a.nav-link, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic.disabled a.nav-link';\n break;\n case 'hover':\n csscontent += '#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item a.nav-link:hover, ';\n csscontent += '#onetopic-tabstyles .nav-tabs .nav-item a.nav-link:hover, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item a.nav-link:hover, ';\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic a.nav-link:hover';\n break;\n case 'childs':\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic a.nav-link';\n break;\n case 'childindex':\n csscontent += '#onetopic-tabstyles .onetopic-tab-body .nav-tabs .nav-item.subtopic.tab_initial a.nav-link';\n break;\n default:\n csscontent += '#onetopic-tabstyles .verticaltabs .format_onetopic-tabs .nav-item a.nav-link, ';\n csscontent += '#onetopic-tabstyles .nav-tabs a.nav-link';\n }\n\n csscontent += '{';\n var units = [];\n var stylesarray = Object.entries(styles);\n\n // Check if exist units for some rules.\n stylesarray.forEach(([key, value]) => {\n // Check if the key start with the units prefix.\n if (key.indexOf('unit-') === 0) {\n\n // Remove the prefix.\n key = key.replace('unit-', '');\n units[key] = value;\n } else if (key == 'tabicon') {\n if (value !== '') {\n var icon = $('#onetopic-styleswindow .listicons span[data-value=\"' + value + '\"]').html();\n $('#onetopic-tabstyles .tabicon-' + type).html(icon).removeClass('hidden');\n }\n }\n });\n\n stylesarray.forEach(([key, value]) => {\n\n // Exclude the tab icons and units rules.\n if (key.indexOf('unit-') === 0) {\n return;\n } else if (key == 'tabicon') {\n return;\n }\n\n // If exist a unit for the rule, apply it.\n if (units[key] !== undefined) {\n value = value + units[key];\n } else if (withunits.indexOf(key) !== -1) {\n // If the rule need units, apply px by default.\n value = value + 'px';\n }\n\n if (key == 'others') {\n csscontent += value + ';';\n } else {\n csscontent += key + ':' + value + ';';\n }\n });\n csscontent += '}';\n });\n\n var $stylecontainer = $tabstyles.find('style');\n\n if ($stylecontainer.length > 0) {\n $stylecontainer.remove();\n }\n\n $stylecontainer = $('');\n $tabstyles.append($stylecontainer);\n\n};\n"],"names":["$tabstyles","$styleswindow","currenttype","globalstyles","$inputtosave","find","each","$tabicon","this","append","removeClass","val","trim","JSON","parse","e","console","error","applyStyles","$colorpicker","$setcolor","$colorpickerinput","on","$node","show","data","color","css","preventDefault","hide","trigger","title","create","done","modal","$modalBody","getBody","newstyles","key","value","stringify","forEach","type","showStylesWindow","toggleClass","$selecticon","$icon","html","addClass","length","is","first","prop","undefined","currentstyles","Object","entries","_ref","withunits","csscontent","_ref2","styles","units","stylesarray","_ref3","indexOf","replace","icon","_ref4","$stylecontainer","remove"],"mappings":"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"} \ No newline at end of file diff --git a/amd/src/onetopicbackground.js b/amd/src/onetopicbackground.js new file mode 100644 index 0000000..3efa302 --- /dev/null +++ b/amd/src/onetopicbackground.js @@ -0,0 +1,115 @@ +// 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 . + +/** + * Onetopic background selector. + * + * @module format_onetopic/onetopicbackground + * @copyright 2021 David Herney Bernal - cirano + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +import $ from 'jquery'; +import ModalFactory from 'core/modal_factory'; +import ModalSaveCancel from 'core/modal_save_cancel'; +import ModalEvents from 'core/modal_events'; + +/** + * Component initialization. + * + * @method init + * @param {String} controlid The control id. + */ +export const init = (controlid) => { + + var $controlinput = $('#' + controlid); + var $control = $controlinput.parent('.backgroundpicker'); + var $controlwindow = $control.find('.backgroundpickerwindow'); + var $controlbutton = $control.find('.backgroundpickerselector'); + var $colorpickerinput = $controlwindow.find('input.form-control[type="text"]'); + + // Initialize the modal window. + var title = $controlwindow.attr('title'); + var buttons = []; + buttons['save'] = $controlwindow.data('savelabel'); + + var setEvents = function(modal) { + modal.getRoot().on(ModalEvents.cancel, () => { + modal.hide(); + }); + + modal.getRoot().on(ModalEvents.save, () => { + var newcolor = $colorpickerinput.val(); + var val = $controlinput.val(); + var color = readColor(val); + if (color) { + val = val.replace(color, newcolor); + } else if (val.trim() === '') { + val = newcolor; + } else { + val += ' ' + newcolor; + } + $controlinput.val(val); + modal.hide(); + }); + }; + + ModalFactory.create({ + 'title': title, + 'body': $controlwindow, + 'type': ModalSaveCancel.TYPE, + 'large': true, + 'buttons': buttons + }) + .done(function(modal) { + var $modalBody = modal.getBody(); + $modalBody.append($controlwindow); + $control.data('modal', modal); + setEvents(modal); + }); + + // Color picker control. + $controlbutton.on('click', function(e) { + e.preventDefault(); + $controlwindow.removeClass('hidden'); + var currentval = $controlinput.val(); + + var color = readColor(currentval); + + $colorpickerinput.val(color); + $control.data('modal').show(); + }); + +}; + +/** + * Extracts the first color from a text string. Recognizes hexadecimal, rgba and hsla. + * + * @param {string} text + * @returns + */ +var readColor = function(text) { + var regexcolor = new RegExp( + /#[0-9a-fA-F]{6}/.source + + /|#[0-9a-fA-F]{3}/.source + + /|rgba?\(\s*([0-9]{1,3}\s*,\s*){2}[0-9]{1,3}\s*(,\s*[0-9.]+\s*)?\)/.source + + /|hsla?\(\s*([0-9]{1,3}\s*,\s*){2}[0-9]{1,3}\s*(,\s*[0-9.]+\s*)?\)/.source); + + var color = text.match(regexcolor); + if (color) { + color = color[0]; + } + + return color; +}; diff --git a/amd/src/tabstyles.js b/amd/src/tabstyles.js index 200824a..52205f2 100644 --- a/amd/src/tabstyles.js +++ b/amd/src/tabstyles.js @@ -331,9 +331,7 @@ var applyStyles = function() { units[key] = value; } else if (key == 'tabicon') { if (value !== '') { - console.log(value); var icon = $('#onetopic-styleswindow .listicons span[data-value="' + value + '"]').html(); - console.log(icon); $('#onetopic-tabstyles .tabicon-' + type).html(icon).removeClass('hidden'); } } diff --git a/classes/header.php b/classes/header.php index 0a45788..0a7cb98 100644 --- a/classes/header.php +++ b/classes/header.php @@ -61,20 +61,20 @@ public function export_for_template(\renderer_base $output) { global $PAGE, $CFG, $OUTPUT; $format = $this->format; - $course = $this->format->get_course(); + $course = $format->get_course(); // Onetopic format is always multipage. $course->realcoursedisplay = property_exists($course, 'coursedisplay') ? $course->coursedisplay : false; $firstsection = ($course->realcoursedisplay == COURSE_DISPLAY_MULTIPAGE) ? 1 : 0; - $currentsection = $this->format->get_sectionnum(); + $currentsection = $format->get_sectionnum(); $tabslist = []; $secondtabslist = null; $tabscssstyles = ''; if ($course->tabsview != \format_onetopic::TABSVIEW_COURSEINDEX && ($format->show_editor() || !$course->hidetabsbar)) { - $tabs = $this->get_tabs($this->format->get_modinfo(), $output); + $tabs = $this->get_tabs($format->get_modinfo(), $output); $tabslist = $tabs->get_list(); $secondtabslist = $tabs->get_secondlist($firstsection ? $currentsection - 1 : $currentsection); $tabscssstyles = $tabs->get_allcssstyles(); @@ -112,11 +112,19 @@ public function export_for_template(\renderer_base $output) { $hassecondrow = is_object($secondtabslist) && count($secondtabslist->tabs) > 0; } + $formatoptions = course_get_format($course)->get_format_options($currentsection); + $tabsectionbackground = $formatoptions['tabsectionbackground'] ?? ''; + + if (!empty($tabsectionbackground)) { + $tabsectionbackground = clean_param($tabsectionbackground, PARAM_NOTAGS); + $tabsectionbackground = 'background: ' . $tabsectionbackground . ';'; + } + $data = (object)[ 'uniqid' => $format->uniqid, 'baseurl' => $CFG->wwwroot, - 'title' => $this->format->page_title(), // This method should be in the course_format class. - 'format' => $this->format->get_format(), + 'title' => $format->page_title(), // This method should be in the course_format class. + 'format' => $format->get_format(), 'templatetopic' => $course->templatetopic, 'withicons' => $course->templatetopic_icons, 'hastopictabs' => $hastopictabs, @@ -131,6 +139,7 @@ public function export_for_template(\renderer_base $output) { 'sectionclasses' => '', 'courseindex' => $courseindex, 'cssstyles' => $tabscssstyles, + 'tabsectionbackground' => $tabsectionbackground, ]; $initialsection = null; @@ -139,10 +148,10 @@ public function export_for_template(\renderer_base $output) { if ($course->realcoursedisplay == COURSE_DISPLAY_MULTIPAGE) { // Load the section 0 and export data for template. - $modinfo = $this->format->get_modinfo(); + $modinfo = $format->get_modinfo(); $section0 = $modinfo->get_section_info(0); - $sectionclass = $this->format->get_output_classname('content\\section'); - $section = new $sectionclass($this->format, $section0); + $sectionclass = $format->get_output_classname('content\\section'); + $section = new $sectionclass($format, $section0); $sectionoutput = new \format_onetopic\output\renderer($PAGE, null); $initialsection = $section->export_for_template($sectionoutput); diff --git a/classes/local/formelement_background.php b/classes/local/formelement_background.php new file mode 100644 index 0000000..7d0dc1a --- /dev/null +++ b/classes/local/formelement_background.php @@ -0,0 +1,147 @@ +. + +/** + * Form element to select a background. + * + * @package format_onetopic + * @copyright 2024 David Herney - https://bambuco.co + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; +require_once($CFG->libdir . '/form/text.php'); +require_once($CFG->libdir . '/adminlib.php'); + +/** + * Display a tab styles form field. + * + * @package format_onetopic + * @copyright 2024 David Herney - https://bambuco.co + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class format_onetopic_background_form_element extends MoodleQuickForm_text { + use templatable_form_element { + export_for_template as export_for_template_base; + } + + /** + * Constructor + * + * @param string $name Element name + * @param mixed $label Label(s) for an element + * @param mixed $attributes Either a typical HTML attribute string or an associative array. + */ + public function __construct($name = null, $label = null, $attributes = null) { + + parent::__construct($name, $label, $attributes); + + // The type is used to determine the template to use. + // I did not find any conflict when handling a type different from the parent class but further review is needed. + $this->_type = 'static'; + } + + /** + * Returns HTML for this form element. + * + * The uppercase in the function name needs to be ignored because it is required in the core. + * + * @return string + */ + // @codingStandardsIgnoreLine moodle.NamingConventions.ValidFunctionName.LowercaseMethod + public function toHtml() { + return $this->to_html(); + } + + /** + * Returns HTML for this form element. + * + * @return string + */ + public function to_html() { + global $PAGE; + + static $loadedcounter = 0; + $loadedcounter++; + + $colorpickerid = 'colorpicker' . $loadedcounter; + $cp = new \admin_setting_configcolourpicker($colorpickerid, + get_string('colorpicker', 'format_onetopic'), + get_string('colorpicker_help', 'format_onetopic'), + '', + ); + + $html = parent::toHtml(); + + $attrs = ['class' => 'backgroundpickerselector btn btn-secondary']; + $html .= html_writer::tag('a', get_string('selectcolor', 'format_onetopic'), $attrs); + + $attrs = [ + 'class' => 'backgroundpickerwindow hidden', + 'title' => get_string('colorpicker', 'format_onetopic'), + 'data-savelabel' => get_string('setcolor', 'format_onetopic'), + ]; + $html .= html_writer::tag('div', $cp->output_html(''), $attrs); + + $attrs = ['class' => 'backgroundpicker']; + $html = html_writer::tag('div', $html, $attrs); + + $PAGE->requires->js_call_amd('format_onetopic/onetopicbackground', 'init', [$this->getAttribute('id')]); + + return $html; + + } + + /** + * Export this element for template renderer. + * + * @param renderer_base $output + * @return array + */ + public function export_for_template(renderer_base $output) { + $context = $this->export_for_template_base($output); + + $context['html'] = $this->to_html(); + return $context; + } + + /** + * Check that all files have the allowed type. + * + * The uppercase in the function name needs to be ignored because it is required in the core. + * + * @param int $value Draft item id with the uploaded files. + * @return string|null Validation error message or null. + */ + // @codingStandardsIgnoreLine moodle.NamingConventions.ValidFunctionName.LowercaseMethod + public function validateSubmitValue($value) { + + if (empty($value)) { + return; + } + + $cleaned = clean_param($value, PARAM_NOTAGS); + + if ($cleaned !== $value) { + return get_string('backgroundpickerinvalid', 'format_onetopic'); + } + + return; + } + +} diff --git a/lang/en/format_onetopic.php b/lang/en/format_onetopic.php index 756bd41..d4d4245 100644 --- a/lang/en/format_onetopic.php +++ b/lang/en/format_onetopic.php @@ -113,15 +113,21 @@ $string['sectionsnavigation_sitelevel'] = 'Use the default site value'; $string['sectionsnavigation_slides'] = 'Like slides'; $string['sectionsnavigation_support'] = 'Only if theme not support the "uses course index" feature'; +$string['selectcolor'] = 'Select color'; $string['settingsheaderdefault'] = 'Default course settings'; $string['settingsheaderstyles'] = 'Default tabs styles'; $string['showfromothers'] = 'Show topic'; $string['subtopictoright'] = 'Move to right as subtopic'; +$string['tabicon'] = 'Icon'; +$string['tabiconselect'] = 'Select icon'; $string['tablabelactive'] = 'Active tab'; $string['tablabeldefault'] = 'Default tab {$a}'; $string['tablabeldisabled'] = 'Disabled'; $string['tablabelhighlighted'] = 'Highlighted'; $string['tablabelparent'] = 'Parent tab'; +$string['tabsectionbackground'] = 'Section content background'; +$string['tabsectionbackground_help'] = 'Used to change the background of the section content. The value can be a color in a CSS valid representation, for example:
  • Hexadecimal: #ffffff
  • RGB: rgb(0,255,0)
  • Name: green
+It can also be a URL attribute and other CSS background options.'; $string['tabstylebuttons_help'] = 'Click on each button to configure the appearance of the tab in each of its possible states.'; $string['tabstyleclear'] = 'Clear styles'; $string['tabstyles'] = 'Tab styles'; @@ -162,11 +168,8 @@ $string['usessectionsnavigation'] = 'Uses sections navigation'; $string['usessectionsnavigation_help'] = 'Show buttons for navigate to next or previous section.'; -$string['tabicon'] = 'Icon'; -$string['tabiconselect'] = 'Select icon'; -$string['tabsectionbackground'] = 'Section content background'; -$string['tabsectionbackground_help'] = 'Used to change the background of the section content. The value can be a color in a CSS valid representation, for example:
  • Hexadecimal: #ffffff
  • RGB: rgb(0,255,0)
  • Name: green
-It can also be a URL attribute and other CSS background options.'; +$string['setcolor'] = 'Set color'; +$string['backgroundpickerinvalid'] = 'Invalid background value'; // Deprecated since Moodle 4.0. $string['disable'] = 'Disable'; diff --git a/lib.php b/lib.php index 3aef54e..91dc7b7 100644 --- a/lib.php +++ b/lib.php @@ -726,14 +726,26 @@ public function create_edit_form_elements(&$mform, $forsection = false) { if ($forsection) { $onetopicconfig = get_config('format_onetopic'); - if ($onetopicconfig->enablecustomstyles && empty($onetopicconfig->useoldstylescontrol)) { - $mform->removeElement('tabstyles'); - MoodleQuickForm::registerElementType('tabstyles', - $CFG->dirroot . '/course/format/onetopic/classes/local/formelement_tabstyles.php', - 'format_onetopic_tabstyles_form_element'); - $element = $mform->addElement('tabstyles', 'tabstyles', get_string('tabstyles', 'format_onetopic')); + if ($onetopicconfig->enablecustomstyles) { + + $mform->removeElement('tabsectionbackground'); + MoodleQuickForm::registerElementType('tabsectionbackground', + $CFG->dirroot . '/course/format/onetopic/classes/local/formelement_background.php', + 'format_onetopic_background_form_element'); + $element = $mform->addElement('tabsectionbackground', 'tabsectionbackground', + get_string('tabsectionbackground', 'format_onetopic')); $elements[] = $element; + + if (empty($onetopicconfig->useoldstylescontrol)) { + $mform->removeElement('tabstyles'); + MoodleQuickForm::registerElementType('tabstyles', + $CFG->dirroot . '/course/format/onetopic/classes/local/formelement_tabstyles.php', + 'format_onetopic_tabstyles_form_element'); + $element = $mform->addElement('tabstyles', 'tabstyles', get_string('tabstyles', 'format_onetopic')); + + $elements[] = $element; + } } } @@ -827,6 +839,11 @@ public function section_format_options($foreditform = false) { ]; if ($onetopicconfig->enablecustomstyles) { + $sectionformatoptions['tabsectionbackground'] = [ + 'default' => '', + 'type' => PARAM_RAW, + ]; + if ($onetopicconfig->useoldstylescontrol) { $sectionformatoptions['fontcolor'] = [ 'default' => '', @@ -877,6 +894,16 @@ public function section_format_options($foreditform = false) { ]; if ($onetopicconfig->enablecustomstyles) { + + $sectionformatoptionsedit['tabsectionbackground'] = [ + 'default' => '', + 'type' => PARAM_RAW, + 'label' => new lang_string('tabsectionbackground', 'format_onetopic'), + 'element_type' => 'text', + 'help' => 'tabsectionbackground', + 'help_component' => 'format_onetopic', + ]; + if ($onetopicconfig->useoldstylescontrol) { $sectionformatoptionsedit['fontcolor'] = [ 'default' => '', diff --git a/styles.css b/styles.css index 540ad85..d4c015d 100644 --- a/styles.css +++ b/styles.css @@ -35,6 +35,11 @@ margin: 0; } +.format-onetopic .onetopic-tab-body { + padding-top: 10px; + padding-bottom: 10px; +} + /* Its a subtabs bar */ .format-onetopic .onetopic-tab-body .format_onetopic-tabs { padding-left: 20px; diff --git a/templates/courseformat/tabtree.mustache b/templates/courseformat/tabtree.mustache index a207a9e..bd6aff0 100644 --- a/templates/courseformat/tabtree.mustache +++ b/templates/courseformat/tabtree.mustache @@ -38,7 +38,7 @@ {{#str}} hiddentabsbar, format_onetopic {{/str}} {{/hidetabsbar}} -