-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
index.js
359 lines (343 loc) · 9.63 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
import mergeOptions from "./util/mergeOptions";
import stamp from "./util/stamp";
import exitIntro from "./core/exitIntro";
import refresh from "./core/refresh";
import introForElement from "./core/introForElement";
import { getDontShowAgain, setDontShowAgain } from "./core/dontShowAgain";
import { version } from "../package.json";
import {
populateHints,
hideHint,
hideHints,
showHint,
showHints,
removeHint,
removeHints,
showHintDialog,
} from "./core/hint";
import {
currentStep,
goToStep,
goToStepNumber,
nextStep,
previousStep,
} from "./core/steps";
/**
* IntroJs main class
*
* @class IntroJs
*/
function IntroJs(obj) {
this._targetElement = obj;
this._introItems = [];
this._options = {
/* Is this tour instance active? Don't show the tour again if this flag is set to false */
isActive: true,
/* 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,
/* Display the pagination detail */
showStepNumbers: false,
/* Pagination "of" label */
stepNumbersOfLabel: "of",
/* 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,
/* To display the "Don't show again" checkbox in the tour */
dontShowAgain: false,
dontShowAgainLabel: "Don't show this again",
/* "Don't show again" cookie name and expiry (in days) */
dontShowAgainCookie: "introjs-dontShowAgain",
dontShowAgainCookieDays: 365,
/* Set how much padding to be used around helper element */
helperElementPadding: 10,
/* Default hint position */
hintPosition: "top-middle",
/* Hint button label */
hintButtonLabel: "Got it",
/* Display the "Got it" button? */
hintShowButton: true,
/* Hints auto-refresh interval in ms (set to -1 to disable) */
hintAutoRefreshInterval: 10,
/* 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,
};
}
const introJs = (targetElm) => {
let instance;
if (typeof targetElm === "object") {
//Ok, create a new instance
instance = new IntroJs(targetElm);
} else if (typeof targetElm === "string") {
//select the target element with query selector
const targetElement = document.querySelector(targetElm);
if (targetElement) {
instance = new IntroJs(targetElement);
} else {
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
// from 0 onward somewhat reliably
introJs.instances[stamp(instance, "introjs-instance")] = instance;
return instance;
};
/**
* Current IntroJs version
*
* @property version
* @type String
*/
introJs.version = version;
/**
* key-val object helper for introJs instances
*
* @property instances
* @type Object
*/
introJs.instances = {};
//Prototype
introJs.fn = IntroJs.prototype = {
isActive() {
if (this._options.dontShowAgain && getDontShowAgain.call(this)) {
return false;
}
return this._options.isActive;
},
clone() {
return new IntroJs(this);
},
setOption(option, value) {
this._options[option] = value;
return this;
},
setOptions(options) {
this._options = mergeOptions(this._options, options);
return this;
},
start() {
introForElement.call(this, this._targetElement);
return this;
},
goToStep(step) {
goToStep.call(this, step);
return this;
},
addStep(options) {
if (!this._options.steps) {
this._options.steps = [];
}
this._options.steps.push(options);
return this;
},
addSteps(steps) {
if (!steps.length) return;
for (let index = 0; index < steps.length; index++) {
this.addStep(steps[index]);
}
return this;
},
goToStepNumber(step) {
goToStepNumber.call(this, step);
return this;
},
nextStep() {
nextStep.call(this);
return this;
},
previousStep() {
previousStep.call(this);
return this;
},
currentStep() {
return currentStep.call(this);
},
exit(force) {
exitIntro.call(this, this._targetElement, force);
return this;
},
refresh(refreshSteps) {
refresh.call(this, refreshSteps);
return this;
},
setDontShowAgain(dontShowAgain) {
setDontShowAgain.call(this, dontShowAgain);
return this;
},
onbeforechange(providedCallback) {
if (typeof providedCallback === "function") {
this._introBeforeChangeCallback = providedCallback;
} else {
throw new Error(
"Provided callback for onbeforechange was not a function"
);
}
return this;
},
onchange(providedCallback) {
if (typeof providedCallback === "function") {
this._introChangeCallback = providedCallback;
} else {
throw new Error("Provided callback for onchange was not a function.");
}
return this;
},
onafterchange(providedCallback) {
if (typeof providedCallback === "function") {
this._introAfterChangeCallback = providedCallback;
} else {
throw new Error("Provided callback for onafterchange was not a function");
}
return this;
},
oncomplete(providedCallback) {
if (typeof providedCallback === "function") {
this._introCompleteCallback = providedCallback;
} else {
throw new Error("Provided callback for oncomplete was not a function.");
}
return this;
},
onhintsadded(providedCallback) {
if (typeof providedCallback === "function") {
this._hintsAddedCallback = providedCallback;
} else {
throw new Error("Provided callback for onhintsadded was not a function.");
}
return this;
},
onhintclick(providedCallback) {
if (typeof providedCallback === "function") {
this._hintClickCallback = providedCallback;
} else {
throw new Error("Provided callback for onhintclick was not a function.");
}
return this;
},
onhintclose(providedCallback) {
if (typeof providedCallback === "function") {
this._hintCloseCallback = providedCallback;
} else {
throw new Error("Provided callback for onhintclose was not a function.");
}
return this;
},
onstart(providedCallback) {
if (typeof providedCallback === "function") {
this._introStartCallback = providedCallback;
} else {
throw new Error("Provided callback for onstart was not a function.");
}
return this;
},
onexit(providedCallback) {
if (typeof providedCallback === "function") {
this._introExitCallback = providedCallback;
} else {
throw new Error("Provided callback for onexit was not a function.");
}
return this;
},
onskip(providedCallback) {
if (typeof providedCallback === "function") {
this._introSkipCallback = providedCallback;
} else {
throw new Error("Provided callback for onskip was not a function.");
}
return this;
},
onbeforeexit(providedCallback) {
if (typeof providedCallback === "function") {
this._introBeforeExitCallback = providedCallback;
} else {
throw new Error("Provided callback for onbeforeexit was not a function.");
}
return this;
},
addHints() {
populateHints.call(this, this._targetElement);
return this;
},
hideHint(stepId) {
hideHint.call(this, stepId);
return this;
},
hideHints() {
hideHints.call(this);
return this;
},
showHint(stepId) {
showHint.call(this, stepId);
return this;
},
showHints() {
showHints.call(this);
return this;
},
removeHints() {
removeHints.call(this);
return this;
},
removeHint(stepId) {
removeHint().call(this, stepId);
return this;
},
showHintDialog(stepId) {
showHintDialog.call(this, stepId);
return this;
},
};
export default introJs;