diff --git a/course/format/amd/build/local/courseindex/cm.min.js b/course/format/amd/build/local/courseindex/cm.min.js index 42b27d90828..121d7aee789 100644 --- a/course/format/amd/build/local/courseindex/cm.min.js +++ b/course/format/amd/build/local/courseindex/cm.min.js @@ -8,6 +8,6 @@ define("core_courseformat/local/courseindex/cm",["exports","core_courseformat/lo * @class core_courseformat/local/courseindex/cm * @copyright 2021 Ferran Recio * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_dndcmitem=_interopRequireDefault(_dndcmitem),_templates=_interopRequireDefault(_templates),_prefetch=_interopRequireDefault(_prefetch),_config=_interopRequireDefault(_config);_prefetch.default.prefetchTemplate("core_courseformat/local/courseindex/cmcompletion");class Component extends _dndcmitem.default{create(){this.name="courseindex_cm",this.selectors={CM_NAME:"[data-for='cm_name']",CM_COMPLETION:"[data-for='cm_completion']"},this.classes={CMHIDDEN:"dimmed",LOCKED:"editinprogress",RESTRICTIONS:"restrictions",PAGEITEM:"pageitem"},this.id=this.element.dataset.id}static init(target,selectors){return new Component({element:document.getElementById(target),selectors:selectors})}stateReady(state){this.configDragDrop(this.id);const cm=state.cm.get(this.id),course=state.course;this._refreshCompletion({state:state,element:cm}),window.location.href!=cm.url&&window.location.href!="".concat(course.baseurl,"#").concat(cm.anchor)||(this.reactive.dispatch("setPageItem","cm",this.id),this.element.scrollIntoView({block:"center"})),_config.default.contextid!=_config.default.courseContextId&&_config.default.contextInstanceId==this.id&&(this.reactive.dispatch("setPageItem","cm",this.id,!0),this.element.scrollIntoView({block:"center"})),cm.uservisible||this.addEventListener(this.getElement(this.selectors.CM_NAME),"click",this._activityAnchor)}getWatchers(){return[{watch:"cm[".concat(this.id,"]:deleted"),handler:this.remove},{watch:"cm[".concat(this.id,"]:updated"),handler:this._refreshCm},{watch:"cm[".concat(this.id,"].completionstate:updated"),handler:this._refreshCompletion},{watch:"course.pageItem:updated",handler:this._refreshPageItem}]}_refreshCm(_ref){var _element$dragging,_element$locked,_element$hascmrestric;let{element:element}=_ref;this.element.classList.toggle(this.classes.CMHIDDEN,!element.visible),this.getElement(this.selectors.CM_NAME).innerHTML=element.name,this.element.classList.toggle(this.classes.DRAGGING,null!==(_element$dragging=element.dragging)&&void 0!==_element$dragging&&_element$dragging),this.element.classList.toggle(this.classes.LOCKED,null!==(_element$locked=element.locked)&&void 0!==_element$locked&&_element$locked),this.element.classList.toggle(this.classes.RESTRICTIONS,null!==(_element$hascmrestric=element.hascmrestrictions)&&void 0!==_element$hascmrestric&&_element$hascmrestric),this.locked=element.locked}_refreshPageItem(_ref2){let{element:element}=_ref2;if(!element.pageItem)return;const isPageId="cm"==element.pageItem.type&&element.pageItem.id==this.id;this.element.classList.toggle(this.classes.PAGEITEM,isPageId),isPageId&&!this.reactive.isEditing&&this.element.scrollIntoView({block:"nearest"})}async _refreshCompletion(_ref3){let{state:state,element:element}=_ref3;if(this.reactive.isEditing||!element.istrackeduser)return;const completionElement=this.getElement(this.selectors.CM_COMPLETION);if(completionElement.dataset.value==element.completionstate)return;const data=this.reactive.getExporter().cmCompletion(state,element);try{const{html:html,js:js}=await _templates.default.renderForPromise("core_courseformat/local/courseindex/cmcompletion",data);_templates.default.replaceNode(completionElement,html,js)}catch(error){throw error}}_activityAnchor(event){const cm=this.reactive.get("cm",this.id);if(document.getElementById(cm.anchor))return void setTimeout((()=>{this.reactive.dispatch("setPageItem","cm",cm.id)}),50);const course=this.reactive.get("course"),section=this.reactive.get("section",cm.sectionid);if(!section)return;const url="".concat(course.baseurl,"§ion=").concat(section.number,"#").concat(cm.anchor);event.preventDefault(),window.location=url}}return _exports.default=Component,_exports.default})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_dndcmitem=_interopRequireDefault(_dndcmitem),_templates=_interopRequireDefault(_templates),_prefetch=_interopRequireDefault(_prefetch),_config=_interopRequireDefault(_config);_prefetch.default.prefetchTemplate("core_courseformat/local/courseindex/cmcompletion");class Component extends _dndcmitem.default{create(){this.name="courseindex_cm",this.selectors={CM_NAME:"[data-for='cm_name']",CM_COMPLETION:"[data-for='cm_completion']"},this.classes={CMHIDDEN:"dimmed",LOCKED:"editinprogress",RESTRICTIONS:"restrictions",PAGEITEM:"pageitem"},this.id=this.element.dataset.id}static init(target,selectors){return new this({element:document.getElementById(target),selectors:selectors})}stateReady(state){this.configDragDrop(this.id);const cm=state.cm.get(this.id),course=state.course;this._refreshCompletion({state:state,element:cm}),window.location.href!=cm.url&&window.location.href!="".concat(course.baseurl,"#").concat(cm.anchor)||(this.reactive.dispatch("setPageItem","cm",this.id),this.element.scrollIntoView({block:"center"})),_config.default.contextid!=_config.default.courseContextId&&_config.default.contextInstanceId==this.id&&(this.reactive.dispatch("setPageItem","cm",this.id,!0),this.element.scrollIntoView({block:"center"})),cm.uservisible||this.addEventListener(this.getElement(this.selectors.CM_NAME),"click",this._activityAnchor)}getWatchers(){return[{watch:"cm[".concat(this.id,"]:deleted"),handler:this.remove},{watch:"cm[".concat(this.id,"]:updated"),handler:this._refreshCm},{watch:"cm[".concat(this.id,"].completionstate:updated"),handler:this._refreshCompletion},{watch:"course.pageItem:updated",handler:this._refreshPageItem}]}_refreshCm(_ref){var _element$dragging,_element$locked,_element$hascmrestric;let{element:element}=_ref;this.element.classList.toggle(this.classes.CMHIDDEN,!element.visible),this.getElement(this.selectors.CM_NAME).innerHTML=element.name,this.element.classList.toggle(this.classes.DRAGGING,null!==(_element$dragging=element.dragging)&&void 0!==_element$dragging&&_element$dragging),this.element.classList.toggle(this.classes.LOCKED,null!==(_element$locked=element.locked)&&void 0!==_element$locked&&_element$locked),this.element.classList.toggle(this.classes.RESTRICTIONS,null!==(_element$hascmrestric=element.hascmrestrictions)&&void 0!==_element$hascmrestric&&_element$hascmrestric),this.locked=element.locked}_refreshPageItem(_ref2){let{element:element}=_ref2;if(!element.pageItem)return;const isPageId="cm"==element.pageItem.type&&element.pageItem.id==this.id;this.element.classList.toggle(this.classes.PAGEITEM,isPageId),isPageId&&!this.reactive.isEditing&&this.element.scrollIntoView({block:"nearest"})}async _refreshCompletion(_ref3){let{state:state,element:element}=_ref3;if(this.reactive.isEditing||!element.istrackeduser)return;const completionElement=this.getElement(this.selectors.CM_COMPLETION);if(completionElement.dataset.value==element.completionstate)return;const data=this.reactive.getExporter().cmCompletion(state,element);try{const{html:html,js:js}=await _templates.default.renderForPromise("core_courseformat/local/courseindex/cmcompletion",data);_templates.default.replaceNode(completionElement,html,js)}catch(error){throw error}}_activityAnchor(event){const cm=this.reactive.get("cm",this.id);if(document.getElementById(cm.anchor))return void setTimeout((()=>{this.reactive.dispatch("setPageItem","cm",cm.id)}),50);const course=this.reactive.get("course"),section=this.reactive.get("section",cm.sectionid);if(!section)return;const url="".concat(course.baseurl,"§ion=").concat(section.number,"#").concat(cm.anchor);event.preventDefault(),window.location=url}}return _exports.default=Component,_exports.default})); //# sourceMappingURL=cm.min.js.map \ No newline at end of file diff --git a/course/format/amd/build/local/courseindex/cm.min.js.map b/course/format/amd/build/local/courseindex/cm.min.js.map index b716c50a069..fac258fa647 100644 --- a/course/format/amd/build/local/courseindex/cm.min.js.map +++ b/course/format/amd/build/local/courseindex/cm.min.js.map @@ -1 +1 @@ -{"version":3,"file":"cm.min.js","sources":["../../../src/local/courseindex/cm.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 * Course index cm component.\n *\n * This component is used to control specific course modules interactions like drag and drop.\n *\n * @module core_courseformat/local/courseindex/cm\n * @class core_courseformat/local/courseindex/cm\n * @copyright 2021 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport DndCmItem from 'core_courseformat/local/courseeditor/dndcmitem';\nimport Templates from 'core/templates';\nimport Prefetch from 'core/prefetch';\nimport Config from 'core/config';\n\n// Prefetch the completion icons template.\nconst completionTemplate = 'core_courseformat/local/courseindex/cmcompletion';\nPrefetch.prefetchTemplate(completionTemplate);\n\nexport default class Component extends DndCmItem {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'courseindex_cm';\n // Default query selectors.\n this.selectors = {\n CM_NAME: `[data-for='cm_name']`,\n CM_COMPLETION: `[data-for='cm_completion']`,\n };\n // Default classes to toggle on refresh.\n this.classes = {\n CMHIDDEN: 'dimmed',\n LOCKED: 'editinprogress',\n RESTRICTIONS: 'restrictions',\n PAGEITEM: 'pageitem',\n };\n // We need our id to watch specific events.\n this.id = this.element.dataset.id;\n }\n\n /**\n * Static method to create a component instance form the mustache template.\n *\n * @param {element|string} target the DOM main element or its ID\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n return new Component({\n element: document.getElementById(target),\n selectors,\n });\n }\n\n /**\n * Initial state ready method.\n *\n * @param {Object} state the course state.\n */\n stateReady(state) {\n this.configDragDrop(this.id);\n const cm = state.cm.get(this.id);\n const course = state.course;\n // Refresh completion icon.\n this._refreshCompletion({\n state,\n element: cm,\n });\n // Check if the current url is the cm url.\n if (window.location.href == cm.url || window.location.href == `${course.baseurl}#${cm.anchor}`) {\n this.reactive.dispatch('setPageItem', 'cm', this.id);\n this.element.scrollIntoView({block: \"center\"});\n }\n // Check if this we are displaying this activity page.\n if (Config.contextid != Config.courseContextId && Config.contextInstanceId == this.id) {\n this.reactive.dispatch('setPageItem', 'cm', this.id, true);\n this.element.scrollIntoView({block: \"center\"});\n }\n // Add anchor logic if the element is not user visible.\n if (!cm.uservisible) {\n this.addEventListener(\n this.getElement(this.selectors.CM_NAME),\n 'click',\n this._activityAnchor,\n );\n }\n }\n\n /**\n * Component watchers.\n *\n * @returns {Array} of watchers\n */\n getWatchers() {\n return [\n {watch: `cm[${this.id}]:deleted`, handler: this.remove},\n {watch: `cm[${this.id}]:updated`, handler: this._refreshCm},\n {watch: `cm[${this.id}].completionstate:updated`, handler: this._refreshCompletion},\n {watch: `course.pageItem:updated`, handler: this._refreshPageItem},\n ];\n }\n\n /**\n * Update a course index cm using the state information.\n *\n * @param {object} param\n * @param {Object} param.element details the update details.\n */\n _refreshCm({element}) {\n // Update classes.\n this.element.classList.toggle(this.classes.CMHIDDEN, !element.visible);\n this.getElement(this.selectors.CM_NAME).innerHTML = element.name;\n this.element.classList.toggle(this.classes.DRAGGING, element.dragging ?? false);\n this.element.classList.toggle(this.classes.LOCKED, element.locked ?? false);\n this.element.classList.toggle(this.classes.RESTRICTIONS, element.hascmrestrictions ?? false);\n this.locked = element.locked;\n }\n\n /**\n * Handle a page item update.\n *\n * @param {Object} details the update details\n * @param {Object} details.element the course state data.\n */\n _refreshPageItem({element}) {\n if (!element.pageItem) {\n return;\n }\n const isPageId = (element.pageItem.type == 'cm' && element.pageItem.id == this.id);\n this.element.classList.toggle(this.classes.PAGEITEM, isPageId);\n if (isPageId && !this.reactive.isEditing) {\n this.element.scrollIntoView({block: \"nearest\"});\n }\n }\n\n /**\n * Update the activity completion icon.\n *\n * @param {Object} details the update details\n * @param {Object} details.state the state data\n * @param {Object} details.element the element data\n */\n async _refreshCompletion({state, element}) {\n // No completion icons are displayed in edit mode.\n if (this.reactive.isEditing || !element.istrackeduser) {\n return;\n }\n // Check if the completion value has changed.\n const completionElement = this.getElement(this.selectors.CM_COMPLETION);\n if (completionElement.dataset.value == element.completionstate) {\n return;\n }\n\n // Collect section information from the state.\n const exporter = this.reactive.getExporter();\n const data = exporter.cmCompletion(state, element);\n\n try {\n const {html, js} = await Templates.renderForPromise(completionTemplate, data);\n Templates.replaceNode(completionElement, html, js);\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * The activity anchor event.\n *\n * @param {Event} event\n */\n _activityAnchor(event) {\n const cm = this.reactive.get('cm', this.id);\n // If the user cannot access the element but the element is present in the page\n // the new url should be an anchor link.\n const element = document.getElementById(cm.anchor);\n if (element) {\n // Marc the element as page item once the event is handled.\n setTimeout(() => {\n this.reactive.dispatch('setPageItem', 'cm', cm.id);\n }, 50);\n return;\n }\n // If the element is not present in the page we need to go to the specific section.\n const course = this.reactive.get('course');\n const section = this.reactive.get('section', cm.sectionid);\n if (!section) {\n return;\n }\n const url = `${course.baseurl}§ion=${section.number}#${cm.anchor}`;\n event.preventDefault();\n window.location = url;\n }\n}\n"],"names":["prefetchTemplate","Component","DndCmItem","create","name","selectors","CM_NAME","CM_COMPLETION","classes","CMHIDDEN","LOCKED","RESTRICTIONS","PAGEITEM","id","this","element","dataset","target","document","getElementById","stateReady","state","configDragDrop","cm","get","course","_refreshCompletion","window","location","href","url","baseurl","anchor","reactive","dispatch","scrollIntoView","block","Config","contextid","courseContextId","contextInstanceId","uservisible","addEventListener","getElement","_activityAnchor","getWatchers","watch","handler","remove","_refreshCm","_refreshPageItem","classList","toggle","visible","innerHTML","DRAGGING","dragging","locked","hascmrestrictions","pageItem","isPageId","type","isEditing","istrackeduser","completionElement","value","completionstate","data","getExporter","cmCompletion","html","js","Templates","renderForPromise","replaceNode","error","event","setTimeout","section","sectionid","number","preventDefault"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"cm.min.js","sources":["../../../src/local/courseindex/cm.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 * Course index cm component.\n *\n * This component is used to control specific course modules interactions like drag and drop.\n *\n * @module core_courseformat/local/courseindex/cm\n * @class core_courseformat/local/courseindex/cm\n * @copyright 2021 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport DndCmItem from 'core_courseformat/local/courseeditor/dndcmitem';\nimport Templates from 'core/templates';\nimport Prefetch from 'core/prefetch';\nimport Config from 'core/config';\n\n// Prefetch the completion icons template.\nconst completionTemplate = 'core_courseformat/local/courseindex/cmcompletion';\nPrefetch.prefetchTemplate(completionTemplate);\n\nexport default class Component extends DndCmItem {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'courseindex_cm';\n // Default query selectors.\n this.selectors = {\n CM_NAME: `[data-for='cm_name']`,\n CM_COMPLETION: `[data-for='cm_completion']`,\n };\n // Default classes to toggle on refresh.\n this.classes = {\n CMHIDDEN: 'dimmed',\n LOCKED: 'editinprogress',\n RESTRICTIONS: 'restrictions',\n PAGEITEM: 'pageitem',\n };\n // We need our id to watch specific events.\n this.id = this.element.dataset.id;\n }\n\n /**\n * Static method to create a component instance form the mustache template.\n *\n * @param {element|string} target the DOM main element or its ID\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n return new this({\n element: document.getElementById(target),\n selectors,\n });\n }\n\n /**\n * Initial state ready method.\n *\n * @param {Object} state the course state.\n */\n stateReady(state) {\n this.configDragDrop(this.id);\n const cm = state.cm.get(this.id);\n const course = state.course;\n // Refresh completion icon.\n this._refreshCompletion({\n state,\n element: cm,\n });\n // Check if the current url is the cm url.\n if (window.location.href == cm.url || window.location.href == `${course.baseurl}#${cm.anchor}`) {\n this.reactive.dispatch('setPageItem', 'cm', this.id);\n this.element.scrollIntoView({block: \"center\"});\n }\n // Check if this we are displaying this activity page.\n if (Config.contextid != Config.courseContextId && Config.contextInstanceId == this.id) {\n this.reactive.dispatch('setPageItem', 'cm', this.id, true);\n this.element.scrollIntoView({block: \"center\"});\n }\n // Add anchor logic if the element is not user visible.\n if (!cm.uservisible) {\n this.addEventListener(\n this.getElement(this.selectors.CM_NAME),\n 'click',\n this._activityAnchor,\n );\n }\n }\n\n /**\n * Component watchers.\n *\n * @returns {Array} of watchers\n */\n getWatchers() {\n return [\n {watch: `cm[${this.id}]:deleted`, handler: this.remove},\n {watch: `cm[${this.id}]:updated`, handler: this._refreshCm},\n {watch: `cm[${this.id}].completionstate:updated`, handler: this._refreshCompletion},\n {watch: `course.pageItem:updated`, handler: this._refreshPageItem},\n ];\n }\n\n /**\n * Update a course index cm using the state information.\n *\n * @param {object} param\n * @param {Object} param.element details the update details.\n */\n _refreshCm({element}) {\n // Update classes.\n this.element.classList.toggle(this.classes.CMHIDDEN, !element.visible);\n this.getElement(this.selectors.CM_NAME).innerHTML = element.name;\n this.element.classList.toggle(this.classes.DRAGGING, element.dragging ?? false);\n this.element.classList.toggle(this.classes.LOCKED, element.locked ?? false);\n this.element.classList.toggle(this.classes.RESTRICTIONS, element.hascmrestrictions ?? false);\n this.locked = element.locked;\n }\n\n /**\n * Handle a page item update.\n *\n * @param {Object} details the update details\n * @param {Object} details.element the course state data.\n */\n _refreshPageItem({element}) {\n if (!element.pageItem) {\n return;\n }\n const isPageId = (element.pageItem.type == 'cm' && element.pageItem.id == this.id);\n this.element.classList.toggle(this.classes.PAGEITEM, isPageId);\n if (isPageId && !this.reactive.isEditing) {\n this.element.scrollIntoView({block: \"nearest\"});\n }\n }\n\n /**\n * Update the activity completion icon.\n *\n * @param {Object} details the update details\n * @param {Object} details.state the state data\n * @param {Object} details.element the element data\n */\n async _refreshCompletion({state, element}) {\n // No completion icons are displayed in edit mode.\n if (this.reactive.isEditing || !element.istrackeduser) {\n return;\n }\n // Check if the completion value has changed.\n const completionElement = this.getElement(this.selectors.CM_COMPLETION);\n if (completionElement.dataset.value == element.completionstate) {\n return;\n }\n\n // Collect section information from the state.\n const exporter = this.reactive.getExporter();\n const data = exporter.cmCompletion(state, element);\n\n try {\n const {html, js} = await Templates.renderForPromise(completionTemplate, data);\n Templates.replaceNode(completionElement, html, js);\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * The activity anchor event.\n *\n * @param {Event} event\n */\n _activityAnchor(event) {\n const cm = this.reactive.get('cm', this.id);\n // If the user cannot access the element but the element is present in the page\n // the new url should be an anchor link.\n const element = document.getElementById(cm.anchor);\n if (element) {\n // Marc the element as page item once the event is handled.\n setTimeout(() => {\n this.reactive.dispatch('setPageItem', 'cm', cm.id);\n }, 50);\n return;\n }\n // If the element is not present in the page we need to go to the specific section.\n const course = this.reactive.get('course');\n const section = this.reactive.get('section', cm.sectionid);\n if (!section) {\n return;\n }\n const url = `${course.baseurl}§ion=${section.number}#${cm.anchor}`;\n event.preventDefault();\n window.location = url;\n }\n}\n"],"names":["prefetchTemplate","Component","DndCmItem","create","name","selectors","CM_NAME","CM_COMPLETION","classes","CMHIDDEN","LOCKED","RESTRICTIONS","PAGEITEM","id","this","element","dataset","target","document","getElementById","stateReady","state","configDragDrop","cm","get","course","_refreshCompletion","window","location","href","url","baseurl","anchor","reactive","dispatch","scrollIntoView","block","Config","contextid","courseContextId","contextInstanceId","uservisible","addEventListener","getElement","_activityAnchor","getWatchers","watch","handler","remove","_refreshCm","_refreshPageItem","classList","toggle","visible","innerHTML","DRAGGING","dragging","locked","hascmrestrictions","pageItem","isPageId","type","isEditing","istrackeduser","completionElement","value","completionstate","data","getExporter","cmCompletion","html","js","Templates","renderForPromise","replaceNode","error","event","setTimeout","section","sectionid","number","preventDefault"],"mappings":"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"} \ No newline at end of file diff --git a/course/format/amd/build/local/courseindex/courseindex.min.js b/course/format/amd/build/local/courseindex/courseindex.min.js index bbbd76a837e..32e84d803df 100644 --- a/course/format/amd/build/local/courseindex/courseindex.min.js +++ b/course/format/amd/build/local/courseindex/courseindex.min.js @@ -6,6 +6,6 @@ define("core_courseformat/local/courseindex/courseindex",["exports","core/reacti * @class core_courseformat/local/courseindex/courseindex * @copyright 2021 Ferran Recio * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_jquery=_interopRequireDefault(_jquery),_contenttree=_interopRequireDefault(_contenttree);class Component extends _reactive.BaseComponent{create(){this.name="courseindex",this.selectors={SECTION:"[data-for='section']",SECTION_CMLIST:"[data-for='cmlist']",CM:"[data-for='cm']",TOGGLER:'[data-action="togglecourseindexsection"]',COLLAPSE:'[data-toggle="collapse"]',DRAWER:".drawer"},this.classes={SECTIONHIDDEN:"dimmed",CMHIDDEN:"dimmed",SECTIONCURRENT:"current",COLLAPSED:"collapsed",SHOW:"show"},this.sections={},this.cms={}}static init(target,selectors){return new Component({element:document.getElementById(target),reactive:(0,_courseeditor.getCurrentCourseEditor)(),selectors:selectors})}stateReady(state){this.addEventListener(this.element,"click",this._sectionTogglers);this.getElements(this.selectors.SECTION).forEach((section=>{this.sections[section.dataset.id]=section}));this.getElements(this.selectors.CM).forEach((cm=>{this.cms[cm.dataset.id]=cm})),this._refreshPageItem({element:state.course,state:state}),this.contentTree=new _contenttree.default(this.element,this.selectors,this.reactive.isEditing)}getWatchers(){return[{watch:"section.indexcollapsed:updated",handler:this._refreshSectionCollapsed},{watch:"cm:created",handler:this._createCm},{watch:"cm:deleted",handler:this._deleteCm},{watch:"section:created",handler:this._createSection},{watch:"section:deleted",handler:this._deleteSection},{watch:"course.pageItem:created",handler:this._refreshPageItem},{watch:"course.pageItem:updated",handler:this._refreshPageItem},{watch:"course.sectionlist:updated",handler:this._refreshCourseSectionlist},{watch:"section.cmlist:updated",handler:this._refreshSectionCmlist}]}_sectionTogglers(event){const sectionlink=event.target.closest(this.selectors.TOGGLER),isChevron=event.target.closest(this.selectors.COLLAPSE);if(sectionlink||isChevron){var _toggler$classList$co;const section=event.target.closest(this.selectors.SECTION),toggler=section.querySelector(this.selectors.COLLAPSE),isCollapsed=null!==(_toggler$classList$co=null==toggler?void 0:toggler.classList.contains(this.classes.COLLAPSED))&&void 0!==_toggler$classList$co&&_toggler$classList$co;if(isChevron||isCollapsed){const sectionId=section.getAttribute("data-id");this.reactive.dispatch("sectionIndexCollapsed",[sectionId],!isCollapsed)}}}_refreshSectionCollapsed(_ref){var _toggler$classList$co2;let{element:element}=_ref;const target=this.getElement(this.selectors.SECTION,element.id);if(!target)throw new Error("Unkown section with ID ".concat(element.id));const toggler=target.querySelector(this.selectors.COLLAPSE),isCollapsed=null!==(_toggler$classList$co2=null==toggler?void 0:toggler.classList.contains(this.classes.COLLAPSED))&&void 0!==_toggler$classList$co2&&_toggler$classList$co2;element.indexcollapsed!==isCollapsed&&this._expandSectionNode(element)}_expandSectionNode(element,forceValue){var _toggler$dataset$targ;const toggler=this.getElement(this.selectors.SECTION,element.id).querySelector(this.selectors.COLLAPSE);let collapsibleId=null!==(_toggler$dataset$targ=toggler.dataset.target)&&void 0!==_toggler$dataset$targ?_toggler$dataset$targ:toggler.getAttribute("href");if(!collapsibleId)return;collapsibleId=collapsibleId.replace("#","");const collapsible=document.getElementById(collapsibleId);if(!collapsible)return;void 0===forceValue&&(forceValue=!element.indexcollapsed);const togglerValue=forceValue?"show":"hide";(0,_jquery.default)(collapsible).collapse(togglerValue)}_refreshPageItem(_ref2){var _element$pageItem;let{element:element,state:state}=_ref2;if(null==element||null===(_element$pageItem=element.pageItem)||void 0===_element$pageItem||!_element$pageItem.isStatic||"cm"!=element.pageItem.type)return;const section=state.section.get(element.pageItem.sectionId);section.indexcollapsed&&(this._expandSectionNode(section,!0),setTimeout((()=>{var _this$cms$element$pag;return null===(_this$cms$element$pag=this.cms[element.pageItem.id])||void 0===_this$cms$element$pag?void 0:_this$cms$element$pag.scrollIntoView({block:"nearest"})}),250))}async _createCm(_ref3){let{state:state,element:element}=_ref3;const fakeelement=document.createElement("li");fakeelement.classList.add("bg-pulse-grey","w-100"),fakeelement.innerHTML=" ",this.cms[element.id]=fakeelement,this._refreshSectionCmlist({state:state,element:state.section.get(element.sectionid)});const data=this.reactive.getExporter().cm(state,element),newelement=(await this.renderComponent(fakeelement,"core_courseformat/local/courseindex/cm",data)).getElement();this.cms[element.id]=newelement,fakeelement.parentNode.replaceChild(newelement,fakeelement)}async _createSection(_ref4){let{state:state,element:element}=_ref4;const fakeelement=document.createElement("div");fakeelement.classList.add("bg-pulse-grey","w-100"),fakeelement.innerHTML=" ",this.sections[element.id]=fakeelement,this._refreshCourseSectionlist({state:state,element:state.course});const data=this.reactive.getExporter().section(state,element),newelement=(await this.renderComponent(fakeelement,"core_courseformat/local/courseindex/section",data)).getElement();this.sections[element.id]=newelement,fakeelement.parentNode.replaceChild(newelement,fakeelement)}_refreshSectionCmlist(_ref5){var _element$cmlist;let{element:element}=_ref5;const cmlist=null!==(_element$cmlist=element.cmlist)&&void 0!==_element$cmlist?_element$cmlist:[],listparent=this.getElement(this.selectors.SECTION_CMLIST,element.id);this._fixOrder(listparent,cmlist,this.cms)}_refreshCourseSectionlist(_ref6){var _element$sectionlist;let{element:element}=_ref6;const sectionlist=null!==(_element$sectionlist=element.sectionlist)&&void 0!==_element$sectionlist?_element$sectionlist:[];this._fixOrder(this.element,sectionlist,this.sections)}_fixOrder(container,neworder,allitems){if(!neworder.length)return container.classList.add("hidden"),void(container.innerHTML="");for(container.classList.remove("hidden"),neworder.forEach(((itemid,index)=>{const item=allitems[itemid],currentitem=container.children[index];void 0!==currentitem?currentitem!==item&&container.insertBefore(item,currentitem):container.append(item)}));container.children.length>neworder.length;)container.removeChild(container.lastChild)}_deleteCm(_ref7){let{element:element}=_ref7;delete this.cms[element.id]}_deleteSection(_ref8){let{element:element}=_ref8;delete this.sections[element.id]}}return _exports.default=Component,_exports.default})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_jquery=_interopRequireDefault(_jquery),_contenttree=_interopRequireDefault(_contenttree);class Component extends _reactive.BaseComponent{create(){this.name="courseindex",this.selectors={SECTION:"[data-for='section']",SECTION_CMLIST:"[data-for='cmlist']",CM:"[data-for='cm']",TOGGLER:'[data-action="togglecourseindexsection"]',COLLAPSE:'[data-toggle="collapse"]',DRAWER:".drawer"},this.classes={SECTIONHIDDEN:"dimmed",CMHIDDEN:"dimmed",SECTIONCURRENT:"current",COLLAPSED:"collapsed",SHOW:"show"},this.sections={},this.cms={}}static init(target,selectors){return new this({element:document.getElementById(target),reactive:(0,_courseeditor.getCurrentCourseEditor)(),selectors:selectors})}stateReady(state){this.addEventListener(this.element,"click",this._sectionTogglers);this.getElements(this.selectors.SECTION).forEach((section=>{this.sections[section.dataset.id]=section}));this.getElements(this.selectors.CM).forEach((cm=>{this.cms[cm.dataset.id]=cm})),this._refreshPageItem({element:state.course,state:state}),this.contentTree=new _contenttree.default(this.element,this.selectors,this.reactive.isEditing)}getWatchers(){return[{watch:"section.indexcollapsed:updated",handler:this._refreshSectionCollapsed},{watch:"cm:created",handler:this._createCm},{watch:"cm:deleted",handler:this._deleteCm},{watch:"section:created",handler:this._createSection},{watch:"section:deleted",handler:this._deleteSection},{watch:"course.pageItem:created",handler:this._refreshPageItem},{watch:"course.pageItem:updated",handler:this._refreshPageItem},{watch:"course.sectionlist:updated",handler:this._refreshCourseSectionlist},{watch:"section.cmlist:updated",handler:this._refreshSectionCmlist}]}_sectionTogglers(event){const sectionlink=event.target.closest(this.selectors.TOGGLER),isChevron=event.target.closest(this.selectors.COLLAPSE);if(sectionlink||isChevron){var _toggler$classList$co;const section=event.target.closest(this.selectors.SECTION),toggler=section.querySelector(this.selectors.COLLAPSE),isCollapsed=null!==(_toggler$classList$co=null==toggler?void 0:toggler.classList.contains(this.classes.COLLAPSED))&&void 0!==_toggler$classList$co&&_toggler$classList$co;if(isChevron||isCollapsed){const sectionId=section.getAttribute("data-id");this.reactive.dispatch("sectionIndexCollapsed",[sectionId],!isCollapsed)}}}_refreshSectionCollapsed(_ref){var _toggler$classList$co2;let{element:element}=_ref;const target=this.getElement(this.selectors.SECTION,element.id);if(!target)throw new Error("Unkown section with ID ".concat(element.id));const toggler=target.querySelector(this.selectors.COLLAPSE),isCollapsed=null!==(_toggler$classList$co2=null==toggler?void 0:toggler.classList.contains(this.classes.COLLAPSED))&&void 0!==_toggler$classList$co2&&_toggler$classList$co2;element.indexcollapsed!==isCollapsed&&this._expandSectionNode(element)}_expandSectionNode(element,forceValue){var _toggler$dataset$targ;const toggler=this.getElement(this.selectors.SECTION,element.id).querySelector(this.selectors.COLLAPSE);let collapsibleId=null!==(_toggler$dataset$targ=toggler.dataset.target)&&void 0!==_toggler$dataset$targ?_toggler$dataset$targ:toggler.getAttribute("href");if(!collapsibleId)return;collapsibleId=collapsibleId.replace("#","");const collapsible=document.getElementById(collapsibleId);if(!collapsible)return;void 0===forceValue&&(forceValue=!element.indexcollapsed);const togglerValue=forceValue?"show":"hide";(0,_jquery.default)(collapsible).collapse(togglerValue)}_refreshPageItem(_ref2){var _element$pageItem;let{element:element,state:state}=_ref2;if(null==element||null===(_element$pageItem=element.pageItem)||void 0===_element$pageItem||!_element$pageItem.isStatic||"cm"!=element.pageItem.type)return;const section=state.section.get(element.pageItem.sectionId);section.indexcollapsed&&(this._expandSectionNode(section,!0),setTimeout((()=>{var _this$cms$element$pag;return null===(_this$cms$element$pag=this.cms[element.pageItem.id])||void 0===_this$cms$element$pag?void 0:_this$cms$element$pag.scrollIntoView({block:"nearest"})}),250))}async _createCm(_ref3){let{state:state,element:element}=_ref3;const fakeelement=document.createElement("li");fakeelement.classList.add("bg-pulse-grey","w-100"),fakeelement.innerHTML=" ",this.cms[element.id]=fakeelement,this._refreshSectionCmlist({state:state,element:state.section.get(element.sectionid)});const data=this.reactive.getExporter().cm(state,element),newelement=(await this.renderComponent(fakeelement,"core_courseformat/local/courseindex/cm",data)).getElement();this.cms[element.id]=newelement,fakeelement.parentNode.replaceChild(newelement,fakeelement)}async _createSection(_ref4){let{state:state,element:element}=_ref4;const fakeelement=document.createElement("div");fakeelement.classList.add("bg-pulse-grey","w-100"),fakeelement.innerHTML=" ",this.sections[element.id]=fakeelement,this._refreshCourseSectionlist({state:state,element:state.course});const data=this.reactive.getExporter().section(state,element),newelement=(await this.renderComponent(fakeelement,"core_courseformat/local/courseindex/section",data)).getElement();this.sections[element.id]=newelement,fakeelement.parentNode.replaceChild(newelement,fakeelement)}_refreshSectionCmlist(_ref5){var _element$cmlist;let{element:element}=_ref5;const cmlist=null!==(_element$cmlist=element.cmlist)&&void 0!==_element$cmlist?_element$cmlist:[],listparent=this.getElement(this.selectors.SECTION_CMLIST,element.id);this._fixOrder(listparent,cmlist,this.cms)}_refreshCourseSectionlist(_ref6){var _element$sectionlist;let{element:element}=_ref6;const sectionlist=null!==(_element$sectionlist=element.sectionlist)&&void 0!==_element$sectionlist?_element$sectionlist:[];this._fixOrder(this.element,sectionlist,this.sections)}_fixOrder(container,neworder,allitems){if(!neworder.length)return container.classList.add("hidden"),void(container.innerHTML="");for(container.classList.remove("hidden"),neworder.forEach(((itemid,index)=>{const item=allitems[itemid],currentitem=container.children[index];void 0!==currentitem?currentitem!==item&&container.insertBefore(item,currentitem):container.append(item)}));container.children.length>neworder.length;)container.removeChild(container.lastChild)}_deleteCm(_ref7){let{element:element}=_ref7;delete this.cms[element.id]}_deleteSection(_ref8){let{element:element}=_ref8;delete this.sections[element.id]}}return _exports.default=Component,_exports.default})); //# sourceMappingURL=courseindex.min.js.map \ No newline at end of file diff --git a/course/format/amd/build/local/courseindex/courseindex.min.js.map b/course/format/amd/build/local/courseindex/courseindex.min.js.map index e313f922faa..cd825c46453 100644 --- a/course/format/amd/build/local/courseindex/courseindex.min.js.map +++ b/course/format/amd/build/local/courseindex/courseindex.min.js.map @@ -1 +1 @@ -{"version":3,"file":"courseindex.min.js","sources":["../../../src/local/courseindex/courseindex.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 * Course index main component.\n *\n * @module core_courseformat/local/courseindex/courseindex\n * @class core_courseformat/local/courseindex/courseindex\n * @copyright 2021 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 jQuery from 'jquery';\nimport ContentTree from 'core_courseformat/local/courseeditor/contenttree';\n\nexport default class Component extends BaseComponent {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'courseindex';\n // Default query selectors.\n this.selectors = {\n SECTION: `[data-for='section']`,\n SECTION_CMLIST: `[data-for='cmlist']`,\n CM: `[data-for='cm']`,\n TOGGLER: `[data-action=\"togglecourseindexsection\"]`,\n COLLAPSE: `[data-toggle=\"collapse\"]`,\n DRAWER: `.drawer`,\n };\n // Default classes to toggle on refresh.\n this.classes = {\n SECTIONHIDDEN: 'dimmed',\n CMHIDDEN: 'dimmed',\n SECTIONCURRENT: 'current',\n COLLAPSED: `collapsed`,\n SHOW: `show`,\n };\n // Arrays to keep cms and sections elements.\n this.sections = {};\n this.cms = {};\n }\n\n /**\n * Static method to create a component instance form the mustache template.\n *\n * @param {element|string} target the DOM main element or its ID\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n return new Component({\n element: document.getElementById(target),\n reactive: getCurrentCourseEditor(),\n selectors,\n });\n }\n\n /**\n * Initial state ready method.\n *\n * @param {Object} state the state data\n */\n stateReady(state) {\n // Activate section togglers.\n this.addEventListener(this.element, 'click', this._sectionTogglers);\n\n // Get cms and sections elements.\n const sections = this.getElements(this.selectors.SECTION);\n sections.forEach((section) => {\n this.sections[section.dataset.id] = section;\n });\n const cms = this.getElements(this.selectors.CM);\n cms.forEach((cm) => {\n this.cms[cm.dataset.id] = cm;\n });\n\n // Set the page item if any.\n this._refreshPageItem({element: state.course, state});\n\n // Configure Aria Tree.\n this.contentTree = new ContentTree(this.element, this.selectors, this.reactive.isEditing);\n }\n\n getWatchers() {\n return [\n {watch: `section.indexcollapsed:updated`, handler: this._refreshSectionCollapsed},\n {watch: `cm:created`, handler: this._createCm},\n {watch: `cm:deleted`, handler: this._deleteCm},\n {watch: `section:created`, handler: this._createSection},\n {watch: `section:deleted`, handler: this._deleteSection},\n {watch: `course.pageItem:created`, handler: this._refreshPageItem},\n {watch: `course.pageItem:updated`, handler: this._refreshPageItem},\n // Sections and cm sorting.\n {watch: `course.sectionlist:updated`, handler: this._refreshCourseSectionlist},\n {watch: `section.cmlist:updated`, handler: this._refreshSectionCmlist},\n ];\n }\n\n /**\n * Setup sections toggler.\n *\n * Toggler click is delegated to the main course index element because new sections can\n * appear at any moment and this way we prevent accidental double bindings.\n *\n * @param {Event} event the triggered event\n */\n _sectionTogglers(event) {\n const sectionlink = event.target.closest(this.selectors.TOGGLER);\n const isChevron = event.target.closest(this.selectors.COLLAPSE);\n\n if (sectionlink || isChevron) {\n\n const section = event.target.closest(this.selectors.SECTION);\n const toggler = section.querySelector(this.selectors.COLLAPSE);\n const isCollapsed = toggler?.classList.contains(this.classes.COLLAPSED) ?? false;\n\n if (isChevron || isCollapsed) {\n // Update the state.\n const sectionId = section.getAttribute('data-id');\n this.reactive.dispatch(\n 'sectionIndexCollapsed',\n [sectionId],\n !isCollapsed\n );\n }\n }\n }\n\n /**\n * Update section collapsed.\n *\n * @param {object} args\n * @param {object} args.element The leement to be expanded\n */\n _refreshSectionCollapsed({element}) {\n const target = this.getElement(this.selectors.SECTION, element.id);\n if (!target) {\n throw new Error(`Unkown section with ID ${element.id}`);\n }\n // Check if it is already done.\n const toggler = target.querySelector(this.selectors.COLLAPSE);\n const isCollapsed = toggler?.classList.contains(this.classes.COLLAPSED) ?? false;\n\n if (element.indexcollapsed !== isCollapsed) {\n this._expandSectionNode(element);\n }\n }\n\n /**\n * Expand a section node.\n *\n * By default the method will use element.indexcollapsed to decide if the\n * section is opened or closed. However, using forceValue it is possible\n * to open or close a section independant from the indexcollapsed attribute.\n *\n * @param {Object} element the course module state element\n * @param {boolean} forceValue optional forced expanded value\n */\n _expandSectionNode(element, forceValue) {\n const target = this.getElement(this.selectors.SECTION, element.id);\n const toggler = target.querySelector(this.selectors.COLLAPSE);\n let collapsibleId = toggler.dataset.target ?? toggler.getAttribute(\"href\");\n if (!collapsibleId) {\n return;\n }\n collapsibleId = collapsibleId.replace('#', '');\n const collapsible = document.getElementById(collapsibleId);\n if (!collapsible) {\n return;\n }\n\n if (forceValue === undefined) {\n forceValue = (element.indexcollapsed) ? false : true;\n }\n\n // Course index is based on Bootstrap 4 collapsibles. To collapse them we need jQuery to\n // interact with collapsibles methods. Hopefully, this will change in Bootstrap 5 because\n // it does not require jQuery anymore (when MDL-71979 is integrated).\n const togglerValue = (forceValue) ? 'show' : 'hide';\n jQuery(collapsible).collapse(togglerValue);\n }\n\n /**\n * Handle a page item update.\n *\n * @param {Object} details the update details\n * @param {Object} details.state the state data.\n * @param {Object} details.element the course state data.\n */\n _refreshPageItem({element, state}) {\n if (!element?.pageItem?.isStatic || element.pageItem.type != 'cm') {\n return;\n }\n // Check if we need to uncollapse the section and scroll to the element.\n const section = state.section.get(element.pageItem.sectionId);\n if (section.indexcollapsed) {\n this._expandSectionNode(section, true);\n setTimeout(\n () => this.cms[element.pageItem.id]?.scrollIntoView({block: \"nearest\"}),\n 250\n );\n }\n }\n\n /**\n * Create a newcm instance.\n *\n * @param {object} param\n * @param {Object} param.state\n * @param {Object} param.element\n */\n async _createCm({state, element}) {\n // Create a fake node while the component is loading.\n const fakeelement = document.createElement('li');\n fakeelement.classList.add('bg-pulse-grey', 'w-100');\n fakeelement.innerHTML = ' ';\n this.cms[element.id] = fakeelement;\n // Place the fake node on the correct position.\n this._refreshSectionCmlist({\n state,\n element: state.section.get(element.sectionid),\n });\n // Collect render data.\n const exporter = this.reactive.getExporter();\n const data = exporter.cm(state, element);\n // Create the new content.\n const newcomponent = await this.renderComponent(fakeelement, 'core_courseformat/local/courseindex/cm', data);\n // Replace the fake node with the real content.\n const newelement = newcomponent.getElement();\n this.cms[element.id] = newelement;\n fakeelement.parentNode.replaceChild(newelement, fakeelement);\n }\n\n /**\n * Create a new section instance.\n *\n * @param {Object} details the update details.\n * @param {Object} details.state the state data.\n * @param {Object} details.element the element data.\n */\n async _createSection({state, element}) {\n // Create a fake node while the component is loading.\n const fakeelement = document.createElement('div');\n fakeelement.classList.add('bg-pulse-grey', 'w-100');\n fakeelement.innerHTML = ' ';\n this.sections[element.id] = fakeelement;\n // Place the fake node on the correct position.\n this._refreshCourseSectionlist({\n state,\n element: state.course,\n });\n // Collect render data.\n const exporter = this.reactive.getExporter();\n const data = exporter.section(state, element);\n // Create the new content.\n const newcomponent = await this.renderComponent(fakeelement, 'core_courseformat/local/courseindex/section', data);\n // Replace the fake node with the real content.\n const newelement = newcomponent.getElement();\n this.sections[element.id] = newelement;\n fakeelement.parentNode.replaceChild(newelement, fakeelement);\n }\n\n /**\n * Refresh a section cm list.\n *\n * @param {object} param\n * @param {Object} param.element\n */\n _refreshSectionCmlist({element}) {\n const cmlist = element.cmlist ?? [];\n const listparent = this.getElement(this.selectors.SECTION_CMLIST, element.id);\n this._fixOrder(listparent, cmlist, this.cms);\n }\n\n /**\n * Refresh the section list.\n *\n * @param {object} param\n * @param {Object} param.element\n */\n _refreshCourseSectionlist({element}) {\n const sectionlist = element.sectionlist ?? [];\n this._fixOrder(this.element, sectionlist, this.sections);\n }\n\n /**\n * Fix/reorder the section or cms order.\n *\n * @param {Element} container the HTML element to reorder.\n * @param {Array} neworder an array with the ids order\n * @param {Array} allitems the list of html elements that can be placed in the container\n */\n _fixOrder(container, neworder, allitems) {\n\n // Empty lists should not be visible.\n if (!neworder.length) {\n container.classList.add('hidden');\n container.innerHTML = '';\n return;\n }\n\n // Grant the list is visible (in case it was empty).\n container.classList.remove('hidden');\n\n // Move the elements in order at the beginning of the list.\n neworder.forEach((itemid, index) => {\n const item = allitems[itemid];\n // Get the current element at that position.\n const currentitem = container.children[index];\n if (currentitem === undefined) {\n container.append(item);\n return;\n }\n if (currentitem !== item) {\n container.insertBefore(item, currentitem);\n }\n });\n // Remove the remaining elements.\n while (container.children.length > neworder.length) {\n container.removeChild(container.lastChild);\n }\n }\n\n /**\n * Remove a cm from the list.\n *\n * The actual DOM element removal is delegated to the cm component.\n *\n * @param {object} param\n * @param {Object} param.element\n */\n _deleteCm({element}) {\n delete this.cms[element.id];\n }\n\n /**\n * Remove a section from the list.\n *\n * The actual DOM element removal is delegated to the section component.\n *\n * @param {Object} details the update details.\n * @param {Object} details.element the element data.\n */\n _deleteSection({element}) {\n delete this.sections[element.id];\n }\n}\n"],"names":["Component","BaseComponent","create","name","selectors","SECTION","SECTION_CMLIST","CM","TOGGLER","COLLAPSE","DRAWER","classes","SECTIONHIDDEN","CMHIDDEN","SECTIONCURRENT","COLLAPSED","SHOW","sections","cms","target","element","document","getElementById","reactive","stateReady","state","addEventListener","this","_sectionTogglers","getElements","forEach","section","dataset","id","cm","_refreshPageItem","course","contentTree","ContentTree","isEditing","getWatchers","watch","handler","_refreshSectionCollapsed","_createCm","_deleteCm","_createSection","_deleteSection","_refreshCourseSectionlist","_refreshSectionCmlist","event","sectionlink","closest","isChevron","toggler","querySelector","isCollapsed","classList","contains","sectionId","getAttribute","dispatch","getElement","Error","indexcollapsed","_expandSectionNode","forceValue","collapsibleId","replace","collapsible","undefined","togglerValue","collapse","pageItem","_element$pageItem","isStatic","type","get","setTimeout","_this$cms$element$pag","scrollIntoView","block","fakeelement","createElement","add","innerHTML","sectionid","data","getExporter","newelement","renderComponent","parentNode","replaceChild","cmlist","listparent","_fixOrder","sectionlist","container","neworder","allitems","length","remove","itemid","index","item","currentitem","children","insertBefore","append","removeChild","lastChild"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"courseindex.min.js","sources":["../../../src/local/courseindex/courseindex.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 * Course index main component.\n *\n * @module core_courseformat/local/courseindex/courseindex\n * @class core_courseformat/local/courseindex/courseindex\n * @copyright 2021 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 jQuery from 'jquery';\nimport ContentTree from 'core_courseformat/local/courseeditor/contenttree';\n\nexport default class Component extends BaseComponent {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'courseindex';\n // Default query selectors.\n this.selectors = {\n SECTION: `[data-for='section']`,\n SECTION_CMLIST: `[data-for='cmlist']`,\n CM: `[data-for='cm']`,\n TOGGLER: `[data-action=\"togglecourseindexsection\"]`,\n COLLAPSE: `[data-toggle=\"collapse\"]`,\n DRAWER: `.drawer`,\n };\n // Default classes to toggle on refresh.\n this.classes = {\n SECTIONHIDDEN: 'dimmed',\n CMHIDDEN: 'dimmed',\n SECTIONCURRENT: 'current',\n COLLAPSED: `collapsed`,\n SHOW: `show`,\n };\n // Arrays to keep cms and sections elements.\n this.sections = {};\n this.cms = {};\n }\n\n /**\n * Static method to create a component instance form the mustache template.\n *\n * @param {element|string} target the DOM main element or its ID\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n return new this({\n element: document.getElementById(target),\n reactive: getCurrentCourseEditor(),\n selectors,\n });\n }\n\n /**\n * Initial state ready method.\n *\n * @param {Object} state the state data\n */\n stateReady(state) {\n // Activate section togglers.\n this.addEventListener(this.element, 'click', this._sectionTogglers);\n\n // Get cms and sections elements.\n const sections = this.getElements(this.selectors.SECTION);\n sections.forEach((section) => {\n this.sections[section.dataset.id] = section;\n });\n const cms = this.getElements(this.selectors.CM);\n cms.forEach((cm) => {\n this.cms[cm.dataset.id] = cm;\n });\n\n // Set the page item if any.\n this._refreshPageItem({element: state.course, state});\n\n // Configure Aria Tree.\n this.contentTree = new ContentTree(this.element, this.selectors, this.reactive.isEditing);\n }\n\n getWatchers() {\n return [\n {watch: `section.indexcollapsed:updated`, handler: this._refreshSectionCollapsed},\n {watch: `cm:created`, handler: this._createCm},\n {watch: `cm:deleted`, handler: this._deleteCm},\n {watch: `section:created`, handler: this._createSection},\n {watch: `section:deleted`, handler: this._deleteSection},\n {watch: `course.pageItem:created`, handler: this._refreshPageItem},\n {watch: `course.pageItem:updated`, handler: this._refreshPageItem},\n // Sections and cm sorting.\n {watch: `course.sectionlist:updated`, handler: this._refreshCourseSectionlist},\n {watch: `section.cmlist:updated`, handler: this._refreshSectionCmlist},\n ];\n }\n\n /**\n * Setup sections toggler.\n *\n * Toggler click is delegated to the main course index element because new sections can\n * appear at any moment and this way we prevent accidental double bindings.\n *\n * @param {Event} event the triggered event\n */\n _sectionTogglers(event) {\n const sectionlink = event.target.closest(this.selectors.TOGGLER);\n const isChevron = event.target.closest(this.selectors.COLLAPSE);\n\n if (sectionlink || isChevron) {\n\n const section = event.target.closest(this.selectors.SECTION);\n const toggler = section.querySelector(this.selectors.COLLAPSE);\n const isCollapsed = toggler?.classList.contains(this.classes.COLLAPSED) ?? false;\n\n if (isChevron || isCollapsed) {\n // Update the state.\n const sectionId = section.getAttribute('data-id');\n this.reactive.dispatch(\n 'sectionIndexCollapsed',\n [sectionId],\n !isCollapsed\n );\n }\n }\n }\n\n /**\n * Update section collapsed.\n *\n * @param {object} args\n * @param {object} args.element The leement to be expanded\n */\n _refreshSectionCollapsed({element}) {\n const target = this.getElement(this.selectors.SECTION, element.id);\n if (!target) {\n throw new Error(`Unkown section with ID ${element.id}`);\n }\n // Check if it is already done.\n const toggler = target.querySelector(this.selectors.COLLAPSE);\n const isCollapsed = toggler?.classList.contains(this.classes.COLLAPSED) ?? false;\n\n if (element.indexcollapsed !== isCollapsed) {\n this._expandSectionNode(element);\n }\n }\n\n /**\n * Expand a section node.\n *\n * By default the method will use element.indexcollapsed to decide if the\n * section is opened or closed. However, using forceValue it is possible\n * to open or close a section independant from the indexcollapsed attribute.\n *\n * @param {Object} element the course module state element\n * @param {boolean} forceValue optional forced expanded value\n */\n _expandSectionNode(element, forceValue) {\n const target = this.getElement(this.selectors.SECTION, element.id);\n const toggler = target.querySelector(this.selectors.COLLAPSE);\n let collapsibleId = toggler.dataset.target ?? toggler.getAttribute(\"href\");\n if (!collapsibleId) {\n return;\n }\n collapsibleId = collapsibleId.replace('#', '');\n const collapsible = document.getElementById(collapsibleId);\n if (!collapsible) {\n return;\n }\n\n if (forceValue === undefined) {\n forceValue = (element.indexcollapsed) ? false : true;\n }\n\n // Course index is based on Bootstrap 4 collapsibles. To collapse them we need jQuery to\n // interact with collapsibles methods. Hopefully, this will change in Bootstrap 5 because\n // it does not require jQuery anymore (when MDL-71979 is integrated).\n const togglerValue = (forceValue) ? 'show' : 'hide';\n jQuery(collapsible).collapse(togglerValue);\n }\n\n /**\n * Handle a page item update.\n *\n * @param {Object} details the update details\n * @param {Object} details.state the state data.\n * @param {Object} details.element the course state data.\n */\n _refreshPageItem({element, state}) {\n if (!element?.pageItem?.isStatic || element.pageItem.type != 'cm') {\n return;\n }\n // Check if we need to uncollapse the section and scroll to the element.\n const section = state.section.get(element.pageItem.sectionId);\n if (section.indexcollapsed) {\n this._expandSectionNode(section, true);\n setTimeout(\n () => this.cms[element.pageItem.id]?.scrollIntoView({block: \"nearest\"}),\n 250\n );\n }\n }\n\n /**\n * Create a newcm instance.\n *\n * @param {object} param\n * @param {Object} param.state\n * @param {Object} param.element\n */\n async _createCm({state, element}) {\n // Create a fake node while the component is loading.\n const fakeelement = document.createElement('li');\n fakeelement.classList.add('bg-pulse-grey', 'w-100');\n fakeelement.innerHTML = ' ';\n this.cms[element.id] = fakeelement;\n // Place the fake node on the correct position.\n this._refreshSectionCmlist({\n state,\n element: state.section.get(element.sectionid),\n });\n // Collect render data.\n const exporter = this.reactive.getExporter();\n const data = exporter.cm(state, element);\n // Create the new content.\n const newcomponent = await this.renderComponent(fakeelement, 'core_courseformat/local/courseindex/cm', data);\n // Replace the fake node with the real content.\n const newelement = newcomponent.getElement();\n this.cms[element.id] = newelement;\n fakeelement.parentNode.replaceChild(newelement, fakeelement);\n }\n\n /**\n * Create a new section instance.\n *\n * @param {Object} details the update details.\n * @param {Object} details.state the state data.\n * @param {Object} details.element the element data.\n */\n async _createSection({state, element}) {\n // Create a fake node while the component is loading.\n const fakeelement = document.createElement('div');\n fakeelement.classList.add('bg-pulse-grey', 'w-100');\n fakeelement.innerHTML = ' ';\n this.sections[element.id] = fakeelement;\n // Place the fake node on the correct position.\n this._refreshCourseSectionlist({\n state,\n element: state.course,\n });\n // Collect render data.\n const exporter = this.reactive.getExporter();\n const data = exporter.section(state, element);\n // Create the new content.\n const newcomponent = await this.renderComponent(fakeelement, 'core_courseformat/local/courseindex/section', data);\n // Replace the fake node with the real content.\n const newelement = newcomponent.getElement();\n this.sections[element.id] = newelement;\n fakeelement.parentNode.replaceChild(newelement, fakeelement);\n }\n\n /**\n * Refresh a section cm list.\n *\n * @param {object} param\n * @param {Object} param.element\n */\n _refreshSectionCmlist({element}) {\n const cmlist = element.cmlist ?? [];\n const listparent = this.getElement(this.selectors.SECTION_CMLIST, element.id);\n this._fixOrder(listparent, cmlist, this.cms);\n }\n\n /**\n * Refresh the section list.\n *\n * @param {object} param\n * @param {Object} param.element\n */\n _refreshCourseSectionlist({element}) {\n const sectionlist = element.sectionlist ?? [];\n this._fixOrder(this.element, sectionlist, this.sections);\n }\n\n /**\n * Fix/reorder the section or cms order.\n *\n * @param {Element} container the HTML element to reorder.\n * @param {Array} neworder an array with the ids order\n * @param {Array} allitems the list of html elements that can be placed in the container\n */\n _fixOrder(container, neworder, allitems) {\n\n // Empty lists should not be visible.\n if (!neworder.length) {\n container.classList.add('hidden');\n container.innerHTML = '';\n return;\n }\n\n // Grant the list is visible (in case it was empty).\n container.classList.remove('hidden');\n\n // Move the elements in order at the beginning of the list.\n neworder.forEach((itemid, index) => {\n const item = allitems[itemid];\n // Get the current element at that position.\n const currentitem = container.children[index];\n if (currentitem === undefined) {\n container.append(item);\n return;\n }\n if (currentitem !== item) {\n container.insertBefore(item, currentitem);\n }\n });\n // Remove the remaining elements.\n while (container.children.length > neworder.length) {\n container.removeChild(container.lastChild);\n }\n }\n\n /**\n * Remove a cm from the list.\n *\n * The actual DOM element removal is delegated to the cm component.\n *\n * @param {object} param\n * @param {Object} param.element\n */\n _deleteCm({element}) {\n delete this.cms[element.id];\n }\n\n /**\n * Remove a section from the list.\n *\n * The actual DOM element removal is delegated to the section component.\n *\n * @param {Object} details the update details.\n * @param {Object} details.element the element data.\n */\n _deleteSection({element}) {\n delete this.sections[element.id];\n }\n}\n"],"names":["Component","BaseComponent","create","name","selectors","SECTION","SECTION_CMLIST","CM","TOGGLER","COLLAPSE","DRAWER","classes","SECTIONHIDDEN","CMHIDDEN","SECTIONCURRENT","COLLAPSED","SHOW","sections","cms","target","this","element","document","getElementById","reactive","stateReady","state","addEventListener","_sectionTogglers","getElements","forEach","section","dataset","id","cm","_refreshPageItem","course","contentTree","ContentTree","isEditing","getWatchers","watch","handler","_refreshSectionCollapsed","_createCm","_deleteCm","_createSection","_deleteSection","_refreshCourseSectionlist","_refreshSectionCmlist","event","sectionlink","closest","isChevron","toggler","querySelector","isCollapsed","classList","contains","sectionId","getAttribute","dispatch","getElement","Error","indexcollapsed","_expandSectionNode","forceValue","collapsibleId","replace","collapsible","undefined","togglerValue","collapse","pageItem","_element$pageItem","isStatic","type","get","setTimeout","_this$cms$element$pag","scrollIntoView","block","fakeelement","createElement","add","innerHTML","sectionid","data","getExporter","newelement","renderComponent","parentNode","replaceChild","cmlist","listparent","_fixOrder","sectionlist","container","neworder","allitems","length","remove","itemid","index","item","currentitem","children","insertBefore","append","removeChild","lastChild"],"mappings":"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"} \ No newline at end of file diff --git a/course/format/amd/build/local/courseindex/drawer.min.js b/course/format/amd/build/local/courseindex/drawer.min.js index 6bb11bbab63..cf5bcc7c034 100644 --- a/course/format/amd/build/local/courseindex/drawer.min.js +++ b/course/format/amd/build/local/courseindex/drawer.min.js @@ -10,6 +10,6 @@ define("core_courseformat/local/courseindex/drawer",["exports","core/reactive"," * @copyright 2021 Ferran Recio * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class Component extends _reactive.BaseComponent{create(){this.name="courseindex-drawer"}static init(target,selectors){return new Component({element:document.getElementById(target),reactive:(0,_courseeditor.getCurrentCourseEditor)(),selectors:selectors})}}return _exports.default=Component,_exports.default})); +class Component extends _reactive.BaseComponent{create(){this.name="courseindex-drawer"}static init(target,selectors){return new this({element:document.getElementById(target),reactive:(0,_courseeditor.getCurrentCourseEditor)(),selectors:selectors})}}return _exports.default=Component,_exports.default})); //# sourceMappingURL=drawer.min.js.map \ No newline at end of file diff --git a/course/format/amd/build/local/courseindex/drawer.min.js.map b/course/format/amd/build/local/courseindex/drawer.min.js.map index b4a3420366d..2100f4a4617 100644 --- a/course/format/amd/build/local/courseindex/drawer.min.js.map +++ b/course/format/amd/build/local/courseindex/drawer.min.js.map @@ -1 +1 @@ -{"version":3,"file":"drawer.min.js","sources":["../../../src/local/courseindex/drawer.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 * Course index drawer wrap.\n *\n * This component is mostly used to ensure all subcomponents find a parent\n * compoment with a reactive instance defined.\n *\n * @module core_courseformat/local/courseindex/drawer\n * @class core_courseformat/local/courseindex/drawer\n * @copyright 2021 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';\n\nexport default class Component extends BaseComponent {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'courseindex-drawer';\n }\n\n /**\n * Static method to create a component instance form the mustache template.\n *\n * @param {element|string} target the DOM main element or its ID\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n return new Component({\n element: document.getElementById(target),\n reactive: getCurrentCourseEditor(),\n selectors,\n });\n }\n}\n"],"names":["Component","BaseComponent","create","name","target","selectors","element","document","getElementById","reactive"],"mappings":";;;;;;;;;;;;MA8BqBA,kBAAkBC,wBAKnCC,cAESC,KAAO,iCAUJC,OAAQC,kBACT,IAAIL,UAAU,CACjBM,QAASC,SAASC,eAAeJ,QACjCK,UAAU,0CACVJ,UAAAA"} \ No newline at end of file +{"version":3,"file":"drawer.min.js","sources":["../../../src/local/courseindex/drawer.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 * Course index drawer wrap.\n *\n * This component is mostly used to ensure all subcomponents find a parent\n * compoment with a reactive instance defined.\n *\n * @module core_courseformat/local/courseindex/drawer\n * @class core_courseformat/local/courseindex/drawer\n * @copyright 2021 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';\n\nexport default class Component extends BaseComponent {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'courseindex-drawer';\n }\n\n /**\n * Static method to create a component instance form the mustache template.\n *\n * @param {element|string} target the DOM main element or its ID\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n return new this({\n element: document.getElementById(target),\n reactive: getCurrentCourseEditor(),\n selectors,\n });\n }\n}\n"],"names":["Component","BaseComponent","create","name","target","selectors","this","element","document","getElementById","reactive"],"mappings":";;;;;;;;;;;;MA8BqBA,kBAAkBC,wBAKnCC,cAESC,KAAO,iCAUJC,OAAQC,kBACT,IAAIC,KAAK,CACZC,QAASC,SAASC,eAAeL,QACjCM,UAAU,0CACVL,UAAAA"} \ No newline at end of file diff --git a/course/format/amd/build/local/courseindex/placeholder.min.js b/course/format/amd/build/local/courseindex/placeholder.min.js index 972147ab2d1..7cb8ff3d8bf 100644 --- a/course/format/amd/build/local/courseindex/placeholder.min.js +++ b/course/format/amd/build/local/courseindex/placeholder.min.js @@ -6,6 +6,6 @@ define("core_courseformat/local/courseindex/placeholder",["exports","core/reacti * @class core_courseformat/local/courseindex/placeholder * @copyright 2021 Ferran Recio * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_templates=_interopRequireDefault(_templates),_pending=_interopRequireDefault(_pending);class Component extends _reactive.BaseComponent{static init(target,selectors){return new Component({element:document.getElementById(target),reactive:(0,_courseeditor.getCurrentCourseEditor)(),selectors:selectors})}create(){this.pendingContent=new _pending.default("core_courseformat/placeholder:loadcourseindex")}async stateReady(state){this.loadStaticContent()||await this.loadTemplateContent(state)}loadStaticContent(){const index=this.reactive.getStorageValue("courseIndex");return!(!index.html||!index.js)&&(_templates.default.replaceNode(this.element,index.html,index.js),this.pendingContent.resolve(),!0)}async loadTemplateContent(state){const data=this.reactive.getExporter().course(state);try{const{html:html,js:js}=await _templates.default.renderForPromise("core_courseformat/local/courseindex/courseindex",data);_templates.default.replaceNode(this.element,html,js),this.pendingContent.resolve(),this.reactive.setStorageValue("courseIndex",{html:html,js:js})}catch(error){throw this.pendingContent.resolve(error),error}}}return _exports.default=Component,_exports.default})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_templates=_interopRequireDefault(_templates),_pending=_interopRequireDefault(_pending);class Component extends _reactive.BaseComponent{static init(target,selectors){return new this({element:document.getElementById(target),reactive:(0,_courseeditor.getCurrentCourseEditor)(),selectors:selectors})}create(){this.pendingContent=new _pending.default("core_courseformat/placeholder:loadcourseindex")}async stateReady(state){this.loadStaticContent()||await this.loadTemplateContent(state)}loadStaticContent(){const index=this.reactive.getStorageValue("courseIndex");return!(!index.html||!index.js)&&(_templates.default.replaceNode(this.element,index.html,index.js),this.pendingContent.resolve(),!0)}async loadTemplateContent(state){const data=this.reactive.getExporter().course(state);try{const{html:html,js:js}=await _templates.default.renderForPromise("core_courseformat/local/courseindex/courseindex",data);_templates.default.replaceNode(this.element,html,js),this.pendingContent.resolve(),this.reactive.setStorageValue("courseIndex",{html:html,js:js})}catch(error){throw this.pendingContent.resolve(error),error}}}return _exports.default=Component,_exports.default})); //# sourceMappingURL=placeholder.min.js.map \ No newline at end of file diff --git a/course/format/amd/build/local/courseindex/placeholder.min.js.map b/course/format/amd/build/local/courseindex/placeholder.min.js.map index b3ca30b1911..740d0308155 100644 --- a/course/format/amd/build/local/courseindex/placeholder.min.js.map +++ b/course/format/amd/build/local/courseindex/placeholder.min.js.map @@ -1 +1 @@ -{"version":3,"file":"placeholder.min.js","sources":["../../../src/local/courseindex/placeholder.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 * Course index placeholder replacer.\n *\n * @module core_courseformat/local/courseindex/placeholder\n * @class core_courseformat/local/courseindex/placeholder\n * @copyright 2021 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {BaseComponent} from 'core/reactive';\nimport Templates from 'core/templates';\nimport {getCurrentCourseEditor} from 'core_courseformat/courseeditor';\nimport Pending from 'core/pending';\n\nexport default class Component extends BaseComponent {\n\n /**\n * Static method to create a component instance form the mustache template.\n *\n * @param {element|string} target the DOM main element or its ID\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n return new Component({\n element: document.getElementById(target),\n reactive: getCurrentCourseEditor(),\n selectors,\n });\n }\n\n /**\n * Component creation hook.\n */\n create() {\n // Add a pending operation waiting for the initial content.\n this.pendingContent = new Pending(`core_courseformat/placeholder:loadcourseindex`);\n }\n\n /**\n * Initial state ready method.\n *\n * This stateReady to be async because it loads the real courseindex.\n *\n * @param {object} state the initial state\n */\n async stateReady(state) {\n\n // Check if we have a static course index already loded from a previous page.\n if (!this.loadStaticContent()) {\n await this.loadTemplateContent(state);\n }\n }\n\n /**\n * Load the course index from the session storage if any.\n *\n * @return {boolean} true if the static version is loaded form the session\n */\n loadStaticContent() {\n // Load the previous static course index from the session cache.\n const index = this.reactive.getStorageValue(`courseIndex`);\n if (index.html && index.js) {\n Templates.replaceNode(this.element, index.html, index.js);\n this.pendingContent.resolve();\n return true;\n }\n return false;\n }\n\n /**\n * Load the course index template.\n *\n * @param {Object} state the initial state\n */\n async loadTemplateContent(state) {\n // Collect section information from the state.\n const exporter = this.reactive.getExporter();\n const data = exporter.course(state);\n try {\n // To render an HTML into our component we just use the regular Templates module.\n const {html, js} = await Templates.renderForPromise(\n 'core_courseformat/local/courseindex/courseindex',\n data,\n );\n Templates.replaceNode(this.element, html, js);\n this.pendingContent.resolve();\n\n // Save the rendered template into the session cache.\n this.reactive.setStorageValue(`courseIndex`, {html, js});\n } catch (error) {\n this.pendingContent.resolve(error);\n throw error;\n }\n }\n}\n"],"names":["Component","BaseComponent","target","selectors","element","document","getElementById","reactive","create","pendingContent","Pending","state","this","loadStaticContent","loadTemplateContent","index","getStorageValue","html","js","replaceNode","resolve","data","getExporter","course","Templates","renderForPromise","setStorageValue","error"],"mappings":";;;;;;;;mLA6BqBA,kBAAkBC,oCASvBC,OAAQC,kBACT,IAAIH,UAAU,CACjBI,QAASC,SAASC,eAAeJ,QACjCK,UAAU,0CACVJ,UAAAA,YAORK,cAESC,eAAiB,IAAIC,mFAUbC,OAGRC,KAAKC,2BACAD,KAAKE,oBAAoBH,OASvCE,0BAEUE,MAAQH,KAAKL,SAASS,wCACxBD,MAAME,OAAQF,MAAMG,yBACVC,YAAYP,KAAKR,QAASW,MAAME,KAAMF,MAAMG,SACjDT,eAAeW,WACb,6BAUWT,aAGhBU,KADWT,KAAKL,SAASe,cACTC,OAAOZ,iBAGnBM,KAACA,KAADC,GAAOA,UAAYM,mBAAUC,iBAC/B,kDACAJ,yBAEMF,YAAYP,KAAKR,QAASa,KAAMC,SACrCT,eAAeW,eAGfb,SAASmB,8BAA+B,CAACT,KAAAA,KAAMC,GAAAA,KACtD,MAAOS,kBACAlB,eAAeW,QAAQO,OACtBA"} \ No newline at end of file +{"version":3,"file":"placeholder.min.js","sources":["../../../src/local/courseindex/placeholder.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 * Course index placeholder replacer.\n *\n * @module core_courseformat/local/courseindex/placeholder\n * @class core_courseformat/local/courseindex/placeholder\n * @copyright 2021 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {BaseComponent} from 'core/reactive';\nimport Templates from 'core/templates';\nimport {getCurrentCourseEditor} from 'core_courseformat/courseeditor';\nimport Pending from 'core/pending';\n\nexport default class Component extends BaseComponent {\n\n /**\n * Static method to create a component instance form the mustache template.\n *\n * @param {element|string} target the DOM main element or its ID\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n return new this({\n element: document.getElementById(target),\n reactive: getCurrentCourseEditor(),\n selectors,\n });\n }\n\n /**\n * Component creation hook.\n */\n create() {\n // Add a pending operation waiting for the initial content.\n this.pendingContent = new Pending(`core_courseformat/placeholder:loadcourseindex`);\n }\n\n /**\n * Initial state ready method.\n *\n * This stateReady to be async because it loads the real courseindex.\n *\n * @param {object} state the initial state\n */\n async stateReady(state) {\n\n // Check if we have a static course index already loded from a previous page.\n if (!this.loadStaticContent()) {\n await this.loadTemplateContent(state);\n }\n }\n\n /**\n * Load the course index from the session storage if any.\n *\n * @return {boolean} true if the static version is loaded form the session\n */\n loadStaticContent() {\n // Load the previous static course index from the session cache.\n const index = this.reactive.getStorageValue(`courseIndex`);\n if (index.html && index.js) {\n Templates.replaceNode(this.element, index.html, index.js);\n this.pendingContent.resolve();\n return true;\n }\n return false;\n }\n\n /**\n * Load the course index template.\n *\n * @param {Object} state the initial state\n */\n async loadTemplateContent(state) {\n // Collect section information from the state.\n const exporter = this.reactive.getExporter();\n const data = exporter.course(state);\n try {\n // To render an HTML into our component we just use the regular Templates module.\n const {html, js} = await Templates.renderForPromise(\n 'core_courseformat/local/courseindex/courseindex',\n data,\n );\n Templates.replaceNode(this.element, html, js);\n this.pendingContent.resolve();\n\n // Save the rendered template into the session cache.\n this.reactive.setStorageValue(`courseIndex`, {html, js});\n } catch (error) {\n this.pendingContent.resolve(error);\n throw error;\n }\n }\n}\n"],"names":["Component","BaseComponent","target","selectors","this","element","document","getElementById","reactive","create","pendingContent","Pending","state","loadStaticContent","loadTemplateContent","index","getStorageValue","html","js","replaceNode","resolve","data","getExporter","course","Templates","renderForPromise","setStorageValue","error"],"mappings":";;;;;;;;mLA6BqBA,kBAAkBC,oCASvBC,OAAQC,kBACT,IAAIC,KAAK,CACZC,QAASC,SAASC,eAAeL,QACjCM,UAAU,0CACVL,UAAAA,YAORM,cAESC,eAAiB,IAAIC,mFAUbC,OAGRR,KAAKS,2BACAT,KAAKU,oBAAoBF,OASvCC,0BAEUE,MAAQX,KAAKI,SAASQ,wCACxBD,MAAME,OAAQF,MAAMG,yBACVC,YAAYf,KAAKC,QAASU,MAAME,KAAMF,MAAMG,SACjDR,eAAeU,WACb,6BAUWR,aAGhBS,KADWjB,KAAKI,SAASc,cACTC,OAAOX,iBAGnBK,KAACA,KAADC,GAAOA,UAAYM,mBAAUC,iBAC/B,kDACAJ,yBAEMF,YAAYf,KAAKC,QAASY,KAAMC,SACrCR,eAAeU,eAGfZ,SAASkB,8BAA+B,CAACT,KAAAA,KAAMC,GAAAA,KACtD,MAAOS,kBACAjB,eAAeU,QAAQO,OACtBA"} \ No newline at end of file diff --git a/course/format/amd/build/local/courseindex/section.min.js b/course/format/amd/build/local/courseindex/section.min.js index e7ffa75de08..e939d192d68 100644 --- a/course/format/amd/build/local/courseindex/section.min.js +++ b/course/format/amd/build/local/courseindex/section.min.js @@ -8,6 +8,6 @@ define("core_courseformat/local/courseindex/section",["exports","core_courseform * @class core_courseformat/local/courseindex/section * @copyright 2021 Ferran Recio * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_sectiontitle=_interopRequireDefault(_sectiontitle),_dndsection=_interopRequireDefault(_dndsection);class Component extends _dndsection.default{create(){this.name="courseindex_section",this.selectors={SECTION_ITEM:"[data-for='section_item']",SECTION_TITLE:"[data-for='section_title']",CM_LAST:'[data-for="cm"]:last-child'},this.classes={SECTIONHIDDEN:"dimmed",SECTIONCURRENT:"current",LOCKED:"editinprogress",RESTRICTIONS:"restrictions",PAGEITEM:"pageitem"},this.id=this.element.dataset.id,this.isPageItem=!1}static init(target,selectors){return new Component({element:document.getElementById(target),selectors:selectors})}stateReady(state){this.configState(state);const sectionItem=this.getElement(this.selectors.SECTION_ITEM);if(this.reactive.isEditing&&this.reactive.supportComponents){const titleitem=new _sectiontitle.default({...this,element:sectionItem,fullregion:this.element});this.configDragDrop(titleitem)}const section=state.section.get(this.id);window.location.href==section.sectionurl.replace(/&/g,"&")&&(this.reactive.dispatch("setPageItem","section",this.id),sectionItem.scrollIntoView())}getWatchers(){return[{watch:"section[".concat(this.id,"]:deleted"),handler:this.remove},{watch:"section[".concat(this.id,"]:updated"),handler:this._refreshSection},{watch:"course.pageItem:updated",handler:this._refreshPageItem}]}getLastCm(){return this.getElement(this.selectors.CM_LAST)}_refreshSection(_ref){var _element$hasrestricti,_element$dragging,_element$locked;let{element:element}=_ref;const sectionItem=this.getElement(this.selectors.SECTION_ITEM);sectionItem.classList.toggle(this.classes.SECTIONHIDDEN,!element.visible),sectionItem.classList.toggle(this.classes.RESTRICTIONS,null!==(_element$hasrestricti=element.hasrestrictions)&&void 0!==_element$hasrestricti&&_element$hasrestricti),this.element.classList.toggle(this.classes.SECTIONCURRENT,element.current),this.element.classList.toggle(this.classes.DRAGGING,null!==(_element$dragging=element.dragging)&&void 0!==_element$dragging&&_element$dragging),this.element.classList.toggle(this.classes.LOCKED,null!==(_element$locked=element.locked)&&void 0!==_element$locked&&_element$locked),this.locked=element.locked,this.getElement(this.selectors.SECTION_TITLE).innerHTML=element.title}_refreshPageItem(_ref2){var _element$pageItem,_this$pageItem;let{element:element,state:state}=_ref2;if(!element.pageItem)return;if(element.pageItem.sectionId!==this.id&&this.isPageItem)return this.pageItem=!1,void this.getElement(this.selectors.SECTION_ITEM).classList.remove(this.classes.PAGEITEM);var _element$pageItem2;!state.section.get(this.id).indexcollapsed||null!==(_element$pageItem=element.pageItem)&&void 0!==_element$pageItem&&_element$pageItem.isStatic?this.pageItem="section"==element.pageItem.type&&element.pageItem.id==this.id:this.pageItem=(null===(_element$pageItem2=element.pageItem)||void 0===_element$pageItem2?void 0:_element$pageItem2.sectionId)==this.id;this.getElement(this.selectors.SECTION_ITEM).classList.toggle(this.classes.PAGEITEM,null!==(_this$pageItem=this.pageItem)&&void 0!==_this$pageItem&&_this$pageItem),this.pageItem&&!this.reactive.isEditing&&this.element.scrollIntoView({block:"nearest"})}}return _exports.default=Component,_exports.default})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_sectiontitle=_interopRequireDefault(_sectiontitle),_dndsection=_interopRequireDefault(_dndsection);class Component extends _dndsection.default{create(){this.name="courseindex_section",this.selectors={SECTION_ITEM:"[data-for='section_item']",SECTION_TITLE:"[data-for='section_title']",CM_LAST:'[data-for="cm"]:last-child'},this.classes={SECTIONHIDDEN:"dimmed",SECTIONCURRENT:"current",LOCKED:"editinprogress",RESTRICTIONS:"restrictions",PAGEITEM:"pageitem"},this.id=this.element.dataset.id,this.isPageItem=!1}static init(target,selectors){return new this({element:document.getElementById(target),selectors:selectors})}stateReady(state){this.configState(state);const sectionItem=this.getElement(this.selectors.SECTION_ITEM);if(this.reactive.isEditing&&this.reactive.supportComponents){const titleitem=new _sectiontitle.default({...this,element:sectionItem,fullregion:this.element});this.configDragDrop(titleitem)}const section=state.section.get(this.id);window.location.href==section.sectionurl.replace(/&/g,"&")&&(this.reactive.dispatch("setPageItem","section",this.id),sectionItem.scrollIntoView())}getWatchers(){return[{watch:"section[".concat(this.id,"]:deleted"),handler:this.remove},{watch:"section[".concat(this.id,"]:updated"),handler:this._refreshSection},{watch:"course.pageItem:updated",handler:this._refreshPageItem}]}getLastCm(){return this.getElement(this.selectors.CM_LAST)}_refreshSection(_ref){var _element$hasrestricti,_element$dragging,_element$locked;let{element:element}=_ref;const sectionItem=this.getElement(this.selectors.SECTION_ITEM);sectionItem.classList.toggle(this.classes.SECTIONHIDDEN,!element.visible),sectionItem.classList.toggle(this.classes.RESTRICTIONS,null!==(_element$hasrestricti=element.hasrestrictions)&&void 0!==_element$hasrestricti&&_element$hasrestricti),this.element.classList.toggle(this.classes.SECTIONCURRENT,element.current),this.element.classList.toggle(this.classes.DRAGGING,null!==(_element$dragging=element.dragging)&&void 0!==_element$dragging&&_element$dragging),this.element.classList.toggle(this.classes.LOCKED,null!==(_element$locked=element.locked)&&void 0!==_element$locked&&_element$locked),this.locked=element.locked,this.getElement(this.selectors.SECTION_TITLE).innerHTML=element.title}_refreshPageItem(_ref2){var _element$pageItem,_this$pageItem;let{element:element,state:state}=_ref2;if(!element.pageItem)return;if(element.pageItem.sectionId!==this.id&&this.isPageItem)return this.pageItem=!1,void this.getElement(this.selectors.SECTION_ITEM).classList.remove(this.classes.PAGEITEM);var _element$pageItem2;!state.section.get(this.id).indexcollapsed||null!==(_element$pageItem=element.pageItem)&&void 0!==_element$pageItem&&_element$pageItem.isStatic?this.pageItem="section"==element.pageItem.type&&element.pageItem.id==this.id:this.pageItem=(null===(_element$pageItem2=element.pageItem)||void 0===_element$pageItem2?void 0:_element$pageItem2.sectionId)==this.id;this.getElement(this.selectors.SECTION_ITEM).classList.toggle(this.classes.PAGEITEM,null!==(_this$pageItem=this.pageItem)&&void 0!==_this$pageItem&&_this$pageItem),this.pageItem&&!this.reactive.isEditing&&this.element.scrollIntoView({block:"nearest"})}}return _exports.default=Component,_exports.default})); //# sourceMappingURL=section.min.js.map \ No newline at end of file diff --git a/course/format/amd/build/local/courseindex/section.min.js.map b/course/format/amd/build/local/courseindex/section.min.js.map index d21497a8064..97f5aa2ac3c 100644 --- a/course/format/amd/build/local/courseindex/section.min.js.map +++ b/course/format/amd/build/local/courseindex/section.min.js.map @@ -1 +1 @@ -{"version":3,"file":"section.min.js","sources":["../../../src/local/courseindex/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 * Course index section component.\n *\n * This component is used to control specific course section interactions like drag and drop.\n *\n * @module core_courseformat/local/courseindex/section\n * @class core_courseformat/local/courseindex/section\n * @copyright 2021 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport SectionTitle from 'core_courseformat/local/courseindex/sectiontitle';\nimport DndSection from 'core_courseformat/local/courseeditor/dndsection';\n\nexport default class Component extends DndSection {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'courseindex_section';\n // Default query selectors.\n this.selectors = {\n SECTION_ITEM: `[data-for='section_item']`,\n SECTION_TITLE: `[data-for='section_title']`,\n CM_LAST: `[data-for=\"cm\"]:last-child`,\n };\n // Default classes to toggle on refresh.\n this.classes = {\n SECTIONHIDDEN: 'dimmed',\n SECTIONCURRENT: 'current',\n LOCKED: 'editinprogress',\n RESTRICTIONS: 'restrictions',\n PAGEITEM: 'pageitem',\n };\n\n // We need our id to watch specific events.\n this.id = this.element.dataset.id;\n this.isPageItem = false;\n }\n\n /**\n * Static method to create a component instance form the mustahce template.\n *\n * @param {string} target the DOM main element or its ID\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n return new Component({\n element: document.getElementById(target),\n selectors,\n });\n }\n\n /**\n * Initial state ready method.\n *\n * @param {Object} state the initial state\n */\n stateReady(state) {\n this.configState(state);\n const sectionItem = this.getElement(this.selectors.SECTION_ITEM);\n // Drag and drop is only available for components compatible course formats.\n if (this.reactive.isEditing && this.reactive.supportComponents) {\n // Init the inner dragable element passing the full section as affected region.\n const titleitem = new SectionTitle({\n ...this,\n element: sectionItem,\n fullregion: this.element,\n });\n this.configDragDrop(titleitem);\n }\n // Check if the current url is the section url.\n const section = state.section.get(this.id);\n if (window.location.href == section.sectionurl.replace(/&/g, \"&\")) {\n this.reactive.dispatch('setPageItem', 'section', this.id);\n sectionItem.scrollIntoView();\n }\n }\n\n /**\n * Component watchers.\n *\n * @returns {Array} of watchers\n */\n getWatchers() {\n return [\n {watch: `section[${this.id}]:deleted`, handler: this.remove},\n {watch: `section[${this.id}]:updated`, handler: this._refreshSection},\n {watch: `course.pageItem:updated`, handler: this._refreshPageItem},\n ];\n }\n\n /**\n * Get the last CM element of that section.\n *\n * @returns {element|null}\n */\n getLastCm() {\n return this.getElement(this.selectors.CM_LAST);\n }\n\n /**\n * Update a course index section using the state information.\n *\n * @param {Object} param details the update details.\n * @param {Object} param.element the section element\n */\n _refreshSection({element}) {\n // Update classes.\n const sectionItem = this.getElement(this.selectors.SECTION_ITEM);\n sectionItem.classList.toggle(this.classes.SECTIONHIDDEN, !element.visible);\n sectionItem.classList.toggle(this.classes.RESTRICTIONS, element.hasrestrictions ?? false);\n this.element.classList.toggle(this.classes.SECTIONCURRENT, element.current);\n this.element.classList.toggle(this.classes.DRAGGING, element.dragging ?? false);\n this.element.classList.toggle(this.classes.LOCKED, element.locked ?? false);\n this.locked = element.locked;\n // Update title.\n this.getElement(this.selectors.SECTION_TITLE).innerHTML = element.title;\n }\n\n /**\n * Handle a page item update.\n *\n * @param {Object} details the update details\n * @param {Object} details.state the state data.\n * @param {Object} details.element the course state data.\n */\n _refreshPageItem({element, state}) {\n if (!element.pageItem) {\n return;\n }\n if (element.pageItem.sectionId !== this.id && this.isPageItem) {\n this.pageItem = false;\n this.getElement(this.selectors.SECTION_ITEM).classList.remove(this.classes.PAGEITEM);\n return;\n }\n const section = state.section.get(this.id);\n if (section.indexcollapsed && !element.pageItem?.isStatic) {\n this.pageItem = (element.pageItem?.sectionId == this.id);\n } else {\n this.pageItem = (element.pageItem.type == 'section' && element.pageItem.id == this.id);\n }\n const sectionItem = this.getElement(this.selectors.SECTION_ITEM);\n sectionItem.classList.toggle(this.classes.PAGEITEM, this.pageItem ?? false);\n if (this.pageItem && !this.reactive.isEditing) {\n this.element.scrollIntoView({block: \"nearest\"});\n }\n }\n}\n"],"names":["Component","DndSection","create","name","selectors","SECTION_ITEM","SECTION_TITLE","CM_LAST","classes","SECTIONHIDDEN","SECTIONCURRENT","LOCKED","RESTRICTIONS","PAGEITEM","id","this","element","dataset","isPageItem","target","document","getElementById","stateReady","state","configState","sectionItem","getElement","reactive","isEditing","supportComponents","titleitem","SectionTitle","fullregion","configDragDrop","section","get","window","location","href","sectionurl","replace","dispatch","scrollIntoView","getWatchers","watch","handler","remove","_refreshSection","_refreshPageItem","getLastCm","classList","toggle","visible","hasrestrictions","current","DRAGGING","dragging","locked","innerHTML","title","pageItem","sectionId","indexcollapsed","_element$pageItem","isStatic","type","block"],"mappings":";;;;;;;;;;+LA6BqBA,kBAAkBC,oBAKnCC,cAESC,KAAO,2BAEPC,UAAY,CACbC,yCACAC,2CACAC,2CAGCC,QAAU,CACXC,cAAe,SACfC,eAAgB,UAChBC,OAAQ,iBACRC,aAAc,eACdC,SAAU,iBAITC,GAAKC,KAAKC,QAAQC,QAAQH,QAC1BI,YAAa,cAUVC,OAAQf,kBACT,IAAIJ,UAAU,CACjBgB,QAASI,SAASC,eAAeF,QACjCf,UAAAA,YASRkB,WAAWC,YACFC,YAAYD,aACXE,YAAcV,KAAKW,WAAWX,KAAKX,UAAUC,iBAE/CU,KAAKY,SAASC,WAAab,KAAKY,SAASE,kBAAmB,OAEtDC,UAAY,IAAIC,sBAAa,IAC5BhB,KACHC,QAASS,YACTO,WAAYjB,KAAKC,eAEhBiB,eAAeH,iBAGlBI,QAAUX,MAAMW,QAAQC,IAAIpB,KAAKD,IACnCsB,OAAOC,SAASC,MAAQJ,QAAQK,WAAWC,QAAQ,SAAU,YACxDb,SAASc,SAAS,cAAe,UAAW1B,KAAKD,IACtDW,YAAYiB,kBASpBC,oBACW,CACH,CAACC,wBAAkB7B,KAAKD,gBAAe+B,QAAS9B,KAAK+B,QACrD,CAACF,wBAAkB7B,KAAKD,gBAAe+B,QAAS9B,KAAKgC,iBACrD,CAACH,gCAAkCC,QAAS9B,KAAKiC,mBASzDC,mBACWlC,KAAKW,WAAWX,KAAKX,UAAUG,SAS1CwC,sFAAgB/B,QAACA,oBAEPS,YAAcV,KAAKW,WAAWX,KAAKX,UAAUC,cACnDoB,YAAYyB,UAAUC,OAAOpC,KAAKP,QAAQC,eAAgBO,QAAQoC,SAClE3B,YAAYyB,UAAUC,OAAOpC,KAAKP,QAAQI,2CAAcI,QAAQqC,8EAC3DrC,QAAQkC,UAAUC,OAAOpC,KAAKP,QAAQE,eAAgBM,QAAQsC,cAC9DtC,QAAQkC,UAAUC,OAAOpC,KAAKP,QAAQ+C,mCAAUvC,QAAQwC,+DACxDxC,QAAQkC,UAAUC,OAAOpC,KAAKP,QAAQG,+BAAQK,QAAQyC,yDACtDA,OAASzC,QAAQyC,YAEjB/B,WAAWX,KAAKX,UAAUE,eAAeoD,UAAY1C,QAAQ2C,MAUtEX,iEAAiBhC,QAACA,QAADO,MAAUA,iBAClBP,QAAQ4C,mBAGT5C,QAAQ4C,SAASC,YAAc9C,KAAKD,IAAMC,KAAKG,uBAC1C0C,UAAW,YACXlC,WAAWX,KAAKX,UAAUC,cAAc6C,UAAUJ,OAAO/B,KAAKP,QAAQK,kCAG/DU,MAAMW,QAAQC,IAAIpB,KAAKD,IAC3BgD,0CAAmB9C,QAAQ4C,uCAARG,kBAAkBC,cAGxCJ,SAAqC,WAAzB5C,QAAQ4C,SAASK,MAAqBjD,QAAQ4C,SAAS9C,IAAMC,KAAKD,QAF9E8C,qCAAY5C,QAAQ4C,iEAAUC,YAAa9C,KAAKD,GAIrCC,KAAKW,WAAWX,KAAKX,UAAUC,cACvC6C,UAAUC,OAAOpC,KAAKP,QAAQK,gCAAUE,KAAK6C,oDACrD7C,KAAK6C,WAAa7C,KAAKY,SAASC,gBAC3BZ,QAAQ0B,eAAe,CAACwB,MAAO"} \ No newline at end of file +{"version":3,"file":"section.min.js","sources":["../../../src/local/courseindex/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 * Course index section component.\n *\n * This component is used to control specific course section interactions like drag and drop.\n *\n * @module core_courseformat/local/courseindex/section\n * @class core_courseformat/local/courseindex/section\n * @copyright 2021 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport SectionTitle from 'core_courseformat/local/courseindex/sectiontitle';\nimport DndSection from 'core_courseformat/local/courseeditor/dndsection';\n\nexport default class Component extends DndSection {\n\n /**\n * Constructor hook.\n */\n create() {\n // Optional component name for debugging.\n this.name = 'courseindex_section';\n // Default query selectors.\n this.selectors = {\n SECTION_ITEM: `[data-for='section_item']`,\n SECTION_TITLE: `[data-for='section_title']`,\n CM_LAST: `[data-for=\"cm\"]:last-child`,\n };\n // Default classes to toggle on refresh.\n this.classes = {\n SECTIONHIDDEN: 'dimmed',\n SECTIONCURRENT: 'current',\n LOCKED: 'editinprogress',\n RESTRICTIONS: 'restrictions',\n PAGEITEM: 'pageitem',\n };\n\n // We need our id to watch specific events.\n this.id = this.element.dataset.id;\n this.isPageItem = false;\n }\n\n /**\n * Static method to create a component instance form the mustahce template.\n *\n * @param {string} target the DOM main element or its ID\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n return new this({\n element: document.getElementById(target),\n selectors,\n });\n }\n\n /**\n * Initial state ready method.\n *\n * @param {Object} state the initial state\n */\n stateReady(state) {\n this.configState(state);\n const sectionItem = this.getElement(this.selectors.SECTION_ITEM);\n // Drag and drop is only available for components compatible course formats.\n if (this.reactive.isEditing && this.reactive.supportComponents) {\n // Init the inner dragable element passing the full section as affected region.\n const titleitem = new SectionTitle({\n ...this,\n element: sectionItem,\n fullregion: this.element,\n });\n this.configDragDrop(titleitem);\n }\n // Check if the current url is the section url.\n const section = state.section.get(this.id);\n if (window.location.href == section.sectionurl.replace(/&/g, \"&\")) {\n this.reactive.dispatch('setPageItem', 'section', this.id);\n sectionItem.scrollIntoView();\n }\n }\n\n /**\n * Component watchers.\n *\n * @returns {Array} of watchers\n */\n getWatchers() {\n return [\n {watch: `section[${this.id}]:deleted`, handler: this.remove},\n {watch: `section[${this.id}]:updated`, handler: this._refreshSection},\n {watch: `course.pageItem:updated`, handler: this._refreshPageItem},\n ];\n }\n\n /**\n * Get the last CM element of that section.\n *\n * @returns {element|null}\n */\n getLastCm() {\n return this.getElement(this.selectors.CM_LAST);\n }\n\n /**\n * Update a course index section using the state information.\n *\n * @param {Object} param details the update details.\n * @param {Object} param.element the section element\n */\n _refreshSection({element}) {\n // Update classes.\n const sectionItem = this.getElement(this.selectors.SECTION_ITEM);\n sectionItem.classList.toggle(this.classes.SECTIONHIDDEN, !element.visible);\n sectionItem.classList.toggle(this.classes.RESTRICTIONS, element.hasrestrictions ?? false);\n this.element.classList.toggle(this.classes.SECTIONCURRENT, element.current);\n this.element.classList.toggle(this.classes.DRAGGING, element.dragging ?? false);\n this.element.classList.toggle(this.classes.LOCKED, element.locked ?? false);\n this.locked = element.locked;\n // Update title.\n this.getElement(this.selectors.SECTION_TITLE).innerHTML = element.title;\n }\n\n /**\n * Handle a page item update.\n *\n * @param {Object} details the update details\n * @param {Object} details.state the state data.\n * @param {Object} details.element the course state data.\n */\n _refreshPageItem({element, state}) {\n if (!element.pageItem) {\n return;\n }\n if (element.pageItem.sectionId !== this.id && this.isPageItem) {\n this.pageItem = false;\n this.getElement(this.selectors.SECTION_ITEM).classList.remove(this.classes.PAGEITEM);\n return;\n }\n const section = state.section.get(this.id);\n if (section.indexcollapsed && !element.pageItem?.isStatic) {\n this.pageItem = (element.pageItem?.sectionId == this.id);\n } else {\n this.pageItem = (element.pageItem.type == 'section' && element.pageItem.id == this.id);\n }\n const sectionItem = this.getElement(this.selectors.SECTION_ITEM);\n sectionItem.classList.toggle(this.classes.PAGEITEM, this.pageItem ?? false);\n if (this.pageItem && !this.reactive.isEditing) {\n this.element.scrollIntoView({block: \"nearest\"});\n }\n }\n}\n"],"names":["Component","DndSection","create","name","selectors","SECTION_ITEM","SECTION_TITLE","CM_LAST","classes","SECTIONHIDDEN","SECTIONCURRENT","LOCKED","RESTRICTIONS","PAGEITEM","id","this","element","dataset","isPageItem","target","document","getElementById","stateReady","state","configState","sectionItem","getElement","reactive","isEditing","supportComponents","titleitem","SectionTitle","fullregion","configDragDrop","section","get","window","location","href","sectionurl","replace","dispatch","scrollIntoView","getWatchers","watch","handler","remove","_refreshSection","_refreshPageItem","getLastCm","classList","toggle","visible","hasrestrictions","current","DRAGGING","dragging","locked","innerHTML","title","pageItem","sectionId","indexcollapsed","_element$pageItem","isStatic","type","block"],"mappings":";;;;;;;;;;+LA6BqBA,kBAAkBC,oBAKnCC,cAESC,KAAO,2BAEPC,UAAY,CACbC,yCACAC,2CACAC,2CAGCC,QAAU,CACXC,cAAe,SACfC,eAAgB,UAChBC,OAAQ,iBACRC,aAAc,eACdC,SAAU,iBAITC,GAAKC,KAAKC,QAAQC,QAAQH,QAC1BI,YAAa,cAUVC,OAAQf,kBACT,IAAIW,KAAK,CACZC,QAASI,SAASC,eAAeF,QACjCf,UAAAA,YASRkB,WAAWC,YACFC,YAAYD,aACXE,YAAcV,KAAKW,WAAWX,KAAKX,UAAUC,iBAE/CU,KAAKY,SAASC,WAAab,KAAKY,SAASE,kBAAmB,OAEtDC,UAAY,IAAIC,sBAAa,IAC5BhB,KACHC,QAASS,YACTO,WAAYjB,KAAKC,eAEhBiB,eAAeH,iBAGlBI,QAAUX,MAAMW,QAAQC,IAAIpB,KAAKD,IACnCsB,OAAOC,SAASC,MAAQJ,QAAQK,WAAWC,QAAQ,SAAU,YACxDb,SAASc,SAAS,cAAe,UAAW1B,KAAKD,IACtDW,YAAYiB,kBASpBC,oBACW,CACH,CAACC,wBAAkB7B,KAAKD,gBAAe+B,QAAS9B,KAAK+B,QACrD,CAACF,wBAAkB7B,KAAKD,gBAAe+B,QAAS9B,KAAKgC,iBACrD,CAACH,gCAAkCC,QAAS9B,KAAKiC,mBASzDC,mBACWlC,KAAKW,WAAWX,KAAKX,UAAUG,SAS1CwC,sFAAgB/B,QAACA,oBAEPS,YAAcV,KAAKW,WAAWX,KAAKX,UAAUC,cACnDoB,YAAYyB,UAAUC,OAAOpC,KAAKP,QAAQC,eAAgBO,QAAQoC,SAClE3B,YAAYyB,UAAUC,OAAOpC,KAAKP,QAAQI,2CAAcI,QAAQqC,8EAC3DrC,QAAQkC,UAAUC,OAAOpC,KAAKP,QAAQE,eAAgBM,QAAQsC,cAC9DtC,QAAQkC,UAAUC,OAAOpC,KAAKP,QAAQ+C,mCAAUvC,QAAQwC,+DACxDxC,QAAQkC,UAAUC,OAAOpC,KAAKP,QAAQG,+BAAQK,QAAQyC,yDACtDA,OAASzC,QAAQyC,YAEjB/B,WAAWX,KAAKX,UAAUE,eAAeoD,UAAY1C,QAAQ2C,MAUtEX,iEAAiBhC,QAACA,QAADO,MAAUA,iBAClBP,QAAQ4C,mBAGT5C,QAAQ4C,SAASC,YAAc9C,KAAKD,IAAMC,KAAKG,uBAC1C0C,UAAW,YACXlC,WAAWX,KAAKX,UAAUC,cAAc6C,UAAUJ,OAAO/B,KAAKP,QAAQK,kCAG/DU,MAAMW,QAAQC,IAAIpB,KAAKD,IAC3BgD,0CAAmB9C,QAAQ4C,uCAARG,kBAAkBC,cAGxCJ,SAAqC,WAAzB5C,QAAQ4C,SAASK,MAAqBjD,QAAQ4C,SAAS9C,IAAMC,KAAKD,QAF9E8C,qCAAY5C,QAAQ4C,iEAAUC,YAAa9C,KAAKD,GAIrCC,KAAKW,WAAWX,KAAKX,UAAUC,cACvC6C,UAAUC,OAAOpC,KAAKP,QAAQK,gCAAUE,KAAK6C,oDACrD7C,KAAK6C,WAAa7C,KAAKY,SAASC,gBAC3BZ,QAAQ0B,eAAe,CAACwB,MAAO"} \ No newline at end of file diff --git a/course/format/amd/build/local/courseindex/sectiontitle.min.js b/course/format/amd/build/local/courseindex/sectiontitle.min.js index 0db01f600a6..d605e049dc5 100644 --- a/course/format/amd/build/local/courseindex/sectiontitle.min.js +++ b/course/format/amd/build/local/courseindex/sectiontitle.min.js @@ -8,6 +8,6 @@ define("core_courseformat/local/courseindex/sectiontitle",["exports","core_cours * @class core_courseformat/local/courseindex/sectiontitle * @copyright 2021 Ferran Recio * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_dndsectionitem=(obj=_dndsectionitem)&&obj.__esModule?obj:{default:obj};class Component extends _dndsectionitem.default{create(descriptor){this.name="courseindex_sectiontitle",this.id=descriptor.id,this.section=descriptor.section,this.course=descriptor.course,this.fullregion=descriptor.fullregion,this.section.number>0&&(this.getDraggableData=this._getDraggableData)}static init(target,selectors){return new Component({element:document.getElementById(target),selectors:selectors})}stateReady(state){this.configDragDrop(this.id,state,this.fullregion)}}return _exports.default=Component,_exports.default})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_dndsectionitem=(obj=_dndsectionitem)&&obj.__esModule?obj:{default:obj};class Component extends _dndsectionitem.default{create(descriptor){this.name="courseindex_sectiontitle",this.id=descriptor.id,this.section=descriptor.section,this.course=descriptor.course,this.fullregion=descriptor.fullregion,this.section.number>0&&(this.getDraggableData=this._getDraggableData)}static init(target,selectors){return new this({element:document.getElementById(target),selectors:selectors})}stateReady(state){this.configDragDrop(this.id,state,this.fullregion)}}return _exports.default=Component,_exports.default})); //# sourceMappingURL=sectiontitle.min.js.map \ No newline at end of file diff --git a/course/format/amd/build/local/courseindex/sectiontitle.min.js.map b/course/format/amd/build/local/courseindex/sectiontitle.min.js.map index c840b91d1c3..380f36775a2 100644 --- a/course/format/amd/build/local/courseindex/sectiontitle.min.js.map +++ b/course/format/amd/build/local/courseindex/sectiontitle.min.js.map @@ -1 +1 @@ -{"version":3,"file":"sectiontitle.min.js","sources":["../../../src/local/courseindex/sectiontitle.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 * Course index section title component.\n *\n * This component is used to control specific course section interactions like drag and drop.\n *\n * @module core_courseformat/local/courseindex/sectiontitle\n * @class core_courseformat/local/courseindex/sectiontitle\n * @copyright 2021 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport DndSectionItem from 'core_courseformat/local/courseeditor/dndsectionitem';\n\nexport default class Component extends DndSectionItem {\n\n /**\n * Constructor hook.\n *\n * @param {Object} descriptor\n */\n create(descriptor) {\n // Optional component name for debugging.\n this.name = 'courseindex_sectiontitle';\n\n this.id = descriptor.id;\n this.section = descriptor.section;\n this.course = descriptor.course;\n this.fullregion = descriptor.fullregion;\n\n // Prevent topic zero from being draggable.\n if (this.section.number > 0) {\n this.getDraggableData = this._getDraggableData;\n }\n }\n\n /**\n * Static method to create a component instance form the mustahce template.\n *\n * @param {element|string} target the DOM main element or its ID\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n return new Component({\n element: document.getElementById(target),\n selectors,\n });\n }\n\n /**\n * Initial state ready method.\n *\n * @param {Object} state the initial state\n */\n stateReady(state) {\n this.configDragDrop(this.id, state, this.fullregion);\n }\n}\n"],"names":["Component","DndSectionItem","create","descriptor","name","id","section","course","fullregion","this","number","getDraggableData","_getDraggableData","target","selectors","element","document","getElementById","stateReady","state","configDragDrop"],"mappings":";;;;;;;;;;mKA4BqBA,kBAAkBC,wBAOnCC,OAAOC,iBAEEC,KAAO,gCAEPC,GAAKF,WAAWE,QAChBC,QAAUH,WAAWG,aACrBC,OAASJ,WAAWI,YACpBC,WAAaL,WAAWK,WAGzBC,KAAKH,QAAQI,OAAS,SACjBC,iBAAmBF,KAAKG,+BAWzBC,OAAQC,kBACT,IAAId,UAAU,CACjBe,QAASC,SAASC,eAAeJ,QACjCC,UAAAA,YASRI,WAAWC,YACFC,eAAeX,KAAKJ,GAAIc,MAAOV,KAAKD"} \ No newline at end of file +{"version":3,"file":"sectiontitle.min.js","sources":["../../../src/local/courseindex/sectiontitle.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 * Course index section title component.\n *\n * This component is used to control specific course section interactions like drag and drop.\n *\n * @module core_courseformat/local/courseindex/sectiontitle\n * @class core_courseformat/local/courseindex/sectiontitle\n * @copyright 2021 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport DndSectionItem from 'core_courseformat/local/courseeditor/dndsectionitem';\n\nexport default class Component extends DndSectionItem {\n\n /**\n * Constructor hook.\n *\n * @param {Object} descriptor\n */\n create(descriptor) {\n // Optional component name for debugging.\n this.name = 'courseindex_sectiontitle';\n\n this.id = descriptor.id;\n this.section = descriptor.section;\n this.course = descriptor.course;\n this.fullregion = descriptor.fullregion;\n\n // Prevent topic zero from being draggable.\n if (this.section.number > 0) {\n this.getDraggableData = this._getDraggableData;\n }\n }\n\n /**\n * Static method to create a component instance form the mustahce template.\n *\n * @param {element|string} target the DOM main element or its ID\n * @param {object} selectors optional css selector overrides\n * @return {Component}\n */\n static init(target, selectors) {\n return new this({\n element: document.getElementById(target),\n selectors,\n });\n }\n\n /**\n * Initial state ready method.\n *\n * @param {Object} state the initial state\n */\n stateReady(state) {\n this.configDragDrop(this.id, state, this.fullregion);\n }\n}\n"],"names":["Component","DndSectionItem","create","descriptor","name","id","section","course","fullregion","this","number","getDraggableData","_getDraggableData","target","selectors","element","document","getElementById","stateReady","state","configDragDrop"],"mappings":";;;;;;;;;;mKA4BqBA,kBAAkBC,wBAOnCC,OAAOC,iBAEEC,KAAO,gCAEPC,GAAKF,WAAWE,QAChBC,QAAUH,WAAWG,aACrBC,OAASJ,WAAWI,YACpBC,WAAaL,WAAWK,WAGzBC,KAAKH,QAAQI,OAAS,SACjBC,iBAAmBF,KAAKG,+BAWzBC,OAAQC,kBACT,IAAIL,KAAK,CACZM,QAASC,SAASC,eAAeJ,QACjCC,UAAAA,YASRI,WAAWC,YACFC,eAAeX,KAAKJ,GAAIc,MAAOV,KAAKD"} \ No newline at end of file diff --git a/course/format/amd/src/local/courseindex/cm.js b/course/format/amd/src/local/courseindex/cm.js index eb7906549fd..1a305f8e5c1 100644 --- a/course/format/amd/src/local/courseindex/cm.js +++ b/course/format/amd/src/local/courseindex/cm.js @@ -65,7 +65,7 @@ export default class Component extends DndCmItem { * @return {Component} */ static init(target, selectors) { - return new Component({ + return new this({ element: document.getElementById(target), selectors, }); diff --git a/course/format/amd/src/local/courseindex/courseindex.js b/course/format/amd/src/local/courseindex/courseindex.js index 9590664c17e..a63614ca728 100644 --- a/course/format/amd/src/local/courseindex/courseindex.js +++ b/course/format/amd/src/local/courseindex/courseindex.js @@ -65,7 +65,7 @@ export default class Component extends BaseComponent { * @return {Component} */ static init(target, selectors) { - return new Component({ + return new this({ element: document.getElementById(target), reactive: getCurrentCourseEditor(), selectors, diff --git a/course/format/amd/src/local/courseindex/drawer.js b/course/format/amd/src/local/courseindex/drawer.js index 6a91b378e45..547149307cf 100644 --- a/course/format/amd/src/local/courseindex/drawer.js +++ b/course/format/amd/src/local/courseindex/drawer.js @@ -46,7 +46,7 @@ export default class Component extends BaseComponent { * @return {Component} */ static init(target, selectors) { - return new Component({ + return new this({ element: document.getElementById(target), reactive: getCurrentCourseEditor(), selectors, diff --git a/course/format/amd/src/local/courseindex/placeholder.js b/course/format/amd/src/local/courseindex/placeholder.js index e1c354c1f97..06976cc3e05 100644 --- a/course/format/amd/src/local/courseindex/placeholder.js +++ b/course/format/amd/src/local/courseindex/placeholder.js @@ -37,7 +37,7 @@ export default class Component extends BaseComponent { * @return {Component} */ static init(target, selectors) { - return new Component({ + return new this({ element: document.getElementById(target), reactive: getCurrentCourseEditor(), selectors, diff --git a/course/format/amd/src/local/courseindex/section.js b/course/format/amd/src/local/courseindex/section.js index 4864e3b84b4..a8d4be1acf9 100644 --- a/course/format/amd/src/local/courseindex/section.js +++ b/course/format/amd/src/local/courseindex/section.js @@ -63,7 +63,7 @@ export default class Component extends DndSection { * @return {Component} */ static init(target, selectors) { - return new Component({ + return new this({ element: document.getElementById(target), selectors, }); diff --git a/course/format/amd/src/local/courseindex/sectiontitle.js b/course/format/amd/src/local/courseindex/sectiontitle.js index 12d05eeddd2..e8e8de7b6f4 100644 --- a/course/format/amd/src/local/courseindex/sectiontitle.js +++ b/course/format/amd/src/local/courseindex/sectiontitle.js @@ -56,7 +56,7 @@ export default class Component extends DndSectionItem { * @return {Component} */ static init(target, selectors) { - return new Component({ + return new this({ element: document.getElementById(target), selectors, });