{"version":3,"file":"section.min.js","sources":["https:\/\/moodle-test3.univ-paris1.fr\/course\/format\/amd\/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: `[data-for='section']`,\n SECTION_ITEM: `[data-for='section_item']`,\n SECTION_TITLE: `[data-for='section_title']`,\n CM_LAST: `[data-for=\"cm\"]:last-child`,\n DND_ALLOWED: `[data-courseindexdndallowed='true']`,\n COLLAPSE: `[data-toggle=\"collapse\"]`,\n TREE_ITEM: `[role=\"treeitem\"]`,\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 OVERLAYBORDERS: 'overlay-preview-borders',\n SHOW: 'show',\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 this._setupExpandedState();\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 && document.querySelector(this.selectors.DND_ALLOWED)) {\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 * Keep the section tree item aria-expanded attribute in sync with its collapsible content.\n *\n * The tree item and the Bootstrap collapsible are not the same element, so the expanded\n * state must be replicated on the tree item to expose it to assistive technologies.\n * For delegated sections the tree item is the activity element wrapping the section.\n *\/\n _setupExpandedState() {\n const treeItem = this.element.closest(this.selectors.TREE_ITEM);\n const toggler = this.getElement(this.selectors.COLLAPSE);\n const collapsibleId = toggler?.dataset.target ?? toggler?.getAttribute('href');\n if (!treeItem || !collapsibleId) {\n return;\n }\n const collapsible = document.getElementById(collapsibleId.replace('#', ''));\n if (!collapsible) {\n return;\n }\n \/\/ The section can be expanded before this component is ready, so the initial\n \/\/ value is taken from the collapsible itself instead of the state.\n this._refreshExpandedState(treeItem, collapsible);\n this.addEventListener(collapsible, 'shown.bs.collapse', () => this._refreshExpandedState(treeItem, collapsible));\n this.addEventListener(collapsible, 'hidden.bs.collapse', () => this._refreshExpandedState(treeItem, collapsible));\n }\n\n \/**\n * Update the tree item aria-expanded attribute using the collapsible current state.\n *\n * @param {Element} treeItem the section tree item element\n * @param {Element} collapsible the section collapsible element\n *\/\n _refreshExpandedState(treeItem, collapsible) {\n treeItem.setAttribute('aria-expanded', collapsible.classList.contains(this.classes.SHOW));\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\n const containsPageItem = this._isPageItemInThisSection(element.pageItem);\n\n if (!containsPageItem || this._isParentSectionIndexCollapsed(state)) {\n this.pageItem = false;\n this.getElement(this.selectors.SECTION_ITEM).classList.remove(this.classes.PAGEITEM);\n return;\n }\n\n const section = state.section.get(this.id);\n if (section.indexcollapsed && !element.pageItem?.isStatic) {\n this.pageItem = containsPageItem;\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 \/**\n * Check if the page item is inside this section.\n *\n * @private\n * @param {Object} pageItem\n * @param {Object} pageItem.sectionId the current page item section id.\n * @returns {boolean}\n *\/\n _isPageItemInThisSection(pageItem) {\n if (pageItem.sectionId == this.id) {\n return true;\n }\n \/\/ Check for any possible subsections.\n const subsection = this.element.querySelector(`${this.selectors.SECTION}[data-id=\"${pageItem.sectionId}\"]`);\n if (subsection) {\n return true;\n }\n return false;\n }\n\n \/**\n * Check if the parent section index is collapsed.\n *\n * @private\n * @param {Object} state the current state\n * @returns {boolean|null} null if no parent section is found.\n *\/\n _isParentSectionIndexCollapsed(state) {\n const parentElement = this.element.parentElement.closest(this.selectors.SECTION);\n if (!parentElement || !parentElement.dataset.id) {\n return null;\n }\n const parentSection = state.section.get(parentElement.dataset.id);\n return !!parentSection.indexcollapsed;\n }\n\n \/**\n * Overridden version of the component addOverlay async method.\n *\n * The course index is not compatible with overlay elements.\n *\/\n async addOverlay() {\n this.element.classList.add(this.classes.OVERLAYBORDERS);\n }\n\n \/**\n * Overridden version of the component removeOverlay.\n *\n * The course index is not compatible with overlay elements.\n *\/\n removeOverlay() {\n this.element.classList.remove(this.classes.OVERLAYBORDERS);\n }\n}\n"],"names":["Component","DndSection","create","name","selectors","SECTION","SECTION_ITEM","SECTION_TITLE","CM_LAST","DND_ALLOWED","COLLAPSE","TREE_ITEM","classes","SECTIONHIDDEN","SECTIONCURRENT","LOCKED","RESTRICTIONS","PAGEITEM","OVERLAYBORDERS","SHOW","id","this","element","dataset","isPageItem","target","document","getElementById","stateReady","state","configState","_setupExpandedState","sectionItem","getElement","reactive","isEditing","supportComponents","querySelector","titleitem","SectionTitle","fullregion","configDragDrop","section","get","window","location","href","sectionurl","replace","dispatch","scrollIntoView","treeItem","closest","toggler","collapsibleId","getAttribute","collapsible","_refreshExpandedState","addEventListener","setAttribute","classList","contains","getWatchers","watch","handler","remove","_refreshSection","_refreshPageItem","getLastCm","toggle","visible","hasrestrictions","current","DRAGGING","dragging","locked","innerHTML","title","pageItem","containsPageItem","_isPageItemInThisSection","_isParentSectionIndexCollapsed","indexcollapsed","_element$pageItem","isStatic","type","block","sectionId","parentElement","add","removeOverlay"],"mappings":";;;;;;;;;;+LA6BqBA,kBAAkBC,oBAKnCC,cAESC,KAAO,2BAEPC,UAAY,CACbC,+BACAC,yCACAC,2CACAC,qCACAC,kDACAC,oCACAC,oCAGCC,QAAU,CACXC,cAAe,SACfC,eAAgB,UAChBC,OAAQ,iBACRC,aAAc,eACdC,SAAU,WACVC,eAAgB,0BAChBC,KAAM,aAILC,GAAKC,KAAKC,QAAQC,QAAQH,QAC1BI,YAAa,cAUVC,OAAQrB,kBACT,IAAIiB,KAAK,CACZC,QAASI,SAASC,eAAeF,QACjCrB,UAAAA,YASRwB,WAAWC,YACFC,YAAYD,YACZE,4BACCC,YAAcX,KAAKY,WAAWZ,KAAKjB,UAAUE,iBAE\/Ce,KAAKa,SAASC,WAAad,KAAKa,SAASE,mBAAqBV,SAASW,cAAchB,KAAKjB,UAAUK,aAAc,OAE5G6B,UAAY,IAAIC,sBAAa,IAC5BlB,KACHC,QAASU,YACTQ,WAAYnB,KAAKC,eAEhBmB,eAAeH,iBAGlBI,QAAUb,MAAMa,QAAQC,IAAItB,KAAKD,IACnCwB,OAAOC,SAASC,MAAQJ,QAAQK,WAAWC,QAAQ,SAAU,YACxDd,SAASe,SAAS,cAAe,UAAW5B,KAAKD,IACtDY,YAAYkB,kBAWpBnB,sDACUoB,SAAW9B,KAAKC,QAAQ8B,QAAQ\/B,KAAKjB,UAAUO,WAC\/C0C,QAAUhC,KAAKY,WAAWZ,KAAKjB,UAAUM,UACzC4C,4CAAgBD,MAAAA,eAAAA,QAAS9B,QAAQE,8DAAU4B,MAAAA,eAAAA,QAASE,aAAa,YAClEJ,WAAaG,2BAGZE,YAAc9B,SAASC,eAAe2B,cAAcN,QAAQ,IAAK,KAClEQ,mBAKAC,sBAAsBN,SAAUK,kBAChCE,iBAAiBF,YAAa,qBAAqB,IAAMnC,KAAKoC,sBAAsBN,SAAUK,oBAC9FE,iBAAiBF,YAAa,sBAAsB,IAAMnC,KAAKoC,sBAAsBN,SAAUK,gBASxGC,sBAAsBN,SAAUK,aAC5BL,SAASQ,aAAa,gBAAiBH,YAAYI,UAAUC,SAASxC,KAAKT,QAAQO,OAQvF2C,oBACW,CACH,CAACC,wBAAkB1C,KAAKD,gBAAe4C,QAAS3C,KAAK4C,QACrD,CAACF,wBAAkB1C,KAAKD,gBAAe4C,QAAS3C,KAAK6C,iBACrD,CAACH,gCAAkCC,QAAS3C,KAAK8C,mBASzDC,mBACW\/C,KAAKY,WAAWZ,KAAKjB,UAAUI,SAS1C0D,sFAAgB5C,QAACA,oBAEPU,YAAcX,KAAKY,WAAWZ,KAAKjB,UAAUE,cACnD0B,YAAY4B,UAAUS,OAAOhD,KAAKT,QAAQC,eAAgBS,QAAQgD,SAClEtC,YAAY4B,UAAUS,OAAOhD,KAAKT,QAAQI,2CAAcM,QAAQiD,8EAC3DjD,QAAQsC,UAAUS,OAAOhD,KAAKT,QAAQE,eAAgBQ,QAAQkD,cAC9DlD,QAAQsC,UAAUS,OAAOhD,KAAKT,QAAQ6D,mCAAUnD,QAAQoD,+DACxDpD,QAAQsC,UAAUS,OAAOhD,KAAKT,QAAQG,+BAAQO,QAAQqD,yDACtDA,OAASrD,QAAQqD,YAEjB1C,WAAWZ,KAAKjB,UAAUG,eAAeqE,UAAYtD,QAAQuD,MAUtEV,iEAAiB7C,QAACA,QAADO,MAAUA,iBAClBP,QAAQwD,sBAIPC,iBAAmB1D,KAAK2D,yBAAyB1D,QAAQwD,cAE1DC,kBAAoB1D,KAAK4D,+BAA+BpD,mBACpDiD,UAAW,YACX7C,WAAWZ,KAAKjB,UAAUE,cAAcsD,UAAUK,OAAO5C,KAAKT,QAAQK,WAI\/DY,MAAMa,QAAQC,IAAItB,KAAKD,IAC3B8D,0CAAmB5D,QAAQwD,uCAARK,kBAAkBC,cAGxCN,SAAqC,WAAzBxD,QAAQwD,SAASO,MAAqB\/D,QAAQwD,SAAS1D,IAAMC,KAAKD,QAF9E0D,SAAWC,iBAIA1D,KAAKY,WAAWZ,KAAKjB,UAAUE,cACvCsD,UAAUS,OAAOhD,KAAKT,QAAQK,gCAAUI,KAAKyD,oDACrDzD,KAAKyD,WAAazD,KAAKa,SAASC,gBAC3Bb,QAAQ4B,eAAe,CAACoC,MAAO,YAY5CN,yBAAyBF,aACjBA,SAASS,WAAalE,KAAKD,UACpB,UAGQC,KAAKC,QAAQe,wBAAiBhB,KAAKjB,UAAUC,6BAAoByE,SAASS,iBAcjGN,+BAA+BpD,aACrB2D,cAAgBnE,KAAKC,QAAQkE,cAAcpC,QAAQ\/B,KAAKjB,UAAUC,aACnEmF,gBAAkBA,cAAcjE,QAAQH,UAClC,aAEWS,MAAMa,QAAQC,IAAI6C,cAAcjE,QAAQH,IACvC8D,uCASlB5D,QAAQsC,UAAU6B,IAAIpE,KAAKT,QAAQM,gBAQ5CwE,qBACSpE,QAAQsC,UAAUK,OAAO5C,KAAKT,QAAQM"}