From 160617d2d56cb21953d15af1da4790f8601a7c12 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Mon, 24 Jun 2024 14:13:29 +0100 Subject: [PATCH] MDL-82024 format_topics: toggle un/highlight section icon correctly. --- course/format/topics/amd/build/section.min.js | 2 +- course/format/topics/amd/build/section.min.js.map | 2 +- course/format/topics/amd/src/section.js | 2 ++ .../courseformat/content/section/controlmenu.php | 13 +++++++++---- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/course/format/topics/amd/build/section.min.js b/course/format/topics/amd/build/section.min.js index 762120f2cbb..3e73dd414e4 100644 --- a/course/format/topics/amd/build/section.min.js +++ b/course/format/topics/amd/build/section.min.js @@ -5,6 +5,6 @@ define("format_topics/section",["exports","core/reactive","core_courseformat/cou * @module format_topics/section * @copyright 2022 Ferran Recio * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_templates=(obj=_templates)&&obj.__esModule?obj:{default:obj};class HighlightSection extends _reactive.BaseComponent{create(){this.name="format_topics_section",this.selectors={SECTION:"[data-for='section']",SETMARKER:'[data-action="sectionHighlight"]',REMOVEMARKER:'[data-action="sectionUnhighlight"]',ACTIONTEXT:".menu-action-text",ICON:".icon"},this.classes={HIDE:"d-none"},this.formatActions={HIGHLIGHT:"sectionHighlight",UNHIGHLIGHT:"sectionUnhighlight"}}getWatchers(){return[{watch:"section.current:updated",handler:this._refreshHighlight}]}async _refreshHighlight(_ref){var _affectedAction$datas,_affectedAction$datas2;let selector,newAction,{element:element}=_ref;element.current?(selector=this.selectors.SETMARKER,newAction=this.formatActions.UNHIGHLIGHT):(selector=this.selectors.REMOVEMARKER,newAction=this.formatActions.HIGHLIGHT);const affectedAction=this.getElement("".concat(this.selectors.SECTION," ").concat(selector),element.id);if(!affectedAction)return;affectedAction.dataset.action=newAction;const actionText=affectedAction.querySelector(this.selectors.ACTIONTEXT);if(null!==(_affectedAction$datas=affectedAction.dataset)&&void 0!==_affectedAction$datas&&_affectedAction$datas.swapname&&actionText){const oldText=null==actionText?void 0:actionText.innerText;actionText.innerText=affectedAction.dataset.swapname,affectedAction.dataset.swapname=oldText}const icon=affectedAction.querySelector(this.selectors.ICON);if(null!==(_affectedAction$datas2=affectedAction.dataset)&&void 0!==_affectedAction$datas2&&_affectedAction$datas2.swapicon&&icon){const newIcon=affectedAction.dataset.swapicon;if(newIcon){const pixHtml=await _templates.default.renderPix(newIcon,"core");_templates.default.replaceNode(icon,pixHtml,"")}}}}_exports.init=()=>{const courseEditor=(0,_courseeditor.getCurrentCourseEditor)();courseEditor.supportComponents&&courseEditor.isEditing&&new HighlightSection({element:document.getElementById("region-main"),reactive:courseEditor})}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_templates=(obj=_templates)&&obj.__esModule?obj:{default:obj};class HighlightSection extends _reactive.BaseComponent{create(){this.name="format_topics_section",this.selectors={SECTION:"[data-for='section']",SETMARKER:'[data-action="sectionHighlight"]',REMOVEMARKER:'[data-action="sectionUnhighlight"]',ACTIONTEXT:".menu-action-text",ICON:".icon"},this.classes={HIDE:"d-none"},this.formatActions={HIGHLIGHT:"sectionHighlight",UNHIGHLIGHT:"sectionUnhighlight"}}getWatchers(){return[{watch:"section.current:updated",handler:this._refreshHighlight}]}async _refreshHighlight(_ref){var _affectedAction$datas,_affectedAction$datas2;let selector,newAction,{element:element}=_ref;element.current?(selector=this.selectors.SETMARKER,newAction=this.formatActions.UNHIGHLIGHT):(selector=this.selectors.REMOVEMARKER,newAction=this.formatActions.HIGHLIGHT);const affectedAction=this.getElement("".concat(this.selectors.SECTION," ").concat(selector),element.id);if(!affectedAction)return;affectedAction.dataset.action=newAction;const actionText=affectedAction.querySelector(this.selectors.ACTIONTEXT);if(null!==(_affectedAction$datas=affectedAction.dataset)&&void 0!==_affectedAction$datas&&_affectedAction$datas.swapname&&actionText){const oldText=null==actionText?void 0:actionText.innerText;actionText.innerText=affectedAction.dataset.swapname,affectedAction.dataset.swapname=oldText}const icon=affectedAction.querySelector(this.selectors.ICON);if(null!==(_affectedAction$datas2=affectedAction.dataset)&&void 0!==_affectedAction$datas2&&_affectedAction$datas2.swapicon&&icon){const newIcon=affectedAction.dataset.swapicon;if(newIcon){const pixHtml=await _templates.default.renderPix(newIcon,"core");_templates.default.replaceNode(icon,pixHtml,""),affectedAction.dataset.swapicon=affectedAction.dataset.icon,affectedAction.dataset.icon=newIcon}}}}_exports.init=()=>{const courseEditor=(0,_courseeditor.getCurrentCourseEditor)();courseEditor.supportComponents&&courseEditor.isEditing&&new HighlightSection({element:document.getElementById("region-main"),reactive:courseEditor})}})); //# sourceMappingURL=section.min.js.map \ No newline at end of file diff --git a/course/format/topics/amd/build/section.min.js.map b/course/format/topics/amd/build/section.min.js.map index 9a9c3d87ffb..e963f563077 100644 --- a/course/format/topics/amd/build/section.min.js.map +++ b/course/format/topics/amd/build/section.min.js.map @@ -1 +1 @@ -{"version":3,"file":"section.min.js","sources":["../src/section.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 * Format topics section extra logic component.\n *\n * @module format_topics/section\n * @copyright 2022 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {BaseComponent} from 'core/reactive';\nimport {getCurrentCourseEditor} from 'core_courseformat/courseeditor';\nimport Templates from 'core/templates';\n\nclass HighlightSection extends BaseComponent {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'format_topics_section';\n // Default query selectors.\n this.selectors = {\n SECTION: `[data-for='section']`,\n SETMARKER: `[data-action=\"sectionHighlight\"]`,\n REMOVEMARKER: `[data-action=\"sectionUnhighlight\"]`,\n ACTIONTEXT: `.menu-action-text`,\n ICON: `.icon`,\n };\n // Default classes to toggle on refresh.\n this.classes = {\n HIDE: 'd-none',\n };\n // The topics format section specific actions.\n this.formatActions = {\n HIGHLIGHT: 'sectionHighlight',\n UNHIGHLIGHT: 'sectionUnhighlight',\n };\n }\n\n /**\n * Component watchers.\n *\n * @returns {Array} of watchers\n */\n getWatchers() {\n return [\n {watch: `section.current:updated`, handler: this._refreshHighlight},\n ];\n }\n\n /**\n * Update a content section using the state information.\n *\n * @param {object} param\n * @param {Object} param.element details the update details.\n */\n async _refreshHighlight({element}) {\n let selector;\n let newAction;\n if (element.current) {\n selector = this.selectors.SETMARKER;\n newAction = this.formatActions.UNHIGHLIGHT;\n } else {\n selector = this.selectors.REMOVEMARKER;\n newAction = this.formatActions.HIGHLIGHT;\n }\n // Find the affected action.\n const affectedAction = this.getElement(`${this.selectors.SECTION} ${selector}`, element.id);\n if (!affectedAction) {\n return;\n }\n // Change action, text and icon.\n affectedAction.dataset.action = newAction;\n const actionText = affectedAction.querySelector(this.selectors.ACTIONTEXT);\n if (affectedAction.dataset?.swapname && actionText) {\n const oldText = actionText?.innerText;\n actionText.innerText = affectedAction.dataset.swapname;\n affectedAction.dataset.swapname = oldText;\n }\n const icon = affectedAction.querySelector(this.selectors.ICON);\n if (affectedAction.dataset?.swapicon && icon) {\n const newIcon = affectedAction.dataset.swapicon;\n if (newIcon) {\n const pixHtml = await Templates.renderPix(newIcon, 'core');\n Templates.replaceNode(icon, pixHtml, '');\n }\n }\n }\n}\n\nexport const init = () => {\n // Add component to the section.\n const courseEditor = getCurrentCourseEditor();\n if (courseEditor.supportComponents && courseEditor.isEditing) {\n new HighlightSection({\n element: document.getElementById('region-main'),\n reactive: courseEditor,\n });\n }\n};\n"],"names":["HighlightSection","BaseComponent","create","name","selectors","SECTION","SETMARKER","REMOVEMARKER","ACTIONTEXT","ICON","classes","HIDE","formatActions","HIGHLIGHT","UNHIGHLIGHT","getWatchers","watch","handler","this","_refreshHighlight","selector","newAction","element","current","affectedAction","getElement","id","dataset","action","actionText","querySelector","swapname","oldText","innerText","icon","swapicon","newIcon","pixHtml","Templates","renderPix","replaceNode","courseEditor","supportComponents","isEditing","document","getElementById","reactive"],"mappings":";;;;;;;sJA2BMA,yBAAyBC,wBAK3BC,cAESC,KAAO,6BAEPC,UAAY,CACbC,+BACAC,6CACAC,kDACAC,+BACAC,mBAGCC,QAAU,CACXC,KAAM,eAGLC,cAAgB,CACjBC,UAAW,mBACXC,YAAa,sBASrBC,oBACW,CACH,CAACC,gCAAkCC,QAASC,KAAKC,uGAWjDC,SACAC,WAFgBC,QAACA,cAGjBA,QAAQC,SACRH,SAAWF,KAAKd,UAAUE,UAC1Be,UAAYH,KAAKN,cAAcE,cAE/BM,SAAWF,KAAKd,UAAUG,aAC1Bc,UAAYH,KAAKN,cAAcC,iBAG7BW,eAAiBN,KAAKO,qBAAcP,KAAKd,UAAUC,oBAAWe,UAAYE,QAAQI,QACnFF,sBAILA,eAAeG,QAAQC,OAASP,gBAC1BQ,WAAaL,eAAeM,cAAcZ,KAAKd,UAAUI,6CAC3DgB,eAAeG,gEAASI,UAAYF,WAAY,OAC1CG,QAAUH,MAAAA,kBAAAA,WAAYI,UAC5BJ,WAAWI,UAAYT,eAAeG,QAAQI,SAC9CP,eAAeG,QAAQI,SAAWC,cAEhCE,KAAOV,eAAeM,cAAcZ,KAAKd,UAAUK,wCACrDe,eAAeG,kEAASQ,UAAYD,KAAM,OACpCE,QAAUZ,eAAeG,QAAQQ,YACnCC,QAAS,OACHC,cAAgBC,mBAAUC,UAAUH,QAAS,2BACzCI,YAAYN,KAAMG,QAAS,qBAMjC,WAEVI,cAAe,0CACjBA,aAAaC,mBAAqBD,aAAaE,eAC3C3C,iBAAiB,CACjBsB,QAASsB,SAASC,eAAe,eACjCC,SAAUL"} \ No newline at end of file +{"version":3,"file":"section.min.js","sources":["../src/section.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 * Format topics section extra logic component.\n *\n * @module format_topics/section\n * @copyright 2022 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {BaseComponent} from 'core/reactive';\nimport {getCurrentCourseEditor} from 'core_courseformat/courseeditor';\nimport Templates from 'core/templates';\n\nclass HighlightSection extends BaseComponent {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'format_topics_section';\n // Default query selectors.\n this.selectors = {\n SECTION: `[data-for='section']`,\n SETMARKER: `[data-action=\"sectionHighlight\"]`,\n REMOVEMARKER: `[data-action=\"sectionUnhighlight\"]`,\n ACTIONTEXT: `.menu-action-text`,\n ICON: `.icon`,\n };\n // Default classes to toggle on refresh.\n this.classes = {\n HIDE: 'd-none',\n };\n // The topics format section specific actions.\n this.formatActions = {\n HIGHLIGHT: 'sectionHighlight',\n UNHIGHLIGHT: 'sectionUnhighlight',\n };\n }\n\n /**\n * Component watchers.\n *\n * @returns {Array} of watchers\n */\n getWatchers() {\n return [\n {watch: `section.current:updated`, handler: this._refreshHighlight},\n ];\n }\n\n /**\n * Update a content section using the state information.\n *\n * @param {object} param\n * @param {Object} param.element details the update details.\n */\n async _refreshHighlight({element}) {\n let selector;\n let newAction;\n if (element.current) {\n selector = this.selectors.SETMARKER;\n newAction = this.formatActions.UNHIGHLIGHT;\n } else {\n selector = this.selectors.REMOVEMARKER;\n newAction = this.formatActions.HIGHLIGHT;\n }\n // Find the affected action.\n const affectedAction = this.getElement(`${this.selectors.SECTION} ${selector}`, element.id);\n if (!affectedAction) {\n return;\n }\n // Change action, text and icon.\n affectedAction.dataset.action = newAction;\n const actionText = affectedAction.querySelector(this.selectors.ACTIONTEXT);\n if (affectedAction.dataset?.swapname && actionText) {\n const oldText = actionText?.innerText;\n actionText.innerText = affectedAction.dataset.swapname;\n affectedAction.dataset.swapname = oldText;\n }\n const icon = affectedAction.querySelector(this.selectors.ICON);\n if (affectedAction.dataset?.swapicon && icon) {\n const newIcon = affectedAction.dataset.swapicon;\n if (newIcon) {\n const pixHtml = await Templates.renderPix(newIcon, 'core');\n Templates.replaceNode(icon, pixHtml, '');\n affectedAction.dataset.swapicon = affectedAction.dataset.icon;\n affectedAction.dataset.icon = newIcon;\n }\n }\n }\n}\n\nexport const init = () => {\n // Add component to the section.\n const courseEditor = getCurrentCourseEditor();\n if (courseEditor.supportComponents && courseEditor.isEditing) {\n new HighlightSection({\n element: document.getElementById('region-main'),\n reactive: courseEditor,\n });\n }\n};\n"],"names":["HighlightSection","BaseComponent","create","name","selectors","SECTION","SETMARKER","REMOVEMARKER","ACTIONTEXT","ICON","classes","HIDE","formatActions","HIGHLIGHT","UNHIGHLIGHT","getWatchers","watch","handler","this","_refreshHighlight","selector","newAction","element","current","affectedAction","getElement","id","dataset","action","actionText","querySelector","swapname","oldText","innerText","icon","swapicon","newIcon","pixHtml","Templates","renderPix","replaceNode","courseEditor","supportComponents","isEditing","document","getElementById","reactive"],"mappings":";;;;;;;sJA2BMA,yBAAyBC,wBAK3BC,cAESC,KAAO,6BAEPC,UAAY,CACbC,+BACAC,6CACAC,kDACAC,+BACAC,mBAGCC,QAAU,CACXC,KAAM,eAGLC,cAAgB,CACjBC,UAAW,mBACXC,YAAa,sBASrBC,oBACW,CACH,CAACC,gCAAkCC,QAASC,KAAKC,uGAWjDC,SACAC,WAFgBC,QAACA,cAGjBA,QAAQC,SACRH,SAAWF,KAAKd,UAAUE,UAC1Be,UAAYH,KAAKN,cAAcE,cAE/BM,SAAWF,KAAKd,UAAUG,aAC1Bc,UAAYH,KAAKN,cAAcC,iBAG7BW,eAAiBN,KAAKO,qBAAcP,KAAKd,UAAUC,oBAAWe,UAAYE,QAAQI,QACnFF,sBAILA,eAAeG,QAAQC,OAASP,gBAC1BQ,WAAaL,eAAeM,cAAcZ,KAAKd,UAAUI,6CAC3DgB,eAAeG,gEAASI,UAAYF,WAAY,OAC1CG,QAAUH,MAAAA,kBAAAA,WAAYI,UAC5BJ,WAAWI,UAAYT,eAAeG,QAAQI,SAC9CP,eAAeG,QAAQI,SAAWC,cAEhCE,KAAOV,eAAeM,cAAcZ,KAAKd,UAAUK,wCACrDe,eAAeG,kEAASQ,UAAYD,KAAM,OACpCE,QAAUZ,eAAeG,QAAQQ,YACnCC,QAAS,OACHC,cAAgBC,mBAAUC,UAAUH,QAAS,2BACzCI,YAAYN,KAAMG,QAAS,IACrCb,eAAeG,QAAQQ,SAAWX,eAAeG,QAAQO,KACzDV,eAAeG,QAAQO,KAAOE,yBAM1B,WAEVK,cAAe,0CACjBA,aAAaC,mBAAqBD,aAAaE,eAC3C3C,iBAAiB,CACjBsB,QAASsB,SAASC,eAAe,eACjCC,SAAUL"} \ No newline at end of file diff --git a/course/format/topics/amd/src/section.js b/course/format/topics/amd/src/section.js index 8cf5b62437d..cc6ec50ef12 100644 --- a/course/format/topics/amd/src/section.js +++ b/course/format/topics/amd/src/section.js @@ -98,6 +98,8 @@ class HighlightSection extends BaseComponent { if (newIcon) { const pixHtml = await Templates.renderPix(newIcon, 'core'); Templates.replaceNode(icon, pixHtml, ''); + affectedAction.dataset.swapicon = affectedAction.dataset.icon; + affectedAction.dataset.icon = newIcon; } } } diff --git a/course/format/topics/classes/output/courseformat/content/section/controlmenu.php b/course/format/topics/classes/output/courseformat/content/section/controlmenu.php index 73c045aa1cb..8a0bcbf08f7 100644 --- a/course/format/topics/classes/output/courseformat/content/section/controlmenu.php +++ b/course/format/topics/classes/output/courseformat/content/section/controlmenu.php @@ -117,13 +117,16 @@ class controlmenu extends controlmenu_base { } $highlightoff = get_string('highlightoff'); + $highlightofficon = 'i/marked'; + $highlighton = get_string('highlight'); + $highlightonicon = 'i/marker'; if ($course->marker == $section->section) { // Show the "light globe" on/off. $url->param('marker', 0); $result = [ 'url' => $url, - 'icon' => 'i/marked', + 'icon' => $highlightofficon, 'name' => $highlightoff, 'pixattr' => ['class' => ''], 'attr' => [ @@ -131,15 +134,16 @@ class controlmenu extends controlmenu_base { 'data-action' => 'sectionUnhighlight', 'data-sectionreturn' => $sectionreturn, 'data-id' => $section->id, + 'data-icon' => $highlightofficon, 'data-swapname' => $highlighton, - 'data-swapicon' => 'i/marker', + 'data-swapicon' => $highlightonicon, ], ]; } else { $url->param('marker', $section->section); $result = [ 'url' => $url, - 'icon' => 'i/marker', + 'icon' => $highlightonicon, 'name' => $highlighton, 'pixattr' => ['class' => ''], 'attr' => [ @@ -147,8 +151,9 @@ class controlmenu extends controlmenu_base { 'data-action' => 'sectionHighlight', 'data-sectionreturn' => $sectionreturn, 'data-id' => $section->id, + 'data-icon' => $highlightonicon, 'data-swapname' => $highlightoff, - 'data-swapicon' => 'i/marked', + 'data-swapicon' => $highlightofficon, ], ]; }