Mini Shell
{"version":3,"file":"scrollspy.min.js","sources":["../src/scrollspy.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 <http://www.gnu.org/licenses/>.\n\n/**\n * Theme LearnR - JS code scroll-spy\n *\n * @module theme_learnr/scrollspy\n * @copyright 2022 Josha Bartsch <[email protected]>\n * @copyright based on code from theme_fordson by Chris Kenniburg.\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * Runs once at initial load, and once at editmode-switch toggle.\n * Incase of initial load, checks sessionStorage whether a position was set and jumps to the appropriate position.\n *\n * Incase of a click on the switch, iterates over central elements (selector .section.main), determines element\n * with minimal distance between pixel-toprow of view and pixel-toprow of the element.\n * Writes element ID + distance of view from element into session storage.\n *\n * Saving a reference point + relative distance grants leeway for varying page elements.\n * (See original implementation: https://raw.githubusercontent.com/dbnschools/moodle-theme_fordson/master/javascript/scrollspy.js)\n */\nconst initScrollSpy = () => {\n // Unfortunately the editmode-switch carries no unique ID\n let editToggle = document.querySelector('form.editmode-switch-form');\n\n editToggle.addEventListener('click', () => {\n\n window.sessionStorage.setItem('edittoggled', true);\n\n let viewporttop = document.getElementById('page').scrollTop;\n let closest = null;\n let closestoffset = null;\n\n document.querySelectorAll('.section.main').forEach((node) => {\n let thisoffset = node.offsetTop;\n\n if (closest && closest.offsetTop) {\n closestoffset = closest.offsetTop;\n }\n if (closest === null || Math.abs(thisoffset - viewporttop) < Math.abs(closestoffset - viewporttop)) {\n closest = node;\n }\n });\n\n window.sessionStorage.setItem('closestid', closest.id);\n window.sessionStorage.setItem('closestdelta', viewporttop - closest.offsetTop);\n });\n\n let edittoggled = window.sessionStorage.getItem('edittoggled');\n\n if (edittoggled) {\n\n let closestid = window.sessionStorage.getItem('closestid');\n let closestdelta = window.sessionStorage.getItem('closestdelta');\n\n if (closestid && closestdelta) {\n let closest = document.getElementById(closestid);\n let y = closest.offsetTop + parseInt(closestdelta);\n\n document.getElementById('page').scrollTo(0, y);\n }\n\n window.sessionStorage.removeItem('edittoggled');\n window.sessionStorage.removeItem('closestid');\n window.sessionStorage.removeItem('closestdelta');\n }\n};\n\n/**\n * Ensures the passed function will be called after the DOM is ready/loaded:\n * Incase DOM is fully loaded when JS is called, call within next tick.\n * Otherwise sets an eventlistener for DOMEventLoaded\n *\n * @param {*} callback\n */\nconst docReady = (callback) => {\n if (document.readyState === \"complete\" || document.readyState === \"interactive\") {\n setTimeout(callback, 1);\n } else {\n document.addEventListener('DOMContentLoaded', callback);\n }\n};\n\nexport const init = () => {\n docReady(initScrollSpy());\n};\n"],"names":["callback","document","querySelector","addEventListener","window","sessionStorage","setItem","viewporttop","getElementById","scrollTop","closest","closestoffset","querySelectorAll","forEach","node","thisoffset","offsetTop","Math","abs","id","getItem","closestid","closestdelta","y","parseInt","scrollTo","removeItem","initScrollSpy","readyState","setTimeout"],"mappings":"gKAiGoB,KARFA,IAAAA,SAAAA,SAtDI,SAEDC,SAASC,cAAc,6BAE7BC,iBAAiB,SAAS,KAEjCC,OAAOC,eAAeC,QAAQ,eAAe,OAEzCC,YAAcN,SAASO,eAAe,QAAQC,UAC9CC,QAAU,KACVC,cAAgB,KAEpBV,SAASW,iBAAiB,iBAAiBC,SAASC,WAC5CC,WAAaD,KAAKE,UAElBN,SAAWA,QAAQM,YACnBL,cAAgBD,QAAQM,YAEZ,OAAZN,SAAoBO,KAAKC,IAAIH,WAAaR,aAAeU,KAAKC,IAAIP,cAAgBJ,gBAClFG,QAAUI,SAIlBV,OAAOC,eAAeC,QAAQ,YAAaI,QAAQS,IACnDf,OAAOC,eAAeC,QAAQ,eAAgBC,YAAcG,QAAQM,cAGtDZ,OAAOC,eAAee,QAAQ,eAE/B,KAETC,UAAYjB,OAAOC,eAAee,QAAQ,aAC1CE,aAAelB,OAAOC,eAAee,QAAQ,mBAE7CC,WAAaC,aAAc,KAEvBC,EADUtB,SAASO,eAAea,WACtBL,UAAYQ,SAASF,cAErCrB,SAASO,eAAe,QAAQiB,SAAS,EAAGF,GAGhDnB,OAAOC,eAAeqB,WAAW,eACjCtB,OAAOC,eAAeqB,WAAW,aACjCtB,OAAOC,eAAeqB,WAAW,kBAoB5BC,GARmB,aAAxB1B,SAAS2B,YAAqD,gBAAxB3B,SAAS2B,WAC/CC,WAAW7B,SAAU,GAErBC,SAASE,iBAAiB,mBAAoBH"}
Zerion Mini Shell 1.0