').hide();\n $('body').append(fakeNode);\n let fakeElemColor = fakeNode.css('backgroundColor');\n fakeNode.remove();\n\n elem = $(elem);\n while (elem.length && elem[0] !== document) {\n let color = elem.css('backgroundColor');\n if (color !== fakeElemColor) {\n return color;\n }\n elem = elem.parent();\n }\n\n return null;\n }\n\n /**\n * Calculate the inheritted position.\n *\n * @method calculatePosition\n * @param {jQuery} elem The element to calculate position for\n * @return {String} Calculated position\n */\n calculatePosition(elem) {\n elem = $(elem);\n while (elem.length && elem[0] !== document) {\n let position = elem.css('position');\n if (position !== 'static') {\n return position;\n }\n elem = elem.parent();\n }\n\n return null;\n }\n\n /**\n * Perform accessibility changes for step shown.\n *\n * This will add aria-hidden=\"true\" to all siblings and parent siblings.\n *\n * @method accessibilityShow\n */\n accessibilityShow() {\n let stateHolder = 'data-has-hidden';\n let attrName = 'aria-hidden';\n let hideFunction = function(child) {\n let flexitourRole = child.data('flexitour');\n if (flexitourRole) {\n switch (flexitourRole) {\n case 'container':\n case 'target':\n return;\n }\n }\n\n let hidden = child.attr(attrName);\n if (!hidden) {\n child.attr(stateHolder, true);\n Aria.hide(child);\n }\n };\n\n this.currentStepNode.siblings().each(function(index, node) {\n hideFunction($(node));\n });\n this.currentStepNode.parentsUntil('body').siblings().each(function(index, node) {\n hideFunction($(node));\n });\n }\n\n /**\n * Perform accessibility changes for step hidden.\n *\n * This will remove any newly added aria-hidden=\"true\".\n *\n * @method accessibilityHide\n */\n accessibilityHide() {\n let stateHolder = 'data-has-hidden';\n let showFunction = function(child) {\n let hidden = child.attr(stateHolder);\n if (typeof hidden !== 'undefined') {\n child.removeAttr(stateHolder);\n Aria.unhide(child);\n }\n };\n\n $('[' + stateHolder + ']').each(function(index, node) {\n showFunction($(node));\n });\n }\n}\n"],"file":"tour.min.js"}
\ No newline at end of file
+{"version":3,"sources":["../src/tour.js"],"names":["Tour","config","init","eventHandlers","reset","originalConfiguration","configure","apply","arguments","storage","window","sessionStorage","storageKey","tourName","e","hide","resetStepListeners","steps","currentStepNumber","eventName","forEach","handler","addEventHandler","resetStepDefaults","template","templateContent","checkMinimumRequirements","Error","length","loadOriginalConfiguration","stepDefaults","setStepDefaults","$","extend","element","placement","delay","moveOnClick","moveAfterTime","orphan","direction","parseInt","stepNumber","setItem","code","DOMException","QUOTA_EXCEEDED_ERR","removeItem","getCurrentStepNumber","nextStepNumber","isStepPotentiallyVisible","getStepConfig","previousStepNumber","getNextStepNumber","getPreviousStepNumber","stepConfig","isStepActuallyVisible","target","getStepTarget","is","gotoStep","endTour","_gotoStep","delayed","setTimeout","bind","fn","stepRenderEvent","dispatchEvent","eventTypes","stepRender","defaultPrevented","renderStep","stepRendered","normalizeStepConfig","reflex","moveAfterClick","content","body","attachTo","attachPoint","first","detail","cancelable","tour","document","push","listeners","node","currentStepNode","args","proxy","next","previous","handleKeyDown","targetNode","parents","listener","on","off","currentStepConfig","setCurrentStepNumber","getTemplateContent","find","html","title","isFirstStep","prop","isLastStep","removeClass","addClass","attr","addStepToPage","processStepListeners","clone","animationTarget","stop","data","zIndex","calculateZIndex","css","positionBackdrop","append","top","left","animate","scrollTop","calculateScrollTop","promise","then","positionStep","revealStep","catch","isOrphan","offset","calculateStepPositionInPage","currentStepPopper","Popper","removeOnDestroy","arrowElement","modifiers","enabled","applyStyle","onLoad","fadeIn","announceStep","focus","stepId","bodyRegion","headerRegion","accessibilityShow","tabbableSelector","keyCode","hasBackdrop","activeElement","stepTarget","tabbableNodes","dialogContainer","currentIndex","filter","index","has","each","nextIndex","nextNode","focusRelevant","shiftKey","closest","last","preventDefault","call","startAt","storageStartValue","getItem","storageStartAt","tourStartEvent","tourStart","tourRunning","tourStarted","startTour","tourEndEvent","tourEnd","previousTarget","tourEnded","transition","stepHideEvent","stepHide","destroy","fadeTime","remove","removeAttr","fadeOut","currentStepElement","accessibilityHide","stepHidden","viewportHeight","height","Math","max","min","ceil","stepHeight","viewportWidth","width","stepWidth","flipBehavior","flip","behaviour","arrow","onCreate","recalculateArrowPosition","onUpdate","split","isVertical","indexOf","instance","popper","querySelector","stepElement","arrowHeight","parseFloat","getComputedStyle","arrowOffset","popperHeight","popperOffset","popperBorderWidth","popperBorderRadiusWidth","arrowPos","maxPos","minPos","newArrowPos","arrowWidth","popperWidth","background","backdrop","insertAfter","buffer","colorNode","outerWidth","outerHeight","backgroundColor","calculateInherittedBackgroundColor","targetRadius","targetPosition","calculatePosition","fader","opacity","elem","position","value","isNaN","parent","fakeNode","fakeElemColor","color","hideFunction","child","flexitourRole","hidden","Aria","siblings","parentsUntil","showFunction","unhide"],"mappings":"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","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 * A user tour.\n *\n * @module tool_usertours/tour\n * @copyright 2018 Andrew Nicols
\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport * as Aria from 'core/aria';\nimport Popper from 'core/popper';\nimport {dispatchEvent} from 'core/event_dispatcher';\nimport {eventTypes} from './events';\n\n/**\n * A user tour.\n *\n * @class tool_usertours/tour\n * @property {boolean} tourRunning Whether the tour is currently running.\n */\nconst Tour = class {\n tourRunning = false;\n\n /**\n * @param {object} config The configuration object.\n */\n constructor(config) {\n this.init(config);\n }\n\n /**\n * Initialise the tour.\n *\n * @method init\n * @param {Object} config The configuration object.\n * @chainable\n * @return {Object} this.\n */\n init(config) {\n // Unset all handlers.\n this.eventHandlers = {};\n\n // Reset the current tour states.\n this.reset();\n\n // Store the initial configuration.\n this.originalConfiguration = config || {};\n\n // Apply configuration.\n this.configure.apply(this, arguments);\n\n try {\n this.storage = window.sessionStorage;\n this.storageKey = 'tourstate_' + this.tourName;\n } catch (e) {\n this.storage = false;\n this.storageKey = '';\n }\n\n return this;\n }\n\n /**\n * Reset the current tour state.\n *\n * @method reset\n * @chainable\n * @return {Object} this.\n */\n reset() {\n // Hide the current step.\n this.hide();\n\n // Unset all handlers.\n this.eventHandlers = [];\n\n // Unset all listeners.\n this.resetStepListeners();\n\n // Unset the original configuration.\n this.originalConfiguration = {};\n\n // Reset the current step number and list of steps.\n this.steps = [];\n\n // Reset the current step number.\n this.currentStepNumber = 0;\n\n return this;\n }\n\n /**\n * Prepare tour configuration.\n *\n * @method configure\n * @param {Object} config The configuration object.\n * @chainable\n * @return {Object} this.\n */\n configure(config) {\n if (typeof config === 'object') {\n // Tour name.\n if (typeof config.tourName !== 'undefined') {\n this.tourName = config.tourName;\n }\n\n // Set up eventHandlers.\n if (config.eventHandlers) {\n for (let eventName in config.eventHandlers) {\n config.eventHandlers[eventName].forEach(function(handler) {\n this.addEventHandler(eventName, handler);\n }, this);\n }\n }\n\n // Reset the step configuration.\n this.resetStepDefaults(true);\n\n // Configure the steps.\n if (typeof config.steps === 'object') {\n this.steps = config.steps;\n }\n\n if (typeof config.template !== 'undefined') {\n this.templateContent = config.template;\n }\n }\n\n // Check that we have enough to start the tour.\n this.checkMinimumRequirements();\n\n return this;\n }\n\n /**\n * Check that the configuration meets the minimum requirements.\n *\n * @method checkMinimumRequirements\n */\n checkMinimumRequirements() {\n // Need a tourName.\n if (!this.tourName) {\n throw new Error(\"Tour Name required\");\n }\n\n // Need a minimum of one step.\n if (!this.steps || !this.steps.length) {\n throw new Error(\"Steps must be specified\");\n }\n }\n\n /**\n * Reset step default configuration.\n *\n * @method resetStepDefaults\n * @param {Boolean} loadOriginalConfiguration Whether to load the original configuration supplied with the Tour.\n * @chainable\n * @return {Object} this.\n */\n resetStepDefaults(loadOriginalConfiguration) {\n if (typeof loadOriginalConfiguration === 'undefined') {\n loadOriginalConfiguration = true;\n }\n\n this.stepDefaults = {};\n if (!loadOriginalConfiguration || typeof this.originalConfiguration.stepDefaults === 'undefined') {\n this.setStepDefaults({});\n } else {\n this.setStepDefaults(this.originalConfiguration.stepDefaults);\n }\n\n return this;\n }\n\n /**\n * Set the step defaults.\n *\n * @method setStepDefaults\n * @param {Object} stepDefaults The step defaults to apply to all steps\n * @chainable\n * @return {Object} this.\n */\n setStepDefaults(stepDefaults) {\n if (!this.stepDefaults) {\n this.stepDefaults = {};\n }\n $.extend(\n this.stepDefaults,\n {\n element: '',\n placement: 'top',\n delay: 0,\n moveOnClick: false,\n moveAfterTime: 0,\n orphan: false,\n direction: 1,\n },\n stepDefaults\n );\n\n return this;\n }\n\n /**\n * Retrieve the current step number.\n *\n * @method getCurrentStepNumber\n * @return {Number} The current step number\n */\n getCurrentStepNumber() {\n return parseInt(this.currentStepNumber, 10);\n }\n\n /**\n * Store the current step number.\n *\n * @method setCurrentStepNumber\n * @param {Number} stepNumber The current step number\n * @chainable\n */\n setCurrentStepNumber(stepNumber) {\n this.currentStepNumber = stepNumber;\n if (this.storage) {\n try {\n this.storage.setItem(this.storageKey, stepNumber);\n } catch (e) {\n if (e.code === DOMException.QUOTA_EXCEEDED_ERR) {\n this.storage.removeItem(this.storageKey);\n }\n }\n }\n }\n\n /**\n * Get the next step number after the currently displayed step.\n *\n * @method getNextStepNumber\n * @param {Number} stepNumber The current step number\n * @return {Number} The next step number to display\n */\n getNextStepNumber(stepNumber) {\n if (typeof stepNumber === 'undefined') {\n stepNumber = this.getCurrentStepNumber();\n }\n let nextStepNumber = stepNumber + 1;\n\n // Keep checking the remaining steps.\n while (nextStepNumber <= this.steps.length) {\n if (this.isStepPotentiallyVisible(this.getStepConfig(nextStepNumber))) {\n return nextStepNumber;\n }\n nextStepNumber++;\n }\n\n return null;\n }\n\n /**\n * Get the previous step number before the currently displayed step.\n *\n * @method getPreviousStepNumber\n * @param {Number} stepNumber The current step number\n * @return {Number} The previous step number to display\n */\n getPreviousStepNumber(stepNumber) {\n if (typeof stepNumber === 'undefined') {\n stepNumber = this.getCurrentStepNumber();\n }\n let previousStepNumber = stepNumber - 1;\n\n // Keep checking the remaining steps.\n while (previousStepNumber >= 0) {\n if (this.isStepPotentiallyVisible(this.getStepConfig(previousStepNumber))) {\n return previousStepNumber;\n }\n previousStepNumber--;\n }\n\n return null;\n }\n\n /**\n * Is the step the final step number?\n *\n * @method isLastStep\n * @param {Number} stepNumber Step number to test\n * @return {Boolean} Whether the step is the final step\n */\n isLastStep(stepNumber) {\n let nextStepNumber = this.getNextStepNumber(stepNumber);\n\n return nextStepNumber === null;\n }\n\n /**\n * Is the step the first step number?\n *\n * @method isFirstStep\n * @param {Number} stepNumber Step number to test\n * @return {Boolean} Whether the step is the first step\n */\n isFirstStep(stepNumber) {\n let previousStepNumber = this.getPreviousStepNumber(stepNumber);\n\n return previousStepNumber === null;\n }\n\n /**\n * Is this step potentially visible?\n *\n * @method isStepPotentiallyVisible\n * @param {Object} stepConfig The step configuration to normalise\n * @return {Boolean} Whether the step is the potentially visible\n */\n isStepPotentiallyVisible(stepConfig) {\n if (!stepConfig) {\n // Without step config, there can be no step.\n return false;\n }\n\n if (this.isStepActuallyVisible(stepConfig)) {\n // If it is actually visible, it is already potentially visible.\n return true;\n }\n\n if (typeof stepConfig.orphan !== 'undefined' && stepConfig.orphan) {\n // Orphan steps have no target. They are always visible.\n return true;\n }\n\n if (typeof stepConfig.delay !== 'undefined' && stepConfig.delay) {\n // Only return true if the activated has not been used yet.\n return true;\n }\n\n // Not theoretically, or actually visible.\n return false;\n }\n\n /**\n * Is this step actually visible?\n *\n * @method isStepActuallyVisible\n * @param {Object} stepConfig The step configuration to normalise\n * @return {Boolean} Whether the step is actually visible\n */\n isStepActuallyVisible(stepConfig) {\n if (!stepConfig) {\n // Without step config, there can be no step.\n return false;\n }\n\n let target = this.getStepTarget(stepConfig);\n if (target && target.length && target.is(':visible')) {\n // Without a target, there can be no step.\n return !!target.length;\n }\n\n return false;\n }\n\n /**\n * Go to the next step in the tour.\n *\n * @method next\n * @chainable\n * @return {Object} this.\n */\n next() {\n return this.gotoStep(this.getNextStepNumber());\n }\n\n /**\n * Go to the previous step in the tour.\n *\n * @method previous\n * @chainable\n * @return {Object} this.\n */\n previous() {\n return this.gotoStep(this.getPreviousStepNumber(), -1);\n }\n\n /**\n * Go to the specified step in the tour.\n *\n * @method gotoStep\n * @param {Number} stepNumber The step number to display\n * @param {Number} direction Next or previous step\n * @chainable\n * @return {Object} this.\n * @fires tool_usertours/stepRender\n * @fires tool_usertours/stepRendered\n * @fires tool_usertours/stepHide\n * @fires tool_usertours/stepHidden\n */\n gotoStep(stepNumber, direction) {\n if (stepNumber < 0) {\n return this.endTour();\n }\n\n let stepConfig = this.getStepConfig(stepNumber);\n if (stepConfig === null) {\n return this.endTour();\n }\n\n return this._gotoStep(stepConfig, direction);\n }\n\n _gotoStep(stepConfig, direction) {\n if (!stepConfig) {\n return this.endTour();\n }\n\n if (typeof stepConfig.delay !== 'undefined' && stepConfig.delay && !stepConfig.delayed) {\n stepConfig.delayed = true;\n window.setTimeout(this._gotoStep.bind(this), stepConfig.delay, stepConfig, direction);\n\n return this;\n } else if (!stepConfig.orphan && !this.isStepActuallyVisible(stepConfig)) {\n let fn = direction == -1 ? 'getPreviousStepNumber' : 'getNextStepNumber';\n return this.gotoStep(this[fn](stepConfig.stepNumber), direction);\n }\n\n this.hide();\n\n const stepRenderEvent = this.dispatchEvent(eventTypes.stepRender, {stepConfig}, true);\n if (!stepRenderEvent.defaultPrevented) {\n this.renderStep(stepConfig);\n this.dispatchEvent(eventTypes.stepRendered, {stepConfig});\n }\n\n return this;\n }\n\n /**\n * Fetch the normalised step configuration for the specified step number.\n *\n * @method getStepConfig\n * @param {Number} stepNumber The step number to fetch configuration for\n * @return {Object} The step configuration\n */\n getStepConfig(stepNumber) {\n if (stepNumber === null || stepNumber < 0 || stepNumber >= this.steps.length) {\n return null;\n }\n\n // Normalise the step configuration.\n let stepConfig = this.normalizeStepConfig(this.steps[stepNumber]);\n\n // Add the stepNumber to the stepConfig.\n stepConfig = $.extend(stepConfig, {stepNumber: stepNumber});\n\n return stepConfig;\n }\n\n /**\n * Normalise the supplied step configuration.\n *\n * @method normalizeStepConfig\n * @param {Object} stepConfig The step configuration to normalise\n * @return {Object} The normalised step configuration\n */\n normalizeStepConfig(stepConfig) {\n\n if (typeof stepConfig.reflex !== 'undefined' && typeof stepConfig.moveAfterClick === 'undefined') {\n stepConfig.moveAfterClick = stepConfig.reflex;\n }\n\n if (typeof stepConfig.element !== 'undefined' && typeof stepConfig.target === 'undefined') {\n stepConfig.target = stepConfig.element;\n }\n\n if (typeof stepConfig.content !== 'undefined' && typeof stepConfig.body === 'undefined') {\n stepConfig.body = stepConfig.content;\n }\n\n stepConfig = $.extend({}, this.stepDefaults, stepConfig);\n\n stepConfig = $.extend({}, {\n attachTo: stepConfig.target,\n attachPoint: 'after',\n }, stepConfig);\n\n if (stepConfig.attachTo) {\n stepConfig.attachTo = $(stepConfig.attachTo).first();\n }\n\n return stepConfig;\n }\n\n /**\n * Fetch the actual step target from the selector.\n *\n * This should not be called until after any delay has completed.\n *\n * @method getStepTarget\n * @param {Object} stepConfig The step configuration\n * @return {$}\n */\n getStepTarget(stepConfig) {\n if (stepConfig.target) {\n return $(stepConfig.target);\n }\n\n return null;\n }\n\n /**\n * Fire any event handlers for the specified event.\n *\n * @param {String} eventName The name of the event\n * @param {Object} [detail={}] Any additional details to pass into the eveent\n * @param {Boolean} [cancelable=false] Whether preventDefault() can be called\n * @returns {CustomEvent}\n */\n dispatchEvent(\n eventName,\n detail = {},\n cancelable = false\n ) {\n return dispatchEvent(eventName, {\n // Add the tour to the detail.\n tour: this,\n ...detail,\n }, document, {\n cancelable,\n });\n }\n\n /**\n * @method addEventHandler\n * @param {string} eventName The name of the event to listen for\n * @param {function} handler The event handler to call\n * @return {Object} this.\n */\n addEventHandler(eventName, handler) {\n if (typeof this.eventHandlers[eventName] === 'undefined') {\n this.eventHandlers[eventName] = [];\n }\n\n this.eventHandlers[eventName].push(handler);\n\n return this;\n }\n\n /**\n * Process listeners for the step being shown.\n *\n * @method processStepListeners\n * @param {object} stepConfig The configuration for the step\n * @chainable\n * @return {Object} this.\n */\n processStepListeners(stepConfig) {\n this.listeners.push(\n // Next/Previous buttons.\n {\n node: this.currentStepNode,\n args: ['click', '[data-role=\"next\"]', $.proxy(this.next, this)]\n }, {\n node: this.currentStepNode,\n args: ['click', '[data-role=\"previous\"]', $.proxy(this.previous, this)]\n },\n\n // Close and end tour buttons.\n {\n node: this.currentStepNode,\n args: ['click', '[data-role=\"end\"]', $.proxy(this.endTour, this)]\n },\n\n // Click backdrop and hide tour.\n {\n node: $('[data-flexitour=\"backdrop\"]'),\n args: ['click', $.proxy(this.hide, this)]\n },\n\n // Keypresses.\n {\n node: $('body'),\n args: ['keydown', $.proxy(this.handleKeyDown, this)]\n });\n\n if (stepConfig.moveOnClick) {\n var targetNode = this.getStepTarget(stepConfig);\n this.listeners.push({\n node: targetNode,\n args: ['click', $.proxy(function(e) {\n if ($(e.target).parents('[data-flexitour=\"container\"]').length === 0) {\n // Ignore clicks when they are in the flexitour.\n window.setTimeout($.proxy(this.next, this), 500);\n }\n }, this)]\n });\n }\n\n this.listeners.forEach(function(listener) {\n listener.node.on.apply(listener.node, listener.args);\n });\n\n return this;\n }\n\n /**\n * Reset step listeners.\n *\n * @method resetStepListeners\n * @chainable\n * @return {Object} this.\n */\n resetStepListeners() {\n // Stop listening to all external handlers.\n if (this.listeners) {\n this.listeners.forEach(function(listener) {\n listener.node.off.apply(listener.node, listener.args);\n });\n }\n this.listeners = [];\n\n return this;\n }\n\n /**\n * The standard step renderer.\n *\n * @method renderStep\n * @param {Object} stepConfig The step configuration of the step\n * @chainable\n * @return {Object} this.\n */\n renderStep(stepConfig) {\n // Store the current step configuration for later.\n this.currentStepConfig = stepConfig;\n this.setCurrentStepNumber(stepConfig.stepNumber);\n\n // Fetch the template and convert it to a $ object.\n let template = $(this.getTemplateContent());\n\n // Title.\n template.find('[data-placeholder=\"title\"]')\n .html(stepConfig.title);\n\n // Body.\n template.find('[data-placeholder=\"body\"]')\n .html(stepConfig.body);\n\n // Is this the first step?\n if (this.isFirstStep(stepConfig.stepNumber)) {\n template.find('[data-role=\"previous\"]').hide();\n } else {\n template.find('[data-role=\"previous\"]').prop('disabled', false);\n }\n\n // Is this the final step?\n if (this.isLastStep(stepConfig.stepNumber)) {\n template.find('[data-role=\"next\"]').hide();\n template.find('[data-role=\"end\"]').removeClass(\"btn-secondary\").addClass(\"btn-primary\");\n } else {\n template.find('[data-role=\"next\"]').prop('disabled', false);\n }\n\n template.find('[data-role=\"previous\"]').attr('role', 'button');\n template.find('[data-role=\"next\"]').attr('role', 'button');\n template.find('[data-role=\"end\"]').attr('role', 'button');\n\n // Replace the template with the updated version.\n stepConfig.template = template;\n\n // Add to the page.\n this.addStepToPage(stepConfig);\n\n // Process step listeners after adding to the page.\n // This uses the currentNode.\n this.processStepListeners(stepConfig);\n\n return this;\n }\n\n /**\n * Getter for the template content.\n *\n * @method getTemplateContent\n * @return {$}\n */\n getTemplateContent() {\n return $(this.templateContent).clone();\n }\n\n /**\n * Helper to add a step to the page.\n *\n * @method addStepToPage\n * @param {Object} stepConfig The step configuration of the step\n * @chainable\n * @return {Object} this.\n */\n addStepToPage(stepConfig) {\n // Create the stepNode from the template data.\n let currentStepNode = $('')\n .html(stepConfig.template)\n .hide();\n\n // The scroll animation occurs on the body or html.\n let animationTarget = $('body, html')\n .stop(true, true);\n\n if (this.isStepActuallyVisible(stepConfig)) {\n let targetNode = this.getStepTarget(stepConfig);\n\n targetNode.data('flexitour', 'target');\n\n let zIndex = this.calculateZIndex(targetNode);\n if (zIndex) {\n stepConfig.zIndex = zIndex + 1;\n }\n\n if (stepConfig.zIndex) {\n currentStepNode.css('zIndex', stepConfig.zIndex + 1);\n }\n\n // Add the backdrop.\n this.positionBackdrop(stepConfig);\n\n $(document.body).append(currentStepNode);\n this.currentStepNode = currentStepNode;\n\n // Ensure that the step node is positioned.\n // Some situations mean that the value is not properly calculated without this step.\n this.currentStepNode.css({\n top: 0,\n left: 0,\n });\n\n animationTarget\n .animate({\n scrollTop: this.calculateScrollTop(stepConfig),\n }).promise().then(function() {\n this.positionStep(stepConfig);\n this.revealStep(stepConfig);\n return;\n }.bind(this))\n .catch(function() {\n // Silently fail.\n });\n\n } else if (stepConfig.orphan) {\n stepConfig.isOrphan = true;\n\n // This will be appended to the body instead.\n stepConfig.attachTo = $('body').first();\n stepConfig.attachPoint = 'append';\n\n // Add the backdrop.\n this.positionBackdrop(stepConfig);\n\n // This is an orphaned step.\n currentStepNode.addClass('orphan');\n\n // It lives in the body.\n $(document.body).append(currentStepNode);\n this.currentStepNode = currentStepNode;\n\n this.currentStepNode.offset(this.calculateStepPositionInPage());\n this.currentStepNode.css('position', 'fixed');\n\n this.currentStepPopper = new Popper(\n $('body'),\n this.currentStepNode[0], {\n removeOnDestroy: true,\n placement: stepConfig.placement + '-start',\n arrowElement: '[data-role=\"arrow\"]',\n // Empty the modifiers. We've already placed the step and don't want it moved.\n modifiers: {\n hide: {\n enabled: false,\n },\n applyStyle: {\n onLoad: null,\n enabled: false,\n },\n }\n }\n );\n\n this.revealStep(stepConfig);\n }\n\n return this;\n }\n\n /**\n * Make the given step visible.\n *\n * @method revealStep\n * @param {Object} stepConfig The step configuration of the step\n * @chainable\n * @return {Object} this.\n */\n revealStep(stepConfig) {\n // Fade the step in.\n this.currentStepNode.fadeIn('', $.proxy(function() {\n // Announce via ARIA.\n this.announceStep(stepConfig);\n\n // Focus on the current step Node.\n this.currentStepNode.focus();\n window.setTimeout($.proxy(function() {\n // After a brief delay, focus again.\n // There seems to be an issue with Jaws where it only reads the dialogue title initially.\n // This second focus helps it to read the full dialogue.\n if (this.currentStepNode) {\n this.currentStepNode.focus();\n }\n }, this), 100);\n\n }, this));\n\n return this;\n }\n\n /**\n * Helper to announce the step on the page.\n *\n * @method announceStep\n * @param {Object} stepConfig The step configuration of the step\n * @chainable\n * @return {Object} this.\n */\n announceStep(stepConfig) {\n // Setup the step Dialogue as per:\n // * https://www.w3.org/TR/wai-aria-practices/#dialog_nonmodal\n // * https://www.w3.org/TR/wai-aria-practices/#dialog_modal\n\n // Generate an ID for the current step node.\n let stepId = 'tour-step-' + this.tourName + '-' + stepConfig.stepNumber;\n this.currentStepNode.attr('id', stepId);\n\n let bodyRegion = this.currentStepNode.find('[data-placeholder=\"body\"]').first();\n bodyRegion.attr('id', stepId + '-body');\n bodyRegion.attr('role', 'document');\n\n let headerRegion = this.currentStepNode.find('[data-placeholder=\"title\"]').first();\n headerRegion.attr('id', stepId + '-title');\n headerRegion.attr('aria-labelledby', stepId + '-body');\n\n // Generally, a modal dialog has a role of dialog.\n this.currentStepNode.attr('role', 'dialog');\n this.currentStepNode.attr('tabindex', 0);\n this.currentStepNode.attr('aria-labelledby', stepId + '-title');\n this.currentStepNode.attr('aria-describedby', stepId + '-body');\n\n // Configure ARIA attributes on the target.\n let target = this.getStepTarget(stepConfig);\n if (target) {\n if (!target.attr('tabindex')) {\n target.attr('tabindex', 0);\n }\n\n target\n .data('original-describedby', target.attr('aria-describedby'))\n .attr('aria-describedby', stepId + '-body')\n ;\n }\n\n this.accessibilityShow(stepConfig);\n\n return this;\n }\n\n /**\n * Handle key down events.\n *\n * @method handleKeyDown\n * @param {EventFacade} e\n */\n handleKeyDown(e) {\n let tabbableSelector = 'a[href], link[href], [draggable=true], [contenteditable=true], ';\n tabbableSelector += ':input:enabled, [tabindex], button:enabled';\n switch (e.keyCode) {\n case 27:\n this.endTour();\n break;\n\n // 9 == Tab - trap focus for items with a backdrop.\n case 9:\n // Tab must be handled on key up only in this instance.\n (function() {\n if (!this.currentStepConfig.hasBackdrop) {\n // Trapping tab focus is only handled for those steps with a backdrop.\n return;\n }\n\n // Find all tabbable locations.\n let activeElement = $(document.activeElement);\n let stepTarget = this.getStepTarget(this.currentStepConfig);\n let tabbableNodes = $(tabbableSelector);\n let dialogContainer = $('span[data-flexitour=\"container\"]');\n let currentIndex;\n // Filter out element which is not belong to target section or dialogue.\n if (stepTarget) {\n tabbableNodes = tabbableNodes.filter(function(index, element) {\n return stepTarget !== null\n && (stepTarget.has(element).length\n || dialogContainer.has(element).length\n || stepTarget.is(element)\n || dialogContainer.is(element));\n });\n }\n\n // Find index of focusing element.\n tabbableNodes.each(function(index, element) {\n if (activeElement.is(element)) {\n currentIndex = index;\n return false;\n }\n // Keep looping.\n return true;\n });\n\n let nextIndex;\n let nextNode;\n let focusRelevant;\n if (currentIndex != void 0) {\n let direction = 1;\n if (e.shiftKey) {\n direction = -1;\n }\n nextIndex = currentIndex;\n do {\n nextIndex += direction;\n nextNode = $(tabbableNodes[nextIndex]);\n } while (nextNode.length && nextNode.is(':disabled') || nextNode.is(':hidden'));\n if (nextNode.length) {\n // A new f\n focusRelevant = nextNode.closest(stepTarget).length;\n focusRelevant = focusRelevant || nextNode.closest(this.currentStepNode).length;\n } else {\n // Unable to find the target somehow.\n focusRelevant = false;\n }\n }\n\n if (focusRelevant) {\n nextNode.focus();\n } else {\n if (e.shiftKey) {\n // Focus on the last tabbable node in the step.\n this.currentStepNode.find(tabbableSelector).last().focus();\n } else {\n if (this.currentStepConfig.isOrphan) {\n // Focus on the step - there is no target.\n this.currentStepNode.focus();\n } else {\n // Focus on the step target.\n stepTarget.focus();\n }\n }\n }\n e.preventDefault();\n }).call(this);\n break;\n }\n }\n\n /**\n * Start the current tour.\n *\n * @method startTour\n * @param {Number} startAt Which step number to start at. If not specified, starts at the last point.\n * @chainable\n * @return {Object} this.\n * @fires tool_usertours/tourStart\n * @fires tool_usertours/tourStarted\n */\n startTour(startAt) {\n if (this.storage && typeof startAt === 'undefined') {\n let storageStartValue = this.storage.getItem(this.storageKey);\n if (storageStartValue) {\n let storageStartAt = parseInt(storageStartValue, 10);\n if (storageStartAt <= this.steps.length) {\n startAt = storageStartAt;\n }\n }\n }\n\n if (typeof startAt === 'undefined') {\n startAt = this.getCurrentStepNumber();\n }\n\n const tourStartEvent = this.dispatchEvent(eventTypes.tourStart, {startAt}, true);\n if (!tourStartEvent.defaultPrevented) {\n this.gotoStep(startAt);\n this.tourRunning = true;\n this.dispatchEvent(eventTypes.tourStarted, {startAt});\n }\n\n return this;\n }\n\n /**\n * Restart the tour from the beginning, resetting the completionlag.\n *\n * @method restartTour\n * @chainable\n * @return {Object} this.\n */\n restartTour() {\n return this.startTour(0);\n }\n\n /**\n * End the current tour.\n *\n * @method endTour\n * @chainable\n * @return {Object} this.\n * @fires tool_usertours/tourEnd\n * @fires tool_usertours/tourEnded\n */\n endTour() {\n const tourEndEvent = this.dispatchEvent(eventTypes.tourEnd, {}, true);\n if (tourEndEvent.defaultPrevented) {\n return this;\n }\n\n if (this.currentStepConfig) {\n let previousTarget = this.getStepTarget(this.currentStepConfig);\n if (previousTarget) {\n if (!previousTarget.attr('tabindex')) {\n previousTarget.attr('tabindex', '-1');\n }\n previousTarget.focus();\n }\n }\n\n this.hide(true);\n\n this.tourRunning = false;\n this.dispatchEvent(eventTypes.tourEnded);\n\n return this;\n }\n\n /**\n * Hide any currently visible steps.\n *\n * @method hide\n * @param {Bool} transition Animate the visibility change\n * @chainable\n * @return {Object} this.\n * @fires tool_usertours/stepHide\n * @fires tool_usertours/stepHidden\n */\n hide(transition) {\n const stepHideEvent = this.dispatchEvent(eventTypes.stepHide, {}, true);\n if (stepHideEvent.defaultPrevented) {\n return this;\n }\n\n if (this.currentStepNode && this.currentStepNode.length) {\n this.currentStepNode.hide();\n if (this.currentStepPopper) {\n this.currentStepPopper.destroy();\n }\n }\n\n // Restore original target configuration.\n if (this.currentStepConfig) {\n let target = this.getStepTarget(this.currentStepConfig);\n if (target) {\n if (target.data('original-labelledby')) {\n target.attr('aria-labelledby', target.data('original-labelledby'));\n }\n\n if (target.data('original-describedby')) {\n target.attr('aria-describedby', target.data('original-describedby'));\n }\n\n if (target.data('original-tabindex')) {\n target.attr('tabindex', target.data('tabindex'));\n }\n }\n\n // Clear the step configuration.\n this.currentStepConfig = null;\n }\n\n let fadeTime = 0;\n if (transition) {\n fadeTime = 400;\n }\n\n // Remove the backdrop features.\n $('[data-flexitour=\"step-background\"]').remove();\n $('[data-flexitour=\"step-backdrop\"]').removeAttr('data-flexitour');\n $('[data-flexitour=\"backdrop\"]').fadeOut(fadeTime, function() {\n $(this).remove();\n });\n\n // Remove aria-describedby and tabindex attributes.\n if (this.currentStepNode && this.currentStepNode.length) {\n let stepId = this.currentStepNode.attr('id');\n if (stepId) {\n let currentStepElement = '[aria-describedby=\"' + stepId + '-body\"]';\n $(currentStepElement).removeAttr('tabindex');\n $(currentStepElement).removeAttr('aria-describedby');\n }\n }\n\n // Reset the listeners.\n this.resetStepListeners();\n\n this.accessibilityHide();\n\n this.dispatchEvent(eventTypes.stepHidden);\n\n this.currentStepNode = null;\n this.currentStepPopper = null;\n return this;\n }\n\n /**\n * Show the current steps.\n *\n * @method show\n * @chainable\n * @return {Object} this.\n */\n show() {\n // Show the current step.\n let startAt = this.getCurrentStepNumber();\n\n return this.gotoStep(startAt);\n }\n\n /**\n * Return the current step node.\n *\n * @method getStepContainer\n * @return {jQuery}\n */\n getStepContainer() {\n return $(this.currentStepNode);\n }\n\n /**\n * Calculate scrollTop.\n *\n * @method calculateScrollTop\n * @param {Object} stepConfig The step configuration of the step\n * @return {Number}\n */\n calculateScrollTop(stepConfig) {\n let scrollTop = $(window).scrollTop();\n let viewportHeight = $(window).height();\n let targetNode = this.getStepTarget(stepConfig);\n\n if (stepConfig.placement === 'top') {\n // If the placement is top, center scroll at the top of the target.\n scrollTop = targetNode.offset().top - (viewportHeight / 2);\n } else if (stepConfig.placement === 'bottom') {\n // If the placement is bottom, center scroll at the bottom of the target.\n scrollTop = targetNode.offset().top + targetNode.height() - (viewportHeight / 2);\n } else if (targetNode.height() <= (viewportHeight * 0.8)) {\n // If the placement is left/right, and the target fits in the viewport, centre screen on the target\n scrollTop = targetNode.offset().top - ((viewportHeight - targetNode.height()) / 2);\n } else {\n // If the placement is left/right, and the target is bigger than the viewport, set scrollTop to target.top + buffer\n // and change step attachmentTarget to top+.\n scrollTop = targetNode.offset().top - (viewportHeight * 0.2);\n }\n\n // Never scroll over the top.\n scrollTop = Math.max(0, scrollTop);\n\n // Never scroll beyond the bottom.\n scrollTop = Math.min($(document).height() - viewportHeight, scrollTop);\n\n return Math.ceil(scrollTop);\n }\n\n /**\n * Calculate dialogue position for page middle.\n *\n * @method calculateScrollTop\n * @return {Number}\n */\n calculateStepPositionInPage() {\n let viewportHeight = $(window).height();\n let stepHeight = this.currentStepNode.height();\n\n let viewportWidth = $(window).width();\n let stepWidth = this.currentStepNode.width();\n\n return {\n top: Math.ceil((viewportHeight - stepHeight) / 2),\n left: Math.ceil((viewportWidth - stepWidth) / 2)\n };\n }\n\n /**\n * Position the step on the page.\n *\n * @method positionStep\n * @param {Object} stepConfig The step configuration of the step\n * @chainable\n * @return {Object} this.\n */\n positionStep(stepConfig) {\n let content = this.currentStepNode;\n if (!content || !content.length) {\n // Unable to find the step node.\n return this;\n }\n\n let flipBehavior;\n switch (stepConfig.placement) {\n case 'left':\n flipBehavior = ['left', 'right', 'top', 'bottom'];\n break;\n case 'right':\n flipBehavior = ['right', 'left', 'top', 'bottom'];\n break;\n case 'top':\n flipBehavior = ['top', 'bottom', 'right', 'left'];\n break;\n case 'bottom':\n flipBehavior = ['bottom', 'top', 'right', 'left'];\n break;\n default:\n flipBehavior = 'flip';\n break;\n }\n\n let target = this.getStepTarget(stepConfig);\n var config = {\n placement: stepConfig.placement + '-start',\n removeOnDestroy: true,\n modifiers: {\n flip: {\n behaviour: flipBehavior,\n },\n arrow: {\n element: '[data-role=\"arrow\"]',\n },\n },\n onCreate: function(data) {\n recalculateArrowPosition(data);\n },\n onUpdate: function(data) {\n recalculateArrowPosition(data);\n },\n };\n\n let recalculateArrowPosition = function(data) {\n let placement = data.placement.split('-')[0];\n const isVertical = ['left', 'right'].indexOf(placement) !== -1;\n const arrowElement = data.instance.popper.querySelector('[data-role=\"arrow\"]');\n const stepElement = $(data.instance.popper.querySelector('[data-role=\"flexitour-step\"]'));\n if (isVertical) {\n let arrowHeight = parseFloat(window.getComputedStyle(arrowElement).height);\n let arrowOffset = parseFloat(window.getComputedStyle(arrowElement).top);\n let popperHeight = parseFloat(window.getComputedStyle(data.instance.popper).height);\n let popperOffset = parseFloat(window.getComputedStyle(data.instance.popper).top);\n let popperBorderWidth = parseFloat(stepElement.css('borderTopWidth'));\n let popperBorderRadiusWidth = parseFloat(stepElement.css('borderTopLeftRadius')) * 2;\n let arrowPos = arrowOffset + (arrowHeight / 2);\n let maxPos = popperHeight + popperOffset - popperBorderWidth - popperBorderRadiusWidth;\n let minPos = popperOffset + popperBorderWidth + popperBorderRadiusWidth;\n if (arrowPos >= maxPos || arrowPos <= minPos) {\n let newArrowPos = 0;\n if (arrowPos > (popperHeight / 2)) {\n newArrowPos = maxPos - arrowHeight;\n } else {\n newArrowPos = minPos + arrowHeight;\n }\n $(arrowElement).css('top', newArrowPos);\n }\n } else {\n let arrowWidth = parseFloat(window.getComputedStyle(arrowElement).width);\n let arrowOffset = parseFloat(window.getComputedStyle(arrowElement).left);\n let popperWidth = parseFloat(window.getComputedStyle(data.instance.popper).width);\n let popperOffset = parseFloat(window.getComputedStyle(data.instance.popper).left);\n let popperBorderWidth = parseFloat(stepElement.css('borderTopWidth'));\n let popperBorderRadiusWidth = parseFloat(stepElement.css('borderTopLeftRadius')) * 2;\n let arrowPos = arrowOffset + (arrowWidth / 2);\n let maxPos = popperWidth + popperOffset - popperBorderWidth - popperBorderRadiusWidth;\n let minPos = popperOffset + popperBorderWidth + popperBorderRadiusWidth;\n if (arrowPos >= maxPos || arrowPos <= minPos) {\n let newArrowPos = 0;\n if (arrowPos > (popperWidth / 2)) {\n newArrowPos = maxPos - arrowWidth;\n } else {\n newArrowPos = minPos + arrowWidth;\n }\n $(arrowElement).css('left', newArrowPos);\n }\n }\n };\n\n let background = $('[data-flexitour=\"step-background\"]');\n if (background.length) {\n target = background;\n }\n this.currentStepPopper = new Popper(target, content[0], config);\n\n return this;\n }\n\n /**\n * Add the backdrop.\n *\n * @method positionBackdrop\n * @param {Object} stepConfig The step configuration of the step\n * @chainable\n * @return {Object} this.\n */\n positionBackdrop(stepConfig) {\n if (stepConfig.backdrop) {\n this.currentStepConfig.hasBackdrop = true;\n let backdrop = $('');\n\n if (stepConfig.zIndex) {\n if (stepConfig.attachPoint === 'append') {\n stepConfig.attachTo.append(backdrop);\n } else {\n backdrop.insertAfter(stepConfig.attachTo);\n }\n } else {\n $('body').append(backdrop);\n }\n\n if (this.isStepActuallyVisible(stepConfig)) {\n // The step has a visible target.\n // Punch a hole through the backdrop.\n let background = $('');\n\n let targetNode = this.getStepTarget(stepConfig);\n\n let buffer = 10;\n\n let colorNode = targetNode;\n if (buffer) {\n colorNode = $('body');\n }\n\n background.css({\n width: targetNode.outerWidth() + buffer + buffer,\n height: targetNode.outerHeight() + buffer + buffer,\n left: targetNode.offset().left - buffer,\n top: targetNode.offset().top - buffer,\n backgroundColor: this.calculateInherittedBackgroundColor(colorNode),\n });\n\n if (targetNode.offset().left < buffer) {\n background.css({\n width: targetNode.outerWidth() + targetNode.offset().left + buffer,\n left: targetNode.offset().left,\n });\n }\n\n if (targetNode.offset().top < buffer) {\n background.css({\n height: targetNode.outerHeight() + targetNode.offset().top + buffer,\n top: targetNode.offset().top,\n });\n }\n\n let targetRadius = targetNode.css('borderRadius');\n if (targetRadius && targetRadius !== $('body').css('borderRadius')) {\n background.css('borderRadius', targetRadius);\n }\n\n let targetPosition = this.calculatePosition(targetNode);\n if (targetPosition === 'fixed') {\n background.css('top', 0);\n } else if (targetPosition === 'absolute') {\n background.css('position', 'fixed');\n }\n\n let fader = background.clone();\n fader.css({\n backgroundColor: backdrop.css('backgroundColor'),\n opacity: backdrop.css('opacity'),\n });\n fader.attr('data-flexitour', 'step-background-fader');\n\n if (stepConfig.zIndex) {\n if (stepConfig.attachPoint === 'append') {\n stepConfig.attachTo.append(background);\n } else {\n fader.insertAfter(stepConfig.attachTo);\n background.insertAfter(stepConfig.attachTo);\n }\n } else {\n $('body').append(fader);\n $('body').append(background);\n }\n\n // Add the backdrop data to the actual target.\n // This is the part which actually does the work.\n targetNode.attr('data-flexitour', 'step-backdrop');\n\n if (stepConfig.zIndex) {\n backdrop.css('zIndex', stepConfig.zIndex);\n background.css('zIndex', stepConfig.zIndex + 1);\n targetNode.css('zIndex', stepConfig.zIndex + 2);\n }\n\n fader.fadeOut('2000', function() {\n $(this).remove();\n });\n }\n }\n return this;\n }\n\n /**\n * Calculate the inheritted z-index.\n *\n * @method calculateZIndex\n * @param {jQuery} elem The element to calculate z-index for\n * @return {Number} Calculated z-index\n */\n calculateZIndex(elem) {\n elem = $(elem);\n while (elem.length && elem[0] !== document) {\n // Ignore z-index if position is set to a value where z-index is ignored by the browser\n // This makes behavior of this function consistent across browsers\n // WebKit always returns auto if the element is positioned.\n let position = elem.css(\"position\");\n if (position === \"absolute\" || position === \"relative\" || position === \"fixed\") {\n // IE returns 0 when zIndex is not specified\n // other browsers return a string\n // we ignore the case of nested elements with an explicit value of 0\n // \n let value = parseInt(elem.css(\"zIndex\"), 10);\n if (!isNaN(value) && value !== 0) {\n return value;\n }\n }\n elem = elem.parent();\n }\n\n return 0;\n }\n\n /**\n * Calculate the inheritted background colour.\n *\n * @method calculateInherittedBackgroundColor\n * @param {jQuery} elem The element to calculate colour for\n * @return {String} Calculated background colour\n */\n calculateInherittedBackgroundColor(elem) {\n // Use a fake node to compare each element against.\n let fakeNode = $('').hide();\n $('body').append(fakeNode);\n let fakeElemColor = fakeNode.css('backgroundColor');\n fakeNode.remove();\n\n elem = $(elem);\n while (elem.length && elem[0] !== document) {\n let color = elem.css('backgroundColor');\n if (color !== fakeElemColor) {\n return color;\n }\n elem = elem.parent();\n }\n\n return null;\n }\n\n /**\n * Calculate the inheritted position.\n *\n * @method calculatePosition\n * @param {jQuery} elem The element to calculate position for\n * @return {String} Calculated position\n */\n calculatePosition(elem) {\n elem = $(elem);\n while (elem.length && elem[0] !== document) {\n let position = elem.css('position');\n if (position !== 'static') {\n return position;\n }\n elem = elem.parent();\n }\n\n return null;\n }\n\n /**\n * Perform accessibility changes for step shown.\n *\n * This will add aria-hidden=\"true\" to all siblings and parent siblings.\n *\n * @method accessibilityShow\n */\n accessibilityShow() {\n let stateHolder = 'data-has-hidden';\n let attrName = 'aria-hidden';\n let hideFunction = function(child) {\n let flexitourRole = child.data('flexitour');\n if (flexitourRole) {\n switch (flexitourRole) {\n case 'container':\n case 'target':\n return;\n }\n }\n\n let hidden = child.attr(attrName);\n if (!hidden) {\n child.attr(stateHolder, true);\n Aria.hide(child);\n }\n };\n\n this.currentStepNode.siblings().each(function(index, node) {\n hideFunction($(node));\n });\n this.currentStepNode.parentsUntil('body').siblings().each(function(index, node) {\n hideFunction($(node));\n });\n }\n\n /**\n * Perform accessibility changes for step hidden.\n *\n * This will remove any newly added aria-hidden=\"true\".\n *\n * @method accessibilityHide\n */\n accessibilityHide() {\n let stateHolder = 'data-has-hidden';\n let showFunction = function(child) {\n let hidden = child.attr(stateHolder);\n if (typeof hidden !== 'undefined') {\n child.removeAttr(stateHolder);\n Aria.unhide(child);\n }\n };\n\n $('[' + stateHolder + ']').each(function(index, node) {\n showFunction($(node));\n });\n }\n};\n\nexport default Tour;\n"],"file":"tour.min.js"}
\ No newline at end of file
diff --git a/admin/tool/usertours/amd/build/usertours.min.js b/admin/tool/usertours/amd/build/usertours.min.js
index 55d813fcae8..ca7903f940f 100644
--- a/admin/tool/usertours/amd/build/usertours.min.js
+++ b/admin/tool/usertours/amd/build/usertours.min.js
@@ -1,2 +1,2 @@
-function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("tool_usertours/usertours",["exports","./tour","core/templates","core/log","core/notification","./repository","core/pending"],function(a,b,c,d,e,f,g){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.resetTourState=a.init=void 0;b=j(b);c=j(c);d=j(d);e=j(e);f=i(f);g=j(g);var m="undefined"!=typeof window?window:"undefined"!=typeof self?self:"undefined"!=typeof global?global:{};function h(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;h=function(){return a};return a}function i(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=h();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var e in a){if(Object.prototype.hasOwnProperty.call(a,e)){var f=d?Object.getOwnPropertyDescriptor(a,e):null;if(f&&(f.get||f.set)){Object.defineProperty(c,e,f)}else{c[e]=a[e]}}}c.default=a;if(b){b.set(a,c)}return c}function j(a){return a&&a.__esModule?a:{default:a}}function k(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function l(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){k(h,d,e,f,g,"next",a)}function g(a){k(h,d,e,f,g,"throw",a)}f(void 0)})}}var n=null,o=null,p=function(a,b){return a.find(function(a){return b.some(function(b){if(b&&b.filterMatches){return b.filterMatches(a)}return!0})})},q=function(){var a=l(regeneratorRuntime.mark(function a(b,c){var d,e,f,g;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:d=[];c.forEach(function(a){d.push("function"==typeof m.define&&m.define.amd?new Promise(function(b,c){m.require(["tool_usertours/filter_".concat(a)],b,c)}):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&m.require&&"component"===m.require.loader?Promise.resolve(require(("tool_usertours/filter_".concat(a)))):Promise.resolve(m["tool_usertours/filter_".concat(a)]))});a.next=4;return Promise.all(d);case 4:e=a.sent;f=p(b,e);if(f){a.next=8;break}return a.abrupt("return");case 8:o=f.tourId;g=f.startTour;if("undefined"==typeof g){g=!0}if(g){r(o)}t();document.querySelector("body").addEventListener("click",function(a){var b=a.target.closest("[data-action=\"tool_usertours/resetpagetour\"]");if(b){a.preventDefault();x(o)}});case 14:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}();a.init=q;var r=function(){var a=l(regeneratorRuntime.mark(function a(b){var d,h,i,j;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:d=new g.default("admin_usertour_fetchTour:".concat(b));a.prev=1;a.next=4;return f.fetchTour(b);case 4:h=a.sent;if(!h.hasOwnProperty("tourconfig")){d.resolve()}a.next=8;return c.default.renderForPromise("tool_usertours/tourstep",h.tourconfig);case 8:i=a.sent;j=i.html;u(b,j,h.tourconfig);d.resolve();a.next=18;break;case 14:a.prev=14;a.t0=a["catch"](1);d.resolve();e.default.exception(a.t0);case 18:case"end":return a.stop();}}},a,null,[[1,14]])}));return function(){return a.apply(this,arguments)}}(),s=function(){var a=document.querySelector(".tool_usertours-resettourcontainer");if(a){return a}a=document.querySelector(".logininfo");if(a){return a}a=document.querySelector("footer");if(a){return a}return document.body},t=function(){var a=new g.default("admin_usertour_addResetLink");c.default.render("tool_usertours/resettour",{}).then(function(a,b){c.default.appendNodeContents(s(),a,b)}).catch().then(a.resolve).catch()},u=function(a,c,d){if(n){d.onEnd=null;n.endTour();n=null}d.eventHandlers={afterEnd:[w],afterRender:[v]};d.tourName=d.name;delete d.name;d.template=c;d.steps=d.steps.map(function(a){if("undefined"!=typeof a.element){a.target=a.element;delete a.element}if("undefined"!=typeof a.reflex){a.moveOnClick=!!a.reflex;delete a.reflex}if("undefined"!=typeof a.content){a.body=a.content;delete a.content}return a});n=new b.default(d);return n.startTour()},v=function(a){var b=a.detail.tour,c=b.getStepConfig(b.getCurrentStepNumber());f.markStepShown(c.stepid,o,c.getCurrentStepNumber()).catch(d.default.error)},w=function(a){var b=a.detail.tour,c=b.getStepConfig(b.getCurrentStepNumber());f.markTourComplete(c.stepid,o,c.getCurrentStepNumber()).catch(d.default.error)},x=function(a){return f.resetTourState(a).then(function(a){if(a.startTour){r(a.startTour)}}).catch(e.default.exception)};a.resetTourState=x});
+function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("tool_usertours/usertours",["exports","./tour","core/templates","core/log","core/notification","./repository","core/pending","./events"],function(a,b,c,d,e,f,g,h){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.resetTourState=a.init=void 0;b=k(b);c=k(c);d=k(d);e=k(e);f=j(f);g=k(g);var n="undefined"!=typeof window?window:"undefined"!=typeof self?self:"undefined"!=typeof global?global:{};function i(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;i=function(){return a};return a}function j(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=i();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var e in a){if(Object.prototype.hasOwnProperty.call(a,e)){var f=d?Object.getOwnPropertyDescriptor(a,e):null;if(f&&(f.get||f.set)){Object.defineProperty(c,e,f)}else{c[e]=a[e]}}}c.default=a;if(b){b.set(a,c)}return c}function k(a){return a&&a.__esModule?a:{default:a}}function l(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function m(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){l(h,d,e,f,g,"next",a)}function g(a){l(h,d,e,f,g,"throw",a)}f(void 0)})}}var o=null,p=null,q=function(a,b){return a.find(function(a){return b.some(function(b){if(b&&b.filterMatches){return b.filterMatches(a)}return!0})})},r=function(){var a=m(regeneratorRuntime.mark(function a(b,c){var d,e,f,g;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:d=[];c.forEach(function(a){d.push("function"==typeof n.define&&n.define.amd?new Promise(function(b,c){n.require(["tool_usertours/filter_".concat(a)],b,c)}):"undefined"!=typeof module&&module.exports&&"undefined"!=typeof require||"undefined"!=typeof module&&module.component&&n.require&&"component"===n.require.loader?Promise.resolve(require(("tool_usertours/filter_".concat(a)))):Promise.resolve(n["tool_usertours/filter_".concat(a)]))});a.next=4;return Promise.all(d);case 4:e=a.sent;f=q(b,e);if(f){a.next=8;break}return a.abrupt("return");case 8:p=f.tourId;g=f.startTour;if("undefined"==typeof g){g=!0}if(g){s(p)}u();document.querySelector("body").addEventListener("click",function(a){var b=a.target.closest("[data-action=\"tool_usertours/resetpagetour\"]");if(b){a.preventDefault();y(p)}});case 14:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}();a.init=r;var s=function(){var a=m(regeneratorRuntime.mark(function a(b){var d,h,i,j;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:d=new g.default("admin_usertour_fetchTour:".concat(b));a.prev=1;a.next=4;return f.fetchTour(b);case 4:h=a.sent;if(!h.hasOwnProperty("tourconfig")){d.resolve()}a.next=8;return c.default.renderForPromise("tool_usertours/tourstep",h.tourconfig);case 8:i=a.sent;j=i.html;v(b,j,h.tourconfig);d.resolve();a.next=18;break;case 14:a.prev=14;a.t0=a["catch"](1);d.resolve();e.default.exception(a.t0);case 18:case"end":return a.stop();}}},a,null,[[1,14]])}));return function(){return a.apply(this,arguments)}}(),t=function(){var a=document.querySelector(".tool_usertours-resettourcontainer");if(a){return a}a=document.querySelector(".logininfo");if(a){return a}a=document.querySelector("footer");if(a){return a}return document.body},u=function(){var a=new g.default("admin_usertour_addResetLink");c.default.render("tool_usertours/resettour",{}).then(function(a,b){c.default.appendNodeContents(t(),a,b)}).catch().then(a.resolve).catch()},v=function(a,c,d){if(o&&o.tourRunning){o.endTour();o=null}document.addEventListener(h.eventTypes.tourEnded,x);document.addEventListener(h.eventTypes.stepRenderer,w);d.tourName=d.name;delete d.name;d.template=c;d.steps=d.steps.map(function(a){if("undefined"!=typeof a.element){a.target=a.element;delete a.element}if("undefined"!=typeof a.reflex){a.moveOnClick=!!a.reflex;delete a.reflex}if("undefined"!=typeof a.content){a.body=a.content;delete a.content}return a});o=new b.default(d);return o.startTour()},w=function(a){var b=a.detail.tour,c=b.getStepConfig(b.getCurrentStepNumber());f.markStepShown(c.stepid,p,b.getCurrentStepNumber()).catch(d.default.error)},x=function(a){document.removeEventListener(h.eventTypes.tourEnded,x);document.removeEventListener(h.eventTypes.stepRenderer,w);var b=a.detail.tour,c=b.getStepConfig(b.getCurrentStepNumber());f.markTourComplete(c.stepid,p,b.getCurrentStepNumber()).catch(d.default.error)},y=function(a){return f.resetTourState(a).then(function(a){if(a.startTour){s(a.startTour)}}).catch(e.default.exception)};a.resetTourState=y});
//# sourceMappingURL=usertours.min.js.map
diff --git a/admin/tool/usertours/amd/build/usertours.min.js.map b/admin/tool/usertours/amd/build/usertours.min.js.map
index e7d52b130b6..8149e0891fc 100644
--- a/admin/tool/usertours/amd/build/usertours.min.js.map
+++ b/admin/tool/usertours/amd/build/usertours.min.js.map
@@ -1 +1 @@
-{"version":3,"sources":["../src/usertours.js"],"names":["currentTour","tourId","findMatchingTour","tourDetails","filters","find","tour","some","filter","filterMatches","init","requirements","forEach","push","Promise","all","filterPlugins","matchingTour","startTour","fetchTour","addResetLink","document","querySelector","addEventListener","e","resetLink","target","closest","preventDefault","resetTourState","pendingPromise","Pending","tourRepository","response","hasOwnProperty","resolve","Templates","renderForPromise","tourconfig","html","startBootstrapTour","notification","exception","getPreferredResetLocation","location","body","render","then","js","appendNodeContents","catch","template","tourConfig","onEnd","endTour","eventHandlers","afterEnd","markTourComplete","afterRender","markStepShown","tourName","name","steps","map","step","element","reflex","moveOnClick","content","BootstrapTour","detail","stepConfig","getStepConfig","getCurrentStepNumber","stepid","log","error"],"mappings":"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","sourcesContent":["/**\n * User tour control library.\n *\n * @module tool_usertours/usertours\n * @copyright 2016 Andrew Nicols
\n */\nimport BootstrapTour from './tour';\nimport Templates from 'core/templates';\nimport log from 'core/log';\nimport notification from 'core/notification';\nimport * as tourRepository from './repository';\nimport Pending from 'core/pending';\n\nlet currentTour = null;\nlet tourId = null;\n\n/**\n * Find the first matching tour.\n *\n * @param {object[]} tourDetails\n * @param {object[]} filters\n * @returns {null|object}\n */\nconst findMatchingTour = (tourDetails, filters) => {\n return tourDetails.find(tour => filters.some(filter => {\n if (filter && filter.filterMatches) {\n return filter.filterMatches(tour);\n }\n\n return true;\n }));\n};\n\n/**\n * Initialise the user tour for the current page.\n *\n * @method init\n * @param {Array} tourDetails The matching tours for this page.\n * @param {Array} filters The names of all client side filters.\n */\nexport const init = async(tourDetails, filters) => {\n const requirements = [];\n filters.forEach(filter => {\n requirements.push(import(`tool_usertours/filter_${filter}`));\n });\n\n const filterPlugins = await Promise.all(requirements);\n\n const matchingTour = findMatchingTour(tourDetails, filterPlugins);\n if (!matchingTour) {\n return;\n }\n\n // Only one tour per page is allowed.\n tourId = matchingTour.tourId;\n\n let startTour = matchingTour.startTour;\n if (typeof startTour === 'undefined') {\n startTour = true;\n }\n\n if (startTour) {\n // Fetch the tour configuration.\n fetchTour(tourId);\n }\n\n addResetLink();\n\n // Watch for the reset link.\n document.querySelector('body').addEventListener('click', e => {\n const resetLink = e.target.closest('[data-action=\"tool_usertours/resetpagetour\"]');\n if (resetLink) {\n e.preventDefault();\n resetTourState(tourId);\n }\n });\n};\n\n/**\n * Fetch the configuration specified tour, and start the tour when it has been fetched.\n *\n * @method fetchTour\n * @param {Number} tourId The ID of the tour to start.\n */\nconst fetchTour = async tourId => {\n const pendingPromise = new Pending(`admin_usertour_fetchTour:${tourId}`);\n\n try {\n const response = await tourRepository.fetchTour(tourId);\n if (!response.hasOwnProperty('tourconfig')) {\n pendingPromise.resolve();\n }\n\n const {html} = await Templates.renderForPromise('tool_usertours/tourstep', response.tourconfig);\n startBootstrapTour(tourId, html, response.tourconfig);\n\n pendingPromise.resolve();\n } catch (error) {\n pendingPromise.resolve();\n notification.exception(error);\n }\n};\n\nconst getPreferredResetLocation = () => {\n let location = document.querySelector('.tool_usertours-resettourcontainer');\n if (location) {\n return location;\n }\n\n location = document.querySelector('.logininfo');\n if (location) {\n return location;\n }\n\n location = document.querySelector('footer');\n if (location) {\n return location;\n }\n\n return document.body;\n};\n\n/**\n * Add a reset link to the page.\n *\n * @method addResetLink\n */\nconst addResetLink = () => {\n const pendingPromise = new Pending('admin_usertour_addResetLink');\n\n Templates.render('tool_usertours/resettour', {})\n .then(function(html, js) {\n // Append the link to the most suitable place on the page with fallback to legacy selectors and finally the body if\n // there is no better place.\n Templates.appendNodeContents(getPreferredResetLocation(), html, js);\n\n return;\n })\n .catch()\n .then(pendingPromise.resolve)\n .catch();\n};\n\n/**\n * Start the specified tour.\n *\n * @method startBootstrapTour\n * @param {Number} tourId The ID of the tour to start.\n * @param {String} template The template to use.\n * @param {Object} tourConfig The tour configuration.\n * @return {Object}\n */\nconst startBootstrapTour = (tourId, template, tourConfig) => {\n if (currentTour) {\n // End the current tour, but disable end tour handler.\n tourConfig.onEnd = null;\n currentTour.endTour();\n currentTour = null;\n }\n\n tourConfig.eventHandlers = {\n afterEnd: [markTourComplete],\n afterRender: [markStepShown],\n };\n\n // Sort out the tour name.\n tourConfig.tourName = tourConfig.name;\n delete tourConfig.name;\n\n // Add the template to the configuration.\n // This enables translations of the buttons.\n tourConfig.template = template;\n\n tourConfig.steps = tourConfig.steps.map(function(step) {\n if (typeof step.element !== 'undefined') {\n step.target = step.element;\n delete step.element;\n }\n\n if (typeof step.reflex !== 'undefined') {\n step.moveOnClick = !!step.reflex;\n delete step.reflex;\n }\n\n if (typeof step.content !== 'undefined') {\n step.body = step.content;\n delete step.content;\n }\n\n return step;\n });\n\n currentTour = new BootstrapTour(tourConfig);\n return currentTour.startTour();\n};\n\n/**\n * Mark the specified step as being shownd by the user.\n *\n * @method markStepShown\n * @param {Event} e\n */\nconst markStepShown = e => {\n const tour = e.detail.tour;\n const stepConfig = tour.getStepConfig(tour.getCurrentStepNumber());\n tourRepository.markStepShown(\n stepConfig.stepid,\n tourId,\n stepConfig.getCurrentStepNumber()\n ).catch(log.error);\n};\n\n/**\n * Mark the specified tour as being completed by the user.\n *\n * @method markTourComplete\n * @param {Event} e\n * @listens tool_usertours/stepRendered\n */\nconst markTourComplete = e => {\n const tour = e.detail.tour;\n const stepConfig = tour.getStepConfig(tour.getCurrentStepNumber());\n tourRepository.markTourComplete(\n stepConfig.stepid,\n tourId,\n stepConfig.getCurrentStepNumber()\n ).catch(log.error);\n};\n\n/**\n * Reset the state, and restart the the tour on the current page.\n *\n * @method resetTourState\n * @param {Number} tourId The ID of the tour to start.\n * @returns {Promise}\n */\nexport const resetTourState = tourId => tourRepository.resetTourState(tourId)\n.then(response => {\n if (response.startTour) {\n fetchTour(response.startTour);\n }\n return;\n}).catch(notification.exception);\n"],"file":"usertours.min.js"}
\ No newline at end of file
+{"version":3,"sources":["../src/usertours.js"],"names":["currentTour","tourId","findMatchingTour","tourDetails","filters","find","tour","some","filter","filterMatches","init","requirements","forEach","push","Promise","all","filterPlugins","matchingTour","startTour","fetchTour","addResetLink","document","querySelector","addEventListener","e","resetLink","target","closest","preventDefault","resetTourState","pendingPromise","Pending","tourRepository","response","hasOwnProperty","resolve","Templates","renderForPromise","tourconfig","html","startBootstrapTour","notification","exception","getPreferredResetLocation","location","body","render","then","js","appendNodeContents","catch","template","tourConfig","tourRunning","endTour","eventTypes","tourEnded","markTourComplete","stepRenderer","markStepShown","tourName","name","steps","map","step","element","reflex","moveOnClick","content","BootstrapTour","detail","stepConfig","getStepConfig","getCurrentStepNumber","stepid","log","error","removeEventListener"],"mappings":"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","sourcesContent":["/**\n * User tour control library.\n *\n * @module tool_usertours/usertours\n * @copyright 2016 Andrew Nicols \n */\nimport BootstrapTour from './tour';\nimport Templates from 'core/templates';\nimport log from 'core/log';\nimport notification from 'core/notification';\nimport * as tourRepository from './repository';\nimport Pending from 'core/pending';\nimport {eventTypes} from './events';\n\nlet currentTour = null;\nlet tourId = null;\n\n/**\n * Find the first matching tour.\n *\n * @param {object[]} tourDetails\n * @param {object[]} filters\n * @returns {null|object}\n */\nconst findMatchingTour = (tourDetails, filters) => {\n return tourDetails.find(tour => filters.some(filter => {\n if (filter && filter.filterMatches) {\n return filter.filterMatches(tour);\n }\n\n return true;\n }));\n};\n\n/**\n * Initialise the user tour for the current page.\n *\n * @method init\n * @param {Array} tourDetails The matching tours for this page.\n * @param {Array} filters The names of all client side filters.\n */\nexport const init = async(tourDetails, filters) => {\n const requirements = [];\n filters.forEach(filter => {\n requirements.push(import(`tool_usertours/filter_${filter}`));\n });\n\n const filterPlugins = await Promise.all(requirements);\n\n const matchingTour = findMatchingTour(tourDetails, filterPlugins);\n if (!matchingTour) {\n return;\n }\n\n // Only one tour per page is allowed.\n tourId = matchingTour.tourId;\n\n let startTour = matchingTour.startTour;\n if (typeof startTour === 'undefined') {\n startTour = true;\n }\n\n if (startTour) {\n // Fetch the tour configuration.\n fetchTour(tourId);\n }\n\n addResetLink();\n\n // Watch for the reset link.\n document.querySelector('body').addEventListener('click', e => {\n const resetLink = e.target.closest('[data-action=\"tool_usertours/resetpagetour\"]');\n if (resetLink) {\n e.preventDefault();\n resetTourState(tourId);\n }\n });\n};\n\n/**\n * Fetch the configuration specified tour, and start the tour when it has been fetched.\n *\n * @method fetchTour\n * @param {Number} tourId The ID of the tour to start.\n */\nconst fetchTour = async tourId => {\n const pendingPromise = new Pending(`admin_usertour_fetchTour:${tourId}`);\n\n try {\n const response = await tourRepository.fetchTour(tourId);\n if (!response.hasOwnProperty('tourconfig')) {\n pendingPromise.resolve();\n }\n\n const {html} = await Templates.renderForPromise('tool_usertours/tourstep', response.tourconfig);\n startBootstrapTour(tourId, html, response.tourconfig);\n\n pendingPromise.resolve();\n } catch (error) {\n pendingPromise.resolve();\n notification.exception(error);\n }\n};\n\nconst getPreferredResetLocation = () => {\n let location = document.querySelector('.tool_usertours-resettourcontainer');\n if (location) {\n return location;\n }\n\n location = document.querySelector('.logininfo');\n if (location) {\n return location;\n }\n\n location = document.querySelector('footer');\n if (location) {\n return location;\n }\n\n return document.body;\n};\n\n/**\n * Add a reset link to the page.\n *\n * @method addResetLink\n */\nconst addResetLink = () => {\n const pendingPromise = new Pending('admin_usertour_addResetLink');\n\n Templates.render('tool_usertours/resettour', {})\n .then(function(html, js) {\n // Append the link to the most suitable place on the page with fallback to legacy selectors and finally the body if\n // there is no better place.\n Templates.appendNodeContents(getPreferredResetLocation(), html, js);\n\n return;\n })\n .catch()\n .then(pendingPromise.resolve)\n .catch();\n};\n\n/**\n * Start the specified tour.\n *\n * @method startBootstrapTour\n * @param {Number} tourId The ID of the tour to start.\n * @param {String} template The template to use.\n * @param {Object} tourConfig The tour configuration.\n * @return {Object}\n */\nconst startBootstrapTour = (tourId, template, tourConfig) => {\n if (currentTour && currentTour.tourRunning) {\n // End the current tour.\n currentTour.endTour();\n currentTour = null;\n }\n\n document.addEventListener(eventTypes.tourEnded, markTourComplete);\n document.addEventListener(eventTypes.stepRenderer, markStepShown);\n\n // Sort out the tour name.\n tourConfig.tourName = tourConfig.name;\n delete tourConfig.name;\n\n // Add the template to the configuration.\n // This enables translations of the buttons.\n tourConfig.template = template;\n\n tourConfig.steps = tourConfig.steps.map(function(step) {\n if (typeof step.element !== 'undefined') {\n step.target = step.element;\n delete step.element;\n }\n\n if (typeof step.reflex !== 'undefined') {\n step.moveOnClick = !!step.reflex;\n delete step.reflex;\n }\n\n if (typeof step.content !== 'undefined') {\n step.body = step.content;\n delete step.content;\n }\n\n return step;\n });\n\n currentTour = new BootstrapTour(tourConfig);\n return currentTour.startTour();\n};\n\n/**\n * Mark the specified step as being shownd by the user.\n *\n * @method markStepShown\n * @param {Event} e\n */\nconst markStepShown = e => {\n const tour = e.detail.tour;\n const stepConfig = tour.getStepConfig(tour.getCurrentStepNumber());\n tourRepository.markStepShown(\n stepConfig.stepid,\n tourId,\n tour.getCurrentStepNumber()\n ).catch(log.error);\n};\n\n/**\n * Mark the specified tour as being completed by the user.\n *\n * @method markTourComplete\n * @param {Event} e\n * @listens tool_usertours/stepRendered\n */\nconst markTourComplete = e => {\n document.removeEventListener(eventTypes.tourEnded, markTourComplete);\n document.removeEventListener(eventTypes.stepRenderer, markStepShown);\n\n const tour = e.detail.tour;\n const stepConfig = tour.getStepConfig(tour.getCurrentStepNumber());\n tourRepository.markTourComplete(\n stepConfig.stepid,\n tourId,\n tour.getCurrentStepNumber()\n ).catch(log.error);\n};\n\n/**\n * Reset the state, and restart the the tour on the current page.\n *\n * @method resetTourState\n * @param {Number} tourId The ID of the tour to start.\n * @returns {Promise}\n */\nexport const resetTourState = tourId => tourRepository.resetTourState(tourId)\n.then(response => {\n if (response.startTour) {\n fetchTour(response.startTour);\n }\n return;\n}).catch(notification.exception);\n"],"file":"usertours.min.js"}
\ No newline at end of file
diff --git a/admin/tool/usertours/amd/src/events.js b/admin/tool/usertours/amd/src/events.js
new file mode 100644
index 00000000000..fb897fba2ed
--- /dev/null
+++ b/admin/tool/usertours/amd/src/events.js
@@ -0,0 +1,136 @@
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see .
+
+/**
+ * Javascript events for the `tool_usertours` subsystem.
+ *
+ * @module tool_usertours/events
+ * @copyright 2021 Andrew Lyons
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ *
+ * @example Example of listening to a step rendering event and cancelling it.
+ * import {eventTypes as userTourEvents} from 'tool_usertours/events';
+ *
+ * document.addEventListener(userTourEvents.stepRender, e => {
+ * console.log(e.detail.tour); // The Tour instance
+ * e.preventDefault();
+ * });
+ */
+
+/**
+ * Events for the component.
+ *
+ * @constant
+ * @property {String} eventTypes.stepRender See {@link event:tool_usertours/stepRender}
+ * @property {String} eventTypes.stepRendered See {@link event:tool_usertours/stepRendered}
+ * @property {String} eventTypes.tourStart See {@link event:tool_usertours/tourStart}
+ * @property {String} eventTypes.tourStarted See {@link event:tool_usertours/tourStarted}
+ * @property {String} eventTypes.tourEnd See {@link event:tool_usertours/tourEnd}
+ * @property {String} eventTypes.tourEnded See {@link event:tool_usertours/tourEnded}
+ * @property {String} eventTypes.stepHide See {@link event:tool_usertours/stepHide}
+ * @property {String} eventTypes.stepHidden See {@link event:tool_usertours/stepHidden}
+ */
+export const eventTypes = {
+ /**
+ * An event triggered before a user tour step is rendered.
+ *
+ * This event is cancellable.
+ *
+ * @event tool_usertours/stepRender
+ * @type {CustomEvent}
+ * @property {object} detail
+ * @property {tool_usertours/tour} detail.tour
+ * @property {object} detail.stepConfig
+ */
+ stepRender: 'tool_usertours/stepRender',
+
+ /**
+ * An event triggered after a user tour step has been rendered.
+ *
+ * @event tool_usertours/stepRendered
+ * @type {CustomEvent}
+ * @property {object} detail
+ * @property {tool_usertours/tour} detail.tour
+ * @property {object} detail.stepConfig
+ */
+ stepRendered: 'tool_usertours/stepRendered',
+
+ /**
+ * An event triggered before a user tour starts.
+ *
+ * This event is cancellable.
+ *
+ * @event tool_usertours/tourStart
+ * @type {CustomEvent}
+ * @property {object} detail
+ * @property {tool_usertours/tour} detail.tour
+ * @property {Number} detail.startAt
+ */
+ tourStart: 'tool_usertours/tourStart',
+
+ /**
+ * An event triggered after a user tour has started.
+ *
+ * @event tool_usertours/tourStarted
+ * @property {object} detail
+ * @property {tool_usertours/tour} detail.tour
+ * @type {CustomEvent}
+ */
+ tourStarted: 'tool_usertours/tourStarted',
+
+ /**
+ * An event triggered before a tour ends.
+ *
+ * This event is cancellable.
+ *
+ * @event tool_usertours/tourEnd
+ * @property {object} detail
+ * @property {tool_usertours/tour} detail.tour
+ * @type {CustomEvent}
+ */
+ tourEnd: 'tool_usertours/tourEnd',
+
+ /**
+ * An event triggered after a tour has ended.
+ *
+ * @event tool_usertours/tourEnded
+ * @property {object} detail
+ * @property {tool_usertours/tour} detail.tour
+ * @type {CustomEvent}
+ */
+ tourEnded: 'tool_usertours/tourEnded',
+
+ /**
+ * An event triggered before a step is hidden.
+ *
+ * This event is cancellable.
+ *
+ * @event tool_usertours/stepHide
+ * @property {object} detail
+ * @property {tool_usertours/tour} detail.tour
+ * @type {CustomEvent}
+ */
+ stepHide: 'tool_usertours/stepHide',
+
+ /**
+ * An event triggered after a step has been hidden.
+ *
+ * @event tool_usertours/stepHidden
+ * @property {object} detail
+ * @property {tool_usertours/tour} detail.tour
+ * @type {CustomEvent}
+ */
+ stepHidden: 'tool_usertours/stepHidden',
+};
diff --git a/admin/tool/usertours/amd/src/tour.js b/admin/tool/usertours/amd/src/tour.js
index a75dca2ef87..b1c9cc215ea 100644
--- a/admin/tool/usertours/amd/src/tour.js
+++ b/admin/tool/usertours/amd/src/tour.js
@@ -14,7 +14,7 @@
// along with Moodle. If not, see .
/**
- * Manage user tours in Moodle.
+ * A user tour.
*
* @module tool_usertours/tour
* @copyright 2018 Andrew Nicols
@@ -24,13 +24,18 @@
import $ from 'jquery';
import * as Aria from 'core/aria';
import Popper from 'core/popper';
+import {dispatchEvent} from 'core/event_dispatcher';
+import {eventTypes} from './events';
/**
- * A Tour.
+ * A user tour.
*
- * @class
+ * @class tool_usertours/tour
+ * @property {boolean} tourRunning Whether the tour is currently running.
*/
-export default class Tour {
+const Tour = class {
+ tourRunning = false;
+
/**
* @param {object} config The configuration object.
*/
@@ -215,7 +220,7 @@ export default class Tour {
* Retrieve the current step number.
*
* @method getCurrentStepNumber
- * @return {Integer} The current step number
+ * @return {Number} The current step number
*/
getCurrentStepNumber() {
return parseInt(this.currentStepNumber, 10);
@@ -225,7 +230,7 @@ export default class Tour {
* Store the current step number.
*
* @method setCurrentStepNumber
- * @param {Integer} stepNumber The current step number
+ * @param {Number} stepNumber The current step number
* @chainable
*/
setCurrentStepNumber(stepNumber) {
@@ -245,8 +250,8 @@ export default class Tour {
* Get the next step number after the currently displayed step.
*
* @method getNextStepNumber
- * @param {Integer} stepNumber The current step number
- * @return {Integer} The next step number to display
+ * @param {Number} stepNumber The current step number
+ * @return {Number} The next step number to display
*/
getNextStepNumber(stepNumber) {
if (typeof stepNumber === 'undefined') {
@@ -269,8 +274,8 @@ export default class Tour {
* Get the previous step number before the currently displayed step.
*
* @method getPreviousStepNumber
- * @param {Integer} stepNumber The current step number
- * @return {Integer} The previous step number to display
+ * @param {Number} stepNumber The current step number
+ * @return {Number} The previous step number to display
*/
getPreviousStepNumber(stepNumber) {
if (typeof stepNumber === 'undefined') {
@@ -293,7 +298,7 @@ export default class Tour {
* Is the step the final step number?
*
* @method isLastStep
- * @param {Integer} stepNumber Step number to test
+ * @param {Number} stepNumber Step number to test
* @return {Boolean} Whether the step is the final step
*/
isLastStep(stepNumber) {
@@ -306,7 +311,7 @@ export default class Tour {
* Is the step the first step number?
*
* @method isFirstStep
- * @param {Integer} stepNumber Step number to test
+ * @param {Number} stepNumber Step number to test
* @return {Boolean} Whether the step is the first step
*/
isFirstStep(stepNumber) {
@@ -395,10 +400,14 @@ export default class Tour {
* Go to the specified step in the tour.
*
* @method gotoStep
- * @param {Integer} stepNumber The step number to display
- * @param {Integer} direction Next or previous step
+ * @param {Number} stepNumber The step number to display
+ * @param {Number} direction Next or previous step
* @chainable
* @return {Object} this.
+ * @fires tool_usertours/stepRender
+ * @fires tool_usertours/stepRendered
+ * @fires tool_usertours/stepHide
+ * @fires tool_usertours/stepHidden
*/
gotoStep(stepNumber, direction) {
if (stepNumber < 0) {
@@ -430,9 +439,11 @@ export default class Tour {
this.hide();
- this.fireEventHandlers('beforeRender', stepConfig);
- this.renderStep(stepConfig);
- this.fireEventHandlers('afterRender', stepConfig);
+ const stepRenderEvent = this.dispatchEvent(eventTypes.stepRender, {stepConfig}, true);
+ if (!stepRenderEvent.defaultPrevented) {
+ this.renderStep(stepConfig);
+ this.dispatchEvent(eventTypes.stepRendered, {stepConfig});
+ }
return this;
}
@@ -441,7 +452,7 @@ export default class Tour {
* Fetch the normalised step configuration for the specified step number.
*
* @method getStepConfig
- * @param {Integer} stepNumber The step number to fetch configuration for
+ * @param {Number} stepNumber The step number to fetch configuration for
* @return {Object} The step configuration
*/
getStepConfig(stepNumber) {
@@ -513,21 +524,23 @@ export default class Tour {
/**
* Fire any event handlers for the specified event.
*
- * @param {String} eventName The name of the event to handle
- * @param {Object} data Any data to pass to the event
- * @chainable
- * @return {Object} this.
+ * @param {String} eventName The name of the event
+ * @param {Object} [detail={}] Any additional details to pass into the eveent
+ * @param {Boolean} [cancelable=false] Whether preventDefault() can be called
+ * @returns {CustomEvent}
*/
- fireEventHandlers(eventName, data) {
- if (typeof this.eventHandlers[eventName] === 'undefined') {
- return this;
- }
-
- this.eventHandlers[eventName].forEach(function(thisEvent) {
- thisEvent.call(this, data);
- }, this);
-
- return this;
+ dispatchEvent(
+ eventName,
+ detail = {},
+ cancelable = false
+ ) {
+ return dispatchEvent(eventName, {
+ // Add the tour to the detail.
+ tour: this,
+ ...detail,
+ }, document, {
+ cancelable,
+ });
}
/**
@@ -968,9 +981,11 @@ export default class Tour {
* Start the current tour.
*
* @method startTour
- * @param {Integer} startAt Which step number to start at. If not specified, starts at the last point.
+ * @param {Number} startAt Which step number to start at. If not specified, starts at the last point.
* @chainable
* @return {Object} this.
+ * @fires tool_usertours/tourStart
+ * @fires tool_usertours/tourStarted
*/
startTour(startAt) {
if (this.storage && typeof startAt === 'undefined') {
@@ -987,9 +1002,12 @@ export default class Tour {
startAt = this.getCurrentStepNumber();
}
- this.fireEventHandlers('beforeStart', startAt);
- this.gotoStep(startAt);
- this.fireEventHandlers('afterStart', startAt);
+ const tourStartEvent = this.dispatchEvent(eventTypes.tourStart, {startAt}, true);
+ if (!tourStartEvent.defaultPrevented) {
+ this.gotoStep(startAt);
+ this.tourRunning = true;
+ this.dispatchEvent(eventTypes.tourStarted, {startAt});
+ }
return this;
}
@@ -1011,9 +1029,14 @@ export default class Tour {
* @method endTour
* @chainable
* @return {Object} this.
+ * @fires tool_usertours/tourEnd
+ * @fires tool_usertours/tourEnded
*/
endTour() {
- this.fireEventHandlers('beforeEnd');
+ const tourEndEvent = this.dispatchEvent(eventTypes.tourEnd, {}, true);
+ if (tourEndEvent.defaultPrevented) {
+ return this;
+ }
if (this.currentStepConfig) {
let previousTarget = this.getStepTarget(this.currentStepConfig);
@@ -1027,7 +1050,8 @@ export default class Tour {
this.hide(true);
- this.fireEventHandlers('afterEnd');
+ this.tourRunning = false;
+ this.dispatchEvent(eventTypes.tourEnded);
return this;
}
@@ -1039,9 +1063,14 @@ export default class Tour {
* @param {Bool} transition Animate the visibility change
* @chainable
* @return {Object} this.
+ * @fires tool_usertours/stepHide
+ * @fires tool_usertours/stepHidden
*/
hide(transition) {
- this.fireEventHandlers('beforeHide');
+ const stepHideEvent = this.dispatchEvent(eventTypes.stepHide, {}, true);
+ if (stepHideEvent.defaultPrevented) {
+ return this;
+ }
if (this.currentStepNode && this.currentStepNode.length) {
this.currentStepNode.hide();
@@ -1098,7 +1127,7 @@ export default class Tour {
this.accessibilityHide();
- this.fireEventHandlers('afterHide');
+ this.dispatchEvent(eventTypes.stepHidden);
this.currentStepNode = null;
this.currentStepPopper = null;
@@ -1533,4 +1562,6 @@ export default class Tour {
showFunction($(node));
});
}
-}
+};
+
+export default Tour;
diff --git a/admin/tool/usertours/amd/src/usertours.js b/admin/tool/usertours/amd/src/usertours.js
index 0c2b1ceb235..28aca149e62 100644
--- a/admin/tool/usertours/amd/src/usertours.js
+++ b/admin/tool/usertours/amd/src/usertours.js
@@ -10,6 +10,7 @@ import log from 'core/log';
import notification from 'core/notification';
import * as tourRepository from './repository';
import Pending from 'core/pending';
+import {eventTypes} from './events';
let currentTour = null;
let tourId = null;
@@ -151,17 +152,14 @@ const addResetLink = () => {
* @return {Object}
*/
const startBootstrapTour = (tourId, template, tourConfig) => {
- if (currentTour) {
- // End the current tour, but disable end tour handler.
- tourConfig.onEnd = null;
+ if (currentTour && currentTour.tourRunning) {
+ // End the current tour.
currentTour.endTour();
currentTour = null;
}
- tourConfig.eventHandlers = {
- afterEnd: [markTourComplete],
- afterRender: [markStepShown],
- };
+ document.addEventListener(eventTypes.tourEnded, markTourComplete);
+ document.addEventListener(eventTypes.stepRenderer, markStepShown);
// Sort out the tour name.
tourConfig.tourName = tourConfig.name;
@@ -206,7 +204,7 @@ const markStepShown = e => {
tourRepository.markStepShown(
stepConfig.stepid,
tourId,
- stepConfig.getCurrentStepNumber()
+ tour.getCurrentStepNumber()
).catch(log.error);
};
@@ -218,12 +216,15 @@ const markStepShown = e => {
* @listens tool_usertours/stepRendered
*/
const markTourComplete = e => {
+ document.removeEventListener(eventTypes.tourEnded, markTourComplete);
+ document.removeEventListener(eventTypes.stepRenderer, markStepShown);
+
const tour = e.detail.tour;
const stepConfig = tour.getStepConfig(tour.getCurrentStepNumber());
tourRepository.markTourComplete(
stepConfig.stepid,
tourId,
- stepConfig.getCurrentStepNumber()
+ tour.getCurrentStepNumber()
).catch(log.error);
};