{"version":3,"file":"uppsala.scrollReactor.min.js","names":["define","$","scrollReactor","visabilityThreshold","stickieThreshold","currentRegionSpan","hiddenByFooterAt","init","length","this","window","innerHeight","scrolledTick","scroll","redraw","document","onkeydown","e","event","which","keyCode","timer","setInterval","clearInterval","click","removeClass","parent","addClass","location","hash","preventDefault","addEventListener","handleVisability","handleStickieness","setCurrentLinkInIndex","show","contentBottom","get","getBoundingClientRect","bottom","visabilityTriggerDOM","top","indexBottom","fadeIn","fadeOut","scrollIntoViewDependingOnDirection","element","wrapper","elementRect","wrapperRect","scrollIntoView","lastId","lastTop","headings","toArray","i","itemTop","id","currentListItem","hasClass","stickyMenuWrapper"],"sources":["uppsala.scrollReactor.js"],"mappings":"AAAA,aAGAA,OAAO,CAAC,WAAW,SAAUC,GACzB,IAAIC,EAAgB,CAChBC,oBAAqB,EACrBC,iBAAkB,EAClBC,kBAAmB,EACnBC,iBAAkB,EAElBC,KAAM,WAGF,GAAgD,IAA5CN,EAAE,+BAA+BO,OAArC,CAIAC,KAAKN,oBAAsBO,OAAOC,YAAc,EAGhDF,KAAKL,iBAAmB,GAGxBK,KAAKJ,kBAAoBK,OAAOC,YAAc,EAG9C,IAAIC,EAAe,EACnBX,EAAES,QAAQG,QAAO,aACbD,EACoB,GAAM,GACtBV,EAAcY,QAEtB,IAGAC,SAASC,UAAY,SAAUC,GAG3B,GAAiB,KADiB,iBADlCA,EAAIA,GAAKP,OAAOQ,OACQC,MAAqBF,EAAEE,MAAQF,EAAEG,SAErD,IAAIC,EAAQX,OAAOY,aAAY,WAE3BpB,EAAcY,SAEdJ,OAAOa,cAAcF,EACzB,GAAG,IAEX,EAGApB,EAAE,oBAAoBuB,OAAM,SAAUP,GAClChB,EAAE,qBAAqBwB,YAAY,kBACnCxB,EAAEQ,MAAMiB,SAASC,SAAS,kBAGtBjB,OAAOkB,SAASC,OAASpB,KAAKoB,OAE9BnB,OAAOkB,SAASC,KAAO,GACvBnB,OAAOkB,SAASC,KAAOpB,KAAKoB,KAC5BZ,EAAEa,iBAEV,IAGApB,OAAOqB,iBAAiB,aAActB,KAAKK,QAG3CL,KAAKK,QApDK,CAqDd,EACAA,OAAQ,WAEJZ,EAAc8B,iBAAiB9B,EAAcC,qBAG7CD,EAAc+B,kBAAkB/B,EAAcE,kBAG9CF,EAAcgC,sBAAsBhC,EAAcG,kBACtD,EACA2B,iBAAkB,SAAU7B,GACxB,IAAIgC,GAAO,EAGX,GAA8B,IAA1B1B,KAAKH,iBAAwB,CAC7B,IAAI8B,EAAgBnC,EAAE,YAAYoC,IAAI,GAAGC,wBAAwBC,OAE7D9B,KAAKH,iBAAmB8B,IACxBD,GAAO,EACP1B,KAAKH,iBAAmB,EAGhC,KACK,CAED,IAAIkC,EAAuBvC,EAAE,gDAAgDoC,IAAI,GACjF,GAA6B,OAAzBG,EAEAL,EAD4BK,EAAqBF,wBACpBG,KAAOtC,EAIxC,IAAIuC,EAAczC,EAAE,kBAAkBoC,IAAI,GAAGC,wBAAwBC,OAGjEG,EAFazC,EAAE,YAAYoC,IAAI,GAAGC,wBAAwBC,SAG1DJ,GAAO,EAGP1B,KAAKH,iBAAmBoC,EAEhC,CAEIP,EACAlC,EAAE,kBAAkB0C,SAEpB1C,EAAE,kBAAkB2C,SAG5B,EACAX,kBAAmB,SAAU7B,GACCH,EAAE,cAAcoC,IAAI,GAAGC,wBAAwBG,KAC9CrC,EACvBH,EAAE,kBAAkB0B,SAAS,cAE7B1B,EAAE,kBAAkBwB,YAAY,aACxC,EAEAoB,mCAAoC,SAAUC,EAASC,GACnD,IAAIC,EAAcF,EAAQR,wBACtBW,EAAcF,EAAQT,wBAGtBU,EAAYT,OAASU,EAAYV,QACjCO,EAAQI,gBAAe,GAEvBF,EAAYP,IAAMQ,EAAYR,KAC9BK,EAAQI,gBAEhB,EAEAhB,sBAAuB,SAAU7B,GAI7B,IAHA,IAAI8C,EAAS,GACTC,GAAW,IACXC,EAAWpD,EAAE,uBAAuBqD,UAC/BC,EAAI,EAAGA,EAAIF,EAAS7C,OAAQ+C,IAAK,CACtC,IAAIC,EAAUH,EAASE,GAAGjB,wBAAwBG,IAClD,KAAIe,GAAWnD,GASX,MANImD,EAAUJ,IACVA,EAAUI,EACVL,EAASE,EAASE,GAAGE,GAKjC,CAEA,GAAe,KAAXN,EAAe,CACf,IAAIO,EAAkBzD,EAAE,2BAA6BkD,EAAS,MAAMzB,SAEpE,GAAIgC,EAAgBlD,OAAS,IAAMkD,EAAgBC,SAAS,kBAAmB,CAC3E1D,EAAE,qBAAqBwB,YAAY,kBACnCiC,EAAgB/B,SAAS,kBAEzB,IAAIiC,EAAoB3D,EAAE,kBAAkB,GAC5CQ,KAAKoC,mCAAmCa,EAAgB,GAAIE,EAChE,CACJ,MAEI3D,EAAE,qBAAqBwB,YAAY,iBAE3C,GAGJ,OAAOvB,CACX","ignoreList":[],"sourcesContent":["'use strict';\n\n// Module is originally designed for sticking a rightside index menu to the view of a guide page, so the index menu follows the view when you scroll a long document.\ndefine(['jquery'], function ($) {\n var scrollReactor = {\n visabilityThreshold: 0,\n stickieThreshold: 0,\n currentRegionSpan: 0,\n hiddenByFooterAt: 0,\n\n init: function () {\n\n // disable functionality if in xm or sm viewport size, so scrolling doesent cost performance.\n if ($(\"#js-stickycontainer:visible\").length === 0)\n return;\n\n // length from top of screen, where the first should trigger visability of stickieElement.\n this.visabilityThreshold = window.innerHeight / 8;\n\n // distance from top of screen, where the stickie menu index should apply stickieness (position fixed)\n this.stickieThreshold = 10;\n\n // the top part of the screen that decides what heading display as current in the stickie index.\n this.currentRegionSpan = window.innerHeight / 3;\n\n // one scroll with mouse wheel will generate many (16+) scroll events. Here we limit the number of events we want to react on.\n var scrolledTick = 0;\n $(window).scroll(function () {\n scrolledTick++;\n if ( scrolledTick % 5 === 0) {\n scrollReactor.redraw();\n }\n });\n\n // tab naviagtion does not trigger scroll event, so here we fire a scroll event.\n document.onkeydown = function (e) {\n e = e || window.event;\n var charCode = typeof e.which === \"number\" ? e.which : e.keyCode;\n if (charCode === 9) {\n var timer = window.setInterval(function () {\n\n scrollReactor.redraw();\n\n window.clearInterval(timer);\n }, 150);\n }\n };\n\n // if a link in the stickie index is clicked, display that link as the current paragraph\n $(\"#js-stickybody a\").click(function (e) {\n $(\"li.currentHeading\").removeClass(\"currentHeading\");\n $(this).parent().addClass(\"currentHeading\");\n\n // is the clicked link bookmark the same as the one in the page url?\n if (window.location.hash === this.hash) {\n // then force hashchange event\n window.location.hash = '';\n window.location.hash = this.hash;\n e.preventDefault();\n }\n });\n\n // if a bookmark link is clicked, update view after page has rerendered.\n window.addEventListener(\"hashchange\", this.redraw);\n\n // do redraw based on initial page state\n this.redraw();\n },\n redraw: function () {\n // show/hide asideIndex, based on first section position\n scrollReactor.handleVisability(scrollReactor.visabilityThreshold);\n\n // stick or unstick the stickie index.\n scrollReactor.handleStickieness(scrollReactor.stickieThreshold);\n\n // set current heading in stickie index\n scrollReactor.setCurrentLinkInIndex(scrollReactor.currentRegionSpan);\n },\n handleVisability: function (visabilityThreshold) {\n var show = false;\n\n // we have allready hidden because of scroll to bottom. Should we start showing again?\n if (this.hiddenByFooterAt !== 0) {\n var contentBottom = $(\"#content\").get(0).getBoundingClientRect().bottom;\n\n if (this.hiddenByFooterAt < contentBottom) {\n show = true;\n this.hiddenByFooterAt = 0;\n }\n\n }\n else {\n // check if we should show because of scrolling past the first heading\n var visabilityTriggerDOM = $(\".js-parts ol li:first > div.item-header > h2\").get(0);\n if (visabilityTriggerDOM !== null) {\n var visabilityTriggerRect = visabilityTriggerDOM.getBoundingClientRect();\n show = visabilityTriggerRect.top <= visabilityThreshold;\n }\n\n // should we hide because of scroll to footer?\n var indexBottom = $(\"#js-stickybody\").get(0).getBoundingClientRect().bottom;\n var contentBot = $(\"#content\").get(0).getBoundingClientRect().bottom;\n\n if (indexBottom > contentBot) {\n show = false;\n\n // we can't get bottom of hidden elements, so we save the last known bottom posittion for index\n this.hiddenByFooterAt = indexBottom;\n }\n }\n\n if (show)\n $(\"#js-stickybody\").fadeIn();\n else\n $(\"#js-stickybody\").fadeOut();\n\n\n },\n handleStickieness: function (stickieThreshold) {\n var topOfStickieTrigger = $(\"#js-sticky\").get(0).getBoundingClientRect().top;\n if (topOfStickieTrigger <= stickieThreshold)\n $(\"#js-stickybody\").addClass(\"stickybody\");\n else\n $(\"#js-stickybody\").removeClass(\"stickybody\");\n },\n\n scrollIntoViewDependingOnDirection: function (element, wrapper) {\n var elementRect = element.getBoundingClientRect();\n var wrapperRect = wrapper.getBoundingClientRect();\n\n\n if (elementRect.bottom > wrapperRect.bottom) {\n element.scrollIntoView(false);\n }\n if (elementRect.top < wrapperRect.top) {\n element.scrollIntoView();\n }\n },\n\n setCurrentLinkInIndex: function (currentRegionSpan) {\n var lastId = \"\";\n var lastTop = -1000000;\n var headings = $(\".js-parts > ol > li\").toArray();\n for (var i = 0; i < headings.length; i++) {\n var itemTop = headings[i].getBoundingClientRect().top;\n if (itemTop <= currentRegionSpan) {\n\n // set corresponding heading to selected in the stickie index\n if (itemTop > lastTop) {\n lastTop = itemTop;\n lastId = headings[i].id;\n }\n }\n else\n break;\n }\n\n if (lastId !== \"\") {\n var currentListItem = $(\"#js-stickybody a[href='#\" + lastId + \"']\").parent();\n\n if (currentListItem.length > 0 && !currentListItem.hasClass(\"currentHeading\")) {\n $(\"li.currentHeading\").removeClass(\"currentHeading\");\n currentListItem.addClass(\"currentHeading\");\n\n var stickyMenuWrapper = $(\"#js-stickybody\")[0];\n this.scrollIntoViewDependingOnDirection(currentListItem[0], stickyMenuWrapper);\n }\n }\n else {\n $(\"li.currentHeading\").removeClass(\"currentHeading\");\n }\n }\n };\n\n return scrollReactor;\n});"]}