intro.js update and according changes to source (fixes #109)
Change-Id: I52e439e64d39e44f2c8b3dd5d2d37e0d13d48743
diff --git a/dev/js/lib/intro.js b/dev/js/lib/intro.js
index 76f0116..cc6820b 100644
--- a/dev/js/lib/intro.js
+++ b/dev/js/lib/intro.js
@@ -1,1531 +1,73 @@
-/**
- * Intro.js v2.9.3
- * https://github.com/usablica/intro.js
+/*!
+ * Intro.js v4.2.2
+ * https://introjs.com
*
- * Copyright (C) 2017 Afshin Mehrabani (@afshinmeh)
+ * Copyright (C) 2012-2021 Afshin Mehrabani (@afshinmeh).
+ * https://raw.githubusercontent.com/usablica/intro.js/master/license.md
+ *
+ * Date: Fri, 27 Aug 2021 12:07:05 GMT
*/
-(function(f) {
- if (typeof exports === "object" && typeof module !== "undefined") {
- module.exports = f();
- // deprecated function
- // @since 2.8.0
- module.exports.introJs = function () {
- console.warn('Deprecated: please use require("intro.js") directly, instead of the introJs method of the function');
- // introJs()
- return f().apply(this, arguments);
- };
- } else if (typeof define === "function" && define.amd) {
- define([], f);
- } else {
- var g;
- if (typeof window !== "undefined") {
- g = window;
- } else if (typeof global !== "undefined") {
- g = global;
- } else if (typeof self !== "undefined") {
- g = self;
- } else {
- g = this;
- }
- g.introJs = f();
- }
-})(function () {
- //Default config/variables
- var VERSION = '2.9.3';
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.introJs = factory());
+}(this, (function () { 'use strict';
- /**
- * IntroJs main class
- *
- * @class IntroJs
- */
- function IntroJs(obj) {
- this._targetElement = obj;
- this._introItems = [];
+ function _typeof(obj) {
+ "@babel/helpers - typeof";
- this._options = {
- /* Next button label in tooltip box */
- nextLabel: 'Next →',
- /* Previous button label in tooltip box */
- prevLabel: '← Back',
- /* Skip button label in tooltip box */
- skipLabel: 'Skip',
- /* Done button label in tooltip box */
- doneLabel: 'Done',
- /* Hide previous button in the first step? Otherwise, it will be disabled button. */
- hidePrev: false,
- /* Hide next button in the last step? Otherwise, it will be disabled button. */
- hideNext: false,
- /* Default tooltip box position */
- tooltipPosition: 'bottom',
- /* Next CSS class for tooltip boxes */
- tooltipClass: '',
- /* CSS class that is added to the helperLayer */
- highlightClass: '',
- /* Close introduction when pressing Escape button? */
- exitOnEsc: true,
- /* Close introduction when clicking on overlay layer? */
- exitOnOverlayClick: true,
- /* Show step numbers in introduction? */
- showStepNumbers: true,
- /* Let user use keyboard to navigate the tour? */
- keyboardNavigation: true,
- /* Show tour control buttons? */
- showButtons: true,
- /* Show tour bullets? */
- showBullets: true,
- /* Show tour progress? */
- showProgress: false,
- /* Scroll to highlighted element? */
- scrollToElement: true,
- /*
- * Should we scroll the tooltip or target element?
- *
- * Options are: 'element' or 'tooltip'
- */
- scrollTo: 'element',
- /* Padding to add after scrolling when element is not in the viewport (in pixels) */
- scrollPadding: 30,
- /* Set the overlay opacity */
- overlayOpacity: 0.8,
- /* Precedence of positions, when auto is enabled */
- positionPrecedence: ["bottom", "top", "right", "left"],
- /* Disable an interaction with element? */
- disableInteraction: false,
- /* Set how much padding to be used around helper element */
- helperElementPadding: 10,
- /* Default hint position */
- hintPosition: 'top-middle',
- /* Hint button label */
- hintButtonLabel: 'Got it',
- /* Adding animation to hints? */
- hintAnimation: true,
- /* additional classes to put on the buttons */
- buttonClass: "introjs-button"
- };
- }
-
- /**
- * Initiate a new introduction/guide from an element in the page
- *
- * @api private
- * @method _introForElement
- * @param {Object} targetElm
- * @param {String} group
- * @returns {Boolean} Success or not?
- */
- function _introForElement(targetElm, group) {
- var allIntroSteps = targetElm.querySelectorAll("*[data-intro]"),
- introItems = [];
-
- if (this._options.steps) {
- //use steps passed programmatically
- _forEach(this._options.steps, function (step) {
- var currentItem = _cloneObject(step);
-
- //set the step
- currentItem.step = introItems.length + 1;
-
- //use querySelector function only when developer used CSS selector
- if (typeof (currentItem.element) === 'string') {
- //grab the element with given selector from the page
- currentItem.element = document.querySelector(currentItem.element);
- }
-
- //intro without element
- if (typeof (currentItem.element) === 'undefined' || currentItem.element === null) {
- var floatingElementQuery = document.querySelector(".introjsFloatingElement");
-
- if (floatingElementQuery === null) {
- floatingElementQuery = document.createElement('div');
- floatingElementQuery.className = 'introjsFloatingElement';
-
- document.body.appendChild(floatingElementQuery);
- }
-
- currentItem.element = floatingElementQuery;
- currentItem.position = 'floating';
- }
-
- currentItem.scrollTo = currentItem.scrollTo || this._options.scrollTo;
-
- if (typeof (currentItem.disableInteraction) === 'undefined') {
- currentItem.disableInteraction = this._options.disableInteraction;
- }
-
- if (currentItem.element !== null) {
- introItems.push(currentItem);
- }
- }.bind(this));
-
- } else {
- //use steps from data-* annotations
- var elmsLength = allIntroSteps.length;
- var disableInteraction;
-
- //if there's no element to intro
- if (elmsLength < 1) {
- return false;
- }
-
- _forEach(allIntroSteps, function (currentElement) {
-
- // PR #80
- // start intro for groups of elements
- if (group && (currentElement.getAttribute("data-intro-group") !== group)) {
- return;
- }
-
- // skip hidden elements
- if (currentElement.style.display === 'none') {
- return;
- }
-
- var step = parseInt(currentElement.getAttribute('data-step'), 10);
-
- if (typeof (currentElement.getAttribute('data-disable-interaction')) !== 'undefined') {
- disableInteraction = !!currentElement.getAttribute('data-disable-interaction');
- } else {
- disableInteraction = this._options.disableInteraction;
- }
-
- if (step > 0) {
- introItems[step - 1] = {
- element: currentElement,
- intro: currentElement.getAttribute('data-intro'),
- step: parseInt(currentElement.getAttribute('data-step'), 10),
- tooltipClass: currentElement.getAttribute('data-tooltipclass'),
- highlightClass: currentElement.getAttribute('data-highlightclass'),
- position: currentElement.getAttribute('data-position') || this._options.tooltipPosition,
- scrollTo: currentElement.getAttribute('data-scrollto') || this._options.scrollTo,
- disableInteraction: disableInteraction
- };
- }
- }.bind(this));
-
- //next add intro items without data-step
- //todo: we need a cleanup here, two loops are redundant
- var nextStep = 0;
-
- _forEach(allIntroSteps, function (currentElement) {
-
- // PR #80
- // start intro for groups of elements
- if (group && (currentElement.getAttribute("data-intro-group") !== group)) {
- return;
- }
-
- if (currentElement.getAttribute('data-step') === null) {
-
- while (true) {
- if (typeof introItems[nextStep] === 'undefined') {
- break;
- } else {
- nextStep++;
- }
- }
-
- if (typeof (currentElement.getAttribute('data-disable-interaction')) !== 'undefined') {
- disableInteraction = !!currentElement.getAttribute('data-disable-interaction');
- } else {
- disableInteraction = this._options.disableInteraction;
- }
-
- introItems[nextStep] = {
- element: currentElement,
- intro: currentElement.getAttribute('data-intro'),
- step: nextStep + 1,
- tooltipClass: currentElement.getAttribute('data-tooltipclass'),
- highlightClass: currentElement.getAttribute('data-highlightclass'),
- position: currentElement.getAttribute('data-position') || this._options.tooltipPosition,
- scrollTo: currentElement.getAttribute('data-scrollto') || this._options.scrollTo,
- disableInteraction: disableInteraction
- };
- }
- }.bind(this));
- }
-
- //removing undefined/null elements
- var tempIntroItems = [];
- for (var z = 0; z < introItems.length; z++) {
- if (introItems[z]) {
- // copy non-falsy values to the end of the array
- tempIntroItems.push(introItems[z]);
- }
- }
-
- introItems = tempIntroItems;
-
- //Ok, sort all items with given steps
- introItems.sort(function (a, b) {
- return a.step - b.step;
- });
-
- //set it to the introJs object
- this._introItems = introItems;
-
- //add overlay layer to the page
- if(_addOverlayLayer.call(this, targetElm)) {
- //then, start the show
- _nextStep.call(this);
-
- if (this._options.keyboardNavigation) {
- DOMEvent.on(window, 'keydown', _onKeyDown, this, true);
- }
- //for window resize
- DOMEvent.on(window, 'resize', _onResize, this, true);
- }
- return false;
- }
-
- function _onResize () {
- this.refresh.call(this);
- }
-
- /**
- * on keyCode:
- * https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
- * This feature has been removed from the Web standards.
- * Though some browsers may still support it, it is in
- * the process of being dropped.
- * Instead, you should use KeyboardEvent.code,
- * if it's implemented.
- *
- * jQuery's approach is to test for
- * (1) e.which, then
- * (2) e.charCode, then
- * (3) e.keyCode
- * https://github.com/jquery/jquery/blob/a6b0705294d336ae2f63f7276de0da1195495363/src/event.js#L638
- *
- * @param type var
- * @return type
- */
- function _onKeyDown (e) {
- var code = (e.code === null) ? e.which : e.code;
-
- // if code/e.which is null
- if (code === null) {
- code = (e.charCode === null) ? e.keyCode : e.charCode;
- }
-
- if ((code === 'Escape' || code === 27) && this._options.exitOnEsc === true) {
- //escape key pressed, exit the intro
- //check if exit callback is defined
- _exitIntro.call(this, this._targetElement);
- } else if (code === 'ArrowLeft' || code === 37) {
- //left arrow
- _previousStep.call(this);
- } else if (code === 'ArrowRight' || code === 39) {
- //right arrow
- _nextStep.call(this);
- } else if (code === 'Enter' || code === 13) {
- //srcElement === ie
- var target = e.target || e.srcElement;
- if (target && target.className.match('introjs-prevbutton')) {
- //user hit enter while focusing on previous button
- _previousStep.call(this);
- } else if (target && target.className.match('introjs-skipbutton')) {
- //user hit enter while focusing on skip button
- if (this._introItems.length - 1 === this._currentStep && typeof (this._introCompleteCallback) === 'function') {
- this._introCompleteCallback.call(this);
- }
-
- _exitIntro.call(this, this._targetElement);
- } else if (target && target.getAttribute('data-stepnumber')) {
- // user hit enter while focusing on step bullet
- target.click();
- } else {
- //default behavior for responding to enter
- _nextStep.call(this);
- }
-
- //prevent default behaviour on hitting Enter, to prevent steps being skipped in some browsers
- if(e.preventDefault) {
- e.preventDefault();
- } else {
- e.returnValue = false;
- }
- }
- }
-
- /*
- * makes a copy of the object
- * @api private
- * @method _cloneObject
- */
- function _cloneObject(object) {
- if (object === null || typeof (object) !== 'object' || typeof (object.nodeType) !== 'undefined') {
- return object;
- }
- var temp = {};
- for (var key in object) {
- if (typeof(window.jQuery) !== 'undefined' && object[key] instanceof window.jQuery) {
- temp[key] = object[key];
- } else {
- temp[key] = _cloneObject(object[key]);
- }
- }
- return temp;
- }
- /**
- * Go to specific step of introduction
- *
- * @api private
- * @method _goToStep
- */
- function _goToStep(step) {
- //because steps starts with zero
- this._currentStep = step - 2;
- if (typeof (this._introItems) !== 'undefined') {
- _nextStep.call(this);
- }
- }
-
- /**
- * Go to the specific step of introduction with the explicit [data-step] number
- *
- * @api private
- * @method _goToStepNumber
- */
- function _goToStepNumber(step) {
- this._currentStepNumber = step;
- if (typeof (this._introItems) !== 'undefined') {
- _nextStep.call(this);
- }
- }
-
- /**
- * Go to next step on intro
- *
- * @api private
- * @method _nextStep
- */
- function _nextStep() {
- this._direction = 'forward';
-
- if (typeof (this._currentStepNumber) !== 'undefined') {
- _forEach(this._introItems, function (item, i) {
- if( item.step === this._currentStepNumber ) {
- this._currentStep = i - 1;
- this._currentStepNumber = undefined;
- }
- }.bind(this));
- }
-
- if (typeof (this._currentStep) === 'undefined') {
- this._currentStep = 0;
- } else {
- ++this._currentStep;
- }
-
- var nextStep = this._introItems[this._currentStep];
- var continueStep = true;
-
- if (typeof (this._introBeforeChangeCallback) !== 'undefined') {
- continueStep = this._introBeforeChangeCallback.call(this, nextStep.element);
- }
-
- // if `onbeforechange` returned `false`, stop displaying the element
- if (continueStep === false) {
- --this._currentStep;
- return false;
- }
-
- if ((this._introItems.length) <= this._currentStep) {
- //end of the intro
- //check if any callback is defined
- if (typeof (this._introCompleteCallback) === 'function') {
- this._introCompleteCallback.call(this);
- }
- _exitIntro.call(this, this._targetElement);
- return;
- }
-
- _showElement.call(this, nextStep);
- }
-
- /**
- * Go to previous step on intro
- *
- * @api private
- * @method _previousStep
- */
- function _previousStep() {
- this._direction = 'backward';
-
- if (this._currentStep === 0) {
- return false;
- }
-
- --this._currentStep;
-
- var nextStep = this._introItems[this._currentStep];
- var continueStep = true;
-
- if (typeof (this._introBeforeChangeCallback) !== 'undefined') {
- continueStep = this._introBeforeChangeCallback.call(this, nextStep.element);
- }
-
- // if `onbeforechange` returned `false`, stop displaying the element
- if (continueStep === false) {
- ++this._currentStep;
- return false;
- }
-
- _showElement.call(this, nextStep);
- }
-
- /**
- * Update placement of the intro objects on the screen
- * @api private
- */
- function _refresh() {
- // re-align intros
- _setHelperLayerPosition.call(this, document.querySelector('.introjs-helperLayer'));
- _setHelperLayerPosition.call(this, document.querySelector('.introjs-tooltipReferenceLayer'));
- _setHelperLayerPosition.call(this, document.querySelector('.introjs-disableInteraction'));
-
- // re-align tooltip
- if(this._currentStep !== undefined && this._currentStep !== null) {
- var oldHelperNumberLayer = document.querySelector('.introjs-helperNumberLayer'),
- oldArrowLayer = document.querySelector('.introjs-arrow'),
- oldtooltipContainer = document.querySelector('.introjs-tooltip');
- _placeTooltip.call(this, this._introItems[this._currentStep].element, oldtooltipContainer, oldArrowLayer, oldHelperNumberLayer);
- }
-
- //re-align hints
- _reAlignHints.call(this);
- return this;
- }
-
- /**
- * Exit from intro
- *
- * @api private
- * @method _exitIntro
- * @param {Object} targetElement
- * @param {Boolean} force - Setting to `true` will skip the result of beforeExit callback
- */
- function _exitIntro(targetElement, force) {
- var continueExit = true;
-
- // calling onbeforeexit callback
- //
- // If this callback return `false`, it would halt the process
- if (this._introBeforeExitCallback !== undefined) {
- continueExit = this._introBeforeExitCallback.call(this);
- }
-
- // skip this check if `force` parameter is `true`
- // otherwise, if `onbeforeexit` returned `false`, don't exit the intro
- if (!force && continueExit === false) return;
-
- //remove overlay layers from the page
- var overlayLayers = targetElement.querySelectorAll('.introjs-overlay');
-
- if (overlayLayers && overlayLayers.length) {
- _forEach(overlayLayers, function (overlayLayer) {
- overlayLayer.style.opacity = 0;
- window.setTimeout(function () {
- if (this.parentNode) {
- this.parentNode.removeChild(this);
- }
- }.bind(overlayLayer), 500);
- }.bind(this));
- }
-
- //remove all helper layers
- var helperLayer = targetElement.querySelector('.introjs-helperLayer');
- if (helperLayer) {
- helperLayer.parentNode.removeChild(helperLayer);
- }
-
- var referenceLayer = targetElement.querySelector('.introjs-tooltipReferenceLayer');
- if (referenceLayer) {
- referenceLayer.parentNode.removeChild(referenceLayer);
- }
-
- //remove disableInteractionLayer
- var disableInteractionLayer = targetElement.querySelector('.introjs-disableInteraction');
- if (disableInteractionLayer) {
- disableInteractionLayer.parentNode.removeChild(disableInteractionLayer);
- }
-
- //remove intro floating element
- var floatingElement = document.querySelector('.introjsFloatingElement');
- if (floatingElement) {
- floatingElement.parentNode.removeChild(floatingElement);
- }
-
- _removeShowElement();
-
- //remove `introjs-fixParent` class from the elements
- var fixParents = document.querySelectorAll('.introjs-fixParent');
- _forEach(fixParents, function (parent) {
- _removeClass(parent, /introjs-fixParent/g);
- });
-
- //clean listeners
- DOMEvent.off(window, 'keydown', _onKeyDown, this, true);
- DOMEvent.off(window, 'resize', _onResize, this, true);
-
- //check if any callback is defined
- if (this._introExitCallback !== undefined) {
- this._introExitCallback.call(this);
- }
-
- //set the step to zero
- this._currentStep = undefined;
- }
-
- /**
- * Render tooltip box in the page
- *
- * @api private
- * @method _placeTooltip
- * @param {HTMLElement} targetElement
- * @param {HTMLElement} tooltipLayer
- * @param {HTMLElement} arrowLayer
- * @param {HTMLElement} helperNumberLayer
- * @param {Boolean} hintMode
- */
- function _placeTooltip(targetElement, tooltipLayer, arrowLayer, helperNumberLayer, hintMode) {
- var tooltipCssClass = '',
- currentStepObj,
- tooltipOffset,
- targetOffset,
- windowSize,
- currentTooltipPosition;
-
- hintMode = hintMode || false;
-
- //reset the old style
- tooltipLayer.style.top = null;
- tooltipLayer.style.right = null;
- tooltipLayer.style.bottom = null;
- tooltipLayer.style.left = null;
- tooltipLayer.style.marginLeft = null;
- tooltipLayer.style.marginTop = null;
-
- arrowLayer.style.display = 'inherit';
-
- if (typeof(helperNumberLayer) !== 'undefined' && helperNumberLayer !== null) {
- helperNumberLayer.style.top = null;
- helperNumberLayer.style.left = null;
- }
-
- //prevent error when `this._currentStep` is undefined
- if (!this._introItems[this._currentStep]) return;
-
- //if we have a custom css class for each step
- currentStepObj = this._introItems[this._currentStep];
- if (typeof (currentStepObj.tooltipClass) === 'string') {
- tooltipCssClass = currentStepObj.tooltipClass;
- } else {
- tooltipCssClass = this._options.tooltipClass;
- }
-
- tooltipLayer.className = ('introjs-tooltip ' + tooltipCssClass).replace(/^\s+|\s+$/g, '');
- tooltipLayer.setAttribute('role', 'dialog');
-
- currentTooltipPosition = this._introItems[this._currentStep].position;
-
- // Floating is always valid, no point in calculating
- if (currentTooltipPosition !== "floating") {
- currentTooltipPosition = _determineAutoPosition.call(this, targetElement, tooltipLayer, currentTooltipPosition);
- }
-
- var tooltipLayerStyleLeft;
- targetOffset = _getOffset(targetElement);
- tooltipOffset = _getOffset(tooltipLayer);
- windowSize = _getWinSize();
-
- _addClass(tooltipLayer, 'introjs-' + currentTooltipPosition);
-
- switch (currentTooltipPosition) {
- case 'top-right-aligned':
- arrowLayer.className = 'introjs-arrow bottom-right';
-
- var tooltipLayerStyleRight = 0;
- _checkLeft(targetOffset, tooltipLayerStyleRight, tooltipOffset, tooltipLayer);
- tooltipLayer.style.bottom = (targetOffset.height + 20) + 'px';
- break;
-
- case 'top-middle-aligned':
- arrowLayer.className = 'introjs-arrow bottom-middle';
-
- var tooltipLayerStyleLeftRight = targetOffset.width / 2 - tooltipOffset.width / 2;
-
- // a fix for middle aligned hints
- if (hintMode) {
- tooltipLayerStyleLeftRight += 5;
- }
-
- if (_checkLeft(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, tooltipLayer)) {
- tooltipLayer.style.right = null;
- _checkRight(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, windowSize, tooltipLayer);
- }
- tooltipLayer.style.bottom = (targetOffset.height + 20) + 'px';
- break;
-
- case 'top-left-aligned':
- // top-left-aligned is the same as the default top
- case 'top':
- arrowLayer.className = 'introjs-arrow bottom';
-
- tooltipLayerStyleLeft = (hintMode) ? 0 : 15;
-
- _checkRight(targetOffset, tooltipLayerStyleLeft, tooltipOffset, windowSize, tooltipLayer);
- tooltipLayer.style.bottom = (targetOffset.height + 20) + 'px';
- break;
- case 'right':
- tooltipLayer.style.left = (targetOffset.width + 20) + 'px';
- if (targetOffset.top + tooltipOffset.height > windowSize.height) {
- // In this case, right would have fallen below the bottom of the screen.
- // Modify so that the bottom of the tooltip connects with the target
- arrowLayer.className = "introjs-arrow left-bottom";
- tooltipLayer.style.top = "-" + (tooltipOffset.height - targetOffset.height - 20) + "px";
- } else {
- arrowLayer.className = 'introjs-arrow left';
- }
- break;
- case 'left':
- if (!hintMode && this._options.showStepNumbers === true) {
- tooltipLayer.style.top = '15px';
- }
-
- if (targetOffset.top + tooltipOffset.height > windowSize.height) {
- // In this case, left would have fallen below the bottom of the screen.
- // Modify so that the bottom of the tooltip connects with the target
- tooltipLayer.style.top = "-" + (tooltipOffset.height - targetOffset.height - 20) + "px";
- arrowLayer.className = 'introjs-arrow right-bottom';
- } else {
- arrowLayer.className = 'introjs-arrow right';
- }
- tooltipLayer.style.right = (targetOffset.width + 20) + 'px';
-
- break;
- case 'floating':
- arrowLayer.style.display = 'none';
-
- //we have to adjust the top and left of layer manually for intro items without element
- tooltipLayer.style.left = '50%';
- tooltipLayer.style.top = '50%';
- tooltipLayer.style.marginLeft = '-' + (tooltipOffset.width / 2) + 'px';
- tooltipLayer.style.marginTop = '-' + (tooltipOffset.height / 2) + 'px';
-
- if (typeof(helperNumberLayer) !== 'undefined' && helperNumberLayer !== null) {
- helperNumberLayer.style.left = '-' + ((tooltipOffset.width / 2) + 18) + 'px';
- helperNumberLayer.style.top = '-' + ((tooltipOffset.height / 2) + 18) + 'px';
- }
-
- break;
- case 'bottom-right-aligned':
- arrowLayer.className = 'introjs-arrow top-right';
-
- tooltipLayerStyleRight = 0;
- _checkLeft(targetOffset, tooltipLayerStyleRight, tooltipOffset, tooltipLayer);
- tooltipLayer.style.top = (targetOffset.height + 20) + 'px';
- break;
-
- case 'bottom-middle-aligned':
- arrowLayer.className = 'introjs-arrow top-middle';
-
- tooltipLayerStyleLeftRight = targetOffset.width / 2 - tooltipOffset.width / 2;
-
- // a fix for middle aligned hints
- if (hintMode) {
- tooltipLayerStyleLeftRight += 5;
- }
-
- if (_checkLeft(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, tooltipLayer)) {
- tooltipLayer.style.right = null;
- _checkRight(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, windowSize, tooltipLayer);
- }
- tooltipLayer.style.top = (targetOffset.height + 20) + 'px';
- break;
-
- // case 'bottom-left-aligned':
- // Bottom-left-aligned is the same as the default bottom
- // case 'bottom':
- // Bottom going to follow the default behavior
- default:
- arrowLayer.className = 'introjs-arrow top';
-
- tooltipLayerStyleLeft = 0;
- _checkRight(targetOffset, tooltipLayerStyleLeft, tooltipOffset, windowSize, tooltipLayer);
- tooltipLayer.style.top = (targetOffset.height + 20) + 'px';
- }
- }
-
- /**
- * Set tooltip left so it doesn't go off the right side of the window
- *
- * @return boolean true, if tooltipLayerStyleLeft is ok. false, otherwise.
- */
- function _checkRight(targetOffset, tooltipLayerStyleLeft, tooltipOffset, windowSize, tooltipLayer) {
- if (targetOffset.left + tooltipLayerStyleLeft + tooltipOffset.width > windowSize.width) {
- // off the right side of the window
- tooltipLayer.style.left = (windowSize.width - tooltipOffset.width - targetOffset.left) + 'px';
- return false;
- }
- tooltipLayer.style.left = tooltipLayerStyleLeft + 'px';
- return true;
- }
-
- /**
- * Set tooltip right so it doesn't go off the left side of the window
- *
- * @return boolean true, if tooltipLayerStyleRight is ok. false, otherwise.
- */
- function _checkLeft(targetOffset, tooltipLayerStyleRight, tooltipOffset, tooltipLayer) {
- if (targetOffset.left + targetOffset.width - tooltipLayerStyleRight - tooltipOffset.width < 0) {
- // off the left side of the window
- tooltipLayer.style.left = (-targetOffset.left) + 'px';
- return false;
- }
- tooltipLayer.style.right = tooltipLayerStyleRight + 'px';
- return true;
- }
-
- /**
- * Determines the position of the tooltip based on the position precedence and availability
- * of screen space.
- *
- * @param {Object} targetElement
- * @param {Object} tooltipLayer
- * @param {String} desiredTooltipPosition
- * @return {String} calculatedPosition
- */
- function _determineAutoPosition(targetElement, tooltipLayer, desiredTooltipPosition) {
-
- // Take a clone of position precedence. These will be the available
- var possiblePositions = this._options.positionPrecedence.slice();
-
- var windowSize = _getWinSize();
- var tooltipHeight = _getOffset(tooltipLayer).height + 10;
- var tooltipWidth = _getOffset(tooltipLayer).width + 20;
- var targetElementRect = targetElement.getBoundingClientRect();
-
- // If we check all the possible areas, and there are no valid places for the tooltip, the element
- // must take up most of the screen real estate. Show the tooltip floating in the middle of the screen.
- var calculatedPosition = "floating";
-
- /*
- * auto determine position
- */
-
- // Check for space below
- if (targetElementRect.bottom + tooltipHeight + tooltipHeight > windowSize.height) {
- _removeEntry(possiblePositions, "bottom");
- }
-
- // Check for space above
- if (targetElementRect.top - tooltipHeight < 0) {
- _removeEntry(possiblePositions, "top");
- }
-
- // Check for space to the right
- if (targetElementRect.right + tooltipWidth > windowSize.width) {
- _removeEntry(possiblePositions, "right");
- }
-
- // Check for space to the left
- if (targetElementRect.left - tooltipWidth < 0) {
- _removeEntry(possiblePositions, "left");
- }
-
- // @var {String} ex: 'right-aligned'
- var desiredAlignment = (function (pos) {
- var hyphenIndex = pos.indexOf('-');
- if (hyphenIndex !== -1) {
- // has alignment
- return pos.substr(hyphenIndex);
- }
- return '';
- })(desiredTooltipPosition || '');
-
- // strip alignment from position
- if (desiredTooltipPosition) {
- // ex: "bottom-right-aligned"
- // should return 'bottom'
- desiredTooltipPosition = desiredTooltipPosition.split('-')[0];
- }
-
- if (possiblePositions.length) {
- if (desiredTooltipPosition !== "auto" &&
- possiblePositions.indexOf(desiredTooltipPosition) > -1) {
- // If the requested position is in the list, choose that
- calculatedPosition = desiredTooltipPosition;
- } else {
- // Pick the first valid position, in order
- calculatedPosition = possiblePositions[0];
- }
- }
-
- // only top and bottom positions have optional alignments
- if (['top', 'bottom'].indexOf(calculatedPosition) !== -1) {
- calculatedPosition += _determineAutoAlignment(targetElementRect.left, tooltipWidth, windowSize, desiredAlignment);
- }
-
- return calculatedPosition;
- }
-
- /**
- * auto-determine alignment
- * @param {Integer} offsetLeft
- * @param {Integer} tooltipWidth
- * @param {Object} windowSize
- * @param {String} desiredAlignment
- * @return {String} calculatedAlignment
- */
- function _determineAutoAlignment (offsetLeft, tooltipWidth, windowSize, desiredAlignment) {
- var halfTooltipWidth = tooltipWidth / 2,
- winWidth = Math.min(windowSize.width, window.screen.width),
- possibleAlignments = ['-left-aligned', '-middle-aligned', '-right-aligned'],
- calculatedAlignment = '';
-
- // valid left must be at least a tooltipWidth
- // away from right side
- if (winWidth - offsetLeft < tooltipWidth) {
- _removeEntry(possibleAlignments, '-left-aligned');
- }
-
- // valid middle must be at least half
- // width away from both sides
- if (offsetLeft < halfTooltipWidth ||
- winWidth - offsetLeft < halfTooltipWidth) {
- _removeEntry(possibleAlignments, '-middle-aligned');
- }
-
- // valid right must be at least a tooltipWidth
- // width away from left side
- if (offsetLeft < tooltipWidth) {
- _removeEntry(possibleAlignments, '-right-aligned');
- }
-
- if (possibleAlignments.length) {
- if (possibleAlignments.indexOf(desiredAlignment) !== -1) {
- // the desired alignment is valid
- calculatedAlignment = desiredAlignment;
- } else {
- // pick the first valid position, in order
- calculatedAlignment = possibleAlignments[0];
- }
- } else {
- // if screen width is too small
- // for ANY alignment, middle is
- // probably the best for visibility
- calculatedAlignment = '-middle-aligned';
- }
-
- return calculatedAlignment;
- }
-
- /**
- * Remove an entry from a string array if it's there, does nothing if it isn't there.
- *
- * @param {Array} stringArray
- * @param {String} stringToRemove
- */
- function _removeEntry(stringArray, stringToRemove) {
- if (stringArray.indexOf(stringToRemove) > -1) {
- stringArray.splice(stringArray.indexOf(stringToRemove), 1);
- }
- }
-
- /**
- * Update the position of the helper layer on the screen
- *
- * @api private
- * @method _setHelperLayerPosition
- * @param {Object} helperLayer
- */
- function _setHelperLayerPosition(helperLayer) {
- if (helperLayer) {
- //prevent error when `this._currentStep` in undefined
- if (!this._introItems[this._currentStep]) return;
-
- var currentElement = this._introItems[this._currentStep],
- elementPosition = _getOffset(currentElement.element),
- widthHeightPadding = this._options.helperElementPadding;
-
- // If the target element is fixed, the tooltip should be fixed as well.
- // Otherwise, remove a fixed class that may be left over from the previous
- // step.
- if (_isFixed(currentElement.element)) {
- _addClass(helperLayer, 'introjs-fixedTooltip');
- } else {
- _removeClass(helperLayer, 'introjs-fixedTooltip');
- }
-
- if (currentElement.position === 'floating') {
- widthHeightPadding = 0;
- }
-
- //set new position to helper layer
- helperLayer.style.cssText = 'width: ' + (elementPosition.width + widthHeightPadding) + 'px; ' +
- 'height:' + (elementPosition.height + widthHeightPadding) + 'px; ' +
- 'top:' + (elementPosition.top - widthHeightPadding / 2) + 'px;' +
- 'left: ' + (elementPosition.left - widthHeightPadding / 2) + 'px;';
-
- }
- }
-
- /**
- * Add disableinteraction layer and adjust the size and position of the layer
- *
- * @api private
- * @method _disableInteraction
- */
- function _disableInteraction() {
- var disableInteractionLayer = document.querySelector('.introjs-disableInteraction');
-
- if (disableInteractionLayer === null) {
- disableInteractionLayer = document.createElement('div');
- disableInteractionLayer.className = 'introjs-disableInteraction';
- this._targetElement.appendChild(disableInteractionLayer);
- }
-
- _setHelperLayerPosition.call(this, disableInteractionLayer);
- }
-
- /**
- * Setting anchors to behave like buttons
- *
- * @api private
- * @method _setAnchorAsButton
- */
- function _setAnchorAsButton(anchor){
- anchor.setAttribute('role', 'button');
- anchor.tabIndex = 0;
- }
-
- /**
- * Show an element on the page
- *
- * @api private
- * @method _showElement
- * @param {Object} targetElement
- */
- function _showElement(targetElement) {
- if (typeof (this._introChangeCallback) !== 'undefined') {
- this._introChangeCallback.call(this, targetElement.element);
- }
-
- var self = this,
- oldHelperLayer = document.querySelector('.introjs-helperLayer'),
- oldReferenceLayer = document.querySelector('.introjs-tooltipReferenceLayer'),
- highlightClass = 'introjs-helperLayer',
- nextTooltipButton,
- prevTooltipButton,
- skipTooltipButton,
- scrollParent;
-
- //check for a current step highlight class
- if (typeof (targetElement.highlightClass) === 'string') {
- highlightClass += (' ' + targetElement.highlightClass);
- }
- //check for options highlight class
- if (typeof (this._options.highlightClass) === 'string') {
- highlightClass += (' ' + this._options.highlightClass);
- }
-
- if (oldHelperLayer !== null) {
- var oldHelperNumberLayer = oldReferenceLayer.querySelector('.introjs-helperNumberLayer'),
- oldtooltipLayer = oldReferenceLayer.querySelector('.introjs-tooltiptext'),
- oldArrowLayer = oldReferenceLayer.querySelector('.introjs-arrow'),
- oldtooltipContainer = oldReferenceLayer.querySelector('.introjs-tooltip');
-
- skipTooltipButton = oldReferenceLayer.querySelector('.introjs-skipbutton');
- prevTooltipButton = oldReferenceLayer.querySelector('.introjs-prevbutton');
- nextTooltipButton = oldReferenceLayer.querySelector('.introjs-nextbutton');
-
- //update or reset the helper highlight class
- oldHelperLayer.className = highlightClass;
- //hide the tooltip
- oldtooltipContainer.style.opacity = 0;
- oldtooltipContainer.style.display = "none";
-
- if (oldHelperNumberLayer !== null) {
- var lastIntroItem = this._introItems[(targetElement.step - 2 >= 0 ? targetElement.step - 2 : 0)];
-
- if (lastIntroItem !== null && (this._direction === 'forward' && lastIntroItem.position === 'floating') || (this._direction === 'backward' && targetElement.position === 'floating')) {
- oldHelperNumberLayer.style.opacity = 0;
- }
- }
-
- // scroll to element
- scrollParent = _getScrollParent( targetElement.element );
-
- if (scrollParent !== document.body) {
- // target is within a scrollable element
- _scrollParentToElement(scrollParent, targetElement.element);
- }
-
- // set new position to helper layer
- _setHelperLayerPosition.call(self, oldHelperLayer);
- _setHelperLayerPosition.call(self, oldReferenceLayer);
-
- //remove `introjs-fixParent` class from the elements
- var fixParents = document.querySelectorAll('.introjs-fixParent');
- _forEach(fixParents, function (parent) {
- _removeClass(parent, /introjs-fixParent/g);
- });
-
- //remove old classes if the element still exist
- _removeShowElement();
-
- //we should wait until the CSS3 transition is competed (it's 0.3 sec) to prevent incorrect `height` and `width` calculation
- if (self._lastShowElementTimer) {
- window.clearTimeout(self._lastShowElementTimer);
- }
-
- self._lastShowElementTimer = window.setTimeout(function() {
- //set current step to the label
- if (oldHelperNumberLayer !== null) {
- oldHelperNumberLayer.innerHTML = targetElement.step;
- }
- //set current tooltip text
- oldtooltipLayer.innerHTML = targetElement.intro;
- //set the tooltip position
- oldtooltipContainer.style.display = "block";
- _placeTooltip.call(self, targetElement.element, oldtooltipContainer, oldArrowLayer, oldHelperNumberLayer);
-
- //change active bullet
- if (self._options.showBullets) {
- oldReferenceLayer.querySelector('.introjs-bullets li > a.active').className = '';
- oldReferenceLayer.querySelector('.introjs-bullets li > a[data-stepnumber="' + targetElement.step + '"]').className = 'active';
- }
- oldReferenceLayer.querySelector('.introjs-progress .introjs-progressbar').style.cssText = 'width:' + _getProgress.call(self) + '%;';
- oldReferenceLayer.querySelector('.introjs-progress .introjs-progressbar').setAttribute('aria-valuenow', _getProgress.call(self));
-
- //show the tooltip
- oldtooltipContainer.style.opacity = 1;
- if (oldHelperNumberLayer) oldHelperNumberLayer.style.opacity = 1;
-
- //reset button focus
- if (typeof skipTooltipButton !== "undefined" && skipTooltipButton !== null && /introjs-donebutton/gi.test(skipTooltipButton.className)) {
- // skip button is now "done" button
- skipTooltipButton.focus();
- } else if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
- //still in the tour, focus on next
- nextTooltipButton.focus();
- }
-
- // change the scroll of the window, if needed
- _scrollTo.call(self, targetElement.scrollTo, targetElement, oldtooltipLayer);
- }, 350);
-
- // end of old element if-else condition
- } else {
- var helperLayer = document.createElement('div'),
- referenceLayer = document.createElement('div'),
- arrowLayer = document.createElement('div'),
- tooltipLayer = document.createElement('div'),
- tooltipTextLayer = document.createElement('div'),
- bulletsLayer = document.createElement('div'),
- progressLayer = document.createElement('div'),
- buttonsLayer = document.createElement('div');
-
- helperLayer.className = highlightClass;
- referenceLayer.className = 'introjs-tooltipReferenceLayer';
-
- // scroll to element
- scrollParent = _getScrollParent( targetElement.element );
-
- if (scrollParent !== document.body) {
- // target is within a scrollable element
- _scrollParentToElement(scrollParent, targetElement.element);
- }
-
- //set new position to helper layer
- _setHelperLayerPosition.call(self, helperLayer);
- _setHelperLayerPosition.call(self, referenceLayer);
-
- //add helper layer to target element
- this._targetElement.appendChild(helperLayer);
- this._targetElement.appendChild(referenceLayer);
-
- arrowLayer.className = 'introjs-arrow';
-
- tooltipTextLayer.className = 'introjs-tooltiptext';
- tooltipTextLayer.innerHTML = targetElement.intro;
-
- bulletsLayer.className = 'introjs-bullets';
-
- if (this._options.showBullets === false) {
- bulletsLayer.style.display = 'none';
- }
-
- var ulContainer = document.createElement('ul');
- ulContainer.setAttribute('role', 'tablist');
-
- var anchorClick = function () {
- self.goToStep(this.getAttribute('data-stepnumber'));
+ if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
+ _typeof = function (obj) {
+ return typeof obj;
};
-
- _forEach(this._introItems, function (item, i) {
- var innerLi = document.createElement('li');
- var anchorLink = document.createElement('a');
-
- innerLi.setAttribute('role', 'presentation');
- anchorLink.setAttribute('role', 'tab');
-
- anchorLink.onclick = anchorClick;
-
- if (i === (targetElement.step-1)) {
- anchorLink.className = 'active';
- }
-
- _setAnchorAsButton(anchorLink);
- anchorLink.innerHTML = " ";
- anchorLink.setAttribute('data-stepnumber', item.step);
-
- innerLi.appendChild(anchorLink);
- ulContainer.appendChild(innerLi);
- });
-
- bulletsLayer.appendChild(ulContainer);
-
- progressLayer.className = 'introjs-progress';
-
- if (this._options.showProgress === false) {
- progressLayer.style.display = 'none';
- }
- var progressBar = document.createElement('div');
- progressBar.className = 'introjs-progressbar';
- progressBar.setAttribute('role', 'progress');
- progressBar.setAttribute('aria-valuemin', 0);
- progressBar.setAttribute('aria-valuemax', 100);
- progressBar.setAttribute('aria-valuenow', _getProgress.call(this));
- progressBar.style.cssText = 'width:' + _getProgress.call(this) + '%;';
-
- progressLayer.appendChild(progressBar);
-
- buttonsLayer.className = 'introjs-tooltipbuttons';
- if (this._options.showButtons === false) {
- buttonsLayer.style.display = 'none';
- }
-
- tooltipLayer.className = 'introjs-tooltip';
- tooltipLayer.appendChild(tooltipTextLayer);
- tooltipLayer.appendChild(bulletsLayer);
- tooltipLayer.appendChild(progressLayer);
-
- //add helper layer number
- var helperNumberLayer = document.createElement('span');
- if (this._options.showStepNumbers === true) {
- helperNumberLayer.className = 'introjs-helperNumberLayer';
- helperNumberLayer.innerHTML = targetElement.step;
- referenceLayer.appendChild(helperNumberLayer);
- }
-
- tooltipLayer.appendChild(arrowLayer);
- referenceLayer.appendChild(tooltipLayer);
-
- //next button
- nextTooltipButton = document.createElement('a');
-
- nextTooltipButton.onclick = function() {
- if (self._introItems.length - 1 !== self._currentStep) {
- _nextStep.call(self);
- }
- };
-
- _setAnchorAsButton(nextTooltipButton);
- nextTooltipButton.innerHTML = this._options.nextLabel;
-
- //previous button
- prevTooltipButton = document.createElement('a');
-
- prevTooltipButton.onclick = function() {
- if (self._currentStep !== 0) {
- _previousStep.call(self);
- }
- };
-
- _setAnchorAsButton(prevTooltipButton);
- prevTooltipButton.innerHTML = this._options.prevLabel;
-
- //skip button
- skipTooltipButton = document.createElement('a');
- skipTooltipButton.className = this._options.buttonClass + ' introjs-skipbutton ';
- _setAnchorAsButton(skipTooltipButton);
- skipTooltipButton.innerHTML = this._options.skipLabel;
-
- skipTooltipButton.onclick = function() {
- if (self._introItems.length - 1 === self._currentStep && typeof (self._introCompleteCallback) === 'function') {
- self._introCompleteCallback.call(self);
- }
-
- if (self._introItems.length - 1 !== self._currentStep && typeof (self._introExitCallback) === 'function') {
- self._introExitCallback.call(self);
- }
-
- if (typeof(self._introSkipCallback) === 'function') {
- self._introSkipCallback.call(self);
- }
-
- _exitIntro.call(self, self._targetElement);
- };
-
- buttonsLayer.appendChild(skipTooltipButton);
-
- //in order to prevent displaying next/previous button always
- if (this._introItems.length > 1) {
- buttonsLayer.appendChild(prevTooltipButton);
- buttonsLayer.appendChild(nextTooltipButton);
- }
-
- tooltipLayer.appendChild(buttonsLayer);
-
- //set proper position
- _placeTooltip.call(self, targetElement.element, tooltipLayer, arrowLayer, helperNumberLayer);
-
- // change the scroll of the window, if needed
- _scrollTo.call(this, targetElement.scrollTo, targetElement, tooltipLayer);
-
- //end of new element if-else condition
- }
-
- // removing previous disable interaction layer
- var disableInteractionLayer = self._targetElement.querySelector('.introjs-disableInteraction');
- if (disableInteractionLayer) {
- disableInteractionLayer.parentNode.removeChild(disableInteractionLayer);
- }
-
- //disable interaction
- if (targetElement.disableInteraction) {
- _disableInteraction.call(self);
- }
-
- // when it's the first step of tour
- if (this._currentStep === 0 && this._introItems.length > 1) {
- if (typeof skipTooltipButton !== "undefined" && skipTooltipButton !== null) {
- skipTooltipButton.className = this._options.buttonClass + ' introjs-skipbutton';
- }
- if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
- nextTooltipButton.className = this._options.buttonClass + ' introjs-nextbutton';
- }
-
- if (this._options.hidePrev === true) {
- if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
- prevTooltipButton.className = this._options.buttonClass + ' introjs-prevbutton introjs-hidden';
- }
- if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
- _addClass(nextTooltipButton, 'introjs-fullbutton');
- }
- } else {
- if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
- prevTooltipButton.className = this._options.buttonClass + ' introjs-prevbutton introjs-disabled';
- }
- }
-
- if (typeof skipTooltipButton !== "undefined" && skipTooltipButton !== null) {
- skipTooltipButton.innerHTML = this._options.skipLabel;
- }
- } else if (this._introItems.length - 1 === this._currentStep || this._introItems.length === 1) {
- // last step of tour
- if (typeof skipTooltipButton !== "undefined" && skipTooltipButton !== null) {
- skipTooltipButton.innerHTML = this._options.doneLabel;
- // adding donebutton class in addition to skipbutton
- _addClass(skipTooltipButton, 'introjs-donebutton');
- }
- if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
- prevTooltipButton.className = this._options.buttonClass + ' introjs-prevbutton';
- }
-
- if (this._options.hideNext === true) {
- if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
- nextTooltipButton.className = this._options.buttonClass + ' introjs-nextbutton introjs-hidden';
- }
- if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
- _addClass(prevTooltipButton, 'introjs-fullbutton');
- }
- } else {
- if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
- nextTooltipButton.className = this._options.buttonClass + ' introjs-nextbutton introjs-disabled';
- }
- }
} else {
- // steps between start and end
- if (typeof skipTooltipButton !== "undefined" && skipTooltipButton !== null) {
- skipTooltipButton.className = this._options.buttonClass + ' introjs-skipbutton';
- }
- if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
- prevTooltipButton.className = this._options.buttonClass + ' introjs-prevbutton';
- }
- if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
- nextTooltipButton.className = this._options.buttonClass + ' introjs-nextbutton';
- }
- if (typeof skipTooltipButton !== "undefined" && skipTooltipButton !== null) {
- skipTooltipButton.innerHTML = this._options.skipLabel;
- }
+ _typeof = function (obj) {
+ return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+ };
}
- prevTooltipButton.setAttribute('role', 'button');
- nextTooltipButton.setAttribute('role', 'button');
- skipTooltipButton.setAttribute('role', 'button');
-
- //Set focus on "next" button, so that hitting Enter always moves you onto the next step
- if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
- nextTooltipButton.focus();
- }
-
- _setShowElement(targetElement);
-
- if (typeof (this._introAfterChangeCallback) !== 'undefined') {
- this._introAfterChangeCallback.call(this, targetElement.element);
- }
+ return _typeof(obj);
}
/**
- * To change the scroll of `window` after highlighting an element
+ * Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
+ * via: http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically
*
- * @api private
- * @method _scrollTo
- * @param {String} scrollTo
- * @param {Object} targetElement
- * @param {Object} tooltipLayer
+ * @param obj1
+ * @param obj2
+ * @returns obj3 a new object based on obj1 and obj2
*/
- function _scrollTo(scrollTo, targetElement, tooltipLayer) {
- if (scrollTo === 'off') return;
- var rect;
+ function mergeOptions(obj1, obj2) {
+ var obj3 = {};
+ var attrname;
- if (!this._options.scrollToElement) return;
-
- if (scrollTo === 'tooltip') {
- rect = tooltipLayer.getBoundingClientRect();
- } else {
- rect = targetElement.element.getBoundingClientRect();
+ for (attrname in obj1) {
+ obj3[attrname] = obj1[attrname];
}
- if (!_elementInViewport(targetElement.element)) {
- var winHeight = _getWinSize().height;
- var top = rect.bottom - (rect.bottom - rect.top);
-
- // TODO (afshinm): do we need scroll padding now?
- // I have changed the scroll option and now it scrolls the window to
- // the center of the target element or tooltip.
-
- if (top < 0 || targetElement.element.clientHeight > winHeight) {
- window.scrollBy(0, rect.top - ((winHeight / 2) - (rect.height / 2)) - this._options.scrollPadding); // 30px padding from edge to look nice
-
- //Scroll down
- } else {
- window.scrollBy(0, rect.top - ((winHeight / 2) - (rect.height / 2)) + this._options.scrollPadding); // 30px padding from edge to look nice
- }
+ for (attrname in obj2) {
+ obj3[attrname] = obj2[attrname];
}
+
+ return obj3;
}
/**
- * To remove all show element(s)
+ * Mark any object with an incrementing number
+ * used for keeping track of objects
*
- * @api private
- * @method _removeShowElement
+ * @param Object obj Any object or DOM Element
+ * @param String key
+ * @return Object
*/
- function _removeShowElement() {
- var elms = document.querySelectorAll('.introjs-showElement');
-
- _forEach(elms, function (elm) {
- _removeClass(elm, /introjs-[a-zA-Z]+/g);
- });
- }
-
- /**
- * To set the show element
- * This function set a relative (in most cases) position and changes the z-index
- *
- * @api private
- * @method _setShowElement
- * @param {Object} targetElement
- */
- function _setShowElement(targetElement) {
- var parentElm;
- // we need to add this show element class to the parent of SVG elements
- // because the SVG elements can't have independent z-index
- if (targetElement.element instanceof SVGElement) {
- parentElm = targetElement.element.parentNode;
-
- while (targetElement.element.parentNode !== null) {
- if (!parentElm.tagName || parentElm.tagName.toLowerCase() === 'body') break;
-
- if (parentElm.tagName.toLowerCase() === 'svg') {
- _addClass(parentElm, 'introjs-showElement introjs-relativePosition');
- }
-
- parentElm = parentElm.parentNode;
- }
- }
-
- _addClass(targetElement.element, 'introjs-showElement');
-
- var currentElementPosition = _getPropValue(targetElement.element, 'position');
- if (currentElementPosition !== 'absolute' &&
- currentElementPosition !== 'relative' &&
- currentElementPosition !== 'fixed') {
- //change to new intro item
- _addClass(targetElement.element, 'introjs-relativePosition');
- }
-
- parentElm = targetElement.element.parentNode;
- while (parentElm !== null) {
- if (!parentElm.tagName || parentElm.tagName.toLowerCase() === 'body') break;
-
- //fix The Stacking Context problem.
- //More detail: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context
- var zIndex = _getPropValue(parentElm, 'z-index');
- var opacity = parseFloat(_getPropValue(parentElm, 'opacity'));
- var transform = _getPropValue(parentElm, 'transform') || _getPropValue(parentElm, '-webkit-transform') || _getPropValue(parentElm, '-moz-transform') || _getPropValue(parentElm, '-ms-transform') || _getPropValue(parentElm, '-o-transform');
- if (/[0-9]+/.test(zIndex) || opacity < 1 || (transform !== 'none' && transform !== undefined)) {
- _addClass(parentElm, 'introjs-fixParent');
- }
-
- parentElm = parentElm.parentNode;
- }
- }
-
- /**
- * Iterates arrays
- *
- * @param {Array} arr
- * @param {Function} forEachFnc
- * @param {Function} completeFnc
- * @return {Null}
- */
- function _forEach(arr, forEachFnc, completeFnc) {
- // in case arr is an empty query selector node list
- if (arr) {
- for (var i = 0, len = arr.length; i < len; i++) {
- forEachFnc(arr[i], i);
- }
- }
-
- if (typeof(completeFnc) === 'function') {
- completeFnc();
- }
- }
-
- /**
- * Mark any object with an incrementing number
- * used for keeping track of objects
- *
- * @param Object obj Any object or DOM Element
- * @param String key
- * @return Object
- */
- var _stamp = (function () {
+ var stamp = function () {
var keys = {};
- return function stamp (obj, key) {
-
- // get group key
- key = key || 'introjs-stamp';
-
+ return function stamp(obj) {
+ var key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "introjs-stamp";
// each group increments from 0
- keys[key] = keys[key] || 0;
+ keys[key] = keys[key] || 0; // stamp only once per object
- // stamp only once per object
if (obj[key] === undefined) {
// increment key for each new object
obj[key] = keys[key]++;
@@ -1533,81 +75,107 @@
return obj[key];
};
- })();
+ }();
/**
- * DOMEvent Handles all DOM events
- *
- * methods:
- *
- * on - add event handler
- * off - remove event
- */
- var DOMEvent = (function () {
- function DOMEvent () {
- var events_key = 'introjs_event';
-
+ * Iterates arrays
+ *
+ * @param {Array} arr
+ * @param {Function} forEachFnc
+ * @param {Function} [completeFnc]
+ * @return {Null}
+ */
+ function forEach(arr, forEachFnc, completeFnc) {
+ // in case arr is an empty query selector node list
+ if (arr) {
+ for (var i = 0, len = arr.length; i < len; i++) {
+ forEachFnc(arr[i], i);
+ }
+ }
+
+ if (typeof completeFnc === "function") {
+ completeFnc();
+ }
+ }
+
+ /**
+ * DOMEvent Handles all DOM events
+ *
+ * methods:
+ *
+ * on - add event handler
+ * off - remove event
+ */
+
+ var DOMEvent = function () {
+ function DOMEvent() {
+ var events_key = "introjs_event";
/**
- * Gets a unique ID for an event listener
- *
- * @param Object obj
- * @param String type event type
- * @param Function listener
- * @param Object context
- * @return String
- */
+ * Gets a unique ID for an event listener
+ *
+ * @param obj Object
+ * @param type event type
+ * @param listener Function
+ * @param context Object
+ * @return String
+ */
+
this._id = function (obj, type, listener, context) {
- return type + _stamp(listener) + (context ? '_' + _stamp(context) : '');
+ return type + stamp(listener) + (context ? "_".concat(stamp(context)) : "");
};
-
/**
- * Adds event listener
- *
- * @param Object obj
- * @param String type event type
- * @param Function listener
- * @param Object context
- * @param Boolean useCapture
- * @return null
- */
- this.on = function (obj, type, listener, context, useCapture) {
- var id = this._id.apply(this, arguments),
- handler = function (e) {
- return listener.call(context || obj, e || window.event);
- };
+ * Adds event listener
+ *
+ * @param obj Object obj
+ * @param type String
+ * @param listener Function
+ * @param context Object
+ * @param useCapture Boolean
+ * @return null
+ */
- if ('addEventListener' in obj) {
+
+ this.on = function (obj, type, listener, context, useCapture) {
+ var id = this._id.apply(this, arguments);
+
+ var handler = function handler(e) {
+ return listener.call(context || obj, e || window.event);
+ };
+
+ if ("addEventListener" in obj) {
obj.addEventListener(type, handler, useCapture);
- } else if ('attachEvent' in obj) {
- obj.attachEvent('on' + type, handler);
+ } else if ("attachEvent" in obj) {
+ obj.attachEvent("on".concat(type), handler);
}
obj[events_key] = obj[events_key] || {};
obj[events_key][id] = handler;
};
-
/**
- * Removes event listener
- *
- * @param Object obj
- * @param String type event type
- * @param Function listener
- * @param Object context
- * @param Boolean useCapture
- * @return null
- */
+ * Removes event listener
+ *
+ * @param obj Object
+ * @param type String
+ * @param listener Function
+ * @param context Object
+ * @param useCapture Boolean
+ * @return null
+ */
+
+
this.off = function (obj, type, listener, context, useCapture) {
- var id = this._id.apply(this, arguments),
- handler = obj[events_key] && obj[events_key][id];
+ var id = this._id.apply(this, arguments);
+
+ var handler = obj[events_key] && obj[events_key][id];
if (!handler) {
return;
}
- if ('removeEventListener' in obj) {
+ if ("removeEventListener" in obj) {
obj.removeEventListener(type, handler, useCapture);
- } else if ('detachEvent' in obj) {
- obj.detachEvent('on' + type, handler);
+ } else if ("detachEvent" in obj) {
+ obj.detachEvent("on".concat(type), handler);
}
obj[events_key][id] = null;
@@ -1615,8 +183,1400 @@
}
return new DOMEvent();
+ }();
+
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
+
+ function createCommonjsModule(fn, module) {
+ return module = { exports: {} }, fn(module, module.exports), module.exports;
+ }
+
+ var check = function (it) {
+ return it && it.Math == Math && it;
+ };
+
+ // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
+ var global_1 =
+ // eslint-disable-next-line es/no-global-this -- safe
+ check(typeof globalThis == 'object' && globalThis) ||
+ check(typeof window == 'object' && window) ||
+ // eslint-disable-next-line no-restricted-globals -- safe
+ check(typeof self == 'object' && self) ||
+ check(typeof commonjsGlobal == 'object' && commonjsGlobal) ||
+ // eslint-disable-next-line no-new-func -- fallback
+ (function () { return this; })() || Function('return this')();
+
+ var fails = function (exec) {
+ try {
+ return !!exec();
+ } catch (error) {
+ return true;
+ }
+ };
+
+ // Detect IE8's incomplete defineProperty implementation
+ var descriptors = !fails(function () {
+ // eslint-disable-next-line es/no-object-defineproperty -- required for testing
+ return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] != 7;
+ });
+
+ var $propertyIsEnumerable = {}.propertyIsEnumerable;
+ // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
+ var getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor;
+
+ // Nashorn ~ JDK8 bug
+ var NASHORN_BUG = getOwnPropertyDescriptor$1 && !$propertyIsEnumerable.call({ 1: 2 }, 1);
+
+ // `Object.prototype.propertyIsEnumerable` method implementation
+ // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
+ var f$4 = NASHORN_BUG ? function propertyIsEnumerable(V) {
+ var descriptor = getOwnPropertyDescriptor$1(this, V);
+ return !!descriptor && descriptor.enumerable;
+ } : $propertyIsEnumerable;
+
+ var objectPropertyIsEnumerable = {
+ f: f$4
+ };
+
+ var createPropertyDescriptor = function (bitmap, value) {
+ return {
+ enumerable: !(bitmap & 1),
+ configurable: !(bitmap & 2),
+ writable: !(bitmap & 4),
+ value: value
+ };
+ };
+
+ var toString = {}.toString;
+
+ var classofRaw = function (it) {
+ return toString.call(it).slice(8, -1);
+ };
+
+ var split = ''.split;
+
+ // fallback for non-array-like ES3 and non-enumerable old V8 strings
+ var indexedObject = fails(function () {
+ // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
+ // eslint-disable-next-line no-prototype-builtins -- safe
+ return !Object('z').propertyIsEnumerable(0);
+ }) ? function (it) {
+ return classofRaw(it) == 'String' ? split.call(it, '') : Object(it);
+ } : Object;
+
+ // `RequireObjectCoercible` abstract operation
+ // https://tc39.es/ecma262/#sec-requireobjectcoercible
+ var requireObjectCoercible = function (it) {
+ if (it == undefined) throw TypeError("Can't call method on " + it);
+ return it;
+ };
+
+ // toObject with fallback for non-array-like ES3 strings
+
+
+
+ var toIndexedObject = function (it) {
+ return indexedObject(requireObjectCoercible(it));
+ };
+
+ var isObject = function (it) {
+ return typeof it === 'object' ? it !== null : typeof it === 'function';
+ };
+
+ var aFunction$1 = function (variable) {
+ return typeof variable == 'function' ? variable : undefined;
+ };
+
+ var getBuiltIn = function (namespace, method) {
+ return arguments.length < 2 ? aFunction$1(global_1[namespace]) : global_1[namespace] && global_1[namespace][method];
+ };
+
+ var engineUserAgent = getBuiltIn('navigator', 'userAgent') || '';
+
+ var process = global_1.process;
+ var Deno = global_1.Deno;
+ var versions = process && process.versions || Deno && Deno.version;
+ var v8 = versions && versions.v8;
+ var match, version$1;
+
+ if (v8) {
+ match = v8.split('.');
+ version$1 = match[0] < 4 ? 1 : match[0] + match[1];
+ } else if (engineUserAgent) {
+ match = engineUserAgent.match(/Edge\/(\d+)/);
+ if (!match || match[1] >= 74) {
+ match = engineUserAgent.match(/Chrome\/(\d+)/);
+ if (match) version$1 = match[1];
+ }
+ }
+
+ var engineV8Version = version$1 && +version$1;
+
+ /* eslint-disable es/no-symbol -- required for testing */
+
+
+
+ // eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing
+ var nativeSymbol = !!Object.getOwnPropertySymbols && !fails(function () {
+ var symbol = Symbol();
+ // Chrome 38 Symbol has incorrect toString conversion
+ // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances
+ return !String(symbol) || !(Object(symbol) instanceof Symbol) ||
+ // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
+ !Symbol.sham && engineV8Version && engineV8Version < 41;
+ });
+
+ /* eslint-disable es/no-symbol -- required for testing */
+
+
+ var useSymbolAsUid = nativeSymbol
+ && !Symbol.sham
+ && typeof Symbol.iterator == 'symbol';
+
+ var isSymbol = useSymbolAsUid ? function (it) {
+ return typeof it == 'symbol';
+ } : function (it) {
+ var $Symbol = getBuiltIn('Symbol');
+ return typeof $Symbol == 'function' && Object(it) instanceof $Symbol;
+ };
+
+ // `OrdinaryToPrimitive` abstract operation
+ // https://tc39.es/ecma262/#sec-ordinarytoprimitive
+ var ordinaryToPrimitive = function (input, pref) {
+ var fn, val;
+ if (pref === 'string' && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
+ if (typeof (fn = input.valueOf) == 'function' && !isObject(val = fn.call(input))) return val;
+ if (pref !== 'string' && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
+ throw TypeError("Can't convert object to primitive value");
+ };
+
+ var setGlobal = function (key, value) {
+ try {
+ // eslint-disable-next-line es/no-object-defineproperty -- safe
+ Object.defineProperty(global_1, key, { value: value, configurable: true, writable: true });
+ } catch (error) {
+ global_1[key] = value;
+ } return value;
+ };
+
+ var SHARED = '__core-js_shared__';
+ var store$1 = global_1[SHARED] || setGlobal(SHARED, {});
+
+ var sharedStore = store$1;
+
+ var shared = createCommonjsModule(function (module) {
+ (module.exports = function (key, value) {
+ return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {});
+ })('versions', []).push({
+ version: '3.16.1',
+ mode: 'global',
+ copyright: '© 2021 Denis Pushkarev (zloirock.ru)'
+ });
+ });
+
+ // `ToObject` abstract operation
+ // https://tc39.es/ecma262/#sec-toobject
+ var toObject = function (argument) {
+ return Object(requireObjectCoercible(argument));
+ };
+
+ var hasOwnProperty = {}.hasOwnProperty;
+
+ var has$1 = Object.hasOwn || function hasOwn(it, key) {
+ return hasOwnProperty.call(toObject(it), key);
+ };
+
+ var id = 0;
+ var postfix = Math.random();
+
+ var uid = function (key) {
+ return 'Symbol(' + String(key === undefined ? '' : key) + ')_' + (++id + postfix).toString(36);
+ };
+
+ var WellKnownSymbolsStore = shared('wks');
+ var Symbol$1 = global_1.Symbol;
+ var createWellKnownSymbol = useSymbolAsUid ? Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid;
+
+ var wellKnownSymbol = function (name) {
+ if (!has$1(WellKnownSymbolsStore, name) || !(nativeSymbol || typeof WellKnownSymbolsStore[name] == 'string')) {
+ if (nativeSymbol && has$1(Symbol$1, name)) {
+ WellKnownSymbolsStore[name] = Symbol$1[name];
+ } else {
+ WellKnownSymbolsStore[name] = createWellKnownSymbol('Symbol.' + name);
+ }
+ } return WellKnownSymbolsStore[name];
+ };
+
+ var TO_PRIMITIVE = wellKnownSymbol('toPrimitive');
+
+ // `ToPrimitive` abstract operation
+ // https://tc39.es/ecma262/#sec-toprimitive
+ var toPrimitive = function (input, pref) {
+ if (!isObject(input) || isSymbol(input)) return input;
+ var exoticToPrim = input[TO_PRIMITIVE];
+ var result;
+ if (exoticToPrim !== undefined) {
+ if (pref === undefined) pref = 'default';
+ result = exoticToPrim.call(input, pref);
+ if (!isObject(result) || isSymbol(result)) return result;
+ throw TypeError("Can't convert object to primitive value");
+ }
+ if (pref === undefined) pref = 'number';
+ return ordinaryToPrimitive(input, pref);
+ };
+
+ // `ToPropertyKey` abstract operation
+ // https://tc39.es/ecma262/#sec-topropertykey
+ var toPropertyKey = function (argument) {
+ var key = toPrimitive(argument, 'string');
+ return isSymbol(key) ? key : String(key);
+ };
+
+ var document$1 = global_1.document;
+ // typeof document.createElement is 'object' in old IE
+ var EXISTS = isObject(document$1) && isObject(document$1.createElement);
+
+ var documentCreateElement = function (it) {
+ return EXISTS ? document$1.createElement(it) : {};
+ };
+
+ // Thank's IE8 for his funny defineProperty
+ var ie8DomDefine = !descriptors && !fails(function () {
+ // eslint-disable-next-line es/no-object-defineproperty -- requied for testing
+ return Object.defineProperty(documentCreateElement('div'), 'a', {
+ get: function () { return 7; }
+ }).a != 7;
+ });
+
+ // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
+ var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
+
+ // `Object.getOwnPropertyDescriptor` method
+ // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
+ var f$3 = descriptors ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
+ O = toIndexedObject(O);
+ P = toPropertyKey(P);
+ if (ie8DomDefine) try {
+ return $getOwnPropertyDescriptor(O, P);
+ } catch (error) { /* empty */ }
+ if (has$1(O, P)) return createPropertyDescriptor(!objectPropertyIsEnumerable.f.call(O, P), O[P]);
+ };
+
+ var objectGetOwnPropertyDescriptor = {
+ f: f$3
+ };
+
+ var anObject = function (it) {
+ if (!isObject(it)) {
+ throw TypeError(String(it) + ' is not an object');
+ } return it;
+ };
+
+ // eslint-disable-next-line es/no-object-defineproperty -- safe
+ var $defineProperty = Object.defineProperty;
+
+ // `Object.defineProperty` method
+ // https://tc39.es/ecma262/#sec-object.defineproperty
+ var f$2 = descriptors ? $defineProperty : function defineProperty(O, P, Attributes) {
+ anObject(O);
+ P = toPropertyKey(P);
+ anObject(Attributes);
+ if (ie8DomDefine) try {
+ return $defineProperty(O, P, Attributes);
+ } catch (error) { /* empty */ }
+ if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');
+ if ('value' in Attributes) O[P] = Attributes.value;
+ return O;
+ };
+
+ var objectDefineProperty = {
+ f: f$2
+ };
+
+ var createNonEnumerableProperty = descriptors ? function (object, key, value) {
+ return objectDefineProperty.f(object, key, createPropertyDescriptor(1, value));
+ } : function (object, key, value) {
+ object[key] = value;
+ return object;
+ };
+
+ var functionToString = Function.toString;
+
+ // this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper
+ if (typeof sharedStore.inspectSource != 'function') {
+ sharedStore.inspectSource = function (it) {
+ return functionToString.call(it);
+ };
+ }
+
+ var inspectSource = sharedStore.inspectSource;
+
+ var WeakMap$1 = global_1.WeakMap;
+
+ var nativeWeakMap = typeof WeakMap$1 === 'function' && /native code/.test(inspectSource(WeakMap$1));
+
+ var keys = shared('keys');
+
+ var sharedKey = function (key) {
+ return keys[key] || (keys[key] = uid(key));
+ };
+
+ var hiddenKeys$1 = {};
+
+ var OBJECT_ALREADY_INITIALIZED = 'Object already initialized';
+ var WeakMap = global_1.WeakMap;
+ var set, get, has;
+
+ var enforce = function (it) {
+ return has(it) ? get(it) : set(it, {});
+ };
+
+ var getterFor = function (TYPE) {
+ return function (it) {
+ var state;
+ if (!isObject(it) || (state = get(it)).type !== TYPE) {
+ throw TypeError('Incompatible receiver, ' + TYPE + ' required');
+ } return state;
+ };
+ };
+
+ if (nativeWeakMap || sharedStore.state) {
+ var store = sharedStore.state || (sharedStore.state = new WeakMap());
+ var wmget = store.get;
+ var wmhas = store.has;
+ var wmset = store.set;
+ set = function (it, metadata) {
+ if (wmhas.call(store, it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);
+ metadata.facade = it;
+ wmset.call(store, it, metadata);
+ return metadata;
+ };
+ get = function (it) {
+ return wmget.call(store, it) || {};
+ };
+ has = function (it) {
+ return wmhas.call(store, it);
+ };
+ } else {
+ var STATE = sharedKey('state');
+ hiddenKeys$1[STATE] = true;
+ set = function (it, metadata) {
+ if (has$1(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);
+ metadata.facade = it;
+ createNonEnumerableProperty(it, STATE, metadata);
+ return metadata;
+ };
+ get = function (it) {
+ return has$1(it, STATE) ? it[STATE] : {};
+ };
+ has = function (it) {
+ return has$1(it, STATE);
+ };
+ }
+
+ var internalState = {
+ set: set,
+ get: get,
+ has: has,
+ enforce: enforce,
+ getterFor: getterFor
+ };
+
+ var redefine = createCommonjsModule(function (module) {
+ var getInternalState = internalState.get;
+ var enforceInternalState = internalState.enforce;
+ var TEMPLATE = String(String).split('String');
+
+ (module.exports = function (O, key, value, options) {
+ var unsafe = options ? !!options.unsafe : false;
+ var simple = options ? !!options.enumerable : false;
+ var noTargetGet = options ? !!options.noTargetGet : false;
+ var state;
+ if (typeof value == 'function') {
+ if (typeof key == 'string' && !has$1(value, 'name')) {
+ createNonEnumerableProperty(value, 'name', key);
+ }
+ state = enforceInternalState(value);
+ if (!state.source) {
+ state.source = TEMPLATE.join(typeof key == 'string' ? key : '');
+ }
+ }
+ if (O === global_1) {
+ if (simple) O[key] = value;
+ else setGlobal(key, value);
+ return;
+ } else if (!unsafe) {
+ delete O[key];
+ } else if (!noTargetGet && O[key]) {
+ simple = true;
+ }
+ if (simple) O[key] = value;
+ else createNonEnumerableProperty(O, key, value);
+ // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
+ })(Function.prototype, 'toString', function toString() {
+ return typeof this == 'function' && getInternalState(this).source || inspectSource(this);
+ });
+ });
+
+ var ceil = Math.ceil;
+ var floor$2 = Math.floor;
+
+ // `ToInteger` abstract operation
+ // https://tc39.es/ecma262/#sec-tointeger
+ var toInteger = function (argument) {
+ return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor$2 : ceil)(argument);
+ };
+
+ var min$4 = Math.min;
+
+ // `ToLength` abstract operation
+ // https://tc39.es/ecma262/#sec-tolength
+ var toLength = function (argument) {
+ return argument > 0 ? min$4(toInteger(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
+ };
+
+ var max$3 = Math.max;
+ var min$3 = Math.min;
+
+ // Helper for a popular repeating case of the spec:
+ // Let integer be ? ToInteger(index).
+ // If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).
+ var toAbsoluteIndex = function (index, length) {
+ var integer = toInteger(index);
+ return integer < 0 ? max$3(integer + length, 0) : min$3(integer, length);
+ };
+
+ // `Array.prototype.{ indexOf, includes }` methods implementation
+ var createMethod$2 = function (IS_INCLUDES) {
+ return function ($this, el, fromIndex) {
+ var O = toIndexedObject($this);
+ var length = toLength(O.length);
+ var index = toAbsoluteIndex(fromIndex, length);
+ var value;
+ // Array#includes uses SameValueZero equality algorithm
+ // eslint-disable-next-line no-self-compare -- NaN check
+ if (IS_INCLUDES && el != el) while (length > index) {
+ value = O[index++];
+ // eslint-disable-next-line no-self-compare -- NaN check
+ if (value != value) return true;
+ // Array#indexOf ignores holes, Array#includes - not
+ } else for (;length > index; index++) {
+ if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
+ } return !IS_INCLUDES && -1;
+ };
+ };
+
+ var arrayIncludes = {
+ // `Array.prototype.includes` method
+ // https://tc39.es/ecma262/#sec-array.prototype.includes
+ includes: createMethod$2(true),
+ // `Array.prototype.indexOf` method
+ // https://tc39.es/ecma262/#sec-array.prototype.indexof
+ indexOf: createMethod$2(false)
+ };
+
+ var indexOf = arrayIncludes.indexOf;
+
+
+ var objectKeysInternal = function (object, names) {
+ var O = toIndexedObject(object);
+ var i = 0;
+ var result = [];
+ var key;
+ for (key in O) !has$1(hiddenKeys$1, key) && has$1(O, key) && result.push(key);
+ // Don't enum bug & hidden keys
+ while (names.length > i) if (has$1(O, key = names[i++])) {
+ ~indexOf(result, key) || result.push(key);
+ }
+ return result;
+ };
+
+ // IE8- don't enum bug keys
+ var enumBugKeys = [
+ 'constructor',
+ 'hasOwnProperty',
+ 'isPrototypeOf',
+ 'propertyIsEnumerable',
+ 'toLocaleString',
+ 'toString',
+ 'valueOf'
+ ];
+
+ var hiddenKeys = enumBugKeys.concat('length', 'prototype');
+
+ // `Object.getOwnPropertyNames` method
+ // https://tc39.es/ecma262/#sec-object.getownpropertynames
+ // eslint-disable-next-line es/no-object-getownpropertynames -- safe
+ var f$1 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
+ return objectKeysInternal(O, hiddenKeys);
+ };
+
+ var objectGetOwnPropertyNames = {
+ f: f$1
+ };
+
+ // eslint-disable-next-line es/no-object-getownpropertysymbols -- safe
+ var f = Object.getOwnPropertySymbols;
+
+ var objectGetOwnPropertySymbols = {
+ f: f
+ };
+
+ // all object keys, includes non-enumerable and symbols
+ var ownKeys = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {
+ var keys = objectGetOwnPropertyNames.f(anObject(it));
+ var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
+ return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;
+ };
+
+ var copyConstructorProperties = function (target, source) {
+ var keys = ownKeys(source);
+ var defineProperty = objectDefineProperty.f;
+ var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
+ for (var i = 0; i < keys.length; i++) {
+ var key = keys[i];
+ if (!has$1(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));
+ }
+ };
+
+ var replacement = /#|\.prototype\./;
+
+ var isForced = function (feature, detection) {
+ var value = data[normalize(feature)];
+ return value == POLYFILL ? true
+ : value == NATIVE ? false
+ : typeof detection == 'function' ? fails(detection)
+ : !!detection;
+ };
+
+ var normalize = isForced.normalize = function (string) {
+ return String(string).replace(replacement, '.').toLowerCase();
+ };
+
+ var data = isForced.data = {};
+ var NATIVE = isForced.NATIVE = 'N';
+ var POLYFILL = isForced.POLYFILL = 'P';
+
+ var isForced_1 = isForced;
+
+ var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
+
+
+
+
+
+
+ /*
+ options.target - name of the target object
+ options.global - target is the global object
+ options.stat - export as static methods of target
+ options.proto - export as prototype methods of target
+ options.real - real prototype method for the `pure` version
+ options.forced - export even if the native feature is available
+ options.bind - bind methods to the target, required for the `pure` version
+ options.wrap - wrap constructors to preventing global pollution, required for the `pure` version
+ options.unsafe - use the simple assignment of property instead of delete + defineProperty
+ options.sham - add a flag to not completely full polyfills
+ options.enumerable - export as enumerable property
+ options.noTargetGet - prevent calling a getter on target
+ */
+ var _export = function (options, source) {
+ var TARGET = options.target;
+ var GLOBAL = options.global;
+ var STATIC = options.stat;
+ var FORCED, target, key, targetProperty, sourceProperty, descriptor;
+ if (GLOBAL) {
+ target = global_1;
+ } else if (STATIC) {
+ target = global_1[TARGET] || setGlobal(TARGET, {});
+ } else {
+ target = (global_1[TARGET] || {}).prototype;
+ }
+ if (target) for (key in source) {
+ sourceProperty = source[key];
+ if (options.noTargetGet) {
+ descriptor = getOwnPropertyDescriptor(target, key);
+ targetProperty = descriptor && descriptor.value;
+ } else targetProperty = target[key];
+ FORCED = isForced_1(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
+ // contained in target
+ if (!FORCED && targetProperty !== undefined) {
+ if (typeof sourceProperty === typeof targetProperty) continue;
+ copyConstructorProperties(sourceProperty, targetProperty);
+ }
+ // add a flag to not completely full polyfills
+ if (options.sham || (targetProperty && targetProperty.sham)) {
+ createNonEnumerableProperty(sourceProperty, 'sham', true);
+ }
+ // extend global
+ redefine(target, key, sourceProperty, options);
+ }
+ };
+
+ var toString_1 = function (argument) {
+ if (isSymbol(argument)) throw TypeError('Cannot convert a Symbol value to a string');
+ return String(argument);
+ };
+
+ // `RegExp.prototype.flags` getter implementation
+ // https://tc39.es/ecma262/#sec-get-regexp.prototype.flags
+ var regexpFlags = function () {
+ var that = anObject(this);
+ var result = '';
+ if (that.global) result += 'g';
+ if (that.ignoreCase) result += 'i';
+ if (that.multiline) result += 'm';
+ if (that.dotAll) result += 's';
+ if (that.unicode) result += 'u';
+ if (that.sticky) result += 'y';
+ return result;
+ };
+
+ // babel-minify transpiles RegExp('a', 'y') -> /a/y and it causes SyntaxError,
+ var RE = function (s, f) {
+ return RegExp(s, f);
+ };
+
+ var UNSUPPORTED_Y$2 = fails(function () {
+ var re = RE('a', 'y');
+ re.lastIndex = 2;
+ return re.exec('abcd') != null;
+ });
+
+ var BROKEN_CARET = fails(function () {
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=773687
+ var re = RE('^r', 'gy');
+ re.lastIndex = 2;
+ return re.exec('str') != null;
+ });
+
+ var regexpStickyHelpers = {
+ UNSUPPORTED_Y: UNSUPPORTED_Y$2,
+ BROKEN_CARET: BROKEN_CARET
+ };
+
+ // `Object.keys` method
+ // https://tc39.es/ecma262/#sec-object.keys
+ // eslint-disable-next-line es/no-object-keys -- safe
+ var objectKeys = Object.keys || function keys(O) {
+ return objectKeysInternal(O, enumBugKeys);
+ };
+
+ // `Object.defineProperties` method
+ // https://tc39.es/ecma262/#sec-object.defineproperties
+ // eslint-disable-next-line es/no-object-defineproperties -- safe
+ var objectDefineProperties = descriptors ? Object.defineProperties : function defineProperties(O, Properties) {
+ anObject(O);
+ var keys = objectKeys(Properties);
+ var length = keys.length;
+ var index = 0;
+ var key;
+ while (length > index) objectDefineProperty.f(O, key = keys[index++], Properties[key]);
+ return O;
+ };
+
+ var html = getBuiltIn('document', 'documentElement');
+
+ /* global ActiveXObject -- old IE, WSH */
+
+
+
+
+
+
+
+
+ var GT = '>';
+ var LT = '<';
+ var PROTOTYPE = 'prototype';
+ var SCRIPT = 'script';
+ var IE_PROTO = sharedKey('IE_PROTO');
+
+ var EmptyConstructor = function () { /* empty */ };
+
+ var scriptTag = function (content) {
+ return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT;
+ };
+
+ // Create object with fake `null` prototype: use ActiveX Object with cleared prototype
+ var NullProtoObjectViaActiveX = function (activeXDocument) {
+ activeXDocument.write(scriptTag(''));
+ activeXDocument.close();
+ var temp = activeXDocument.parentWindow.Object;
+ activeXDocument = null; // avoid memory leak
+ return temp;
+ };
+
+ // Create object with fake `null` prototype: use iframe Object with cleared prototype
+ var NullProtoObjectViaIFrame = function () {
+ // Thrash, waste and sodomy: IE GC bug
+ var iframe = documentCreateElement('iframe');
+ var JS = 'java' + SCRIPT + ':';
+ var iframeDocument;
+ if (iframe.style) {
+ iframe.style.display = 'none';
+ html.appendChild(iframe);
+ // https://github.com/zloirock/core-js/issues/475
+ iframe.src = String(JS);
+ iframeDocument = iframe.contentWindow.document;
+ iframeDocument.open();
+ iframeDocument.write(scriptTag('document.F=Object'));
+ iframeDocument.close();
+ return iframeDocument.F;
+ }
+ };
+
+ // Check for document.domain and active x support
+ // No need to use active x approach when document.domain is not set
+ // see https://github.com/es-shims/es5-shim/issues/150
+ // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346
+ // avoid IE GC bug
+ var activeXDocument;
+ var NullProtoObject = function () {
+ try {
+ activeXDocument = new ActiveXObject('htmlfile');
+ } catch (error) { /* ignore */ }
+ NullProtoObject = document.domain && activeXDocument ?
+ NullProtoObjectViaActiveX(activeXDocument) : // old IE
+ NullProtoObjectViaIFrame() ||
+ NullProtoObjectViaActiveX(activeXDocument); // WSH
+ var length = enumBugKeys.length;
+ while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]];
+ return NullProtoObject();
+ };
+
+ hiddenKeys$1[IE_PROTO] = true;
+
+ // `Object.create` method
+ // https://tc39.es/ecma262/#sec-object.create
+ var objectCreate = Object.create || function create(O, Properties) {
+ var result;
+ if (O !== null) {
+ EmptyConstructor[PROTOTYPE] = anObject(O);
+ result = new EmptyConstructor();
+ EmptyConstructor[PROTOTYPE] = null;
+ // add "__proto__" for Object.getPrototypeOf polyfill
+ result[IE_PROTO] = O;
+ } else result = NullProtoObject();
+ return Properties === undefined ? result : objectDefineProperties(result, Properties);
+ };
+
+ var regexpUnsupportedDotAll = fails(function () {
+ // babel-minify transpiles RegExp('.', 's') -> /./s and it causes SyntaxError
+ var re = RegExp('.', (typeof '').charAt(0));
+ return !(re.dotAll && re.exec('\n') && re.flags === 's');
+ });
+
+ var regexpUnsupportedNcg = fails(function () {
+ // babel-minify transpiles RegExp('.', 'g') -> /./g and it causes SyntaxError
+ var re = RegExp('(?<a>b)', (typeof '').charAt(5));
+ return re.exec('b').groups.a !== 'b' ||
+ 'b'.replace(re, '$<a>c') !== 'bc';
+ });
+
+ /* eslint-disable regexp/no-assertion-capturing-group, regexp/no-empty-group, regexp/no-lazy-ends -- testing */
+ /* eslint-disable regexp/no-useless-quantifier -- testing */
+
+
+
+
+
+ var getInternalState = internalState.get;
+
+
+
+ var nativeExec = RegExp.prototype.exec;
+ var nativeReplace = shared('native-string-replace', String.prototype.replace);
+
+ var patchedExec = nativeExec;
+
+ var UPDATES_LAST_INDEX_WRONG = (function () {
+ var re1 = /a/;
+ var re2 = /b*/g;
+ nativeExec.call(re1, 'a');
+ nativeExec.call(re2, 'a');
+ return re1.lastIndex !== 0 || re2.lastIndex !== 0;
})();
+ var UNSUPPORTED_Y$1 = regexpStickyHelpers.UNSUPPORTED_Y || regexpStickyHelpers.BROKEN_CARET;
+
+ // nonparticipating capturing group, copied from es5-shim's String#split patch.
+ var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;
+
+ var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y$1 || regexpUnsupportedDotAll || regexpUnsupportedNcg;
+
+ if (PATCH) {
+ // eslint-disable-next-line max-statements -- TODO
+ patchedExec = function exec(string) {
+ var re = this;
+ var state = getInternalState(re);
+ var str = toString_1(string);
+ var raw = state.raw;
+ var result, reCopy, lastIndex, match, i, object, group;
+
+ if (raw) {
+ raw.lastIndex = re.lastIndex;
+ result = patchedExec.call(raw, str);
+ re.lastIndex = raw.lastIndex;
+ return result;
+ }
+
+ var groups = state.groups;
+ var sticky = UNSUPPORTED_Y$1 && re.sticky;
+ var flags = regexpFlags.call(re);
+ var source = re.source;
+ var charsAdded = 0;
+ var strCopy = str;
+
+ if (sticky) {
+ flags = flags.replace('y', '');
+ if (flags.indexOf('g') === -1) {
+ flags += 'g';
+ }
+
+ strCopy = str.slice(re.lastIndex);
+ // Support anchored sticky behavior.
+ if (re.lastIndex > 0 && (!re.multiline || re.multiline && str.charAt(re.lastIndex - 1) !== '\n')) {
+ source = '(?: ' + source + ')';
+ strCopy = ' ' + strCopy;
+ charsAdded++;
+ }
+ // ^(? + rx + ) is needed, in combination with some str slicing, to
+ // simulate the 'y' flag.
+ reCopy = new RegExp('^(?:' + source + ')', flags);
+ }
+
+ if (NPCG_INCLUDED) {
+ reCopy = new RegExp('^' + source + '$(?!\\s)', flags);
+ }
+ if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex;
+
+ match = nativeExec.call(sticky ? reCopy : re, strCopy);
+
+ if (sticky) {
+ if (match) {
+ match.input = match.input.slice(charsAdded);
+ match[0] = match[0].slice(charsAdded);
+ match.index = re.lastIndex;
+ re.lastIndex += match[0].length;
+ } else re.lastIndex = 0;
+ } else if (UPDATES_LAST_INDEX_WRONG && match) {
+ re.lastIndex = re.global ? match.index + match[0].length : lastIndex;
+ }
+ if (NPCG_INCLUDED && match && match.length > 1) {
+ // Fix browsers whose `exec` methods don't consistently return `undefined`
+ // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/
+ nativeReplace.call(match[0], reCopy, function () {
+ for (i = 1; i < arguments.length - 2; i++) {
+ if (arguments[i] === undefined) match[i] = undefined;
+ }
+ });
+ }
+
+ if (match && groups) {
+ match.groups = object = objectCreate(null);
+ for (i = 0; i < groups.length; i++) {
+ group = groups[i];
+ object[group[0]] = match[group[1]];
+ }
+ }
+
+ return match;
+ };
+ }
+
+ var regexpExec = patchedExec;
+
+ // `RegExp.prototype.exec` method
+ // https://tc39.es/ecma262/#sec-regexp.prototype.exec
+ _export({ target: 'RegExp', proto: true, forced: /./.exec !== regexpExec }, {
+ exec: regexpExec
+ });
+
+ // TODO: Remove from `core-js@4` since it's moved to entry points
+
+
+
+
+
+
+
+ var SPECIES$4 = wellKnownSymbol('species');
+ var RegExpPrototype$1 = RegExp.prototype;
+
+ var fixRegexpWellKnownSymbolLogic = function (KEY, exec, FORCED, SHAM) {
+ var SYMBOL = wellKnownSymbol(KEY);
+
+ var DELEGATES_TO_SYMBOL = !fails(function () {
+ // String methods call symbol-named RegEp methods
+ var O = {};
+ O[SYMBOL] = function () { return 7; };
+ return ''[KEY](O) != 7;
+ });
+
+ var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails(function () {
+ // Symbol-named RegExp methods call .exec
+ var execCalled = false;
+ var re = /a/;
+
+ if (KEY === 'split') {
+ // We can't use real regex here since it causes deoptimization
+ // and serious performance degradation in V8
+ // https://github.com/zloirock/core-js/issues/306
+ re = {};
+ // RegExp[@@split] doesn't call the regex's exec method, but first creates
+ // a new one. We need to return the patched regex when creating the new one.
+ re.constructor = {};
+ re.constructor[SPECIES$4] = function () { return re; };
+ re.flags = '';
+ re[SYMBOL] = /./[SYMBOL];
+ }
+
+ re.exec = function () { execCalled = true; return null; };
+
+ re[SYMBOL]('');
+ return !execCalled;
+ });
+
+ if (
+ !DELEGATES_TO_SYMBOL ||
+ !DELEGATES_TO_EXEC ||
+ FORCED
+ ) {
+ var nativeRegExpMethod = /./[SYMBOL];
+ var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {
+ var $exec = regexp.exec;
+ if ($exec === regexpExec || $exec === RegExpPrototype$1.exec) {
+ if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
+ // The native String method already delegates to @@method (this
+ // polyfilled function), leasing to infinite recursion.
+ // We avoid it by directly calling the native @@method method.
+ return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) };
+ }
+ return { done: true, value: nativeMethod.call(str, regexp, arg2) };
+ }
+ return { done: false };
+ });
+
+ redefine(String.prototype, KEY, methods[0]);
+ redefine(RegExpPrototype$1, SYMBOL, methods[1]);
+ }
+
+ if (SHAM) createNonEnumerableProperty(RegExpPrototype$1[SYMBOL], 'sham', true);
+ };
+
+ // `String.prototype.codePointAt` methods implementation
+ var createMethod$1 = function (CONVERT_TO_STRING) {
+ return function ($this, pos) {
+ var S = toString_1(requireObjectCoercible($this));
+ var position = toInteger(pos);
+ var size = S.length;
+ var first, second;
+ if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined;
+ first = S.charCodeAt(position);
+ return first < 0xD800 || first > 0xDBFF || position + 1 === size
+ || (second = S.charCodeAt(position + 1)) < 0xDC00 || second > 0xDFFF
+ ? CONVERT_TO_STRING ? S.charAt(position) : first
+ : CONVERT_TO_STRING ? S.slice(position, position + 2) : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;
+ };
+ };
+
+ var stringMultibyte = {
+ // `String.prototype.codePointAt` method
+ // https://tc39.es/ecma262/#sec-string.prototype.codepointat
+ codeAt: createMethod$1(false),
+ // `String.prototype.at` method
+ // https://github.com/mathiasbynens/String.prototype.at
+ charAt: createMethod$1(true)
+ };
+
+ var charAt = stringMultibyte.charAt;
+
+ // `AdvanceStringIndex` abstract operation
+ // https://tc39.es/ecma262/#sec-advancestringindex
+ var advanceStringIndex = function (S, index, unicode) {
+ return index + (unicode ? charAt(S, index).length : 1);
+ };
+
+ // `RegExpExec` abstract operation
+ // https://tc39.es/ecma262/#sec-regexpexec
+ var regexpExecAbstract = function (R, S) {
+ var exec = R.exec;
+ if (typeof exec === 'function') {
+ var result = exec.call(R, S);
+ if (typeof result !== 'object') {
+ throw TypeError('RegExp exec method returned something other than an Object or null');
+ }
+ return result;
+ }
+
+ if (classofRaw(R) !== 'RegExp') {
+ throw TypeError('RegExp#exec called on incompatible receiver');
+ }
+
+ return regexpExec.call(R, S);
+ };
+
+ // @@match logic
+ fixRegexpWellKnownSymbolLogic('match', function (MATCH, nativeMatch, maybeCallNative) {
+ return [
+ // `String.prototype.match` method
+ // https://tc39.es/ecma262/#sec-string.prototype.match
+ function match(regexp) {
+ var O = requireObjectCoercible(this);
+ var matcher = regexp == undefined ? undefined : regexp[MATCH];
+ return matcher !== undefined ? matcher.call(regexp, O) : new RegExp(regexp)[MATCH](toString_1(O));
+ },
+ // `RegExp.prototype[@@match]` method
+ // https://tc39.es/ecma262/#sec-regexp.prototype-@@match
+ function (string) {
+ var rx = anObject(this);
+ var S = toString_1(string);
+ var res = maybeCallNative(nativeMatch, rx, S);
+
+ if (res.done) return res.value;
+
+ if (!rx.global) return regexpExecAbstract(rx, S);
+
+ var fullUnicode = rx.unicode;
+ rx.lastIndex = 0;
+ var A = [];
+ var n = 0;
+ var result;
+ while ((result = regexpExecAbstract(rx, S)) !== null) {
+ var matchStr = toString_1(result[0]);
+ A[n] = matchStr;
+ if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
+ n++;
+ }
+ return n === 0 ? null : A;
+ }
+ ];
+ });
+
+ // `IsArray` abstract operation
+ // https://tc39.es/ecma262/#sec-isarray
+ // eslint-disable-next-line es/no-array-isarray -- safe
+ var isArray = Array.isArray || function isArray(arg) {
+ return classofRaw(arg) == 'Array';
+ };
+
+ var createProperty = function (object, key, value) {
+ var propertyKey = toPropertyKey(key);
+ if (propertyKey in object) objectDefineProperty.f(object, propertyKey, createPropertyDescriptor(0, value));
+ else object[propertyKey] = value;
+ };
+
+ var SPECIES$3 = wellKnownSymbol('species');
+
+ // a part of `ArraySpeciesCreate` abstract operation
+ // https://tc39.es/ecma262/#sec-arrayspeciescreate
+ var arraySpeciesConstructor = function (originalArray) {
+ var C;
+ if (isArray(originalArray)) {
+ C = originalArray.constructor;
+ // cross-realm fallback
+ if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
+ else if (isObject(C)) {
+ C = C[SPECIES$3];
+ if (C === null) C = undefined;
+ }
+ } return C === undefined ? Array : C;
+ };
+
+ // `ArraySpeciesCreate` abstract operation
+ // https://tc39.es/ecma262/#sec-arrayspeciescreate
+ var arraySpeciesCreate = function (originalArray, length) {
+ return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length);
+ };
+
+ var SPECIES$2 = wellKnownSymbol('species');
+
+ var arrayMethodHasSpeciesSupport = function (METHOD_NAME) {
+ // We can't use this feature detection in V8 since it causes
+ // deoptimization and serious performance degradation
+ // https://github.com/zloirock/core-js/issues/677
+ return engineV8Version >= 51 || !fails(function () {
+ var array = [];
+ var constructor = array.constructor = {};
+ constructor[SPECIES$2] = function () {
+ return { foo: 1 };
+ };
+ return array[METHOD_NAME](Boolean).foo !== 1;
+ });
+ };
+
+ var IS_CONCAT_SPREADABLE = wellKnownSymbol('isConcatSpreadable');
+ var MAX_SAFE_INTEGER$1 = 0x1FFFFFFFFFFFFF;
+ var MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded';
+
+ // We can't use this feature detection in V8 since it causes
+ // deoptimization and serious performance degradation
+ // https://github.com/zloirock/core-js/issues/679
+ var IS_CONCAT_SPREADABLE_SUPPORT = engineV8Version >= 51 || !fails(function () {
+ var array = [];
+ array[IS_CONCAT_SPREADABLE] = false;
+ return array.concat()[0] !== array;
+ });
+
+ var SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('concat');
+
+ var isConcatSpreadable = function (O) {
+ if (!isObject(O)) return false;
+ var spreadable = O[IS_CONCAT_SPREADABLE];
+ return spreadable !== undefined ? !!spreadable : isArray(O);
+ };
+
+ var FORCED$1 = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT;
+
+ // `Array.prototype.concat` method
+ // https://tc39.es/ecma262/#sec-array.prototype.concat
+ // with adding support of @@isConcatSpreadable and @@species
+ _export({ target: 'Array', proto: true, forced: FORCED$1 }, {
+ // eslint-disable-next-line no-unused-vars -- required for `.length`
+ concat: function concat(arg) {
+ var O = toObject(this);
+ var A = arraySpeciesCreate(O, 0);
+ var n = 0;
+ var i, k, length, len, E;
+ for (i = -1, length = arguments.length; i < length; i++) {
+ E = i === -1 ? O : arguments[i];
+ if (isConcatSpreadable(E)) {
+ len = toLength(E.length);
+ if (n + len > MAX_SAFE_INTEGER$1) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
+ for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]);
+ } else {
+ if (n >= MAX_SAFE_INTEGER$1) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
+ createProperty(A, n++, E);
+ }
+ }
+ A.length = n;
+ return A;
+ }
+ });
+
+ var TO_STRING_TAG$1 = wellKnownSymbol('toStringTag');
+ var test$1 = {};
+
+ test$1[TO_STRING_TAG$1] = 'z';
+
+ var toStringTagSupport = String(test$1) === '[object z]';
+
+ var TO_STRING_TAG = wellKnownSymbol('toStringTag');
+ // ES3 wrong here
+ var CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) == 'Arguments';
+
+ // fallback for IE11 Script Access Denied error
+ var tryGet = function (it, key) {
+ try {
+ return it[key];
+ } catch (error) { /* empty */ }
+ };
+
+ // getting tag from ES6+ `Object.prototype.toString`
+ var classof = toStringTagSupport ? classofRaw : function (it) {
+ var O, tag, result;
+ return it === undefined ? 'Undefined' : it === null ? 'Null'
+ // @@toStringTag case
+ : typeof (tag = tryGet(O = Object(it), TO_STRING_TAG)) == 'string' ? tag
+ // builtinTag case
+ : CORRECT_ARGUMENTS ? classofRaw(O)
+ // ES3 arguments fallback
+ : (result = classofRaw(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : result;
+ };
+
+ // `Object.prototype.toString` method implementation
+ // https://tc39.es/ecma262/#sec-object.prototype.tostring
+ var objectToString = toStringTagSupport ? {}.toString : function toString() {
+ return '[object ' + classof(this) + ']';
+ };
+
+ // `Object.prototype.toString` method
+ // https://tc39.es/ecma262/#sec-object.prototype.tostring
+ if (!toStringTagSupport) {
+ redefine(Object.prototype, 'toString', objectToString, { unsafe: true });
+ }
+
+ var TO_STRING = 'toString';
+ var RegExpPrototype = RegExp.prototype;
+ var nativeToString = RegExpPrototype[TO_STRING];
+
+ var NOT_GENERIC = fails(function () { return nativeToString.call({ source: 'a', flags: 'b' }) != '/a/b'; });
+ // FF44- RegExp#toString has a wrong name
+ var INCORRECT_NAME = nativeToString.name != TO_STRING;
+
+ // `RegExp.prototype.toString` method
+ // https://tc39.es/ecma262/#sec-regexp.prototype.tostring
+ if (NOT_GENERIC || INCORRECT_NAME) {
+ redefine(RegExp.prototype, TO_STRING, function toString() {
+ var R = anObject(this);
+ var p = toString_1(R.source);
+ var rf = R.flags;
+ var f = toString_1(rf === undefined && R instanceof RegExp && !('flags' in RegExpPrototype) ? regexpFlags.call(R) : rf);
+ return '/' + p + '/' + f;
+ }, { unsafe: true });
+ }
+
+ var MATCH$1 = wellKnownSymbol('match');
+
+ // `IsRegExp` abstract operation
+ // https://tc39.es/ecma262/#sec-isregexp
+ var isRegexp = function (it) {
+ var isRegExp;
+ return isObject(it) && ((isRegExp = it[MATCH$1]) !== undefined ? !!isRegExp : classofRaw(it) == 'RegExp');
+ };
+
+ var aFunction = function (it) {
+ if (typeof it != 'function') {
+ throw TypeError(String(it) + ' is not a function');
+ } return it;
+ };
+
+ var SPECIES$1 = wellKnownSymbol('species');
+
+ // `SpeciesConstructor` abstract operation
+ // https://tc39.es/ecma262/#sec-speciesconstructor
+ var speciesConstructor = function (O, defaultConstructor) {
+ var C = anObject(O).constructor;
+ var S;
+ return C === undefined || (S = anObject(C)[SPECIES$1]) == undefined ? defaultConstructor : aFunction(S);
+ };
+
+ var UNSUPPORTED_Y = regexpStickyHelpers.UNSUPPORTED_Y;
+ var arrayPush = [].push;
+ var min$2 = Math.min;
+ var MAX_UINT32 = 0xFFFFFFFF;
+
+ // Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
+ // Weex JS has frozen built-in prototypes, so use try / catch wrapper
+ var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails(function () {
+ // eslint-disable-next-line regexp/no-empty-group -- required for testing
+ var re = /(?:)/;
+ var originalExec = re.exec;
+ re.exec = function () { return originalExec.apply(this, arguments); };
+ var result = 'ab'.split(re);
+ return result.length !== 2 || result[0] !== 'a' || result[1] !== 'b';
+ });
+
+ // @@split logic
+ fixRegexpWellKnownSymbolLogic('split', function (SPLIT, nativeSplit, maybeCallNative) {
+ var internalSplit;
+ if (
+ 'abbc'.split(/(b)*/)[1] == 'c' ||
+ // eslint-disable-next-line regexp/no-empty-group -- required for testing
+ 'test'.split(/(?:)/, -1).length != 4 ||
+ 'ab'.split(/(?:ab)*/).length != 2 ||
+ '.'.split(/(.?)(.?)/).length != 4 ||
+ // eslint-disable-next-line regexp/no-assertion-capturing-group, regexp/no-empty-group -- required for testing
+ '.'.split(/()()/).length > 1 ||
+ ''.split(/.?/).length
+ ) {
+ // based on es5-shim implementation, need to rework it
+ internalSplit = function (separator, limit) {
+ var string = toString_1(requireObjectCoercible(this));
+ var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
+ if (lim === 0) return [];
+ if (separator === undefined) return [string];
+ // If `separator` is not a regex, use native split
+ if (!isRegexp(separator)) {
+ return nativeSplit.call(string, separator, lim);
+ }
+ var output = [];
+ var flags = (separator.ignoreCase ? 'i' : '') +
+ (separator.multiline ? 'm' : '') +
+ (separator.unicode ? 'u' : '') +
+ (separator.sticky ? 'y' : '');
+ var lastLastIndex = 0;
+ // Make `global` and avoid `lastIndex` issues by working with a copy
+ var separatorCopy = new RegExp(separator.source, flags + 'g');
+ var match, lastIndex, lastLength;
+ while (match = regexpExec.call(separatorCopy, string)) {
+ lastIndex = separatorCopy.lastIndex;
+ if (lastIndex > lastLastIndex) {
+ output.push(string.slice(lastLastIndex, match.index));
+ if (match.length > 1 && match.index < string.length) arrayPush.apply(output, match.slice(1));
+ lastLength = match[0].length;
+ lastLastIndex = lastIndex;
+ if (output.length >= lim) break;
+ }
+ if (separatorCopy.lastIndex === match.index) separatorCopy.lastIndex++; // Avoid an infinite loop
+ }
+ if (lastLastIndex === string.length) {
+ if (lastLength || !separatorCopy.test('')) output.push('');
+ } else output.push(string.slice(lastLastIndex));
+ return output.length > lim ? output.slice(0, lim) : output;
+ };
+ // Chakra, V8
+ } else if ('0'.split(undefined, 0).length) {
+ internalSplit = function (separator, limit) {
+ return separator === undefined && limit === 0 ? [] : nativeSplit.call(this, separator, limit);
+ };
+ } else internalSplit = nativeSplit;
+
+ return [
+ // `String.prototype.split` method
+ // https://tc39.es/ecma262/#sec-string.prototype.split
+ function split(separator, limit) {
+ var O = requireObjectCoercible(this);
+ var splitter = separator == undefined ? undefined : separator[SPLIT];
+ return splitter !== undefined
+ ? splitter.call(separator, O, limit)
+ : internalSplit.call(toString_1(O), separator, limit);
+ },
+ // `RegExp.prototype[@@split]` method
+ // https://tc39.es/ecma262/#sec-regexp.prototype-@@split
+ //
+ // NOTE: This cannot be properly polyfilled in engines that don't support
+ // the 'y' flag.
+ function (string, limit) {
+ var rx = anObject(this);
+ var S = toString_1(string);
+ var res = maybeCallNative(internalSplit, rx, S, limit, internalSplit !== nativeSplit);
+
+ if (res.done) return res.value;
+
+ var C = speciesConstructor(rx, RegExp);
+
+ var unicodeMatching = rx.unicode;
+ var flags = (rx.ignoreCase ? 'i' : '') +
+ (rx.multiline ? 'm' : '') +
+ (rx.unicode ? 'u' : '') +
+ (UNSUPPORTED_Y ? 'g' : 'y');
+
+ // ^(? + rx + ) is needed, in combination with some S slicing, to
+ // simulate the 'y' flag.
+ var splitter = new C(UNSUPPORTED_Y ? '^(?:' + rx.source + ')' : rx, flags);
+ var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
+ if (lim === 0) return [];
+ if (S.length === 0) return regexpExecAbstract(splitter, S) === null ? [S] : [];
+ var p = 0;
+ var q = 0;
+ var A = [];
+ while (q < S.length) {
+ splitter.lastIndex = UNSUPPORTED_Y ? 0 : q;
+ var z = regexpExecAbstract(splitter, UNSUPPORTED_Y ? S.slice(q) : S);
+ var e;
+ if (
+ z === null ||
+ (e = min$2(toLength(splitter.lastIndex + (UNSUPPORTED_Y ? q : 0)), S.length)) === p
+ ) {
+ q = advanceStringIndex(S, q, unicodeMatching);
+ } else {
+ A.push(S.slice(p, q));
+ if (A.length === lim) return A;
+ for (var i = 1; i <= z.length - 1; i++) {
+ A.push(z[i]);
+ if (A.length === lim) return A;
+ }
+ q = p = e;
+ }
+ }
+ A.push(S.slice(p));
+ return A;
+ }
+ ];
+ }, !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC, UNSUPPORTED_Y);
+
/**
* Append a class to an element
*
@@ -1626,46 +1586,31 @@
* @param {String} className
* @returns null
*/
- function _addClass(element, className) {
+
+ function addClass(element, className) {
if (element instanceof SVGElement) {
// svg
- var pre = element.getAttribute('class') || '';
+ var pre = element.getAttribute("class") || "";
- element.setAttribute('class', pre + ' ' + className);
+ if (!pre.match(className)) {
+ // check if element doesn't already have className
+ element.setAttribute("class", "".concat(pre, " ").concat(className));
+ }
} else {
if (element.classList !== undefined) {
// check for modern classList property
- var classes = className.split(' ');
- _forEach(classes, function (cls) {
- element.classList.add( cls );
+ var classes = className.split(" ");
+ forEach(classes, function (cls) {
+ element.classList.add(cls);
});
- } else if (!element.className.match( className )) {
+ } else if (!element.className.match(className)) {
// check if element doesn't already have className
- element.className += ' ' + className;
+ element.className += " ".concat(className);
}
}
}
/**
- * Remove a class from an element
- *
- * @api private
- * @method _removeClass
- * @param {Object} element
- * @param {RegExp|String} classNameRegex can be regex or string
- * @returns null
- */
- function _removeClass(element, classNameRegex) {
- if (element instanceof SVGElement) {
- var pre = element.getAttribute('class') || '';
-
- element.setAttribute('class', pre.replace(classNameRegex, '').replace(/^\s+|\s+$/g, ''));
- } else {
- element.className = element.className.replace(classNameRegex, '').replace(/^\s+|\s+$/g, '');
- }
- }
-
- /**
* Get an element CSS property on the page
* Thanks to JavaScript Kit: http://www.javascriptkit.com/dhtmltutors/dhtmlcascade4.shtml
*
@@ -1673,17 +1618,20 @@
* @method _getPropValue
* @param {Object} element
* @param {String} propName
- * @returns Element's property value
+ * @returns string property value
*/
- function _getPropValue (element, propName) {
- var propValue = '';
- if (element.currentStyle) { //IE
- propValue = element.currentStyle[propName];
- } else if (document.defaultView && document.defaultView.getComputedStyle) { //Others
- propValue = document.defaultView.getComputedStyle(element, null).getPropertyValue(propName);
- }
+ function getPropValue(element, propName) {
+ var propValue = "";
- //Prevent exception in IE
+ if (element.currentStyle) {
+ //IE
+ propValue = element.currentStyle[propName];
+ } else if (document.defaultView && document.defaultView.getComputedStyle) {
+ //Others
+ propValue = document.defaultView.getComputedStyle(element, null).getPropertyValue(propName);
+ } //Prevent exception in IE
+
+
if (propValue && propValue.toLowerCase) {
return propValue.toLowerCase();
} else {
@@ -1692,25 +1640,63 @@
}
/**
- * Checks to see if target element (or parents) position is fixed or not
+ * To set the show element
+ * This function set a relative (in most cases) position and changes the z-index
*
* @api private
- * @method _isFixed
- * @param {Object} element
- * @returns Boolean
+ * @method _setShowElement
+ * @param {Object} targetElement
*/
- function _isFixed (element) {
- var p = element.parentNode;
- if (!p || p.nodeName === 'HTML') {
- return false;
+ function setShowElement(_ref) {
+ var element = _ref.element;
+ addClass(element, "introjs-showElement");
+ var currentElementPosition = getPropValue(element, "position");
+
+ if (currentElementPosition !== "absolute" && currentElementPosition !== "relative" && currentElementPosition !== "sticky" && currentElementPosition !== "fixed") {
+ //change to new intro item
+ addClass(element, "introjs-relativePosition");
+ }
+ }
+
+ /**
+ * Find the nearest scrollable parent
+ * copied from https://stackoverflow.com/questions/35939886/find-first-scrollable-parent
+ *
+ * @param Element element
+ * @return Element
+ */
+ function getScrollParent(element) {
+ var style = window.getComputedStyle(element);
+ var excludeStaticParent = style.position === "absolute";
+ var overflowRegex = /(auto|scroll)/;
+ if (style.position === "fixed") return document.body;
+
+ for (var parent = element; parent = parent.parentElement;) {
+ style = window.getComputedStyle(parent);
+
+ if (excludeStaticParent && style.position === "static") {
+ continue;
+ }
+
+ if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) return parent;
}
- if (_getPropValue(element, 'position') === 'fixed') {
- return true;
- }
+ return document.body;
+ }
- return _isFixed(p);
+ /**
+ * scroll a scrollable element to a child element
+ *
+ * @param {Object} targetElement
+ */
+
+ function scrollParentToElement(targetElement) {
+ var element = targetElement.element;
+ if (!this._options.scrollToElement) return;
+ var parent = getScrollParent(element);
+ if (parent === document.body) return;
+ parent.scrollTop = element.offsetTop - parent.offsetTop;
}
/**
@@ -1721,12 +1707,18 @@
* @method _getWinSize
* @returns {Object} width and height attributes
*/
- function _getWinSize() {
+ function getWinSize() {
if (window.innerWidth !== undefined) {
- return { width: window.innerWidth, height: window.innerHeight };
+ return {
+ width: window.innerWidth,
+ height: window.innerHeight
+ };
} else {
var D = document.documentElement;
- return { width: D.clientWidth, height: D.clientHeight };
+ return {
+ width: D.clientWidth,
+ height: D.clientHeight
+ };
}
}
@@ -1738,547 +1730,1092 @@
* @method _elementInViewport
* @param {Object} el
*/
- function _elementInViewport(el) {
+ function elementInViewport(el) {
var rect = el.getBoundingClientRect();
-
- return (
- rect.top >= 0 &&
- rect.left >= 0 &&
- (rect.bottom+80) <= window.innerHeight && // add 80 to get the text right
- rect.right <= window.innerWidth
- );
+ return rect.top >= 0 && rect.left >= 0 && rect.bottom + 80 <= window.innerHeight && // add 80 to get the text right
+ rect.right <= window.innerWidth;
}
/**
- * Add overlay layer to the page
+ * To change the scroll of `window` after highlighting an element
*
* @api private
- * @method _addOverlayLayer
- * @param {Object} targetElm
+ * @param {String} scrollTo
+ * @param {Object} targetElement
+ * @param {Object} tooltipLayer
*/
- function _addOverlayLayer(targetElm) {
- var overlayLayer = document.createElement('div'),
- styleText = '',
- self = this;
- //set css class name
- overlayLayer.className = 'introjs-overlay';
+ function scrollTo(scrollTo, _ref, tooltipLayer) {
+ var element = _ref.element;
+ if (scrollTo === "off") return;
+ var rect;
+ if (!this._options.scrollToElement) return;
- //check if the target element is body, we should calculate the size of overlay layer in a better way
- if (!targetElm.tagName || targetElm.tagName.toLowerCase() === 'body') {
- styleText += 'top: 0;bottom: 0; left: 0;right: 0;position: fixed;';
- overlayLayer.style.cssText = styleText;
+ if (scrollTo === "tooltip") {
+ rect = tooltipLayer.getBoundingClientRect();
} else {
- //set overlay layer position
- var elementPosition = _getOffset(targetElm);
- if (elementPosition) {
- styleText += 'width: ' + elementPosition.width + 'px; height:' + elementPosition.height + 'px; top:' + elementPosition.top + 'px;left: ' + elementPosition.left + 'px;';
- overlayLayer.style.cssText = styleText;
- }
+ rect = element.getBoundingClientRect();
}
- targetElm.appendChild(overlayLayer);
+ if (!elementInViewport(element)) {
+ var winHeight = getWinSize().height;
+ var top = rect.bottom - (rect.bottom - rect.top); // TODO (afshinm): do we need scroll padding now?
+ // I have changed the scroll option and now it scrolls the window to
+ // the center of the target element or tooltip.
- overlayLayer.onclick = function() {
- if (self._options.exitOnOverlayClick === true) {
- _exitIntro.call(self, targetElm);
+ if (top < 0 || element.clientHeight > winHeight) {
+ window.scrollBy(0, rect.top - (winHeight / 2 - rect.height / 2) - this._options.scrollPadding); // 30px padding from edge to look nice
+ //Scroll down
+ } else {
+ window.scrollBy(0, rect.top - (winHeight / 2 - rect.height / 2) + this._options.scrollPadding); // 30px padding from edge to look nice
}
- };
-
- window.setTimeout(function() {
- styleText += 'opacity: ' + self._options.overlayOpacity.toString() + ';';
- overlayLayer.style.cssText = styleText;
- }, 10);
-
- return true;
- }
-
- /**
- * Removes open hint (tooltip hint)
- *
- * @api private
- * @method _removeHintTooltip
- */
- function _removeHintTooltip() {
- var tooltip = document.querySelector('.introjs-hintReference');
-
- if (tooltip) {
- var step = tooltip.getAttribute('data-step');
- tooltip.parentNode.removeChild(tooltip);
- return step;
}
}
/**
- * Start parsing hint items
+ * Setting anchors to behave like buttons
*
* @api private
- * @param {Object} targetElm
- * @method _startHint
+ * @method _setAnchorAsButton
*/
- function _populateHints(targetElm) {
+ function setAnchorAsButton(anchor) {
+ anchor.setAttribute("role", "button");
+ anchor.tabIndex = 0;
+ }
- this._introItems = [];
+ // eslint-disable-next-line es/no-object-assign -- safe
+ var $assign = Object.assign;
+ // eslint-disable-next-line es/no-object-defineproperty -- required for testing
+ var defineProperty = Object.defineProperty;
- if (this._options.hints) {
- _forEach(this._options.hints, function (hint) {
- var currentItem = _cloneObject(hint);
-
- if (typeof(currentItem.element) === 'string') {
- //grab the element with given selector from the page
- currentItem.element = document.querySelector(currentItem.element);
- }
-
- currentItem.hintPosition = currentItem.hintPosition || this._options.hintPosition;
- currentItem.hintAnimation = currentItem.hintAnimation || this._options.hintAnimation;
-
- if (currentItem.element !== null) {
- this._introItems.push(currentItem);
- }
- }.bind(this));
- } else {
- var hints = targetElm.querySelectorAll('*[data-hint]');
-
- if (!hints || !hints.length) {
- return false;
- }
-
- //first add intro items with data-step
- _forEach(hints, function (currentElement) {
- // hint animation
- var hintAnimation = currentElement.getAttribute('data-hintanimation');
-
- if (hintAnimation) {
- hintAnimation = (hintAnimation === 'true');
- } else {
- hintAnimation = this._options.hintAnimation;
- }
-
- this._introItems.push({
- element: currentElement,
- hint: currentElement.getAttribute('data-hint'),
- hintPosition: currentElement.getAttribute('data-hintposition') || this._options.hintPosition,
- hintAnimation: hintAnimation,
- tooltipClass: currentElement.getAttribute('data-tooltipclass'),
- position: currentElement.getAttribute('data-position') || this._options.tooltipPosition
+ // `Object.assign` method
+ // https://tc39.es/ecma262/#sec-object.assign
+ var objectAssign = !$assign || fails(function () {
+ // should have correct order of operations (Edge bug)
+ if (descriptors && $assign({ b: 1 }, $assign(defineProperty({}, 'a', {
+ enumerable: true,
+ get: function () {
+ defineProperty(this, 'b', {
+ value: 3,
+ enumerable: false
});
- }.bind(this));
- }
-
- _addHints.call(this);
-
- /*
- todo:
- these events should be removed at some point
- */
- DOMEvent.on(document, 'click', _removeHintTooltip, this, false);
- DOMEvent.on(window, 'resize', _reAlignHints, this, true);
- }
-
- /**
- * Re-aligns all hint elements
- *
- * @api private
- * @method _reAlignHints
- */
- function _reAlignHints() {
- _forEach(this._introItems, function (item) {
- if (typeof(item.targetElement) === 'undefined') {
- return;
}
-
- _alignHintPosition.call(this, item.hintPosition, item.element, item.targetElement);
- }.bind(this));
- }
-
- /**
- * Get a queryselector within the hint wrapper
- *
- * @param {String} selector
- * @return {NodeList|Array}
- */
- function _hintQuerySelectorAll(selector) {
- var hintsWrapper = document.querySelector('.introjs-hints');
- return (hintsWrapper) ? hintsWrapper.querySelectorAll(selector) : [];
- }
-
- /**
- * Hide a hint
- *
- * @api private
- * @method _hideHint
- */
- function _hideHint(stepId) {
- var hint = _hintQuerySelectorAll('.introjs-hint[data-step="' + stepId + '"]')[0];
-
- _removeHintTooltip.call(this);
-
- if (hint) {
- _addClass(hint, 'introjs-hidehint');
- }
-
- // call the callback function (if any)
- if (typeof (this._hintCloseCallback) !== 'undefined') {
- this._hintCloseCallback.call(this, stepId);
- }
- }
-
- /**
- * Hide all hints
- *
- * @api private
- * @method _hideHints
- */
- function _hideHints() {
- var hints = _hintQuerySelectorAll('.introjs-hint');
-
- _forEach(hints, function (hint) {
- _hideHint.call(this, hint.getAttribute('data-step'));
- }.bind(this));
- }
-
- /**
- * Show all hints
- *
- * @api private
- * @method _showHints
- */
- function _showHints() {
- var hints = _hintQuerySelectorAll('.introjs-hint');
-
- if (hints && hints.length) {
- _forEach(hints, function (hint) {
- _showHint.call(this, hint.getAttribute('data-step'));
- }.bind(this));
- } else {
- _populateHints.call(this, this._targetElement);
- }
- }
-
- /**
- * Show a hint
- *
- * @api private
- * @method _showHint
- */
- function _showHint(stepId) {
- var hint = _hintQuerySelectorAll('.introjs-hint[data-step="' + stepId + '"]')[0];
-
- if (hint) {
- _removeClass(hint, /introjs-hidehint/g);
- }
- }
-
- /**
- * Removes all hint elements on the page
- * Useful when you want to destroy the elements and add them again (e.g. a modal or popup)
- *
- * @api private
- * @method _removeHints
- */
- function _removeHints() {
- var hints = _hintQuerySelectorAll('.introjs-hint');
-
- _forEach(hints, function (hint) {
- _removeHint.call(this, hint.getAttribute('data-step'));
- }.bind(this));
- }
-
- /**
- * Remove one single hint element from the page
- * Useful when you want to destroy the element and add them again (e.g. a modal or popup)
- * Use removeHints if you want to remove all elements.
- *
- * @api private
- * @method _removeHint
- */
- function _removeHint(stepId) {
- var hint = _hintQuerySelectorAll('.introjs-hint[data-step="' + stepId + '"]')[0];
-
- if (hint) {
- hint.parentNode.removeChild(hint);
- }
- }
-
- /**
- * Add all available hints to the page
- *
- * @api private
- * @method _addHints
- */
- function _addHints() {
- var self = this;
-
- var hintsWrapper = document.querySelector('.introjs-hints');
-
- if (hintsWrapper === null) {
- hintsWrapper = document.createElement('div');
- hintsWrapper.className = 'introjs-hints';
- }
-
- /**
- * Returns an event handler unique to the hint iteration
- *
- * @param {Integer} i
- * @return {Function}
- */
- var getHintClick = function (i) {
- return function(e) {
- var evt = e ? e : window.event;
-
- if (evt.stopPropagation) {
- evt.stopPropagation();
- }
-
- if (evt.cancelBubble !== null) {
- evt.cancelBubble = true;
- }
-
- _showHintDialog.call(self, i);
- };
- };
-
- _forEach(this._introItems, function(item, i) {
- // avoid append a hint twice
- if (document.querySelector('.introjs-hint[data-step="' + i + '"]')) {
- return;
+ }), { b: 2 })).b !== 1) return true;
+ // should work with symbols and should have deterministic property order (V8 bug)
+ var A = {};
+ var B = {};
+ // eslint-disable-next-line es/no-symbol -- safe
+ var symbol = Symbol();
+ var alphabet = 'abcdefghijklmnopqrst';
+ A[symbol] = 7;
+ alphabet.split('').forEach(function (chr) { B[chr] = chr; });
+ return $assign({}, A)[symbol] != 7 || objectKeys($assign({}, B)).join('') != alphabet;
+ }) ? function assign(target, source) { // eslint-disable-line no-unused-vars -- required for `.length`
+ var T = toObject(target);
+ var argumentsLength = arguments.length;
+ var index = 1;
+ var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
+ var propertyIsEnumerable = objectPropertyIsEnumerable.f;
+ while (argumentsLength > index) {
+ var S = indexedObject(arguments[index++]);
+ var keys = getOwnPropertySymbols ? objectKeys(S).concat(getOwnPropertySymbols(S)) : objectKeys(S);
+ var length = keys.length;
+ var j = 0;
+ var key;
+ while (length > j) {
+ key = keys[j++];
+ if (!descriptors || propertyIsEnumerable.call(S, key)) T[key] = S[key];
}
+ } return T;
+ } : $assign;
- var hint = document.createElement('a');
- _setAnchorAsButton(hint);
-
- hint.onclick = getHintClick(i);
-
- hint.className = 'introjs-hint';
-
- if (!item.hintAnimation) {
- _addClass(hint, 'introjs-hint-no-anim');
- }
-
- // hint's position should be fixed if the target element's position is fixed
- if (_isFixed(item.element)) {
- _addClass(hint, 'introjs-fixedhint');
- }
-
- var hintDot = document.createElement('div');
- hintDot.className = 'introjs-hint-dot';
- var hintPulse = document.createElement('div');
- hintPulse.className = 'introjs-hint-pulse';
-
- hint.appendChild(hintDot);
- hint.appendChild(hintPulse);
- hint.setAttribute('data-step', i);
-
- // we swap the hint element with target element
- // because _setHelperLayerPosition uses `element` property
- item.targetElement = item.element;
- item.element = hint;
-
- // align the hint position
- _alignHintPosition.call(this, item.hintPosition, hint, item.targetElement);
-
- hintsWrapper.appendChild(hint);
- }.bind(this));
-
- // adding the hints wrapper
- document.body.appendChild(hintsWrapper);
-
- // call the callback function (if any)
- if (typeof (this._hintsAddedCallback) !== 'undefined') {
- this._hintsAddedCallback.call(this);
- }
- }
+ // `Object.assign` method
+ // https://tc39.es/ecma262/#sec-object.assign
+ // eslint-disable-next-line es/no-object-assign -- required for testing
+ _export({ target: 'Object', stat: true, forced: Object.assign !== objectAssign }, {
+ assign: objectAssign
+ });
/**
- * Aligns hint position
+ * Checks to see if target element (or parents) position is fixed or not
*
* @api private
- * @method _alignHintPosition
- * @param {String} position
- * @param {Object} hint
+ * @method _isFixed
* @param {Object} element
+ * @returns Boolean
*/
- function _alignHintPosition(position, hint, element) {
- // get/calculate offset of target element
- var offset = _getOffset.call(this, element);
- var iconWidth = 20;
- var iconHeight = 20;
- // align the hint element
- switch (position) {
- default:
- case 'top-left':
- hint.style.left = offset.left + 'px';
- hint.style.top = offset.top + 'px';
- break;
- case 'top-right':
- hint.style.left = (offset.left + offset.width - iconWidth) + 'px';
- hint.style.top = offset.top + 'px';
- break;
- case 'bottom-left':
- hint.style.left = offset.left + 'px';
- hint.style.top = (offset.top + offset.height - iconHeight) + 'px';
- break;
- case 'bottom-right':
- hint.style.left = (offset.left + offset.width - iconWidth) + 'px';
- hint.style.top = (offset.top + offset.height - iconHeight) + 'px';
- break;
- case 'middle-left':
- hint.style.left = offset.left + 'px';
- hint.style.top = (offset.top + (offset.height - iconHeight) / 2) + 'px';
- break;
- case 'middle-right':
- hint.style.left = (offset.left + offset.width - iconWidth) + 'px';
- hint.style.top = (offset.top + (offset.height - iconHeight) / 2) + 'px';
- break;
- case 'middle-middle':
- hint.style.left = (offset.left + (offset.width - iconWidth) / 2) + 'px';
- hint.style.top = (offset.top + (offset.height - iconHeight) / 2) + 'px';
- break;
- case 'bottom-middle':
- hint.style.left = (offset.left + (offset.width - iconWidth) / 2) + 'px';
- hint.style.top = (offset.top + offset.height - iconHeight) + 'px';
- break;
- case 'top-middle':
- hint.style.left = (offset.left + (offset.width - iconWidth) / 2) + 'px';
- hint.style.top = offset.top + 'px';
- break;
+ function isFixed(element) {
+ var p = element.parentNode;
+
+ if (!p || p.nodeName === "HTML") {
+ return false;
}
+
+ if (getPropValue(element, "position") === "fixed") {
+ return true;
+ }
+
+ return isFixed(p);
}
/**
- * Triggers when user clicks on the hint element
- *
- * @api private
- * @method _showHintDialog
- * @param {Number} stepId
- */
- function _showHintDialog(stepId) {
- var hintElement = document.querySelector('.introjs-hint[data-step="' + stepId + '"]');
- var item = this._introItems[stepId];
-
- // call the callback function (if any)
- if (typeof (this._hintClickCallback) !== 'undefined') {
- this._hintClickCallback.call(this, hintElement, item, stepId);
- }
-
- // remove all open tooltips
- var removedStep = _removeHintTooltip.call(this);
-
- // to toggle the tooltip
- if (parseInt(removedStep, 10) === stepId) {
- return;
- }
-
- var tooltipLayer = document.createElement('div');
- var tooltipTextLayer = document.createElement('div');
- var arrowLayer = document.createElement('div');
- var referenceLayer = document.createElement('div');
-
- tooltipLayer.className = 'introjs-tooltip';
-
- tooltipLayer.onclick = function (e) {
- //IE9 & Other Browsers
- if (e.stopPropagation) {
- e.stopPropagation();
- }
- //IE8 and Lower
- else {
- e.cancelBubble = true;
- }
- };
-
- tooltipTextLayer.className = 'introjs-tooltiptext';
-
- var tooltipWrapper = document.createElement('p');
- tooltipWrapper.innerHTML = item.hint;
-
- var closeButton = document.createElement('a');
- closeButton.className = this._options.buttonClass;
- closeButton.setAttribute('role', 'button');
- closeButton.innerHTML = this._options.hintButtonLabel;
- closeButton.onclick = _hideHint.bind(this, stepId);
-
- tooltipTextLayer.appendChild(tooltipWrapper);
- tooltipTextLayer.appendChild(closeButton);
-
- arrowLayer.className = 'introjs-arrow';
- tooltipLayer.appendChild(arrowLayer);
-
- tooltipLayer.appendChild(tooltipTextLayer);
-
- // set current step for _placeTooltip function
- this._currentStep = hintElement.getAttribute('data-step');
-
- // align reference layer position
- referenceLayer.className = 'introjs-tooltipReferenceLayer introjs-hintReference';
- referenceLayer.setAttribute('data-step', hintElement.getAttribute('data-step'));
- _setHelperLayerPosition.call(this, referenceLayer);
-
- referenceLayer.appendChild(tooltipLayer);
- document.body.appendChild(referenceLayer);
-
- //set proper position
- _placeTooltip.call(this, hintElement, tooltipLayer, arrowLayer, null, true);
- }
-
- /**
- * Get an element position on the page
+ * Get an element position on the page relative to another element (or body)
* Thanks to `meouw`: http://stackoverflow.com/a/442474/375966
*
* @api private
- * @method _getOffset
+ * @method getOffset
* @param {Object} element
+ * @param {Object} relativeEl
* @returns Element's position info
*/
- function _getOffset(element) {
+
+ function getOffset(element, relativeEl) {
var body = document.body;
var docEl = document.documentElement;
var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
+ relativeEl = relativeEl || body;
var x = element.getBoundingClientRect();
- return {
- top: x.top + scrollTop,
+ var xr = relativeEl.getBoundingClientRect();
+ var relativeElPosition = getPropValue(relativeEl, "position");
+ var obj = {
width: x.width,
- height: x.height,
- left: x.left + scrollLeft
+ height: x.height
};
+
+ if (relativeEl.tagName.toLowerCase() !== "body" && relativeElPosition === "relative" || relativeElPosition === "sticky") {
+ // when the container of our target element is _not_ body and has either "relative" or "sticky" position, we should not
+ // consider the scroll position but we need to include the relative x/y of the container element
+ return Object.assign(obj, {
+ top: x.top - xr.top,
+ left: x.left - xr.left
+ });
+ } else {
+ if (isFixed(element)) {
+ return Object.assign(obj, {
+ top: x.top,
+ left: x.left
+ });
+ } else {
+ return Object.assign(obj, {
+ top: x.top + scrollTop,
+ left: x.left + scrollLeft
+ });
+ }
+ }
+ }
+
+ var floor$1 = Math.floor;
+ var replace = ''.replace;
+ var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d{1,2}|<[^>]*>)/g;
+ var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d{1,2})/g;
+
+ // `GetSubstitution` abstract operation
+ // https://tc39.es/ecma262/#sec-getsubstitution
+ var getSubstitution = function (matched, str, position, captures, namedCaptures, replacement) {
+ var tailPos = position + matched.length;
+ var m = captures.length;
+ var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
+ if (namedCaptures !== undefined) {
+ namedCaptures = toObject(namedCaptures);
+ symbols = SUBSTITUTION_SYMBOLS;
+ }
+ return replace.call(replacement, symbols, function (match, ch) {
+ var capture;
+ switch (ch.charAt(0)) {
+ case '$': return '$';
+ case '&': return matched;
+ case '`': return str.slice(0, position);
+ case "'": return str.slice(tailPos);
+ case '<':
+ capture = namedCaptures[ch.slice(1, -1)];
+ break;
+ default: // \d\d?
+ var n = +ch;
+ if (n === 0) return match;
+ if (n > m) {
+ var f = floor$1(n / 10);
+ if (f === 0) return match;
+ if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
+ return match;
+ }
+ capture = captures[n - 1];
+ }
+ return capture === undefined ? '' : capture;
+ });
+ };
+
+ var REPLACE = wellKnownSymbol('replace');
+ var max$2 = Math.max;
+ var min$1 = Math.min;
+
+ var maybeToString = function (it) {
+ return it === undefined ? it : String(it);
+ };
+
+ // IE <= 11 replaces $0 with the whole match, as if it was $&
+ // https://stackoverflow.com/questions/6024666/getting-ie-to-replace-a-regex-with-the-literal-string-0
+ var REPLACE_KEEPS_$0 = (function () {
+ // eslint-disable-next-line regexp/prefer-escape-replacement-dollar-char -- required for testing
+ return 'a'.replace(/./, '$0') === '$0';
+ })();
+
+ // Safari <= 13.0.3(?) substitutes nth capture where n>m with an empty string
+ var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = (function () {
+ if (/./[REPLACE]) {
+ return /./[REPLACE]('a', '$0') === '';
+ }
+ return false;
+ })();
+
+ var REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {
+ var re = /./;
+ re.exec = function () {
+ var result = [];
+ result.groups = { a: '7' };
+ return result;
+ };
+ return ''.replace(re, '$<a>') !== '7';
+ });
+
+ // @@replace logic
+ fixRegexpWellKnownSymbolLogic('replace', function (_, nativeReplace, maybeCallNative) {
+ var UNSAFE_SUBSTITUTE = REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE ? '$' : '$0';
+
+ return [
+ // `String.prototype.replace` method
+ // https://tc39.es/ecma262/#sec-string.prototype.replace
+ function replace(searchValue, replaceValue) {
+ var O = requireObjectCoercible(this);
+ var replacer = searchValue == undefined ? undefined : searchValue[REPLACE];
+ return replacer !== undefined
+ ? replacer.call(searchValue, O, replaceValue)
+ : nativeReplace.call(toString_1(O), searchValue, replaceValue);
+ },
+ // `RegExp.prototype[@@replace]` method
+ // https://tc39.es/ecma262/#sec-regexp.prototype-@@replace
+ function (string, replaceValue) {
+ var rx = anObject(this);
+ var S = toString_1(string);
+
+ if (
+ typeof replaceValue === 'string' &&
+ replaceValue.indexOf(UNSAFE_SUBSTITUTE) === -1 &&
+ replaceValue.indexOf('$<') === -1
+ ) {
+ var res = maybeCallNative(nativeReplace, rx, S, replaceValue);
+ if (res.done) return res.value;
+ }
+
+ var functionalReplace = typeof replaceValue === 'function';
+ if (!functionalReplace) replaceValue = toString_1(replaceValue);
+
+ var global = rx.global;
+ if (global) {
+ var fullUnicode = rx.unicode;
+ rx.lastIndex = 0;
+ }
+ var results = [];
+ while (true) {
+ var result = regexpExecAbstract(rx, S);
+ if (result === null) break;
+
+ results.push(result);
+ if (!global) break;
+
+ var matchStr = toString_1(result[0]);
+ if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
+ }
+
+ var accumulatedResult = '';
+ var nextSourcePosition = 0;
+ for (var i = 0; i < results.length; i++) {
+ result = results[i];
+
+ var matched = toString_1(result[0]);
+ var position = max$2(min$1(toInteger(result.index), S.length), 0);
+ var captures = [];
+ // NOTE: This is equivalent to
+ // captures = result.slice(1).map(maybeToString)
+ // but for some reason `nativeSlice.call(result, 1, result.length)` (called in
+ // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and
+ // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.
+ for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));
+ var namedCaptures = result.groups;
+ if (functionalReplace) {
+ var replacerArgs = [matched].concat(captures, position, S);
+ if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
+ var replacement = toString_1(replaceValue.apply(undefined, replacerArgs));
+ } else {
+ replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
+ }
+ if (position >= nextSourcePosition) {
+ accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
+ nextSourcePosition = position + matched.length;
+ }
+ }
+ return accumulatedResult + S.slice(nextSourcePosition);
+ }
+ ];
+ }, !REPLACE_SUPPORTS_NAMED_GROUPS || !REPLACE_KEEPS_$0 || REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE);
+
+ /**
+ * Remove a class from an element
+ *
+ * @api private
+ * @method _removeClass
+ * @param {Object} element
+ * @param {RegExp|String} classNameRegex can be regex or string
+ * @returns null
+ */
+ function removeClass(element, classNameRegex) {
+ if (element instanceof SVGElement) {
+ var pre = element.getAttribute("class") || "";
+ element.setAttribute("class", pre.replace(classNameRegex, "").replace(/^\s+|\s+$/g, ""));
+ } else {
+ element.className = element.className.replace(classNameRegex, "").replace(/^\s+|\s+$/g, "");
+ }
}
/**
- * Find the nearest scrollable parent
- * copied from https://stackoverflow.com/questions/35939886/find-first-scrollable-parent
- *
- * @param Element element
- * @return Element
- */
- function _getScrollParent(element) {
- var style = window.getComputedStyle(element);
- var excludeStaticParent = (style.position === "absolute");
- var overflowRegex = /(auto|scroll)/;
+ * Sets the style of an DOM element
+ *
+ * @param {Object} element
+ * @param {Object|string} style
+ * @return null
+ */
+ function setStyle(element, style) {
+ var cssText = "";
- if (style.position === "fixed") return document.body;
-
- for (var parent = element; (parent = parent.parentElement);) {
- style = window.getComputedStyle(parent);
- if (excludeStaticParent && style.position === "static") {
- continue;
- }
- if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) return parent;
+ if (element.style.cssText) {
+ cssText += element.style.cssText;
}
- return document.body;
+ if (typeof style === "string") {
+ cssText += style;
+ } else {
+ for (var rule in style) {
+ cssText += "".concat(rule, ":").concat(style[rule], ";");
+ }
+ }
+
+ element.style.cssText = cssText;
}
/**
- * scroll a scrollable element to a child element
- *
- * @param Element parent
- * @param Element element
- * @return Null
- */
- function _scrollParentToElement (parent, element) {
- parent.scrollTop = element.offsetTop - parent.offsetTop;
+ * Update the position of the helper layer on the screen
+ *
+ * @api private
+ * @method _setHelperLayerPosition
+ * @param {Object} helperLayer
+ */
+
+ function setHelperLayerPosition(helperLayer) {
+ if (helperLayer) {
+ //prevent error when `this._currentStep` in undefined
+ if (!this._introItems[this._currentStep]) return;
+ var currentElement = this._introItems[this._currentStep];
+ var elementPosition = getOffset(currentElement.element, this._targetElement);
+ var widthHeightPadding = this._options.helperElementPadding; // If the target element is fixed, the tooltip should be fixed as well.
+ // Otherwise, remove a fixed class that may be left over from the previous
+ // step.
+
+ if (isFixed(currentElement.element)) {
+ addClass(helperLayer, "introjs-fixedTooltip");
+ } else {
+ removeClass(helperLayer, "introjs-fixedTooltip");
+ }
+
+ if (currentElement.position === "floating") {
+ widthHeightPadding = 0;
+ } //set new position to helper layer
+
+
+ setStyle(helperLayer, {
+ width: "".concat(elementPosition.width + widthHeightPadding, "px"),
+ height: "".concat(elementPosition.height + widthHeightPadding, "px"),
+ top: "".concat(elementPosition.top - widthHeightPadding / 2, "px"),
+ left: "".concat(elementPosition.left - widthHeightPadding / 2, "px")
+ });
+ }
+ }
+
+ var UNSCOPABLES = wellKnownSymbol('unscopables');
+ var ArrayPrototype = Array.prototype;
+
+ // Array.prototype[@@unscopables]
+ // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
+ if (ArrayPrototype[UNSCOPABLES] == undefined) {
+ objectDefineProperty.f(ArrayPrototype, UNSCOPABLES, {
+ configurable: true,
+ value: objectCreate(null)
+ });
+ }
+
+ // add a key to Array.prototype[@@unscopables]
+ var addToUnscopables = function (key) {
+ ArrayPrototype[UNSCOPABLES][key] = true;
+ };
+
+ var $includes = arrayIncludes.includes;
+
+
+ // `Array.prototype.includes` method
+ // https://tc39.es/ecma262/#sec-array.prototype.includes
+ _export({ target: 'Array', proto: true }, {
+ includes: function includes(el /* , fromIndex = 0 */) {
+ return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);
+ }
+ });
+
+ // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
+ addToUnscopables('includes');
+
+ var HAS_SPECIES_SUPPORT$2 = arrayMethodHasSpeciesSupport('slice');
+
+ var SPECIES = wellKnownSymbol('species');
+ var nativeSlice = [].slice;
+ var max$1 = Math.max;
+
+ // `Array.prototype.slice` method
+ // https://tc39.es/ecma262/#sec-array.prototype.slice
+ // fallback for not array-like ES3 strings and DOM objects
+ _export({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$2 }, {
+ slice: function slice(start, end) {
+ var O = toIndexedObject(this);
+ var length = toLength(O.length);
+ var k = toAbsoluteIndex(start, length);
+ var fin = toAbsoluteIndex(end === undefined ? length : end, length);
+ // inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible
+ var Constructor, result, n;
+ if (isArray(O)) {
+ Constructor = O.constructor;
+ // cross-realm fallback
+ if (typeof Constructor == 'function' && (Constructor === Array || isArray(Constructor.prototype))) {
+ Constructor = undefined;
+ } else if (isObject(Constructor)) {
+ Constructor = Constructor[SPECIES];
+ if (Constructor === null) Constructor = undefined;
+ }
+ if (Constructor === Array || Constructor === undefined) {
+ return nativeSlice.call(O, k, fin);
+ }
+ }
+ result = new (Constructor === undefined ? Array : Constructor)(max$1(fin - k, 0));
+ for (n = 0; k < fin; k++, n++) if (k in O) createProperty(result, n, O[k]);
+ result.length = n;
+ return result;
+ }
+ });
+
+ var notARegexp = function (it) {
+ if (isRegexp(it)) {
+ throw TypeError("The method doesn't accept regular expressions");
+ } return it;
+ };
+
+ var MATCH = wellKnownSymbol('match');
+
+ var correctIsRegexpLogic = function (METHOD_NAME) {
+ var regexp = /./;
+ try {
+ '/./'[METHOD_NAME](regexp);
+ } catch (error1) {
+ try {
+ regexp[MATCH] = false;
+ return '/./'[METHOD_NAME](regexp);
+ } catch (error2) { /* empty */ }
+ } return false;
+ };
+
+ // `String.prototype.includes` method
+ // https://tc39.es/ecma262/#sec-string.prototype.includes
+ _export({ target: 'String', proto: true, forced: !correctIsRegexpLogic('includes') }, {
+ includes: function includes(searchString /* , position = 0 */) {
+ return !!~toString_1(requireObjectCoercible(this))
+ .indexOf(toString_1(notARegexp(searchString)), arguments.length > 1 ? arguments[1] : undefined);
+ }
+ });
+
+ var arrayMethodIsStrict = function (METHOD_NAME, argument) {
+ var method = [][METHOD_NAME];
+ return !!method && fails(function () {
+ // eslint-disable-next-line no-useless-call,no-throw-literal -- required for testing
+ method.call(null, argument || function () { throw 1; }, 1);
+ });
+ };
+
+ var nativeJoin = [].join;
+
+ var ES3_STRINGS = indexedObject != Object;
+ var STRICT_METHOD$1 = arrayMethodIsStrict('join', ',');
+
+ // `Array.prototype.join` method
+ // https://tc39.es/ecma262/#sec-array.prototype.join
+ _export({ target: 'Array', proto: true, forced: ES3_STRINGS || !STRICT_METHOD$1 }, {
+ join: function join(separator) {
+ return nativeJoin.call(toIndexedObject(this), separator === undefined ? ',' : separator);
+ }
+ });
+
+ // optional / simple context binding
+ var functionBindContext = function (fn, that, length) {
+ aFunction(fn);
+ if (that === undefined) return fn;
+ switch (length) {
+ case 0: return function () {
+ return fn.call(that);
+ };
+ case 1: return function (a) {
+ return fn.call(that, a);
+ };
+ case 2: return function (a, b) {
+ return fn.call(that, a, b);
+ };
+ case 3: return function (a, b, c) {
+ return fn.call(that, a, b, c);
+ };
+ }
+ return function (/* ...args */) {
+ return fn.apply(that, arguments);
+ };
+ };
+
+ var push = [].push;
+
+ // `Array.prototype.{ forEach, map, filter, some, every, find, findIndex, filterReject }` methods implementation
+ var createMethod = function (TYPE) {
+ var IS_MAP = TYPE == 1;
+ var IS_FILTER = TYPE == 2;
+ var IS_SOME = TYPE == 3;
+ var IS_EVERY = TYPE == 4;
+ var IS_FIND_INDEX = TYPE == 6;
+ var IS_FILTER_REJECT = TYPE == 7;
+ var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
+ return function ($this, callbackfn, that, specificCreate) {
+ var O = toObject($this);
+ var self = indexedObject(O);
+ var boundFunction = functionBindContext(callbackfn, that, 3);
+ var length = toLength(self.length);
+ var index = 0;
+ var create = specificCreate || arraySpeciesCreate;
+ var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_REJECT ? create($this, 0) : undefined;
+ var value, result;
+ for (;length > index; index++) if (NO_HOLES || index in self) {
+ value = self[index];
+ result = boundFunction(value, index, O);
+ if (TYPE) {
+ if (IS_MAP) target[index] = result; // map
+ else if (result) switch (TYPE) {
+ case 3: return true; // some
+ case 5: return value; // find
+ case 6: return index; // findIndex
+ case 2: push.call(target, value); // filter
+ } else switch (TYPE) {
+ case 4: return false; // every
+ case 7: push.call(target, value); // filterReject
+ }
+ }
+ }
+ return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target;
+ };
+ };
+
+ var arrayIteration = {
+ // `Array.prototype.forEach` method
+ // https://tc39.es/ecma262/#sec-array.prototype.foreach
+ forEach: createMethod(0),
+ // `Array.prototype.map` method
+ // https://tc39.es/ecma262/#sec-array.prototype.map
+ map: createMethod(1),
+ // `Array.prototype.filter` method
+ // https://tc39.es/ecma262/#sec-array.prototype.filter
+ filter: createMethod(2),
+ // `Array.prototype.some` method
+ // https://tc39.es/ecma262/#sec-array.prototype.some
+ some: createMethod(3),
+ // `Array.prototype.every` method
+ // https://tc39.es/ecma262/#sec-array.prototype.every
+ every: createMethod(4),
+ // `Array.prototype.find` method
+ // https://tc39.es/ecma262/#sec-array.prototype.find
+ find: createMethod(5),
+ // `Array.prototype.findIndex` method
+ // https://tc39.es/ecma262/#sec-array.prototype.findIndex
+ findIndex: createMethod(6),
+ // `Array.prototype.filterReject` method
+ // https://github.com/tc39/proposal-array-filtering
+ filterReject: createMethod(7)
+ };
+
+ var $filter = arrayIteration.filter;
+
+
+ var HAS_SPECIES_SUPPORT$1 = arrayMethodHasSpeciesSupport('filter');
+
+ // `Array.prototype.filter` method
+ // https://tc39.es/ecma262/#sec-array.prototype.filter
+ // with adding support of @@species
+ _export({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$1 }, {
+ filter: function filter(callbackfn /* , thisArg */) {
+ return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
+ }
+ });
+
+ /**
+ * Set tooltip left so it doesn't go off the right side of the window
+ *
+ * @return boolean true, if tooltipLayerStyleLeft is ok. false, otherwise.
+ */
+ function checkRight(targetOffset, tooltipLayerStyleLeft, tooltipOffset, windowSize, tooltipLayer) {
+ if (targetOffset.left + tooltipLayerStyleLeft + tooltipOffset.width > windowSize.width) {
+ // off the right side of the window
+ tooltipLayer.style.left = "".concat(windowSize.width - tooltipOffset.width - targetOffset.left, "px");
+ return false;
+ }
+
+ tooltipLayer.style.left = "".concat(tooltipLayerStyleLeft, "px");
+ return true;
+ }
+
+ /**
+ * Set tooltip right so it doesn't go off the left side of the window
+ *
+ * @return boolean true, if tooltipLayerStyleRight is ok. false, otherwise.
+ */
+ function checkLeft(targetOffset, tooltipLayerStyleRight, tooltipOffset, tooltipLayer) {
+ if (targetOffset.left + targetOffset.width - tooltipLayerStyleRight - tooltipOffset.width < 0) {
+ // off the left side of the window
+ tooltipLayer.style.left = "".concat(-targetOffset.left, "px");
+ return false;
+ }
+
+ tooltipLayer.style.right = "".concat(tooltipLayerStyleRight, "px");
+ return true;
+ }
+
+ var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('splice');
+
+ var max = Math.max;
+ var min = Math.min;
+ var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF;
+ var MAXIMUM_ALLOWED_LENGTH_EXCEEDED = 'Maximum allowed length exceeded';
+
+ // `Array.prototype.splice` method
+ // https://tc39.es/ecma262/#sec-array.prototype.splice
+ // with adding support of @@species
+ _export({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, {
+ splice: function splice(start, deleteCount /* , ...items */) {
+ var O = toObject(this);
+ var len = toLength(O.length);
+ var actualStart = toAbsoluteIndex(start, len);
+ var argumentsLength = arguments.length;
+ var insertCount, actualDeleteCount, A, k, from, to;
+ if (argumentsLength === 0) {
+ insertCount = actualDeleteCount = 0;
+ } else if (argumentsLength === 1) {
+ insertCount = 0;
+ actualDeleteCount = len - actualStart;
+ } else {
+ insertCount = argumentsLength - 2;
+ actualDeleteCount = min(max(toInteger(deleteCount), 0), len - actualStart);
+ }
+ if (len + insertCount - actualDeleteCount > MAX_SAFE_INTEGER) {
+ throw TypeError(MAXIMUM_ALLOWED_LENGTH_EXCEEDED);
+ }
+ A = arraySpeciesCreate(O, actualDeleteCount);
+ for (k = 0; k < actualDeleteCount; k++) {
+ from = actualStart + k;
+ if (from in O) createProperty(A, k, O[from]);
+ }
+ A.length = actualDeleteCount;
+ if (insertCount < actualDeleteCount) {
+ for (k = actualStart; k < len - actualDeleteCount; k++) {
+ from = k + actualDeleteCount;
+ to = k + insertCount;
+ if (from in O) O[to] = O[from];
+ else delete O[to];
+ }
+ for (k = len; k > len - actualDeleteCount + insertCount; k--) delete O[k - 1];
+ } else if (insertCount > actualDeleteCount) {
+ for (k = len - actualDeleteCount; k > actualStart; k--) {
+ from = k + actualDeleteCount - 1;
+ to = k + insertCount - 1;
+ if (from in O) O[to] = O[from];
+ else delete O[to];
+ }
+ }
+ for (k = 0; k < insertCount; k++) {
+ O[k + actualStart] = arguments[k + 2];
+ }
+ O.length = len - actualDeleteCount + insertCount;
+ return A;
+ }
+ });
+
+ /**
+ * Remove an entry from a string array if it's there, does nothing if it isn't there.
+ *
+ * @param {Array} stringArray
+ * @param {String} stringToRemove
+ */
+ function removeEntry(stringArray, stringToRemove) {
+ if (stringArray.includes(stringToRemove)) {
+ stringArray.splice(stringArray.indexOf(stringToRemove), 1);
+ }
+ }
+
+ /**
+ * auto-determine alignment
+ * @param {Integer} offsetLeft
+ * @param {Integer} tooltipWidth
+ * @param {Object} windowSize
+ * @param {String} desiredAlignment
+ * @return {String} calculatedAlignment
+ */
+
+ function _determineAutoAlignment(offsetLeft, tooltipWidth, _ref, desiredAlignment) {
+ var width = _ref.width;
+ var halfTooltipWidth = tooltipWidth / 2;
+ var winWidth = Math.min(width, window.screen.width);
+ var possibleAlignments = ["-left-aligned", "-middle-aligned", "-right-aligned"];
+ var calculatedAlignment = ""; // valid left must be at least a tooltipWidth
+ // away from right side
+
+ if (winWidth - offsetLeft < tooltipWidth) {
+ removeEntry(possibleAlignments, "-left-aligned");
+ } // valid middle must be at least half
+ // width away from both sides
+
+
+ if (offsetLeft < halfTooltipWidth || winWidth - offsetLeft < halfTooltipWidth) {
+ removeEntry(possibleAlignments, "-middle-aligned");
+ } // valid right must be at least a tooltipWidth
+ // width away from left side
+
+
+ if (offsetLeft < tooltipWidth) {
+ removeEntry(possibleAlignments, "-right-aligned");
+ }
+
+ if (possibleAlignments.length) {
+ if (possibleAlignments.includes(desiredAlignment)) {
+ // the desired alignment is valid
+ calculatedAlignment = desiredAlignment;
+ } else {
+ // pick the first valid position, in order
+ calculatedAlignment = possibleAlignments[0];
+ }
+ } else {
+ // if screen width is too small
+ // for ANY alignment, middle is
+ // probably the best for visibility
+ calculatedAlignment = "-middle-aligned";
+ }
+
+ return calculatedAlignment;
+ }
+ /**
+ * Determines the position of the tooltip based on the position precedence and availability
+ * of screen space.
+ *
+ * @param {Object} targetElement
+ * @param {Object} tooltipLayer
+ * @param {String} desiredTooltipPosition
+ * @return {String} calculatedPosition
+ */
+
+
+ function _determineAutoPosition(targetElement, tooltipLayer, desiredTooltipPosition) {
+ // Take a clone of position precedence. These will be the available
+ var possiblePositions = this._options.positionPrecedence.slice();
+
+ var windowSize = getWinSize();
+ var tooltipHeight = getOffset(tooltipLayer).height + 10;
+ var tooltipWidth = getOffset(tooltipLayer).width + 20;
+ var targetElementRect = targetElement.getBoundingClientRect(); // If we check all the possible areas, and there are no valid places for the tooltip, the element
+ // must take up most of the screen real estate. Show the tooltip floating in the middle of the screen.
+
+ var calculatedPosition = "floating";
+ /*
+ * auto determine position
+ */
+ // Check for space below
+
+ if (targetElementRect.bottom + tooltipHeight > windowSize.height) {
+ removeEntry(possiblePositions, "bottom");
+ } // Check for space above
+
+
+ if (targetElementRect.top - tooltipHeight < 0) {
+ removeEntry(possiblePositions, "top");
+ } // Check for space to the right
+
+
+ if (targetElementRect.right + tooltipWidth > windowSize.width) {
+ removeEntry(possiblePositions, "right");
+ } // Check for space to the left
+
+
+ if (targetElementRect.left - tooltipWidth < 0) {
+ removeEntry(possiblePositions, "left");
+ } // @var {String} ex: 'right-aligned'
+
+
+ var desiredAlignment = function (pos) {
+ var hyphenIndex = pos.indexOf("-");
+
+ if (hyphenIndex !== -1) {
+ // has alignment
+ return pos.substr(hyphenIndex);
+ }
+
+ return "";
+ }(desiredTooltipPosition || ""); // strip alignment from position
+
+
+ if (desiredTooltipPosition) {
+ // ex: "bottom-right-aligned"
+ // should return 'bottom'
+ desiredTooltipPosition = desiredTooltipPosition.split("-")[0];
+ }
+
+ if (possiblePositions.length) {
+ if (possiblePositions.includes(desiredTooltipPosition)) {
+ // If the requested position is in the list, choose that
+ calculatedPosition = desiredTooltipPosition;
+ } else {
+ // Pick the first valid position, in order
+ calculatedPosition = possiblePositions[0];
+ }
+ } // only top and bottom positions have optional alignments
+
+
+ if (["top", "bottom"].includes(calculatedPosition)) {
+ calculatedPosition += _determineAutoAlignment(targetElementRect.left, tooltipWidth, windowSize, desiredAlignment);
+ }
+
+ return calculatedPosition;
+ }
+ /**
+ * Render tooltip box in the page
+ *
+ * @api private
+ * @method placeTooltip
+ * @param {HTMLElement} targetElement
+ * @param {HTMLElement} tooltipLayer
+ * @param {HTMLElement} arrowLayer
+ * @param {Boolean} hintMode
+ */
+
+
+ function placeTooltip(targetElement, tooltipLayer, arrowLayer, hintMode) {
+ var tooltipCssClass = "";
+ var currentStepObj;
+ var tooltipOffset;
+ var targetOffset;
+ var windowSize;
+ var currentTooltipPosition;
+ hintMode = hintMode || false; //reset the old style
+
+ tooltipLayer.style.top = null;
+ tooltipLayer.style.right = null;
+ tooltipLayer.style.bottom = null;
+ tooltipLayer.style.left = null;
+ tooltipLayer.style.marginLeft = null;
+ tooltipLayer.style.marginTop = null;
+ arrowLayer.style.display = "inherit"; //prevent error when `this._currentStep` is undefined
+
+ if (!this._introItems[this._currentStep]) return; //if we have a custom css class for each step
+
+ currentStepObj = this._introItems[this._currentStep];
+
+ if (typeof currentStepObj.tooltipClass === "string") {
+ tooltipCssClass = currentStepObj.tooltipClass;
+ } else {
+ tooltipCssClass = this._options.tooltipClass;
+ }
+
+ tooltipLayer.className = ["introjs-tooltip", tooltipCssClass].filter(Boolean).join(" ");
+ tooltipLayer.setAttribute("role", "dialog");
+ currentTooltipPosition = this._introItems[this._currentStep].position; // Floating is always valid, no point in calculating
+
+ if (currentTooltipPosition !== "floating" && this._options.autoPosition) {
+ currentTooltipPosition = _determineAutoPosition.call(this, targetElement, tooltipLayer, currentTooltipPosition);
+ }
+
+ var tooltipLayerStyleLeft;
+ targetOffset = getOffset(targetElement);
+ tooltipOffset = getOffset(tooltipLayer);
+ windowSize = getWinSize();
+ addClass(tooltipLayer, "introjs-".concat(currentTooltipPosition));
+
+ switch (currentTooltipPosition) {
+ case "top-right-aligned":
+ arrowLayer.className = "introjs-arrow bottom-right";
+ var tooltipLayerStyleRight = 0;
+ checkLeft(targetOffset, tooltipLayerStyleRight, tooltipOffset, tooltipLayer);
+ tooltipLayer.style.bottom = "".concat(targetOffset.height + 20, "px");
+ break;
+
+ case "top-middle-aligned":
+ arrowLayer.className = "introjs-arrow bottom-middle";
+ var tooltipLayerStyleLeftRight = targetOffset.width / 2 - tooltipOffset.width / 2; // a fix for middle aligned hints
+
+ if (hintMode) {
+ tooltipLayerStyleLeftRight += 5;
+ }
+
+ if (checkLeft(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, tooltipLayer)) {
+ tooltipLayer.style.right = null;
+ checkRight(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, windowSize, tooltipLayer);
+ }
+
+ tooltipLayer.style.bottom = "".concat(targetOffset.height + 20, "px");
+ break;
+
+ case "top-left-aligned": // top-left-aligned is the same as the default top
+
+ case "top":
+ arrowLayer.className = "introjs-arrow bottom";
+ tooltipLayerStyleLeft = hintMode ? 0 : 15;
+ checkRight(targetOffset, tooltipLayerStyleLeft, tooltipOffset, windowSize, tooltipLayer);
+ tooltipLayer.style.bottom = "".concat(targetOffset.height + 20, "px");
+ break;
+
+ case "right":
+ tooltipLayer.style.left = "".concat(targetOffset.width + 20, "px");
+
+ if (targetOffset.top + tooltipOffset.height > windowSize.height) {
+ // In this case, right would have fallen below the bottom of the screen.
+ // Modify so that the bottom of the tooltip connects with the target
+ arrowLayer.className = "introjs-arrow left-bottom";
+ tooltipLayer.style.top = "-".concat(tooltipOffset.height - targetOffset.height - 20, "px");
+ } else {
+ arrowLayer.className = "introjs-arrow left";
+ }
+
+ break;
+
+ case "left":
+ if (!hintMode && this._options.showStepNumbers === true) {
+ tooltipLayer.style.top = "15px";
+ }
+
+ if (targetOffset.top + tooltipOffset.height > windowSize.height) {
+ // In this case, left would have fallen below the bottom of the screen.
+ // Modify so that the bottom of the tooltip connects with the target
+ tooltipLayer.style.top = "-".concat(tooltipOffset.height - targetOffset.height - 20, "px");
+ arrowLayer.className = "introjs-arrow right-bottom";
+ } else {
+ arrowLayer.className = "introjs-arrow right";
+ }
+
+ tooltipLayer.style.right = "".concat(targetOffset.width + 20, "px");
+ break;
+
+ case "floating":
+ arrowLayer.style.display = "none"; //we have to adjust the top and left of layer manually for intro items without element
+
+ tooltipLayer.style.left = "50%";
+ tooltipLayer.style.top = "50%";
+ tooltipLayer.style.marginLeft = "-".concat(tooltipOffset.width / 2, "px");
+ tooltipLayer.style.marginTop = "-".concat(tooltipOffset.height / 2, "px");
+ break;
+
+ case "bottom-right-aligned":
+ arrowLayer.className = "introjs-arrow top-right";
+ tooltipLayerStyleRight = 0;
+ checkLeft(targetOffset, tooltipLayerStyleRight, tooltipOffset, tooltipLayer);
+ tooltipLayer.style.top = "".concat(targetOffset.height + 20, "px");
+ break;
+
+ case "bottom-middle-aligned":
+ arrowLayer.className = "introjs-arrow top-middle";
+ tooltipLayerStyleLeftRight = targetOffset.width / 2 - tooltipOffset.width / 2; // a fix for middle aligned hints
+
+ if (hintMode) {
+ tooltipLayerStyleLeftRight += 5;
+ }
+
+ if (checkLeft(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, tooltipLayer)) {
+ tooltipLayer.style.right = null;
+ checkRight(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, windowSize, tooltipLayer);
+ }
+
+ tooltipLayer.style.top = "".concat(targetOffset.height + 20, "px");
+ break;
+ // case 'bottom-left-aligned':
+ // Bottom-left-aligned is the same as the default bottom
+ // case 'bottom':
+ // Bottom going to follow the default behavior
+
+ default:
+ arrowLayer.className = "introjs-arrow top";
+ tooltipLayerStyleLeft = 0;
+ checkRight(targetOffset, tooltipLayerStyleLeft, tooltipOffset, windowSize, tooltipLayer);
+ tooltipLayer.style.top = "".concat(targetOffset.height + 20, "px");
+ }
+ }
+
+ /**
+ * To remove all show element(s)
+ *
+ * @api private
+ * @method _removeShowElement
+ */
+
+ function removeShowElement() {
+ var elms = document.querySelectorAll(".introjs-showElement");
+ forEach(elms, function (elm) {
+ removeClass(elm, /introjs-[a-zA-Z]+/g);
+ });
+ }
+
+ function _createElement(tagname, attrs) {
+ var element = document.createElement(tagname);
+ attrs = attrs || {}; // regex for matching attributes that need to be set with setAttribute
+
+ var setAttRegex = /^(?:role|data-|aria-)/;
+
+ for (var k in attrs) {
+ var v = attrs[k];
+
+ if (k === "style") {
+ setStyle(element, v);
+ } else if (k.match(setAttRegex)) {
+ element.setAttribute(k, v);
+ } else {
+ element[k] = v;
+ }
+ }
+
+ return element;
+ }
+
+ /**
+ * Appends `element` to `parentElement`
+ *
+ * @param {Element} parentElement
+ * @param {Element} element
+ * @param {Boolean} [animate=false]
+ */
+
+ function appendChild(parentElement, element, animate) {
+ if (animate) {
+ var existingOpacity = element.style.opacity || "1";
+ setStyle(element, {
+ opacity: "0"
+ });
+ window.setTimeout(function () {
+ setStyle(element, {
+ opacity: existingOpacity
+ });
+ }, 10);
+ }
+
+ parentElement.appendChild(element);
}
/**
@@ -2288,93 +2825,1763 @@
* @method _getProgress
* @returns current progress percentage
*/
+
function _getProgress() {
// Steps are 0 indexed
- var currentStep = parseInt((this._currentStep + 1), 10);
- return ((currentStep / this._introItems.length) * 100);
+ var currentStep = parseInt(this._currentStep + 1, 10);
+ return currentStep / this._introItems.length * 100;
+ }
+ /**
+ * Add disableinteraction layer and adjust the size and position of the layer
+ *
+ * @api private
+ * @method _disableInteraction
+ */
+
+
+ function _disableInteraction() {
+ var disableInteractionLayer = document.querySelector(".introjs-disableInteraction");
+
+ if (disableInteractionLayer === null) {
+ disableInteractionLayer = _createElement("div", {
+ className: "introjs-disableInteraction"
+ });
+
+ this._targetElement.appendChild(disableInteractionLayer);
+ }
+
+ setHelperLayerPosition.call(this, disableInteractionLayer);
+ }
+ /**
+ * Creates the bullets layer
+ * @returns HTMLElement
+ * @private
+ */
+
+
+ function _createBullets(targetElement) {
+ var self = this;
+ var bulletsLayer = _createElement("div", {
+ className: "introjs-bullets"
+ });
+
+ if (this._options.showBullets === false) {
+ bulletsLayer.style.display = "none";
+ }
+
+ var ulContainer = _createElement("ul");
+ ulContainer.setAttribute("role", "tablist");
+
+ var anchorClick = function anchorClick() {
+ self.goToStep(this.getAttribute("data-stepnumber"));
+ };
+
+ forEach(this._introItems, function (_ref, i) {
+ var step = _ref.step;
+ var innerLi = _createElement("li");
+ var anchorLink = _createElement("a");
+ innerLi.setAttribute("role", "presentation");
+ anchorLink.setAttribute("role", "tab");
+ anchorLink.onclick = anchorClick;
+
+ if (i === targetElement.step - 1) {
+ anchorLink.className = "active";
+ }
+
+ setAnchorAsButton(anchorLink);
+ anchorLink.innerHTML = " ";
+ anchorLink.setAttribute("data-stepnumber", step);
+ innerLi.appendChild(anchorLink);
+ ulContainer.appendChild(innerLi);
+ });
+ bulletsLayer.appendChild(ulContainer);
+ return bulletsLayer;
+ }
+ /**
+ * Deletes and recreates the bullets layer
+ * @param oldReferenceLayer
+ * @param targetElement
+ * @private
+ */
+
+
+ function _recreateBullets(oldReferenceLayer, targetElement) {
+ if (this._options.showBullets) {
+ var existing = document.querySelector(".introjs-bullets");
+ existing.parentNode.replaceChild(_createBullets.call(this, targetElement), existing);
+ }
+ }
+ /**
+ * Updates the bullets
+ *
+ * @param oldReferenceLayer
+ * @param targetElement
+ */
+
+ function _updateBullets(oldReferenceLayer, targetElement) {
+ if (this._options.showBullets) {
+ oldReferenceLayer.querySelector(".introjs-bullets li > a.active").className = "";
+ oldReferenceLayer.querySelector(".introjs-bullets li > a[data-stepnumber=\"".concat(targetElement.step, "\"]")).className = "active";
+ }
+ }
+ /**
+ * Creates the progress-bar layer and elements
+ * @returns {*}
+ * @private
+ */
+
+
+ function _createProgressBar() {
+ var progressLayer = _createElement("div");
+ progressLayer.className = "introjs-progress";
+
+ if (this._options.showProgress === false) {
+ progressLayer.style.display = "none";
+ }
+
+ var progressBar = _createElement("div", {
+ className: "introjs-progressbar"
+ });
+
+ if (this._options.progressBarAdditionalClass) {
+ progressBar.className += " " + this._options.progressBarAdditionalClass;
+ }
+
+ progressBar.setAttribute("role", "progress");
+ progressBar.setAttribute("aria-valuemin", 0);
+ progressBar.setAttribute("aria-valuemax", 100);
+ progressBar.setAttribute("aria-valuenow", _getProgress.call(this));
+ progressBar.style.cssText = "width:".concat(_getProgress.call(this), "%;");
+ progressLayer.appendChild(progressBar);
+ return progressLayer;
+ }
+ /**
+ * Updates an existing progress bar variables
+ * @param oldReferenceLayer
+ * @private
+ */
+
+
+ function _updateProgressBar(oldReferenceLayer) {
+ oldReferenceLayer.querySelector(".introjs-progress .introjs-progressbar").style.cssText = "width:".concat(_getProgress.call(this), "%;");
+ oldReferenceLayer.querySelector(".introjs-progress .introjs-progressbar").setAttribute("aria-valuenow", _getProgress.call(this));
+ }
+ /**
+ * Show an element on the page
+ *
+ * @api private
+ * @method _showElement
+ * @param {Object} targetElement
+ */
+
+ function _showElement(targetElement) {
+ var _this = this;
+
+ if (typeof this._introChangeCallback !== "undefined") {
+ this._introChangeCallback.call(this, targetElement.element);
+ }
+
+ var self = this;
+ var oldHelperLayer = document.querySelector(".introjs-helperLayer");
+ var oldReferenceLayer = document.querySelector(".introjs-tooltipReferenceLayer");
+ var highlightClass = "introjs-helperLayer";
+ var nextTooltipButton;
+ var prevTooltipButton;
+ var skipTooltipButton; //check for a current step highlight class
+
+ if (typeof targetElement.highlightClass === "string") {
+ highlightClass += " ".concat(targetElement.highlightClass);
+ } //check for options highlight class
+
+
+ if (typeof this._options.highlightClass === "string") {
+ highlightClass += " ".concat(this._options.highlightClass);
+ }
+
+ if (oldHelperLayer !== null && oldReferenceLayer !== null) {
+ var oldHelperNumberLayer = oldReferenceLayer.querySelector(".introjs-helperNumberLayer");
+ var oldtooltipLayer = oldReferenceLayer.querySelector(".introjs-tooltiptext");
+ var oldTooltipTitleLayer = oldReferenceLayer.querySelector(".introjs-tooltip-title");
+ var oldArrowLayer = oldReferenceLayer.querySelector(".introjs-arrow");
+ var oldtooltipContainer = oldReferenceLayer.querySelector(".introjs-tooltip");
+ skipTooltipButton = oldReferenceLayer.querySelector(".introjs-skipbutton");
+ prevTooltipButton = oldReferenceLayer.querySelector(".introjs-prevbutton");
+ nextTooltipButton = oldReferenceLayer.querySelector(".introjs-nextbutton"); //update or reset the helper highlight class
+
+ oldHelperLayer.className = highlightClass; //hide the tooltip
+
+ oldtooltipContainer.style.opacity = 0;
+ oldtooltipContainer.style.display = "none"; // if the target element is within a scrollable element
+
+ scrollParentToElement.call(self, targetElement); // set new position to helper layer
+
+ setHelperLayerPosition.call(self, oldHelperLayer);
+ setHelperLayerPosition.call(self, oldReferenceLayer); //remove old classes if the element still exist
+
+ removeShowElement(); //we should wait until the CSS3 transition is competed (it's 0.3 sec) to prevent incorrect `height` and `width` calculation
+
+ if (self._lastShowElementTimer) {
+ window.clearTimeout(self._lastShowElementTimer);
+ }
+
+ self._lastShowElementTimer = window.setTimeout(function () {
+ // set current step to the label
+ if (oldHelperNumberLayer !== null) {
+ oldHelperNumberLayer.innerHTML = "".concat(targetElement.step, " of ").concat(_this._introItems.length);
+ } // set current tooltip text
+
+
+ oldtooltipLayer.innerHTML = targetElement.intro; // set current tooltip title
+
+ oldTooltipTitleLayer.innerHTML = targetElement.title; //set the tooltip position
+
+ oldtooltipContainer.style.display = "block";
+ placeTooltip.call(self, targetElement.element, oldtooltipContainer, oldArrowLayer); //change active bullet
+
+ _updateBullets.call(self, oldReferenceLayer, targetElement);
+
+ _updateProgressBar.call(self, oldReferenceLayer); //show the tooltip
+
+
+ oldtooltipContainer.style.opacity = 1; //reset button focus
+
+ if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null && /introjs-donebutton/gi.test(nextTooltipButton.className)) {
+ // skip button is now "done" button
+ nextTooltipButton.focus();
+ } else if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
+ //still in the tour, focus on next
+ nextTooltipButton.focus();
+ } // change the scroll of the window, if needed
+
+
+ scrollTo.call(self, targetElement.scrollTo, targetElement, oldtooltipLayer);
+ }, 350); // end of old element if-else condition
+ } else {
+ var helperLayer = _createElement("div", {
+ className: highlightClass
+ });
+ var referenceLayer = _createElement("div", {
+ className: "introjs-tooltipReferenceLayer"
+ });
+ var arrowLayer = _createElement("div", {
+ className: "introjs-arrow"
+ });
+ var tooltipLayer = _createElement("div", {
+ className: "introjs-tooltip"
+ });
+ var tooltipTextLayer = _createElement("div", {
+ className: "introjs-tooltiptext"
+ });
+ var tooltipHeaderLayer = _createElement("div", {
+ className: "introjs-tooltip-header"
+ });
+ var tooltipTitleLayer = _createElement("h1", {
+ className: "introjs-tooltip-title"
+ });
+ var buttonsLayer = _createElement("div");
+ setStyle(helperLayer, {
+ "box-shadow": "0 0 1px 2px rgba(33, 33, 33, 0.8), rgba(33, 33, 33, ".concat(self._options.overlayOpacity.toString(), ") 0 0 0 5000px")
+ }); // target is within a scrollable element
+
+ scrollParentToElement.call(self, targetElement); //set new position to helper layer
+
+ setHelperLayerPosition.call(self, helperLayer);
+ setHelperLayerPosition.call(self, referenceLayer); //add helper layer to target element
+
+ appendChild(this._targetElement, helperLayer, true);
+ appendChild(this._targetElement, referenceLayer);
+ tooltipTextLayer.innerHTML = targetElement.intro;
+ tooltipTitleLayer.innerHTML = targetElement.title;
+ buttonsLayer.className = "introjs-tooltipbuttons";
+
+ if (this._options.showButtons === false) {
+ buttonsLayer.style.display = "none";
+ }
+
+ tooltipHeaderLayer.appendChild(tooltipTitleLayer);
+ tooltipLayer.appendChild(tooltipHeaderLayer);
+ tooltipLayer.appendChild(tooltipTextLayer);
+ tooltipLayer.appendChild(_createBullets.call(this, targetElement));
+ tooltipLayer.appendChild(_createProgressBar.call(this)); // add helper layer number
+
+ var helperNumberLayer = _createElement("div");
+
+ if (this._options.showStepNumbers === true) {
+ helperNumberLayer.className = "introjs-helperNumberLayer";
+ helperNumberLayer.innerHTML = "".concat(targetElement.step, " of ").concat(this._introItems.length);
+ tooltipLayer.appendChild(helperNumberLayer);
+ }
+
+ tooltipLayer.appendChild(arrowLayer);
+ referenceLayer.appendChild(tooltipLayer); //next button
+
+ nextTooltipButton = _createElement("a");
+
+ nextTooltipButton.onclick = function () {
+ if (self._introItems.length - 1 !== self._currentStep) {
+ nextStep.call(self);
+ } else if (/introjs-donebutton/gi.test(nextTooltipButton.className)) {
+ if (typeof self._introCompleteCallback === "function") {
+ self._introCompleteCallback.call(self);
+ }
+
+ exitIntro.call(self, self._targetElement);
+ }
+ };
+
+ setAnchorAsButton(nextTooltipButton);
+ nextTooltipButton.innerHTML = this._options.nextLabel; //previous button
+
+ prevTooltipButton = _createElement("a");
+
+ prevTooltipButton.onclick = function () {
+ if (self._currentStep !== 0) {
+ previousStep.call(self);
+ }
+ };
+
+ setAnchorAsButton(prevTooltipButton);
+ prevTooltipButton.innerHTML = this._options.prevLabel; //skip button
+
+ skipTooltipButton = _createElement("a", {
+ className: "introjs-skipbutton"
+ });
+ setAnchorAsButton(skipTooltipButton);
+ skipTooltipButton.innerHTML = this._options.skipLabel;
+
+ skipTooltipButton.onclick = function () {
+ if (self._introItems.length - 1 === self._currentStep && typeof self._introCompleteCallback === "function") {
+ self._introCompleteCallback.call(self);
+ }
+
+ if (typeof self._introSkipCallback === "function") {
+ self._introSkipCallback.call(self);
+ }
+
+ exitIntro.call(self, self._targetElement);
+ };
+
+ tooltipHeaderLayer.appendChild(skipTooltipButton); //in order to prevent displaying previous button always
+
+ if (this._introItems.length > 1) {
+ buttonsLayer.appendChild(prevTooltipButton);
+ } // we always need the next button because this
+ // button changes to "Done" in the last step of the tour
+
+
+ buttonsLayer.appendChild(nextTooltipButton);
+ tooltipLayer.appendChild(buttonsLayer); //set proper position
+
+ placeTooltip.call(self, targetElement.element, tooltipLayer, arrowLayer); // change the scroll of the window, if needed
+
+ scrollTo.call(this, targetElement.scrollTo, targetElement, tooltipLayer); //end of new element if-else condition
+ } // removing previous disable interaction layer
+
+
+ var disableInteractionLayer = self._targetElement.querySelector(".introjs-disableInteraction");
+
+ if (disableInteractionLayer) {
+ disableInteractionLayer.parentNode.removeChild(disableInteractionLayer);
+ } //disable interaction
+
+
+ if (targetElement.disableInteraction) {
+ _disableInteraction.call(self);
+ } // when it's the first step of tour
+
+
+ if (this._currentStep === 0 && this._introItems.length > 1) {
+ if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
+ nextTooltipButton.className = "".concat(this._options.buttonClass, " introjs-nextbutton");
+ nextTooltipButton.innerHTML = this._options.nextLabel;
+ }
+
+ if (this._options.hidePrev === true) {
+ if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
+ prevTooltipButton.className = "".concat(this._options.buttonClass, " introjs-prevbutton introjs-hidden");
+ }
+
+ if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
+ addClass(nextTooltipButton, "introjs-fullbutton");
+ }
+ } else {
+ if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
+ prevTooltipButton.className = "".concat(this._options.buttonClass, " introjs-prevbutton introjs-disabled");
+ }
+ }
+ } else if (this._introItems.length - 1 === this._currentStep || this._introItems.length === 1) {
+ // last step of tour
+ if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
+ prevTooltipButton.className = "".concat(this._options.buttonClass, " introjs-prevbutton");
+ }
+
+ if (this._options.hideNext === true) {
+ if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
+ nextTooltipButton.className = "".concat(this._options.buttonClass, " introjs-nextbutton introjs-hidden");
+ }
+
+ if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
+ addClass(prevTooltipButton, "introjs-fullbutton");
+ }
+ } else {
+ if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
+ if (this._options.nextToDone === true) {
+ nextTooltipButton.innerHTML = this._options.doneLabel;
+ addClass(nextTooltipButton, "".concat(this._options.buttonClass, " introjs-nextbutton introjs-donebutton"));
+ } else {
+ nextTooltipButton.className = "".concat(this._options.buttonClass, " introjs-nextbutton introjs-disabled");
+ }
+ }
+ }
+ } else {
+ // steps between start and end
+ if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
+ prevTooltipButton.className = "".concat(this._options.buttonClass, " introjs-prevbutton");
+ }
+
+ if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
+ nextTooltipButton.className = "".concat(this._options.buttonClass, " introjs-nextbutton");
+ nextTooltipButton.innerHTML = this._options.nextLabel;
+ }
+ }
+
+ if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
+ prevTooltipButton.setAttribute("role", "button");
+ }
+
+ if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
+ nextTooltipButton.setAttribute("role", "button");
+ }
+
+ if (typeof skipTooltipButton !== "undefined" && skipTooltipButton !== null) {
+ skipTooltipButton.setAttribute("role", "button");
+ } //Set focus on "next" button, so that hitting Enter always moves you onto the next step
+
+
+ if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
+ nextTooltipButton.focus();
+ }
+
+ setShowElement(targetElement);
+
+ if (typeof this._introAfterChangeCallback !== "undefined") {
+ this._introAfterChangeCallback.call(this, targetElement.element);
+ }
}
/**
- * Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
- * via: http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically
+ * Go to specific step of introduction
*
- * @param obj1
- * @param obj2
- * @returns obj3 a new object based on obj1 and obj2
+ * @api private
+ * @method _goToStep
*/
- function _mergeOptions(obj1,obj2) {
- var obj3 = {},
- attrname;
- for (attrname in obj1) { obj3[attrname] = obj1[attrname]; }
- for (attrname in obj2) { obj3[attrname] = obj2[attrname]; }
- return obj3;
+
+ function goToStep(step) {
+ //because steps starts with zero
+ this._currentStep = step - 2;
+
+ if (typeof this._introItems !== "undefined") {
+ nextStep.call(this);
+ }
+ }
+ /**
+ * Go to the specific step of introduction with the explicit [data-step] number
+ *
+ * @api private
+ * @method _goToStepNumber
+ */
+
+ function goToStepNumber(step) {
+ this._currentStepNumber = step;
+
+ if (typeof this._introItems !== "undefined") {
+ nextStep.call(this);
+ }
+ }
+ /**
+ * Go to next step on intro
+ *
+ * @api private
+ * @method _nextStep
+ */
+
+ function nextStep() {
+ var _this = this;
+
+ this._direction = "forward";
+
+ if (typeof this._currentStepNumber !== "undefined") {
+ forEach(this._introItems, function (_ref, i) {
+ var step = _ref.step;
+
+ if (step === _this._currentStepNumber) {
+ _this._currentStep = i - 1;
+ _this._currentStepNumber = undefined;
+ }
+ });
+ }
+
+ if (typeof this._currentStep === "undefined") {
+ this._currentStep = 0;
+ } else {
+ ++this._currentStep;
+ }
+
+ var nextStep = this._introItems[this._currentStep];
+ var continueStep = true;
+
+ if (typeof this._introBeforeChangeCallback !== "undefined") {
+ continueStep = this._introBeforeChangeCallback.call(this, nextStep && nextStep.element);
+ } // if `onbeforechange` returned `false`, stop displaying the element
+
+
+ if (continueStep === false) {
+ --this._currentStep;
+ return false;
+ }
+
+ if (this._introItems.length <= this._currentStep) {
+ //end of the intro
+ //check if any callback is defined
+ if (typeof this._introCompleteCallback === "function") {
+ this._introCompleteCallback.call(this);
+ }
+
+ exitIntro.call(this, this._targetElement);
+ return;
+ }
+
+ _showElement.call(this, nextStep);
+ }
+ /**
+ * Go to previous step on intro
+ *
+ * @api private
+ * @method _previousStep
+ */
+
+ function previousStep() {
+ this._direction = "backward";
+
+ if (this._currentStep === 0) {
+ return false;
+ }
+
+ --this._currentStep;
+ var nextStep = this._introItems[this._currentStep];
+ var continueStep = true;
+
+ if (typeof this._introBeforeChangeCallback !== "undefined") {
+ continueStep = this._introBeforeChangeCallback.call(this, nextStep && nextStep.element);
+ } // if `onbeforechange` returned `false`, stop displaying the element
+
+
+ if (continueStep === false) {
+ ++this._currentStep;
+ return false;
+ }
+
+ _showElement.call(this, nextStep);
+ }
+ /**
+ * Returns the current step of the intro
+ *
+ * @returns {number | boolean}
+ */
+
+ function currentStep() {
+ return this._currentStep;
}
- var introJs = function (targetElm) {
+ /**
+ * on keyCode:
+ * https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
+ * This feature has been removed from the Web standards.
+ * Though some browsers may still support it, it is in
+ * the process of being dropped.
+ * Instead, you should use KeyboardEvent.code,
+ * if it's implemented.
+ *
+ * jQuery's approach is to test for
+ * (1) e.which, then
+ * (2) e.charCode, then
+ * (3) e.keyCode
+ * https://github.com/jquery/jquery/blob/a6b0705294d336ae2f63f7276de0da1195495363/src/event.js#L638
+ *
+ * @param type var
+ * @return type
+ */
+
+ function onKeyDown(e) {
+ var code = e.code === undefined ? e.which : e.code; // if e.which is null
+
+ if (code === null) {
+ code = e.charCode === null ? e.keyCode : e.charCode;
+ }
+
+ if ((code === "Escape" || code === 27) && this._options.exitOnEsc === true) {
+ //escape key pressed, exit the intro
+ //check if exit callback is defined
+ exitIntro.call(this, this._targetElement);
+ } else if (code === "ArrowLeft" || code === 37) {
+ //left arrow
+ previousStep.call(this);
+ } else if (code === "ArrowRight" || code === 39) {
+ //right arrow
+ nextStep.call(this);
+ } else if (code === "Enter" || code === "NumpadEnter" || code === 13) {
+ //srcElement === ie
+ var target = e.target || e.srcElement;
+
+ if (target && target.className.match("introjs-prevbutton")) {
+ //user hit enter while focusing on previous button
+ previousStep.call(this);
+ } else if (target && target.className.match("introjs-skipbutton")) {
+ //user hit enter while focusing on skip button
+ if (this._introItems.length - 1 === this._currentStep && typeof this._introCompleteCallback === "function") {
+ this._introCompleteCallback.call(this);
+ }
+
+ exitIntro.call(this, this._targetElement);
+ } else if (target && target.getAttribute("data-stepnumber")) {
+ // user hit enter while focusing on step bullet
+ target.click();
+ } else {
+ //default behavior for responding to enter
+ nextStep.call(this);
+ } //prevent default behaviour on hitting Enter, to prevent steps being skipped in some browsers
+
+
+ if (e.preventDefault) {
+ e.preventDefault();
+ } else {
+ e.returnValue = false;
+ }
+ }
+ }
+
+ /*
+ * makes a copy of the object
+ * @api private
+ * @method _cloneObject
+ */
+ function cloneObject(object) {
+ if (object === null || _typeof(object) !== "object" || typeof object.nodeType !== "undefined") {
+ return object;
+ }
+
+ var temp = {};
+
+ for (var key in object) {
+ if (typeof window.jQuery !== "undefined" && object[key] instanceof window.jQuery) {
+ temp[key] = object[key];
+ } else {
+ temp[key] = cloneObject(object[key]);
+ }
+ }
+
+ return temp;
+ }
+
+ /**
+ * Get a queryselector within the hint wrapper
+ *
+ * @param {String} selector
+ * @return {NodeList|Array}
+ */
+
+ function hintQuerySelectorAll(selector) {
+ var hintsWrapper = document.querySelector(".introjs-hints");
+ return hintsWrapper ? hintsWrapper.querySelectorAll(selector) : [];
+ }
+ /**
+ * Hide a hint
+ *
+ * @api private
+ * @method hideHint
+ */
+
+ function hideHint(stepId) {
+ var hint = hintQuerySelectorAll(".introjs-hint[data-step=\"".concat(stepId, "\"]"))[0];
+ removeHintTooltip.call(this);
+
+ if (hint) {
+ addClass(hint, "introjs-hidehint");
+ } // call the callback function (if any)
+
+
+ if (typeof this._hintCloseCallback !== "undefined") {
+ this._hintCloseCallback.call(this, stepId);
+ }
+ }
+ /**
+ * Hide all hints
+ *
+ * @api private
+ * @method hideHints
+ */
+
+ function hideHints() {
+ var _this = this;
+
+ var hints = hintQuerySelectorAll(".introjs-hint");
+ forEach(hints, function (hint) {
+ hideHint.call(_this, hint.getAttribute("data-step"));
+ });
+ }
+ /**
+ * Show all hints
+ *
+ * @api private
+ * @method _showHints
+ */
+
+ function showHints() {
+ var _this2 = this;
+
+ var hints = hintQuerySelectorAll(".introjs-hint");
+
+ if (hints && hints.length) {
+ forEach(hints, function (hint) {
+ showHint.call(_this2, hint.getAttribute("data-step"));
+ });
+ } else {
+ populateHints.call(this, this._targetElement);
+ }
+ }
+ /**
+ * Show a hint
+ *
+ * @api private
+ * @method showHint
+ */
+
+ function showHint(stepId) {
+ var hint = hintQuerySelectorAll(".introjs-hint[data-step=\"".concat(stepId, "\"]"))[0];
+
+ if (hint) {
+ removeClass(hint, /introjs-hidehint/g);
+ }
+ }
+ /**
+ * Removes all hint elements on the page
+ * Useful when you want to destroy the elements and add them again (e.g. a modal or popup)
+ *
+ * @api private
+ * @method removeHints
+ */
+
+ function removeHints() {
+ var _this3 = this;
+
+ var hints = hintQuerySelectorAll(".introjs-hint");
+ forEach(hints, function (hint) {
+ removeHint.call(_this3, hint.getAttribute("data-step"));
+ });
+ }
+ /**
+ * Remove one single hint element from the page
+ * Useful when you want to destroy the element and add them again (e.g. a modal or popup)
+ * Use removeHints if you want to remove all elements.
+ *
+ * @api private
+ * @method removeHint
+ */
+
+ function removeHint(stepId) {
+ var hint = hintQuerySelectorAll(".introjs-hint[data-step=\"".concat(stepId, "\"]"))[0];
+
+ if (hint) {
+ hint.parentNode.removeChild(hint);
+ }
+ }
+ /**
+ * Add all available hints to the page
+ *
+ * @api private
+ * @method addHints
+ */
+
+ function addHints() {
+ var _this4 = this;
+
+ var self = this;
+ var hintsWrapper = document.querySelector(".introjs-hints");
+
+ if (hintsWrapper === null) {
+ hintsWrapper = _createElement("div", {
+ className: "introjs-hints"
+ });
+ }
+ /**
+ * Returns an event handler unique to the hint iteration
+ *
+ * @param {Integer} i
+ * @return {Function}
+ */
+
+
+ var getHintClick = function getHintClick(i) {
+ return function (e) {
+ var evt = e ? e : window.event;
+
+ if (evt.stopPropagation) {
+ evt.stopPropagation();
+ }
+
+ if (evt.cancelBubble !== null) {
+ evt.cancelBubble = true;
+ }
+
+ showHintDialog.call(self, i);
+ };
+ };
+
+ forEach(this._introItems, function (item, i) {
+ // avoid append a hint twice
+ if (document.querySelector(".introjs-hint[data-step=\"".concat(i, "\"]"))) {
+ return;
+ }
+
+ var hint = _createElement("a", {
+ className: "introjs-hint"
+ });
+ setAnchorAsButton(hint);
+ hint.onclick = getHintClick(i);
+
+ if (!item.hintAnimation) {
+ addClass(hint, "introjs-hint-no-anim");
+ } // hint's position should be fixed if the target element's position is fixed
+
+
+ if (isFixed(item.element)) {
+ addClass(hint, "introjs-fixedhint");
+ }
+
+ var hintDot = _createElement("div", {
+ className: "introjs-hint-dot"
+ });
+ var hintPulse = _createElement("div", {
+ className: "introjs-hint-pulse"
+ });
+ hint.appendChild(hintDot);
+ hint.appendChild(hintPulse);
+ hint.setAttribute("data-step", i); // we swap the hint element with target element
+ // because _setHelperLayerPosition uses `element` property
+
+ item.targetElement = item.element;
+ item.element = hint; // align the hint position
+
+ alignHintPosition.call(_this4, item.hintPosition, hint, item.targetElement);
+ hintsWrapper.appendChild(hint);
+ }); // adding the hints wrapper
+
+ document.body.appendChild(hintsWrapper); // call the callback function (if any)
+
+ if (typeof this._hintsAddedCallback !== "undefined") {
+ this._hintsAddedCallback.call(this);
+ }
+ }
+ /**
+ * Aligns hint position
+ *
+ * @api private
+ * @method alignHintPosition
+ * @param {String} position
+ * @param {Object} hint
+ * @param {Object} element
+ */
+
+ function alignHintPosition(position, _ref, element) {
+ var style = _ref.style;
+ // get/calculate offset of target element
+ var offset = getOffset.call(this, element);
+ var iconWidth = 20;
+ var iconHeight = 20; // align the hint element
+
+ switch (position) {
+ default:
+ case "top-left":
+ style.left = "".concat(offset.left, "px");
+ style.top = "".concat(offset.top, "px");
+ break;
+
+ case "top-right":
+ style.left = "".concat(offset.left + offset.width - iconWidth, "px");
+ style.top = "".concat(offset.top, "px");
+ break;
+
+ case "bottom-left":
+ style.left = "".concat(offset.left, "px");
+ style.top = "".concat(offset.top + offset.height - iconHeight, "px");
+ break;
+
+ case "bottom-right":
+ style.left = "".concat(offset.left + offset.width - iconWidth, "px");
+ style.top = "".concat(offset.top + offset.height - iconHeight, "px");
+ break;
+
+ case "middle-left":
+ style.left = "".concat(offset.left, "px");
+ style.top = "".concat(offset.top + (offset.height - iconHeight) / 2, "px");
+ break;
+
+ case "middle-right":
+ style.left = "".concat(offset.left + offset.width - iconWidth, "px");
+ style.top = "".concat(offset.top + (offset.height - iconHeight) / 2, "px");
+ break;
+
+ case "middle-middle":
+ style.left = "".concat(offset.left + (offset.width - iconWidth) / 2, "px");
+ style.top = "".concat(offset.top + (offset.height - iconHeight) / 2, "px");
+ break;
+
+ case "bottom-middle":
+ style.left = "".concat(offset.left + (offset.width - iconWidth) / 2, "px");
+ style.top = "".concat(offset.top + offset.height - iconHeight, "px");
+ break;
+
+ case "top-middle":
+ style.left = "".concat(offset.left + (offset.width - iconWidth) / 2, "px");
+ style.top = "".concat(offset.top, "px");
+ break;
+ }
+ }
+ /**
+ * Triggers when user clicks on the hint element
+ *
+ * @api private
+ * @method _showHintDialog
+ * @param {Number} stepId
+ */
+
+ function showHintDialog(stepId) {
+ var hintElement = document.querySelector(".introjs-hint[data-step=\"".concat(stepId, "\"]"));
+ var item = this._introItems[stepId]; // call the callback function (if any)
+
+ if (typeof this._hintClickCallback !== "undefined") {
+ this._hintClickCallback.call(this, hintElement, item, stepId);
+ } // remove all open tooltips
+
+
+ var removedStep = removeHintTooltip.call(this); // to toggle the tooltip
+
+ if (parseInt(removedStep, 10) === stepId) {
+ return;
+ }
+
+ var tooltipLayer = _createElement("div", {
+ className: "introjs-tooltip"
+ });
+ var tooltipTextLayer = _createElement("div");
+ var arrowLayer = _createElement("div");
+ var referenceLayer = _createElement("div");
+
+ tooltipLayer.onclick = function (e) {
+ //IE9 & Other Browsers
+ if (e.stopPropagation) {
+ e.stopPropagation();
+ } //IE8 and Lower
+ else {
+ e.cancelBubble = true;
+ }
+ };
+
+ tooltipTextLayer.className = "introjs-tooltiptext";
+ var tooltipWrapper = _createElement("p");
+ tooltipWrapper.innerHTML = item.hint;
+ var closeButton = _createElement("a");
+ closeButton.className = this._options.buttonClass;
+ closeButton.setAttribute("role", "button");
+ closeButton.innerHTML = this._options.hintButtonLabel;
+ closeButton.onclick = hideHint.bind(this, stepId);
+ tooltipTextLayer.appendChild(tooltipWrapper);
+ tooltipTextLayer.appendChild(closeButton);
+ arrowLayer.className = "introjs-arrow";
+ tooltipLayer.appendChild(arrowLayer);
+ tooltipLayer.appendChild(tooltipTextLayer); // set current step for _placeTooltip function
+
+ this._currentStep = hintElement.getAttribute("data-step"); // align reference layer position
+
+ referenceLayer.className = "introjs-tooltipReferenceLayer introjs-hintReference";
+ referenceLayer.setAttribute("data-step", hintElement.getAttribute("data-step"));
+ setHelperLayerPosition.call(this, referenceLayer);
+ referenceLayer.appendChild(tooltipLayer);
+ document.body.appendChild(referenceLayer); //set proper position
+
+ placeTooltip.call(this, hintElement, tooltipLayer, arrowLayer, true);
+ }
+ /**
+ * Removes open hint (tooltip hint)
+ *
+ * @api private
+ * @method _removeHintTooltip
+ */
+
+ function removeHintTooltip() {
+ var tooltip = document.querySelector(".introjs-hintReference");
+
+ if (tooltip) {
+ var step = tooltip.getAttribute("data-step");
+ tooltip.parentNode.removeChild(tooltip);
+ return step;
+ }
+ }
+ /**
+ * Start parsing hint items
+ *
+ * @api private
+ * @param {Object} targetElm
+ * @method _startHint
+ */
+
+ function populateHints(targetElm) {
+ var _this5 = this;
+
+ this._introItems = [];
+
+ if (this._options.hints) {
+ forEach(this._options.hints, function (hint) {
+ var currentItem = cloneObject(hint);
+
+ if (typeof currentItem.element === "string") {
+ //grab the element with given selector from the page
+ currentItem.element = document.querySelector(currentItem.element);
+ }
+
+ currentItem.hintPosition = currentItem.hintPosition || _this5._options.hintPosition;
+ currentItem.hintAnimation = currentItem.hintAnimation || _this5._options.hintAnimation;
+
+ if (currentItem.element !== null) {
+ _this5._introItems.push(currentItem);
+ }
+ });
+ } else {
+ var hints = targetElm.querySelectorAll("*[data-hint]");
+
+ if (!hints || !hints.length) {
+ return false;
+ } //first add intro items with data-step
+
+
+ forEach(hints, function (currentElement) {
+ // hint animation
+ var hintAnimation = currentElement.getAttribute("data-hintanimation");
+
+ if (hintAnimation) {
+ hintAnimation = hintAnimation === "true";
+ } else {
+ hintAnimation = _this5._options.hintAnimation;
+ }
+
+ _this5._introItems.push({
+ element: currentElement,
+ hint: currentElement.getAttribute("data-hint"),
+ hintPosition: currentElement.getAttribute("data-hintposition") || _this5._options.hintPosition,
+ hintAnimation: hintAnimation,
+ tooltipClass: currentElement.getAttribute("data-tooltipclass"),
+ position: currentElement.getAttribute("data-position") || _this5._options.tooltipPosition
+ });
+ });
+ }
+
+ addHints.call(this);
+ /*
+ todo:
+ these events should be removed at some point
+ */
+
+ DOMEvent.on(document, "click", removeHintTooltip, this, false);
+ DOMEvent.on(window, "resize", reAlignHints, this, true);
+ }
+ /**
+ * Re-aligns all hint elements
+ *
+ * @api private
+ * @method _reAlignHints
+ */
+
+ function reAlignHints() {
+ var _this6 = this;
+
+ forEach(this._introItems, function (_ref2) {
+ var targetElement = _ref2.targetElement,
+ hintPosition = _ref2.hintPosition,
+ element = _ref2.element;
+
+ if (typeof targetElement === "undefined") {
+ return;
+ }
+
+ alignHintPosition.call(_this6, hintPosition, element, targetElement);
+ });
+ }
+
+ // TODO: use something more complex like timsort?
+ var floor = Math.floor;
+
+ var mergeSort = function (array, comparefn) {
+ var length = array.length;
+ var middle = floor(length / 2);
+ return length < 8 ? insertionSort(array, comparefn) : merge(
+ mergeSort(array.slice(0, middle), comparefn),
+ mergeSort(array.slice(middle), comparefn),
+ comparefn
+ );
+ };
+
+ var insertionSort = function (array, comparefn) {
+ var length = array.length;
+ var i = 1;
+ var element, j;
+
+ while (i < length) {
+ j = i;
+ element = array[i];
+ while (j && comparefn(array[j - 1], element) > 0) {
+ array[j] = array[--j];
+ }
+ if (j !== i++) array[j] = element;
+ } return array;
+ };
+
+ var merge = function (left, right, comparefn) {
+ var llength = left.length;
+ var rlength = right.length;
+ var lindex = 0;
+ var rindex = 0;
+ var result = [];
+
+ while (lindex < llength || rindex < rlength) {
+ if (lindex < llength && rindex < rlength) {
+ result.push(comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++]);
+ } else {
+ result.push(lindex < llength ? left[lindex++] : right[rindex++]);
+ }
+ } return result;
+ };
+
+ var arraySort = mergeSort;
+
+ var firefox = engineUserAgent.match(/firefox\/(\d+)/i);
+
+ var engineFfVersion = !!firefox && +firefox[1];
+
+ var engineIsIeOrEdge = /MSIE|Trident/.test(engineUserAgent);
+
+ var webkit = engineUserAgent.match(/AppleWebKit\/(\d+)\./);
+
+ var engineWebkitVersion = !!webkit && +webkit[1];
+
+ var test = [];
+ var nativeSort = test.sort;
+
+ // IE8-
+ var FAILS_ON_UNDEFINED = fails(function () {
+ test.sort(undefined);
+ });
+ // V8 bug
+ var FAILS_ON_NULL = fails(function () {
+ test.sort(null);
+ });
+ // Old WebKit
+ var STRICT_METHOD = arrayMethodIsStrict('sort');
+
+ var STABLE_SORT = !fails(function () {
+ // feature detection can be too slow, so check engines versions
+ if (engineV8Version) return engineV8Version < 70;
+ if (engineFfVersion && engineFfVersion > 3) return;
+ if (engineIsIeOrEdge) return true;
+ if (engineWebkitVersion) return engineWebkitVersion < 603;
+
+ var result = '';
+ var code, chr, value, index;
+
+ // generate an array with more 512 elements (Chakra and old V8 fails only in this case)
+ for (code = 65; code < 76; code++) {
+ chr = String.fromCharCode(code);
+
+ switch (code) {
+ case 66: case 69: case 70: case 72: value = 3; break;
+ case 68: case 71: value = 4; break;
+ default: value = 2;
+ }
+
+ for (index = 0; index < 47; index++) {
+ test.push({ k: chr + index, v: value });
+ }
+ }
+
+ test.sort(function (a, b) { return b.v - a.v; });
+
+ for (index = 0; index < test.length; index++) {
+ chr = test[index].k.charAt(0);
+ if (result.charAt(result.length - 1) !== chr) result += chr;
+ }
+
+ return result !== 'DGBEFHACIJK';
+ });
+
+ var FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD || !STABLE_SORT;
+
+ var getSortCompare = function (comparefn) {
+ return function (x, y) {
+ if (y === undefined) return -1;
+ if (x === undefined) return 1;
+ if (comparefn !== undefined) return +comparefn(x, y) || 0;
+ return toString_1(x) > toString_1(y) ? 1 : -1;
+ };
+ };
+
+ // `Array.prototype.sort` method
+ // https://tc39.es/ecma262/#sec-array.prototype.sort
+ _export({ target: 'Array', proto: true, forced: FORCED }, {
+ sort: function sort(comparefn) {
+ if (comparefn !== undefined) aFunction(comparefn);
+
+ var array = toObject(this);
+
+ if (STABLE_SORT) return comparefn === undefined ? nativeSort.call(array) : nativeSort.call(array, comparefn);
+
+ var items = [];
+ var arrayLength = toLength(array.length);
+ var itemsLength, index;
+
+ for (index = 0; index < arrayLength; index++) {
+ if (index in array) items.push(array[index]);
+ }
+
+ items = arraySort(items, getSortCompare(comparefn));
+ itemsLength = items.length;
+ index = 0;
+
+ while (index < itemsLength) array[index] = items[index++];
+ while (index < arrayLength) delete array[index++];
+
+ return array;
+ }
+ });
+
+ /**
+ * Finds all Intro steps from the data-* attributes and the options.steps array
+ *
+ * @api private
+ * @param targetElm
+ * @returns {[]}
+ */
+
+ function fetchIntroSteps(targetElm) {
+ var _this = this;
+
+ var allIntroSteps = targetElm.querySelectorAll("*[data-intro]");
+ var introItems = [];
+
+ if (this._options.steps) {
+ //use steps passed programmatically
+ forEach(this._options.steps, function (step) {
+ var currentItem = cloneObject(step); //set the step
+
+ currentItem.step = introItems.length + 1;
+ currentItem.title = currentItem.title || ""; //use querySelector function only when developer used CSS selector
+
+ if (typeof currentItem.element === "string") {
+ //grab the element with given selector from the page
+ currentItem.element = document.querySelector(currentItem.element);
+ } //intro without element
+
+
+ if (typeof currentItem.element === "undefined" || currentItem.element === null) {
+ var floatingElementQuery = document.querySelector(".introjsFloatingElement");
+
+ if (floatingElementQuery === null) {
+ floatingElementQuery = _createElement("div", {
+ className: "introjsFloatingElement"
+ });
+ document.body.appendChild(floatingElementQuery);
+ }
+
+ currentItem.element = floatingElementQuery;
+ currentItem.position = "floating";
+ }
+
+ currentItem.position = currentItem.position || _this._options.tooltipPosition;
+ currentItem.scrollTo = currentItem.scrollTo || _this._options.scrollTo;
+
+ if (typeof currentItem.disableInteraction === "undefined") {
+ currentItem.disableInteraction = _this._options.disableInteraction;
+ }
+
+ if (currentItem.element !== null) {
+ introItems.push(currentItem);
+ }
+ });
+ } else {
+ //use steps from data-* annotations
+ var elmsLength = allIntroSteps.length;
+ var disableInteraction; //if there's no element to intro
+
+ if (elmsLength < 1) {
+ return [];
+ }
+
+ forEach(allIntroSteps, function (currentElement) {
+ // start intro for groups of elements
+ if (_this._options.group && currentElement.getAttribute("data-intro-group") !== _this._options.group) {
+ return;
+ } // skip hidden elements
+
+
+ if (currentElement.style.display === "none") {
+ return;
+ }
+
+ var step = parseInt(currentElement.getAttribute("data-step"), 10);
+
+ if (currentElement.hasAttribute("data-disable-interaction")) {
+ disableInteraction = !!currentElement.getAttribute("data-disable-interaction");
+ } else {
+ disableInteraction = _this._options.disableInteraction;
+ }
+
+ if (step > 0) {
+ introItems[step - 1] = {
+ element: currentElement,
+ title: currentElement.getAttribute("data-title") || "",
+ intro: currentElement.getAttribute("data-intro"),
+ step: parseInt(currentElement.getAttribute("data-step"), 10),
+ tooltipClass: currentElement.getAttribute("data-tooltipclass"),
+ highlightClass: currentElement.getAttribute("data-highlightclass"),
+ position: currentElement.getAttribute("data-position") || _this._options.tooltipPosition,
+ scrollTo: currentElement.getAttribute("data-scrollto") || _this._options.scrollTo,
+ disableInteraction: disableInteraction
+ };
+ }
+ }); //next add intro items without data-step
+ //todo: we need a cleanup here, two loops are redundant
+
+ var nextStep = 0;
+ forEach(allIntroSteps, function (currentElement) {
+ // start intro for groups of elements
+ if (_this._options.group && currentElement.getAttribute("data-intro-group") !== _this._options.group) {
+ return;
+ }
+
+ if (currentElement.getAttribute("data-step") === null) {
+ while (true) {
+ if (typeof introItems[nextStep] === "undefined") {
+ break;
+ } else {
+ nextStep++;
+ }
+ }
+
+ if (currentElement.hasAttribute("data-disable-interaction")) {
+ disableInteraction = !!currentElement.getAttribute("data-disable-interaction");
+ } else {
+ disableInteraction = _this._options.disableInteraction;
+ }
+
+ introItems[nextStep] = {
+ element: currentElement,
+ title: currentElement.getAttribute("data-title") || "",
+ intro: currentElement.getAttribute("data-intro"),
+ step: nextStep + 1,
+ tooltipClass: currentElement.getAttribute("data-tooltipclass"),
+ highlightClass: currentElement.getAttribute("data-highlightclass"),
+ position: currentElement.getAttribute("data-position") || _this._options.tooltipPosition,
+ scrollTo: currentElement.getAttribute("data-scrollto") || _this._options.scrollTo,
+ disableInteraction: disableInteraction
+ };
+ }
+ });
+ } //removing undefined/null elements
+
+
+ var tempIntroItems = [];
+
+ for (var z = 0; z < introItems.length; z++) {
+ if (introItems[z]) {
+ // copy non-falsy values to the end of the array
+ tempIntroItems.push(introItems[z]);
+ }
+ }
+
+ introItems = tempIntroItems; //Ok, sort all items with given steps
+
+ introItems.sort(function (a, b) {
+ return a.step - b.step;
+ });
+ return introItems;
+ }
+
+ /**
+ * Update placement of the intro objects on the screen
+ * @api private
+ * @param {boolean} refreshSteps to refresh the intro steps as well
+ */
+
+ function refresh(refreshSteps) {
+ var referenceLayer = document.querySelector(".introjs-tooltipReferenceLayer");
+ var helperLayer = document.querySelector(".introjs-helperLayer");
+ var disableInteractionLayer = document.querySelector(".introjs-disableInteraction"); // re-align intros
+
+ setHelperLayerPosition.call(this, helperLayer);
+ setHelperLayerPosition.call(this, referenceLayer);
+ setHelperLayerPosition.call(this, disableInteractionLayer);
+
+ if (refreshSteps) {
+ this._introItems = fetchIntroSteps.call(this, this._targetElement);
+
+ _recreateBullets.call(this, referenceLayer, this._introItems[this._currentStep]);
+
+ _updateProgressBar.call(this, referenceLayer);
+ } // re-align tooltip
+
+
+ if (this._currentStep !== undefined && this._currentStep !== null) {
+ var oldArrowLayer = document.querySelector(".introjs-arrow");
+ var oldtooltipContainer = document.querySelector(".introjs-tooltip");
+ placeTooltip.call(this, this._introItems[this._currentStep].element, oldtooltipContainer, oldArrowLayer);
+ } //re-align hints
+
+
+ reAlignHints.call(this);
+ return this;
+ }
+
+ function onResize() {
+ refresh.call(this);
+ }
+
+ /**
+ * Removes `element` from `parentElement`
+ *
+ * @param {Element} element
+ * @param {Boolean} [animate=false]
+ */
+
+ function removeChild(element, animate) {
+ if (!element || !element.parentElement) return;
+ var parentElement = element.parentElement;
+
+ if (animate) {
+ setStyle(element, {
+ opacity: "0"
+ });
+ window.setTimeout(function () {
+ try {
+ // removeChild(..) throws an exception if the child has already been removed (https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild)
+ // this try-catch is added to make sure this function doesn't throw an exception if the child has been removed
+ // this scenario can happen when start()/exit() is called multiple times and the helperLayer is removed by the
+ // previous exit() call (note: this is a timeout)
+ parentElement.removeChild(element);
+ } catch (e) {}
+ }, 500);
+ } else {
+ parentElement.removeChild(element);
+ }
+ }
+
+ /**
+ * Exit from intro
+ *
+ * @api private
+ * @method _exitIntro
+ * @param {Object} targetElement
+ * @param {Boolean} force - Setting to `true` will skip the result of beforeExit callback
+ */
+
+ function exitIntro(targetElement, force) {
+ var continueExit = true; // calling onbeforeexit callback
+ //
+ // If this callback return `false`, it would halt the process
+
+ if (this._introBeforeExitCallback !== undefined) {
+ continueExit = this._introBeforeExitCallback.call(this);
+ } // skip this check if `force` parameter is `true`
+ // otherwise, if `onbeforeexit` returned `false`, don't exit the intro
+
+
+ if (!force && continueExit === false) return; // remove overlay layers from the page
+
+ var overlayLayers = targetElement.querySelectorAll(".introjs-overlay");
+
+ if (overlayLayers && overlayLayers.length) {
+ forEach(overlayLayers, function (overlayLayer) {
+ return removeChild(overlayLayer);
+ });
+ } //remove all helper layers
+
+
+ var helperLayer = targetElement.querySelector(".introjs-helperLayer");
+ removeChild(helperLayer, true);
+ var referenceLayer = targetElement.querySelector(".introjs-tooltipReferenceLayer");
+ removeChild(referenceLayer); //remove disableInteractionLayer
+
+ var disableInteractionLayer = targetElement.querySelector(".introjs-disableInteraction");
+ removeChild(disableInteractionLayer); //remove intro floating element
+
+ var floatingElement = document.querySelector(".introjsFloatingElement");
+ removeChild(floatingElement);
+ removeShowElement(); //clean listeners
+
+ DOMEvent.off(window, "keydown", onKeyDown, this, true);
+ DOMEvent.off(window, "resize", onResize, this, true); //check if any callback is defined
+
+ if (this._introExitCallback !== undefined) {
+ this._introExitCallback.call(this);
+ } //set the step to zero
+
+
+ this._currentStep = undefined;
+ }
+
+ /**
+ * Add overlay layer to the page
+ *
+ * @api private
+ * @method _addOverlayLayer
+ * @param {Object} targetElm
+ */
+
+ function addOverlayLayer(targetElm) {
+ var _this = this;
+
+ var overlayLayer = _createElement("div", {
+ className: "introjs-overlay"
+ });
+ setStyle(overlayLayer, {
+ top: 0,
+ bottom: 0,
+ left: 0,
+ right: 0,
+ position: "fixed"
+ });
+ targetElm.appendChild(overlayLayer);
+
+ if (this._options.exitOnOverlayClick === true) {
+ setStyle(overlayLayer, {
+ cursor: "pointer"
+ });
+
+ overlayLayer.onclick = function () {
+ exitIntro.call(_this, targetElm);
+ };
+ }
+
+ return true;
+ }
+
+ /**
+ * Initiate a new introduction/guide from an element in the page
+ *
+ * @api private
+ * @method introForElement
+ * @param {Object} targetElm
+ * @returns {Boolean} Success or not?
+ */
+
+ function introForElement(targetElm) {
+ //set it to the introJs object
+ var steps = fetchIntroSteps.call(this, targetElm);
+
+ if (steps.length === 0) {
+ return false;
+ }
+
+ this._introItems = steps; //add overlay layer to the page
+
+ if (addOverlayLayer.call(this, targetElm)) {
+ //then, start the show
+ nextStep.call(this);
+
+ if (this._options.keyboardNavigation) {
+ DOMEvent.on(window, "keydown", onKeyDown, this, true);
+ } //for window resize
+
+
+ DOMEvent.on(window, "resize", onResize, this, true);
+ }
+
+ return false;
+ }
+
+ var version = "4.2.2";
+
+ /**
+ * IntroJs main class
+ *
+ * @class IntroJs
+ */
+
+ function IntroJs(obj) {
+ this._targetElement = obj;
+ this._introItems = [];
+ this._options = {
+ /* Next button label in tooltip box */
+ nextLabel: "Next",
+
+ /* Previous button label in tooltip box */
+ prevLabel: "Back",
+
+ /* Skip button label in tooltip box */
+ skipLabel: "×",
+
+ /* Done button label in tooltip box */
+ doneLabel: "Done",
+
+ /* Hide previous button in the first step? Otherwise, it will be disabled button. */
+ hidePrev: false,
+
+ /* Hide next button in the last step? Otherwise, it will be disabled button (note: this will also hide the "Done" button) */
+ hideNext: false,
+
+ /* Change the Next button to Done in the last step of the intro? otherwise, it will render a disabled button */
+ nextToDone: true,
+
+ /* Default tooltip box position */
+ tooltipPosition: "bottom",
+
+ /* Next CSS class for tooltip boxes */
+ tooltipClass: "",
+
+ /* Start intro for a group of elements */
+ group: "",
+
+ /* CSS class that is added to the helperLayer */
+ highlightClass: "",
+
+ /* Close introduction when pressing Escape button? */
+ exitOnEsc: true,
+
+ /* Close introduction when clicking on overlay layer? */
+ exitOnOverlayClick: true,
+
+ /* Show step numbers in introduction? */
+ showStepNumbers: false,
+
+ /* Let user use keyboard to navigate the tour? */
+ keyboardNavigation: true,
+
+ /* Show tour control buttons? */
+ showButtons: true,
+
+ /* Show tour bullets? */
+ showBullets: true,
+
+ /* Show tour progress? */
+ showProgress: false,
+
+ /* Scroll to highlighted element? */
+ scrollToElement: true,
+
+ /*
+ * Should we scroll the tooltip or target element?
+ *
+ * Options are: 'element' or 'tooltip'
+ */
+ scrollTo: "element",
+
+ /* Padding to add after scrolling when element is not in the viewport (in pixels) */
+ scrollPadding: 30,
+
+ /* Set the overlay opacity */
+ overlayOpacity: 0.5,
+
+ /* To determine the tooltip position automatically based on the window.width/height */
+ autoPosition: true,
+
+ /* Precedence of positions, when auto is enabled */
+ positionPrecedence: ["bottom", "top", "right", "left"],
+
+ /* Disable an interaction with element? */
+ disableInteraction: false,
+
+ /* Set how much padding to be used around helper element */
+ helperElementPadding: 10,
+
+ /* Default hint position */
+ hintPosition: "top-middle",
+
+ /* Hint button label */
+ hintButtonLabel: "Got it",
+
+ /* Adding animation to hints? */
+ hintAnimation: true,
+
+ /* additional classes to put on the buttons */
+ buttonClass: "introjs-button",
+
+ /* additional classes to put on progress bar */
+ progressBarAdditionalClass: false
+ };
+ }
+
+ var introJs = function introJs(targetElm) {
var instance;
- if (typeof (targetElm) === 'object') {
+ if (_typeof(targetElm) === "object") {
//Ok, create a new instance
instance = new IntroJs(targetElm);
-
- } else if (typeof (targetElm) === 'string') {
+ } else if (typeof targetElm === "string") {
//select the target element with query selector
var targetElement = document.querySelector(targetElm);
if (targetElement) {
instance = new IntroJs(targetElement);
} else {
- throw new Error('There is no element with given selector.');
+ throw new Error("There is no element with given selector.");
}
} else {
instance = new IntroJs(document.body);
- }
- // add instance to list of _instances
- // passing group to _stamp to increment
+ } // add instance to list of _instances
+ // passing group to stamp to increment
// from 0 onward somewhat reliably
- introJs.instances[ _stamp(instance, 'introjs-instance') ] = instance;
+
+ introJs.instances[stamp(instance, "introjs-instance")] = instance;
return instance;
};
-
/**
* Current IntroJs version
*
* @property version
* @type String
*/
- introJs.version = VERSION;
+
+ introJs.version = version;
/**
- * key-val object helper for introJs instances
- *
- * @property instances
- * @type Object
- */
- introJs.instances = {};
+ * key-val object helper for introJs instances
+ *
+ * @property instances
+ * @type Object
+ */
- //Prototype
+ introJs.instances = {}; //Prototype
+
introJs.fn = IntroJs.prototype = {
- clone: function () {
+ clone: function clone() {
return new IntroJs(this);
},
- setOption: function(option, value) {
+ setOption: function setOption(option, value) {
this._options[option] = value;
return this;
},
- setOptions: function(options) {
- this._options = _mergeOptions(this._options, options);
+ setOptions: function setOptions(options) {
+ this._options = mergeOptions(this._options, options);
return this;
},
- start: function (group) {
- _introForElement.call(this, this._targetElement, group);
+ start: function start() {
+ introForElement.call(this, this._targetElement);
return this;
},
- goToStep: function(step) {
- _goToStep.call(this, step);
+ goToStep: function goToStep$1(step) {
+ goToStep.call(this, step);
+
return this;
},
- addStep: function(options) {
+ addStep: function addStep(options) {
if (!this._options.steps) {
this._options.steps = [];
}
@@ -2383,149 +4590,173 @@
return this;
},
- addSteps: function(steps) {
+ addSteps: function addSteps(steps) {
if (!steps.length) return;
- for(var index = 0; index < steps.length; index++) {
+ for (var index = 0; index < steps.length; index++) {
this.addStep(steps[index]);
}
return this;
},
- goToStepNumber: function(step) {
- _goToStepNumber.call(this, step);
+ goToStepNumber: function goToStepNumber$1(step) {
+ goToStepNumber.call(this, step);
return this;
},
- nextStep: function() {
- _nextStep.call(this);
+ nextStep: function nextStep$1() {
+ nextStep.call(this);
+
return this;
},
- previousStep: function() {
- _previousStep.call(this);
+ previousStep: function previousStep$1() {
+ previousStep.call(this);
+
return this;
},
- exit: function(force) {
- _exitIntro.call(this, this._targetElement, force);
+ currentStep: function currentStep$1() {
+ return currentStep.call(this);
+ },
+ exit: function exit(force) {
+ exitIntro.call(this, this._targetElement, force);
return this;
},
- refresh: function() {
- _refresh.call(this);
+ refresh: function refresh$1(refreshSteps) {
+ refresh.call(this, refreshSteps);
+
return this;
},
- onbeforechange: function(providedCallback) {
- if (typeof (providedCallback) === 'function') {
+ onbeforechange: function onbeforechange(providedCallback) {
+ if (typeof providedCallback === "function") {
this._introBeforeChangeCallback = providedCallback;
} else {
- throw new Error('Provided callback for onbeforechange was not a function');
+ throw new Error("Provided callback for onbeforechange was not a function");
}
+
return this;
},
- onchange: function(providedCallback) {
- if (typeof (providedCallback) === 'function') {
+ onchange: function onchange(providedCallback) {
+ if (typeof providedCallback === "function") {
this._introChangeCallback = providedCallback;
} else {
- throw new Error('Provided callback for onchange was not a function.');
+ throw new Error("Provided callback for onchange was not a function.");
}
+
return this;
},
- onafterchange: function(providedCallback) {
- if (typeof (providedCallback) === 'function') {
+ onafterchange: function onafterchange(providedCallback) {
+ if (typeof providedCallback === "function") {
this._introAfterChangeCallback = providedCallback;
} else {
- throw new Error('Provided callback for onafterchange was not a function');
+ throw new Error("Provided callback for onafterchange was not a function");
}
+
return this;
},
- oncomplete: function(providedCallback) {
- if (typeof (providedCallback) === 'function') {
+ oncomplete: function oncomplete(providedCallback) {
+ if (typeof providedCallback === "function") {
this._introCompleteCallback = providedCallback;
} else {
- throw new Error('Provided callback for oncomplete was not a function.');
+ throw new Error("Provided callback for oncomplete was not a function.");
}
+
return this;
},
- onhintsadded: function(providedCallback) {
- if (typeof (providedCallback) === 'function') {
+ onhintsadded: function onhintsadded(providedCallback) {
+ if (typeof providedCallback === "function") {
this._hintsAddedCallback = providedCallback;
} else {
- throw new Error('Provided callback for onhintsadded was not a function.');
+ throw new Error("Provided callback for onhintsadded was not a function.");
}
+
return this;
},
- onhintclick: function(providedCallback) {
- if (typeof (providedCallback) === 'function') {
+ onhintclick: function onhintclick(providedCallback) {
+ if (typeof providedCallback === "function") {
this._hintClickCallback = providedCallback;
} else {
- throw new Error('Provided callback for onhintclick was not a function.');
+ throw new Error("Provided callback for onhintclick was not a function.");
}
+
return this;
},
- onhintclose: function(providedCallback) {
- if (typeof (providedCallback) === 'function') {
+ onhintclose: function onhintclose(providedCallback) {
+ if (typeof providedCallback === "function") {
this._hintCloseCallback = providedCallback;
} else {
- throw new Error('Provided callback for onhintclose was not a function.');
+ throw new Error("Provided callback for onhintclose was not a function.");
}
+
return this;
},
- onexit: function(providedCallback) {
- if (typeof (providedCallback) === 'function') {
+ onexit: function onexit(providedCallback) {
+ if (typeof providedCallback === "function") {
this._introExitCallback = providedCallback;
} else {
- throw new Error('Provided callback for onexit was not a function.');
+ throw new Error("Provided callback for onexit was not a function.");
}
+
return this;
},
- onskip: function(providedCallback) {
- if (typeof (providedCallback) === 'function') {
+ onskip: function onskip(providedCallback) {
+ if (typeof providedCallback === "function") {
this._introSkipCallback = providedCallback;
} else {
- throw new Error('Provided callback for onskip was not a function.');
+ throw new Error("Provided callback for onskip was not a function.");
}
+
return this;
},
- onbeforeexit: function(providedCallback) {
- if (typeof (providedCallback) === 'function') {
+ onbeforeexit: function onbeforeexit(providedCallback) {
+ if (typeof providedCallback === "function") {
this._introBeforeExitCallback = providedCallback;
} else {
- throw new Error('Provided callback for onbeforeexit was not a function.');
+ throw new Error("Provided callback for onbeforeexit was not a function.");
}
+
return this;
},
- addHints: function() {
- _populateHints.call(this, this._targetElement);
+ addHints: function addHints() {
+ populateHints.call(this, this._targetElement);
return this;
},
- hideHint: function (stepId) {
- _hideHint.call(this, stepId);
+ hideHint: function hideHint$1(stepId) {
+ hideHint.call(this, stepId);
+
return this;
},
- hideHints: function () {
- _hideHints.call(this);
+ hideHints: function hideHints$1() {
+ hideHints.call(this);
+
return this;
},
- showHint: function (stepId) {
- _showHint.call(this, stepId);
+ showHint: function showHint$1(stepId) {
+ showHint.call(this, stepId);
+
return this;
},
- showHints: function () {
- _showHints.call(this);
+ showHints: function showHints$1() {
+ showHints.call(this);
+
return this;
},
- removeHints: function () {
- _removeHints.call(this);
+ removeHints: function removeHints$1() {
+ removeHints.call(this);
+
return this;
},
- removeHint: function (stepId) {
- _removeHint.call(this, stepId);
+ removeHint: function removeHint$1(stepId) {
+ removeHint().call(this, stepId);
+
return this;
},
- showHintDialog: function (stepId) {
- _showHintDialog.call(this, stepId);
+ showHintDialog: function showHintDialog$1(stepId) {
+ showHintDialog.call(this, stepId);
+
return this;
}
};
return introJs;
-});
+
+})));
diff --git a/dev/js/spec/tourSpec.js b/dev/js/spec/tourSpec.js
index 3cd1a5b..e65d273 100644
--- a/dev/js/spec/tourSpec.js
+++ b/dev/js/spec/tourSpec.js
@@ -459,9 +459,9 @@
let welc = document.createElement("DIV");
welc.innerHTML = loc.TOUR_welc;
expect(document.querySelector(".introjs-tooltiptext").textContent).toEqual(welc.textContent);
- expect(document.querySelector(".introjs-skipbutton").textContent).toEqual(loc.TOUR_lskip);
expect(document.querySelector(".introjs-prevbutton").textContent).toEqual(loc.TOUR_lprev);
expect(document.querySelector(".introjs-nextbutton").textContent).toEqual(loc.TOUR_lnext);
+ expect(document.querySelector(".introjs-skipbutton")).toBeDefined();
searchTour.exit();
for(let i = 2; i <= totalSteps; i++){
@@ -483,6 +483,7 @@
case totalSteps:
expect(document.querySelector(".introjs-donebutton").textContent).toEqual(loc.TOUR_ldoneSearch);
expect(document.querySelector(".introjs-prevbutton").textContent).toEqual(loc.TOUR_lprev);
+ expect(document.querySelector(".introjs-skipbutton")).toBeDefined();
break;
}
searchTour.exit();
@@ -494,9 +495,9 @@
resultTour.start(resultkor);
let totalStepsR = resultTour.stepCount;
expect(document.querySelector(".introjs-tooltiptext").textContent).toEqual(loc.TOUR_kwic);
- expect(document.querySelector(".introjs-skipbutton").textContent).toEqual(loc.TOUR_lskip);
expect(document.querySelector(".introjs-prevbutton").textContent).toEqual(loc.TOUR_lprev);
expect(document.querySelector(".introjs-nextbutton").textContent).toEqual(loc.TOUR_lnext);
+ expect(document.querySelector(".introjs-skipbutton")).toBeDefined();
resultTour.exit();
for(let i = 2; i <= totalStepsR; i++){
resultTour.goToStepNumber(i);
diff --git a/dev/js/src/loc/de.js b/dev/js/src/loc/de.js
index 6daed13..a7c0080 100644
--- a/dev/js/src/loc/de.js
+++ b/dev/js/src/loc/de.js
@@ -37,22 +37,19 @@
//Corpus statistic
loc.SHOW_STAT = 'Korpusstatistik';
loc.REFRESH = 'Neu laden';
- //verbose description, for title attributes for example
- //loc.VERB_SHOWSTAT = 'Korpusstatistik';
-
+
loc.NEW_CONSTRAINT = 'Neue Bedingung';
//Guided Tour:Buttonlabels
- loc.TOUR_lskip = "Abbrechen";
loc.TOUR_lprev = "Zurück";
loc.TOUR_lnext = "Weiter";
loc.TOUR_ldone = "Beenden";
loc.TOUR_ldoneSearch = "Suchen";
//Guided Tour: Steps
- loc.TOUR_welc = "<span class = 'tgreeting'>Willkommen zur KorAP Tour! </span> " +
- "<p class='pfirstStep'> Hier zeigen wir Ihnen einige wichtige Funktionalitäten von KorAP. " +
- "Wir führen Sie Schritt bei Schritt anhand eines Beispiels durch die Anwendung. </p>";
+ loc.TOUR_welcti = " <span class='tgreeting'> Willkommen zur KorAP Tour! </span>";
+ loc.TOUR_welc = "Hier zeigen wir Ihnen einige wichtige Funktionalitäten von KorAP. " +
+ "Wir führen Sie Schritt bei Schritt anhand eines Beispiels durch die Anwendung.";
loc.TOUR_sear1 = "Eingabe der Suchanfrage, zum Beispiel die Suche nach '" + loc.TOUR_Qexample + "'." ;
loc.TOUR_searAnnot ="Für die Suche nach Annotationen steht der Annotationsassistent zur Verfügung.";
loc.TOUR_annotAss = "Der Annotationsassistent erleichert die Formulierung von Suchanfragen mit Annotationen.";
diff --git a/dev/js/src/tour/tours.js b/dev/js/src/tour/tours.js
index d67b518..8f6f042 100644
--- a/dev/js/src/tour/tours.js
+++ b/dev/js/src/tour/tours.js
@@ -11,17 +11,16 @@
//needed for localization of labels and contents of the tour
const loc = KorAP.Locale;
- //labels for nextStep, previousStep, done and abort
- loc.TOUR_lskip = loc.TOUR_lskip || "Abort";
+ //labels for nextStep, previousStep and done
loc.TOUR_lprev = loc.TOUR_lprev || "Back";
loc.TOUR_lnext = loc.TOUR_lnext || "Next";
loc.TOUR_ldone = loc.TOUR_ldone || "Done";
loc.TOUR_ldoneSearch = loc.TOUR_ldoneSearch || "Search";
//localization guided tour gTstartSearch
- loc.TOUR_welc = loc.TOUR_welc || "<span class='tgreeting'> Welcome to our guided tour!</span>" +
- "<p class='pfirstStep'> This tour should give you a quick introduction to KorAP. " +
- "We lead you step by step through an example. </p>";
+ loc.TOUR_welcti = loc.TOUR_welcti || "<span class='tgreeting'> Welcome to our guided tour! </span>";
+ loc.TOUR_welc = loc.TOUR_welc || "This tour should give you a quick introduction to KorAP. " +
+ "We lead you step by step through an example.";
loc.TOUR_sear1 = loc.TOUR_sear1 || "Input field for the query, for example the search for '" + loc.TOUR_Qexample + "'.";
loc.TOUR_searAnnot = loc.TOUR_searAnnot || "Annotation helper";
loc.TOUR_annotAss = loc.TOUR_annotAss || "The assistant displays the annotations of the different layers and helps to formulate queries.";
@@ -48,7 +47,6 @@
//localization of button labels
let labelOpts= {
- 'skipLabel': loc.TOUR_lskip,
'prevLabel': loc.TOUR_lprev,
'nextLabel': loc.TOUR_lnext,
'doneLabel': loc.TOUR_ldone,
@@ -58,10 +56,10 @@
//usability options of tours
let usabilityOpts ={
'showBullets': false,
- 'overlayOpacity': 0.7,
+ 'overlayOpacity': 0.5,
'exitOnOverlayClick': false,
- 'disableInteraction': true,
- 'hideNext': true,
+ 'disableInteraction': true,
+ 'tooltipClass': 'customTooltip',
'hidePrev': true
};
@@ -75,7 +73,6 @@
gTstartSearch:function(elparam){
let intro = introClass();
intro.setOptions(labelOpts);
- intro.setOption('tooltipClass', 'gTstartSearch');
/*
* Sets button labels for the last step of the tour
* Because Kalamar is a multipage webapplication, this tours starts by
@@ -96,6 +93,7 @@
//steps of the example tour
let Steps =[
{
+ title: loc.TOUR_welcti,
intro: loc.TOUR_welc,
},
{
@@ -139,7 +137,7 @@
position: "bottom",
},
{
- element:'#glimpse',
+ element: '#glimpse',
intro: loc.TOUR_glimpse,
position: "bottom",
},