Rev 1 | AutorÃa | Comparar con el anterior | Ultima modificación | Ver Log |
{"version":3,"file":"tour.min.js","sources":["../src/tour.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * A user tour.\n *\n * @module tool_usertours/tour\n * @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * A list of steps.\n *\n * @typedef {Obje
ct[]} StepList\n * @property {Number} stepId The id of the step in the database\n * @property {Number} position The position of the step within the tour (zero-indexed)\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';\nimport {getString} from 'core/str';\nimport {prefetchStrings} from 'core/prefetch';\nimport {notifyFilterContentUpdated} from 'core/event';\nimport PendingPromise from 'core/pending';\n\n/**\n * The minimum spacing for tour step to display.\n *\n * @private\n * @constant\n * @type {number}\n */\nconst MINSPACING = 10;\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 // Unset recalculate state.\n this.possitionNeedToBeRecalculated = false;\n\n // Unset recalculate count.\n this.recalculatedNo = 0;\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 prefetchStrings('tool_usertours', [\n 'nextstep_sequence',\n 'skip_tour
'\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.setSte
pDefaults({});\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 getCurrentStepNumbe
r\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 displa
y\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 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 (!st
epConfig) {\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 * Get potentially visible steps in a tour.\n *\n * @returns {StepList} A list of ordered steps\n */\n getPotentiallyVisibleSteps() {\n let position = 1;\n let result = [];\n // Checking the total steps.\n for (let stepNumbe
r = 0; stepNumber < this.steps.length; stepNumber++) {\n const stepConfig = this.getStepConfig(stepNumber);\n if (this.isStepPotentiallyVisible(stepConfig)) {\n result[stepNumber] = {stepId: stepConfig.stepid, position: position};\n position++;\n }\n }\n\n return result;\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 // Check if the CSS styles are allowed on the browser or not.\n if (!this.isCSSAllowed()) {\n return false;\n }\n\n let target = this.getStepTarget(stepConfig);\n if (target && target.le
ngth && 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 * Is the browser actually allow CSS styles?\n *\n * @returns {boolean} True if the browser is allowing CSS styles\n */\n isCSSAllowed() {\n const testCSSElement = document.createElement('div');\n testCSSElement.classList.add('hide');\n document.body.appendChild(testCSSElement);\n const styles = window.getComputedStyle(testCSSElement);\n const isAllowed = styles.display === 'none';\n testCSSElement.remove();\n\n return isAllowed;\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
const pendingPromise = new PendingPromise(`tool_usertours/tour:_gotoStep-${stepConfig.stepNumber}`);\n\n if (typeof stepConfig.delay !== 'undefined' && stepConfig.delay && !stepConfig.delayed) {\n stepConfig.delayed = true;\n window.setTimeout(function(stepConfig, direction) {\n this._gotoStep(stepConfig, direction);\n pendingPromise.resolve();\n }, stepConfig.delay, stepConfig, direction);\n\n return this;\n } else if (!stepConfig.orphan && !this.isStepActuallyVisible(stepConfig)) {\n const fn = direction == -1 ? 'getPreviousStepNumber' : 'getNextStepNumber';\n this.gotoStep(this[fn](stepConfig.stepNumber), direction);\n\n pendingPromise.resolve();\n return this;\n }\n\n this.hide();\n\n const stepRenderEvent = this.dispatchEvent(eventTypes.stepRender, {stepConfig}, true);\n if (!stepRenderEvent.defaultPrevented) {\n this.renderStep(ste
pConfig);\n this.dispatchEvent(eventTypes.stepRendered, {stepConfig});\n }\n\n pendingPromise.resolve();\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 {Obje
ct} 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 button.\n {\n node: this.currentStepNode,\n args: ['click', '[data-role=\"
next\"]', $.proxy(this.next, 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 configurati
on 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 // Buttons.\n const nextBtn = template.find('[data-role=\"next\"]');\n const endBtn = template.find('[data-role=\"end\"]');\n\n // Is this the final step?\n if (this.isLastStep(stepConfig.stepNumber)) {\n nextBtn.hide();\n endBtn.removeClass(\"btn-secondary\").addClass(\"btn-primary\");\n } else {\n nextBtn.prop('disabled', false);\n // Use Skip tour label for the End tour button.\n getString('skip_tour', 'tool_usertours').then(value => {\n e
ndBtn.html(value);\n return;\n }).catch();\n }\n\n nextBtn.attr('role', 'button');\n endBtn.attr('role', 'button');\n\n if (this.originalConfiguration.displaystepnumbers) {\n const stepsPotentiallyVisible = this.getPotentiallyVisibleSteps();\n const totalStepsPotentiallyVisible = stepsPotentiallyVisible.length;\n const position = stepsPotentiallyVisible[stepConfig.stepNumber].position;\n if (totalStepsPotentiallyVisible > 1) {\n // Change the label of the Next button to include the sequence.\n getString('nextstep_sequence', 'tool_usertours',\n {position: position, total: totalStepsPotentiallyVisible}).then(value => {\n nextBtn.html(value);\n return;\n }).catch();\n }\n }\n\n // Replace the template with the updated version.\n stepConfig.template = template;\n\n // Add to th
e 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 = $('<span data-flexitour=\"container\"></span>')\n .html(stepConfig.template)\n .hide();\n // Trigger the Moodle filters.\n notifyFilterContentUpdated(currentStepNode);\n\n // The scroll ani
mation 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 if (targetNode.parents('[data-usertour=\"scroller\"]').length) {\n animationTarget = targetNode.parents('[data-usertour=\"scroller\"]');\n }\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 const pendingPromise = new PendingPromise(`tool_usertours/tour:addStepToPage-${stepConfig.stepNumber}`);\n animationTarget\n .animate({\n scrollTop: this.calculateScrollTop(stepConfig),\n }).promise().then(function() {\n this.positionStep(stepConfig);\n this.revealStep(stepConfig);\n pendingPromise.resolve();\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.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 onCreate: () => {\n // First, we need to check if the step's content contains any images.\n const images = this.currentStepNode.find('img');\n if (images.length) {\n // Images found, need to calculate the position when the image is loaded.\n images.on('load', () => {\n this.calculateStepPositionInPage(currentStepNode);\n });\n }\n this.calculateStepPositionInPage(currentStepNode);\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 con
figuration of the step\n * @chainable\n * @return {Object} this.\n */\n revealStep(stepConfig) {\n // Fade the step in.\n const pendingPromise = new PendingPromise(`tool_usertours/tour:revealStep-${stepConfig.stepNumber}`);\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 pendingPromise.resolve();\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 + '-tit
le');\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 target.data('original-tabindex', target.attr('tabindex'));\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 tabbableNod
es = $(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 retu
rn 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.getStepTarge
t(this.currentStepConfig);\n if (previousTarget) {\n if (!previousTarget.attr('tabindex')) {\n previousTarget.attr('tabindex', '-1');\n }\n previousTarget.first().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 const pendingPromise = new PendingPromise('tool_usertours/tour:hide');\n if (this.currentStepNode && this.curre
ntStepNode.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 } else {\n // If the target does not have the tabindex attribute at the beginning. We need to remove it.\n // We should wait a
little here before removing the attribute to prevent the browser from adding it again.\n window.setTimeout(() => {\n target.removeAttr('tabindex');\n }, 400);\n }\n }\n\n // Clear the step configuration.\n this.currentStepConfig = null;\n }\n\n // Remove the backdrop features.\n $('[data-flexitour=\"step-background\"]').remove();\n $('[data-flexitour=\"step-backdrop\"]').removeAttr('data-flexitour');\n\n const backdrop = $('[data-flexitour=\"backdrop\"]');\n if (backdrop.length) {\n if (transition) {\n const backdropRemovalPromise = new PendingPromise('tool_usertours/tour:hide:backdrop');\n backdrop.fadeOut(400, function() {\n $(this).remove();\n backdropRemovalPromise.resolve();\n });\n } else {\n backdrop.remove();\n }\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\n pendingPromise.resolve();\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 viewportHeight = $(window).height();\n let targetNode = this.getStepTarget(stepConfig);\n\n let scrollParent = $(window);\n if (targetNode.parents('[data-usertour=\"scroller\"]').length) {\n scrollParent = targetNode.parents('[data-usertour=\"scroller\"]');\n }\n let scrollTop = scrollParent.scrollTop();\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 - (viewpor
tHeight / 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() + scrollTop - (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() - vie
wportHeight, scrollTop);\n\n return Math.ceil(scrollTop);\n }\n\n /**\n * Calculate dialogue position for page middle.\n *\n * @param {jQuery} currentStepNode Current step node\n * @method calculateScrollTop\n */\n calculateStepPositionInPage(currentStepNode) {\n let top = MINSPACING;\n const viewportHeight = $(window).height();\n const stepHeight = currentStepNode.height();\n const viewportWidth = $(window).width();\n const stepWidth = currentStepNode.width();\n if (viewportHeight >= (stepHeight + (MINSPACING * 2))) {\n top = Math.ceil((viewportHeight - stepHeight) / 2);\n } else {\n const headerHeight = currentStepNode.find('.modal-header').first().outerHeight() ?? 0;\n const footerHeight = currentStepNode.find('.modal-footer').first().outerHeight() ?? 0;\n const currentStepBody = currentStepNode.find('[data-placeholder=\"body\"]').first();\n const maxHeight = viewpor
tHeight - (MINSPACING * 2) - headerHeight - footerHeight;\n currentStepBody.css({\n 'max-height': maxHeight + 'px',\n 'overflow': 'auto',\n });\n }\n currentStepNode.offset({\n top: top,\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 let thisT = this;\n if (!content || !content.length) {\n // Unable to find the step node.\n return this;\n }\n\n stepConfig.placement = this.recalculatePlacement(stepConfig);\n let flipBehavior;\n switch (stepConfig.placement) {\n case 'left':\n flipBehavior = ['left', 'right', 't
op', '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 recalculateStepPo
sition(data);\n },\n onUpdate: function(data) {\n recalculateArrowPosition(data);\n if (thisT.possitionNeedToBeRecalculated) {\n thisT.recalculatedNo++;\n thisT.possitionNeedToBeRecalculated = false;\n recalculateStepPosition(data);\n }\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 pop
perHeight = 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', newArro
wPos);\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 const recalculateStepPosition = function(data) {\n const placement = data.placement.split('-')[0];\n const isVertical = ['left', 'right'].indexOf(placement) !== -1;\n const popperElement = $(data.instance.popper);\n const targetElement = $(data.instance.reference);\n const arrowElement = popperElement.find('[data-role=\"arrow\"]');\n const stepElement = popperElement.find('[data-role=\"flexitour-step\"]');\n const viewportHeight = $(window).height();\n const viewportWidth = $(window).width();\n const arrowHeight = parseFloat(arrowElement.outerHeight(true));\n const popperHeight = parseFloat(po
pperElement.outerHeight(true));\n const targetHeight = parseFloat(targetElement.outerHeight(true));\n const arrowWidth = parseFloat(arrowElement.outerWidth(true));\n const popperWidth = parseFloat(popperElement.outerWidth(true));\n const targetWidth = parseFloat(targetElement.outerWidth(true));\n let maxHeight;\n\n if (thisT.recalculatedNo > 1) {\n // The current screen is too small, and cannot fit with the original placement.\n // We should set the placement to auto so the PopperJS can calculate the perfect placement.\n thisT.currentStepPopper.options.placement = isVertical ? 'auto-left' : 'auto-bottom';\n }\n if (thisT.recalculatedNo > 2) {\n // Return here to prevent recursive calling.\n return;\n }\n\n if (isVertical) {\n // Find the best place to put the tour: Left of right.\n const leftSpace
= targetElement.offset().left > 0 ? targetElement.offset().left : 0;\n const rightSpace = viewportWidth - leftSpace - targetWidth;\n const remainingSpace = leftSpace >= rightSpace ? leftSpace : rightSpace;\n maxHeight = viewportHeight - MINSPACING * 2;\n if (remainingSpace < (popperWidth + arrowWidth)) {\n const maxWidth = remainingSpace - MINSPACING - arrowWidth;\n if (maxWidth > 0) {\n popperElement.css({\n 'max-width': maxWidth + 'px',\n });\n // Not enough space, flag true to make Popper to recalculate the position.\n thisT.possitionNeedToBeRecalculated = true;\n }\n } else if (maxHeight < popperHeight) {\n // Check if the Popper's height can fit the viewport height or not.\n // If not, set the correct max-height value
for the Popper element.\n popperElement.css({\n 'max-height': maxHeight + 'px',\n });\n }\n } else {\n // Find the best place to put the tour: Top of bottom.\n const topSpace = targetElement.offset().top > 0 ? targetElement.offset().top : 0;\n const bottomSpace = viewportHeight - topSpace - targetHeight;\n const remainingSpace = topSpace >= bottomSpace ? topSpace : bottomSpace;\n maxHeight = remainingSpace - MINSPACING - arrowHeight;\n if (remainingSpace < (popperHeight + arrowHeight)) {\n // Not enough space, flag true to make Popper to recalculate the position.\n thisT.possitionNeedToBeRecalculated = true;\n }\n }\n\n // Check if the Popper's height can fit the viewport height or not.\n // If not, set the correct max-height value for the body.\n
const currentStepBody = stepElement.find('[data-placeholder=\"body\"]').first();\n const headerEle = stepElement.find('.modal-header').first();\n const footerEle = stepElement.find('.modal-footer').first();\n const headerHeight = headerEle.outerHeight(true) ?? 0;\n const footerHeight = footerEle.outerHeight(true) ?? 0;\n maxHeight = maxHeight - headerHeight - footerHeight;\n if (maxHeight > 0) {\n headerEle.removeClass('minimal');\n footerEle.removeClass('minimal');\n currentStepBody.css({\n 'max-height': maxHeight + 'px',\n 'overflow': 'auto',\n });\n } else {\n headerEle.addClass('minimal');\n footerEle.addClass('minimal');\n }\n // Call the Popper update method to update the position.\n thisT.currentStepPopper.update();\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 * For left/right placement, checks that there is room for the step at current window size.\n *\n * If there is not enough room, changes placement to 'top'.\n *\n * @method recalculatePlacement\n * @param {Object} stepConfig The step configuration of the step\n * @return {String} The placement after recalculate\n */\n recalculatePlacement(stepConfig) {\n const buffer = 10;\n const arrowWidth = 16;\n let target = this.getStepTarget(stepConfig);\n let widthContent = this.currentStepNode.width() + arrowWidth;\n let targetOffsetLeft = target.offset().left - buffer;\n let targetOffsetRight = target.offset().left + target.width() + buffer;\n let placement = stepConfig.p
lacement;\n\n if (['left', 'right'].indexOf(placement) !== -1) {\n if ((targetOffsetLeft < (widthContent + buffer)) &&\n ((targetOffsetRight + widthContent + buffer) > document.documentElement.clientWidth)) {\n placement = 'top';\n }\n }\n return placement;\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 = $('<div data-flexitour=\"backdrop\"></div>');\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 = $('[data-flexitour=\"step-background\"]');\n if (!background.length) {\n background = $('<div data-flexitour=\"step-background\"></div>');\n }\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 let drawertop = 0;\n if (targetNode.parents('[data-usertour=\"scroller\"]').length) {\n const scrollerElement = targetNode.parents('[data-usertour=\"scroller\"]');\n const navigationBuffer = scrollerElement.offset().top;\n
if (scrollerElement.scrollTop() >= navigationBuffer) {\n drawertop = scrollerElement.scrollTop() - navigationBuffer;\n background.css({\n position: 'fixed'\n });\n }\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 + drawertop - 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 + drawertop) < 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 === '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 let targetClone = targetNode.clone();\n background.append(targetClone.first());\n $('body').append(fader);\n $('body').append(background);\n } else {\n if (stepConfig.attachPoint === 'append') {\n stepConfig.attachTo.append(background);\n } else {\n fader.insertAfter(stepConfig.attachTo);\n background.insertAfter(stepConfig.attachTo);\n }\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', stepC
onfig.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 if (this.requireDefaultTourZindex(elem)) {\n return 0;\n }\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 positio
n = elem.css(\"position\");\n if (position === \"absolute\" || 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 // <div style=\"z-index: -10;\"><div style=\"z-index: 0;\"></div></div>\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 * Check if the element require the default tour z-index.\n *\n * Some page elements have fixed z-index. However, their weight is not enough to cover\n * other page elements like the top navbar or a sticky footer so they use the default\n * tour z-index instead.\n *\n * @param {jQuery} elem the page element to highlight\n * @ret
urn {Boolean} true if the element requires the default tour z-index instead of the calculated one\n */\n requireDefaultTourZindex(elem) {\n if (elem.parents('[data-region=\"fixed-drawer\"]').length !== 0) {\n return true;\n }\n return false;\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 = $('<div>').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"],"names":["constructor","config","init","eventHandlers","reset","originalConfiguration","configure","apply","this","arguments","possitionNeedToBeRecalculated","recalculatedNo","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","de
lay","moveOnClick","moveAfterTime","orphan","direction","getCurrentStepNumber","parseInt","setCurrentStepNumber","stepNumber","setItem","code","DOMException","QUOTA_EXCEEDED_ERR","removeItem","getNextStepNumber","nextStepNumber","isStepPotentiallyVisible","getStepConfig","getPreviousStepNumber","previousStepNumber","isLastStep","stepConfig","isStepActuallyVisible","getPotentiallyVisibleSteps","position","result","stepId","stepid","isCSSAllowed","target","getStepTarget","is","testCSSElement","document","createElement","classList","add","body","appendChild","isAllowed","getComputedStyle","display","remove","next","gotoStep","previous","endTour","_gotoStep","pendingPromise","PendingPromise","delayed","setTimeout","resolve","fn","dispatchEvent","eventTypes","stepRender","defaultPrevented","renderStep","stepRendered","normalizeStepConfig","$","reflex","moveAfterClick","content","attachTo","attachPoint","first","detail","cancelable","tour","push","processStepListeners","listeners","node","currentStepNode","args","
proxy","handleKeyDown","targetNode","parents","listener","on","off","currentStepConfig","getTemplateContent","find","html","title","nextBtn","endBtn","removeClass","addClass","prop","then","value","catch","attr","displaystepnumbers","stepsPotentiallyVisible","totalStepsPotentiallyVisible","total","addStepToPage","clone","animationTarget","stop","data","zIndex","calculateZIndex","css","positionBackdrop","append","top","left","animate","scrollTop","calculateScrollTop","promise","positionStep","revealStep","bind","isOrphan","currentStepPopper","Popper","removeOnDestroy","arrowElement","modifiers","enabled","applyStyle","onLoad","onCreate","images","calculateStepPositionInPage","fadeIn","announceStep","focus","bodyRegion","headerRegion","accessibilityShow","tabbableSelector","keyCode","hasBackdrop","currentIndex","nextIndex","nextNode","focusRelevant","activeElement","stepTarget","tabbableNodes","dialogContainer","filter","index","has","each","shiftKey","closest","last","preventDefault","call","startTour","start
At","storageStartValue","getItem","storageStartAt","tourStart","tourRunning","tourStarted","restartTour","tourEnd","previousTarget","tourEnded","transition","stepHide","destroy","removeAttr","backdrop","backdropRemovalPromise","fadeOut","currentStepElement","accessibilityHide","stepHidden","show","getStepContainer","viewportHeight","height","scrollParent","offset","Math","max","min","ceil","stepHeight","viewportWidth","width","stepWidth","MINSPACING","maxHeight","outerHeight","flipBehavior","thisT","recalculatePlacement","flip","behaviour","arrow","recalculateArrowPosition","recalculateStepPosition","onUpdate","split","isVertical","indexOf","instance","popper","querySelector","stepElement","arrowHeight","parseFloat","arrowOffset","popperHeight","popperOffset","popperBorderWidth","popperBorderRadiusWidth","arrowPos","maxPos","minPos","newArrowPos","arrowWidth","popperWidth","popperElement","targetElement","reference","targetHeight","outerWidth","targetWidth","options","leftSpace","rightSpace","remainingSpace"
,"maxWidth","topSpace","bottomSpace","currentStepBody","headerEle","footerEle","update","background","widthContent","targetOffsetLeft","targetOffsetRight","documentElement","clientWidth","insertAfter","buffer","colorNode","drawertop","scrollerElement","navigationBuffer","backgroundColor","calculateInherittedBackgroundColor","targetRadius","calculatePosition","fader","opacity","targetClone","elem","requireDefaultTourZindex","isNaN","parent","fakeNode","fakeElemColor","color","hideFunction","child","flexitourRole","Aria","siblings","parentsUntil","unhide"],"mappings":"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"}