camaleon_cms 2.8.2 → 2.8.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of camaleon_cms might be problematic. Click here for more details.

Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/camaleon_cms/admin/_actions.js +3 -2
  3. data/app/assets/javascripts/camaleon_cms/admin/_libraries.js +0 -1
  4. data/app/assets/javascripts/camaleon_cms/admin/admin-manifest.js +1 -2
  5. data/app/assets/javascripts/camaleon_cms/admin/introjs/intro.min.js +11 -0
  6. data/app/assets/javascripts/camaleon_cms/admin/introjs/intro.min.js.map +1 -0
  7. data/app/assets/javascripts/camaleon_cms/admin/jquery.validate.js +5 -5
  8. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/messages_ar.js +52 -0
  9. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/messages_de.js +70 -0
  10. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/{es.js → messages_es.js} +9 -10
  11. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/{fr.js → messages_fr.js} +7 -3
  12. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/messages_it.js +27 -0
  13. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/{nl.js → messages_nl.js} +1 -0
  14. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/{pt-BR.js → messages_pt-BR.js} +24 -19
  15. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/{ru.js → messages_ru.js} +6 -2
  16. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/{zh-CN.js → messages_zh-CN.js} +9 -8
  17. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/methods_de.js +12 -0
  18. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/methods_nl.js +12 -0
  19. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/methods_pt.js +9 -0
  20. data/app/assets/stylesheets/camaleon_cms/admin/_custom_admin.css.scss +19 -7
  21. data/app/assets/stylesheets/camaleon_cms/admin/admin-manifest.css +1 -1
  22. data/app/assets/stylesheets/camaleon_cms/admin/introjs/introjs.min.css +2 -0
  23. data/app/assets/stylesheets/camaleon_cms/admin/introjs/introjs.min.css.map +1 -0
  24. data/app/controllers/camaleon_cms/admin/media_controller.rb +2 -1
  25. data/app/helpers/camaleon_cms/uploader_helper.rb +1 -1
  26. data/app/uploaders/camaleon_cms_aws_uploader.rb +2 -0
  27. data/app/uploaders/camaleon_cms_local_uploader.rb +3 -1
  28. data/app/uploaders/camaleon_cms_uploader.rb +2 -4
  29. data/app/views/layouts/camaleon_cms/admin.html.erb +7 -1
  30. data/lib/camaleon_cms/version.rb +1 -1
  31. metadata +20 -15
  32. data/app/assets/javascripts/camaleon_cms/admin/_underscore.js +0 -1536
  33. data/app/assets/javascripts/camaleon_cms/admin/introjs/_intro.min.js +0 -1317
  34. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/de.js +0 -20
  35. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/it.js +0 -23
  36. data/app/assets/stylesheets/camaleon_cms/admin/introjs/_introjs.min.css +0 -1
  37. /data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/{uk.js → messages_uk.js} +0 -0
@@ -1,1317 +0,0 @@
1
- /**
2
- * Intro.js v1.1.1
3
- * https://github.com/usablica/intro.js
4
- * MIT licensed
5
- *
6
- * Copyright (C) 2013 usabli.ca - A weekend project by Afshin Mehrabani (@afshinmeh)
7
- */
8
-
9
- (function (root, factory) {
10
- if (typeof exports === 'object') {
11
- // CommonJS
12
- factory(exports);
13
- } else if (typeof define === 'function' && define.amd) {
14
- // AMD. Register as an anonymous module.
15
- define(['exports'], factory);
16
- } else {
17
- // Browser globals
18
- factory(root);
19
- }
20
- } (this, function (exports) {
21
- //Default config/variables
22
- var VERSION = '1.1.1';
23
-
24
- /**
25
- * IntroJs main class
26
- *
27
- * @class IntroJs
28
- */
29
- function IntroJs(obj) {
30
- this._targetElement = obj;
31
-
32
- this._options = {
33
- /* Next button label in tooltip box */
34
- nextLabel: 'Next →',
35
- /* Previous button label in tooltip box */
36
- prevLabel: '← Back',
37
- /* Skip button label in tooltip box */
38
- skipLabel: 'Skip',
39
- /* Done button label in tooltip box */
40
- doneLabel: 'Done',
41
- /* Default tooltip box position */
42
- tooltipPosition: 'bottom',
43
- /* Next CSS class for tooltip boxes */
44
- tooltipClass: '',
45
- /* CSS class that is added to the helperLayer */
46
- highlightClass: '',
47
- /* Close introduction when pressing Escape button? */
48
- exitOnEsc: true,
49
- /* Close introduction when clicking on overlay layer? */
50
- exitOnOverlayClick: true,
51
- /* Show step numbers in introduction? */
52
- showStepNumbers: true,
53
- /* Let user use keyboard to navigate the tour? */
54
- keyboardNavigation: true,
55
- /* Show tour control buttons? */
56
- showButtons: true,
57
- /* Show tour bullets? */
58
- showBullets: true,
59
- /* Show tour progress? */
60
- showProgress: false,
61
- /* Scroll to highlighted element? */
62
- scrollToElement: true,
63
- /* Set the overlay opacity */
64
- overlayOpacity: 0.8,
65
- /* Precedence of positions, when auto is enabled */
66
- positionPrecedence: ["bottom", "top", "right", "left"],
67
- /* Disable an interaction with element? */
68
- disableInteraction: false
69
- };
70
- }
71
-
72
- /**
73
- * Initiate a new introduction/guide from an element in the page
74
- *
75
- * @api private
76
- * @method _introForElement
77
- * @param {Object} targetElm
78
- * @returns {Boolean} Success or not?
79
- */
80
- function _introForElement(targetElm) {
81
- var introItems = [],
82
- self = this;
83
-
84
- if (this._options.steps) {
85
- //use steps passed programmatically
86
- for (var i = 0, stepsLength = this._options.steps.length; i < stepsLength; i++) {
87
- var currentItem = _cloneObject(this._options.steps[i]);
88
- //set the step
89
- currentItem.step = introItems.length + 1;
90
- //use querySelector function only when developer used CSS selector
91
- if (typeof(currentItem.element) === 'string') {
92
- //grab the element with given selector from the page
93
- currentItem.element = document.querySelector(currentItem.element);
94
- }
95
-
96
- //intro without element
97
- if (typeof(currentItem.element) === 'undefined' || currentItem.element == null) {
98
- var floatingElementQuery = document.querySelector(".introjsFloatingElement");
99
-
100
- if (floatingElementQuery == null) {
101
- floatingElementQuery = document.createElement('div');
102
- floatingElementQuery.className = 'introjsFloatingElement';
103
-
104
- document.body.appendChild(floatingElementQuery);
105
- }
106
-
107
- currentItem.element = floatingElementQuery;
108
- currentItem.position = 'floating';
109
- }
110
-
111
- if (currentItem.element != null) {
112
- introItems.push(currentItem);
113
- }
114
- }
115
-
116
- } else {
117
- //use steps from data-* annotations
118
- var allIntroSteps = targetElm.querySelectorAll('*[data-intro]');
119
- //if there's no element to intro
120
- if (allIntroSteps.length < 1) {
121
- return false;
122
- }
123
-
124
- //first add intro items with data-step
125
- for (var i = 0, elmsLength = allIntroSteps.length; i < elmsLength; i++) {
126
- var currentElement = allIntroSteps[i];
127
- var step = parseInt(currentElement.getAttribute('data-step'), 10);
128
-
129
- if (step > 0) {
130
- introItems[step - 1] = {
131
- element: currentElement,
132
- intro: currentElement.getAttribute('data-intro'),
133
- step: parseInt(currentElement.getAttribute('data-step'), 10),
134
- tooltipClass: currentElement.getAttribute('data-tooltipClass'),
135
- highlightClass: currentElement.getAttribute('data-highlightClass'),
136
- position: currentElement.getAttribute('data-position') || this._options.tooltipPosition
137
- };
138
- }
139
- }
140
-
141
- //next add intro items without data-step
142
- //todo: we need a cleanup here, two loops are redundant
143
- var nextStep = 0;
144
- for (var i = 0, elmsLength = allIntroSteps.length; i < elmsLength; i++) {
145
- var currentElement = allIntroSteps[i];
146
-
147
- if (currentElement.getAttribute('data-step') == null) {
148
-
149
- while (true) {
150
- if (typeof introItems[nextStep] == 'undefined') {
151
- break;
152
- } else {
153
- nextStep++;
154
- }
155
- }
156
-
157
- introItems[nextStep] = {
158
- element: currentElement,
159
- intro: currentElement.getAttribute('data-intro'),
160
- step: nextStep + 1,
161
- tooltipClass: currentElement.getAttribute('data-tooltipClass'),
162
- highlightClass: currentElement.getAttribute('data-highlightClass'),
163
- position: currentElement.getAttribute('data-position') || this._options.tooltipPosition
164
- };
165
- }
166
- }
167
- }
168
-
169
- //removing undefined/null elements
170
- var tempIntroItems = [];
171
- for (var z = 0; z < introItems.length; z++) {
172
- introItems[z] && tempIntroItems.push(introItems[z]); // copy non-empty values to the end of the array
173
- }
174
-
175
- introItems = tempIntroItems;
176
-
177
- //Ok, sort all items with given steps
178
- introItems.sort(function (a, b) {
179
- return a.step - b.step;
180
- });
181
-
182
- //set it to the introJs object
183
- self._introItems = introItems;
184
-
185
- //add overlay layer to the page
186
- if(_addOverlayLayer.call(self, targetElm)) {
187
- //then, start the show
188
- _nextStep.call(self);
189
-
190
- var skipButton = targetElm.querySelector('.introjs-skipbutton'),
191
- nextStepButton = targetElm.querySelector('.introjs-nextbutton');
192
-
193
- self._onKeyDown = function(e) {
194
- if (e.keyCode === 27 && self._options.exitOnEsc == true) {
195
- //escape key pressed, exit the intro
196
- //check if exit callback is defined
197
- if (self._introExitCallback != undefined) {
198
- self._introExitCallback.call(self);
199
- }
200
- _exitIntro.call(self, targetElm);
201
- } else if(e.keyCode === 37) {
202
- //left arrow
203
- _previousStep.call(self);
204
- } else if (e.keyCode === 39) {
205
- //right arrow
206
- _nextStep.call(self);
207
- } else if (e.keyCode === 13) {
208
- //srcElement === ie
209
- var target = e.target || e.srcElement;
210
- if (target && target.className.indexOf('introjs-prevbutton') > 0) {
211
- //user hit enter while focusing on previous button
212
- _previousStep.call(self);
213
- } else if (target && target.className.indexOf('introjs-skipbutton') > 0) {
214
- //user hit enter while focusing on skip button
215
- if (self._introItems.length - 1 == self._currentStep && typeof (self._introCompleteCallback) === 'function') {
216
- self._introCompleteCallback.call(self);
217
- }
218
- //check if any callback is defined
219
- if (self._introExitCallback != undefined) {
220
- self._introExitCallback.call(self);
221
- }
222
- _exitIntro.call(self, targetElm);
223
- } else {
224
- //default behavior for responding to enter
225
- _nextStep.call(self);
226
- }
227
-
228
- //prevent default behaviour on hitting Enter, to prevent steps being skipped in some browsers
229
- if(e.preventDefault) {
230
- e.preventDefault();
231
- } else {
232
- e.returnValue = false;
233
- }
234
- }
235
- };
236
-
237
- self._onResize = function(e) {
238
- _setHelperLayerPosition.call(self, document.querySelector('.introjs-helperLayer'));
239
- _setHelperLayerPosition.call(self, document.querySelector('.introjs-tooltipReferenceLayer'));
240
- };
241
-
242
- if (window.addEventListener) {
243
- if (this._options.keyboardNavigation) {
244
- window.addEventListener('keydown', self._onKeyDown, true);
245
- }
246
- //for window resize
247
- window.addEventListener('resize', self._onResize, true);
248
- } else if (document.attachEvent) { //IE
249
- if (this._options.keyboardNavigation) {
250
- document.attachEvent('onkeydown', self._onKeyDown);
251
- }
252
- //for window resize
253
- document.attachEvent('onresize', self._onResize);
254
- }
255
- }
256
- return false;
257
- }
258
-
259
- /*
260
- * makes a copy of the object
261
- * @api private
262
- * @method _cloneObject
263
- */
264
- function _cloneObject(object) {
265
- if (object == null || typeof (object) != 'object' || typeof (object.nodeType) != 'undefined') {
266
- return object;
267
- }
268
- var temp = {};
269
- for (var key in object) {
270
- if (typeof (jQuery) != 'undefined' && object[key] instanceof jQuery) {
271
- temp[key] = object[key];
272
- } else {
273
- temp[key] = _cloneObject(object[key]);
274
- }
275
- }
276
- return temp;
277
- }
278
- /**
279
- * Go to specific step of introduction
280
- *
281
- * @api private
282
- * @method _goToStep
283
- */
284
- function _goToStep(step) {
285
- //because steps starts with zero
286
- this._currentStep = step - 2;
287
- if (typeof (this._introItems) !== 'undefined') {
288
- _nextStep.call(this);
289
- }
290
- }
291
-
292
- /**
293
- * Go to next step on intro
294
- *
295
- * @api private
296
- * @method _nextStep
297
- */
298
- function _nextStep() {
299
- this._direction = 'forward';
300
-
301
- if (typeof (this._currentStep) === 'undefined') {
302
- this._currentStep = 0;
303
- } else {
304
- ++this._currentStep;
305
- }
306
-
307
- if ((this._introItems.length) <= this._currentStep) {
308
- //end of the intro
309
- //check if any callback is defined
310
- if (typeof (this._introCompleteCallback) === 'function') {
311
- this._introCompleteCallback.call(this);
312
- }
313
- _exitIntro.call(this, this._targetElement);
314
- return;
315
- }
316
-
317
- var nextStep = this._introItems[this._currentStep];
318
- if (typeof (this._introBeforeChangeCallback) !== 'undefined') {
319
- this._introBeforeChangeCallback.call(this, nextStep.element);
320
- }
321
-
322
- //_showElement.call(this, nextStep);
323
- var w = $(nextStep.element).attr("data-wait");
324
- var thiss = this;
325
- var _f = function(){ _showElement.call(thiss, nextStep); };
326
- if(w) setTimeout(_f, w); else _f();
327
- }
328
-
329
- /**
330
- * Go to previous step on intro
331
- *
332
- * @api private
333
- * @method _nextStep
334
- */
335
- function _previousStep() {
336
- this._direction = 'backward';
337
-
338
- if (this._currentStep === 0) {
339
- return false;
340
- }
341
-
342
- var nextStep = this._introItems[--this._currentStep];
343
- if (typeof (this._introBeforeChangeCallback) !== 'undefined') {
344
- this._introBeforeChangeCallback.call(this, nextStep.element);
345
- }
346
-
347
- //_showElement.call(this, nextStep);
348
- var w = $(nextStep.element).attr("data-wait");
349
- var thiss = this;
350
- var _f = function(){ _showElement.call(thiss, nextStep); };
351
- if(w) setTimeout(_f, w); else _f();
352
- }
353
-
354
- /**
355
- * Exit from intro
356
- *
357
- * @api private
358
- * @method _exitIntro
359
- * @param {Object} targetElement
360
- */
361
- function _exitIntro(targetElement) {
362
- //remove overlay layer from the page
363
- var overlayLayer = targetElement.querySelector('.introjs-overlay');
364
-
365
- //return if intro already completed or skipped
366
- if (overlayLayer == null) {
367
- return;
368
- }
369
-
370
- //for fade-out animation
371
- overlayLayer.style.opacity = 0;
372
- setTimeout(function () {
373
- if (overlayLayer.parentNode) {
374
- overlayLayer.parentNode.removeChild(overlayLayer);
375
- }
376
- }, 500);
377
-
378
- //remove all helper layers
379
- var helperLayer = targetElement.querySelector('.introjs-helperLayer');
380
- if (helperLayer) {
381
- helperLayer.parentNode.removeChild(helperLayer);
382
- }
383
-
384
- var referenceLayer = targetElement.querySelector('.introjs-tooltipReferenceLayer');
385
- if (referenceLayer) {
386
- referenceLayer.parentNode.removeChild(referenceLayer);
387
- }
388
- //remove disableInteractionLayer
389
- var disableInteractionLayer = targetElement.querySelector('.introjs-disableInteraction');
390
- if (disableInteractionLayer) {
391
- disableInteractionLayer.parentNode.removeChild(disableInteractionLayer);
392
- }
393
-
394
- //remove intro floating element
395
- var floatingElement = document.querySelector('.introjsFloatingElement');
396
- if (floatingElement) {
397
- floatingElement.parentNode.removeChild(floatingElement);
398
- }
399
-
400
- //remove `introjs-showElement` class from the element
401
- var showElement = document.querySelector('.introjs-showElement');
402
- if (showElement) {
403
- showElement.className = showElement.className.replace(/introjs-[a-zA-Z]+/g, '').replace(/^\s+|\s+$/g, ''); // This is a manual trim.
404
- }
405
-
406
- //remove `introjs-fixParent` class from the elements
407
- var fixParents = document.querySelectorAll('.introjs-fixParent');
408
- if (fixParents && fixParents.length > 0) {
409
- for (var i = fixParents.length - 1; i >= 0; i--) {
410
- fixParents[i].className = fixParents[i].className.replace(/introjs-fixParent/g, '').replace(/^\s+|\s+$/g, '');
411
- }
412
- }
413
-
414
- //clean listeners
415
- if (window.removeEventListener) {
416
- window.removeEventListener('keydown', this._onKeyDown, true);
417
- } else if (document.detachEvent) { //IE
418
- document.detachEvent('onkeydown', this._onKeyDown);
419
- }
420
-
421
- //set the step to zero
422
- this._currentStep = undefined;
423
- }
424
-
425
- /**
426
- * Render tooltip box in the page
427
- *
428
- * @api private
429
- * @method _placeTooltip
430
- * @param {HTMLElement} targetElement
431
- * @param {HTMLElement} tooltipLayer
432
- * @param {HTMLElement} arrowLayer
433
- * @param {HTMLElement} helperNumberLayer
434
- */
435
- function _placeTooltip(targetElement, tooltipLayer, arrowLayer, helperNumberLayer) {
436
- var tooltipCssClass = '',
437
- currentStepObj,
438
- tooltipOffset,
439
- targetOffset,
440
- windowSize,
441
- currentTooltipPosition;
442
-
443
- //reset the old style
444
- tooltipLayer.style.top = null;
445
- tooltipLayer.style.right = null;
446
- tooltipLayer.style.bottom = null;
447
- tooltipLayer.style.left = null;
448
- tooltipLayer.style.marginLeft = null;
449
- tooltipLayer.style.marginTop = null;
450
-
451
- arrowLayer.style.display = 'inherit';
452
-
453
- if (typeof(helperNumberLayer) != 'undefined' && helperNumberLayer != null) {
454
- helperNumberLayer.style.top = null;
455
- helperNumberLayer.style.left = null;
456
- }
457
-
458
- //prevent error when `this._currentStep` is undefined
459
- if (!this._introItems[this._currentStep]) return;
460
-
461
- //if we have a custom css class for each step
462
- currentStepObj = this._introItems[this._currentStep];
463
- if (typeof (currentStepObj.tooltipClass) === 'string') {
464
- tooltipCssClass = currentStepObj.tooltipClass;
465
- } else {
466
- tooltipCssClass = this._options.tooltipClass;
467
- }
468
-
469
- tooltipLayer.className = ('introjs-tooltip ' + tooltipCssClass).replace(/^\s+|\s+$/g, '');
470
-
471
- currentTooltipPosition = this._introItems[this._currentStep].position;
472
- if ((currentTooltipPosition == "auto" || this._options.tooltipPosition == "auto")) {
473
- if (currentTooltipPosition != "floating") { // Floating is always valid, no point in calculating
474
- currentTooltipPosition = _determineAutoPosition.call(this, targetElement, tooltipLayer, currentTooltipPosition);
475
- }
476
- }
477
- targetOffset = _getOffset(targetElement);
478
- tooltipOffset = _getOffset(tooltipLayer);
479
- windowSize = _getWinSize();
480
- switch (currentTooltipPosition) {
481
- case 'top':
482
- arrowLayer.className = 'introjs-arrow bottom';
483
-
484
- var tooltipLayerStyleLeft = 15;
485
- _checkRight(targetOffset, tooltipLayerStyleLeft, tooltipOffset, windowSize, tooltipLayer);
486
- tooltipLayer.style.bottom = (targetOffset.height + 20) + 'px';
487
- break;
488
- case 'right':
489
- tooltipLayer.style.left = (targetOffset.width + 20) + 'px';
490
- if (targetOffset.top + tooltipOffset.height > windowSize.height) {
491
- // In this case, right would have fallen below the bottom of the screen.
492
- // Modify so that the bottom of the tooltip connects with the target
493
- arrowLayer.className = "introjs-arrow left-bottom";
494
- tooltipLayer.style.top = "-" + (tooltipOffset.height - targetOffset.height - 20) + "px";
495
- } else {
496
- arrowLayer.className = 'introjs-arrow left';
497
- }
498
- break;
499
- case 'left':
500
- if (this._options.showStepNumbers == true) {
501
- tooltipLayer.style.top = '15px';
502
- }
503
-
504
- if (targetOffset.top + tooltipOffset.height > windowSize.height) {
505
- // In this case, left would have fallen below the bottom of the screen.
506
- // Modify so that the bottom of the tooltip connects with the target
507
- tooltipLayer.style.top = "-" + (tooltipOffset.height - targetOffset.height - 20) + "px";
508
- arrowLayer.className = 'introjs-arrow right-bottom';
509
- } else {
510
- arrowLayer.className = 'introjs-arrow right';
511
- }
512
- tooltipLayer.style.right = (targetOffset.width + 20) + 'px';
513
-
514
- break;
515
- case 'floating':
516
- arrowLayer.style.display = 'none';
517
-
518
- //we have to adjust the top and left of layer manually for intro items without element
519
- tooltipLayer.style.left = '50%';
520
- tooltipLayer.style.top = '50%';
521
- tooltipLayer.style.marginLeft = '-' + (tooltipOffset.width / 2) + 'px';
522
- tooltipLayer.style.marginTop = '-' + (tooltipOffset.height / 2) + 'px';
523
-
524
- if (typeof(helperNumberLayer) != 'undefined' && helperNumberLayer != null) {
525
- helperNumberLayer.style.left = '-' + ((tooltipOffset.width / 2) + 18) + 'px';
526
- helperNumberLayer.style.top = '-' + ((tooltipOffset.height / 2) + 18) + 'px';
527
- }
528
-
529
- break;
530
- case 'bottom-right-aligned':
531
- arrowLayer.className = 'introjs-arrow top-right';
532
-
533
- var tooltipLayerStyleRight = 0;
534
- _checkLeft(targetOffset, tooltipLayerStyleRight, tooltipOffset, tooltipLayer);
535
- tooltipLayer.style.top = (targetOffset.height + 20) + 'px';
536
- break;
537
-
538
- case 'bottom-middle-aligned':
539
- arrowLayer.className = 'introjs-arrow top-middle';
540
-
541
- var tooltipLayerStyleLeftRight = targetOffset.width / 2 - tooltipOffset.width / 2;
542
- if (_checkLeft(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, tooltipLayer)) {
543
- tooltipLayer.style.right = null;
544
- _checkRight(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, windowSize, tooltipLayer);
545
- }
546
- tooltipLayer.style.top = (targetOffset.height + 20) + 'px';
547
- break;
548
-
549
- case 'bottom-left-aligned':
550
- // Bottom-left-aligned is the same as the default bottom
551
- case 'bottom':
552
- // Bottom going to follow the default behavior
553
- default:
554
- arrowLayer.className = 'introjs-arrow top';
555
-
556
- var tooltipLayerStyleLeft = 0;
557
- _checkRight(targetOffset, tooltipLayerStyleLeft, tooltipOffset, windowSize, tooltipLayer);
558
- tooltipLayer.style.top = (targetOffset.height + 20) + 'px';
559
- break;
560
- }
561
- }
562
-
563
- /**
564
- * Set tooltip left so it doesn't go off the right side of the window
565
- *
566
- * @return boolean true, if tooltipLayerStyleLeft is ok. false, otherwise.
567
- */
568
- function _checkRight(targetOffset, tooltipLayerStyleLeft, tooltipOffset, windowSize, tooltipLayer) {
569
- if (targetOffset.left + tooltipLayerStyleLeft + tooltipOffset.width > windowSize.width) {
570
- // off the right side of the window
571
- tooltipLayer.style.left = (windowSize.width - tooltipOffset.width - targetOffset.left) + 'px';
572
- return false;
573
- }
574
- tooltipLayer.style.left = tooltipLayerStyleLeft + 'px';
575
- return true;
576
- }
577
-
578
- /**
579
- * Set tooltip right so it doesn't go off the left side of the window
580
- *
581
- * @return boolean true, if tooltipLayerStyleRight is ok. false, otherwise.
582
- */
583
- function _checkLeft(targetOffset, tooltipLayerStyleRight, tooltipOffset, tooltipLayer) {
584
- if (targetOffset.left + targetOffset.width - tooltipLayerStyleRight - tooltipOffset.width < 0) {
585
- // off the left side of the window
586
- tooltipLayer.style.left = (-targetOffset.left) + 'px';
587
- return false;
588
- }
589
- tooltipLayer.style.right = tooltipLayerStyleRight + 'px';
590
- return true;
591
- }
592
-
593
- /**
594
- * Determines the position of the tooltip based on the position precedence and availability
595
- * of screen space.
596
- *
597
- * @param {Object} targetElement
598
- * @param {Object} tooltipLayer
599
- * @param {Object} desiredTooltipPosition
600
- *
601
- */
602
- function _determineAutoPosition(targetElement, tooltipLayer, desiredTooltipPosition) {
603
-
604
- // Take a clone of position precedence. These will be the available
605
- var possiblePositions = this._options.positionPrecedence.slice();
606
-
607
- var windowSize = _getWinSize();
608
- var tooltipHeight = _getOffset(tooltipLayer).height + 10;
609
- var tooltipWidth = _getOffset(tooltipLayer).width + 20;
610
- var targetOffset = _getOffset(targetElement);
611
-
612
- // If we check all the possible areas, and there are no valid places for the tooltip, the element
613
- // must take up most of the screen real estate. Show the tooltip floating in the middle of the screen.
614
- var calculatedPosition = "floating";
615
-
616
- // Check if the width of the tooltip + the starting point would spill off the right side of the screen
617
- // If no, neither bottom or top are valid
618
- if (targetOffset.left + tooltipWidth > windowSize.width || ((targetOffset.left + (targetOffset.width / 2)) - tooltipWidth) < 0) {
619
- _removeEntry(possiblePositions, "bottom");
620
- _removeEntry(possiblePositions, "top");
621
- } else {
622
- // Check for space below
623
- if ((targetOffset.height + targetOffset.top + tooltipHeight) > windowSize.height) {
624
- _removeEntry(possiblePositions, "bottom");
625
- }
626
-
627
- // Check for space above
628
- if (targetOffset.top - tooltipHeight < 0) {
629
- _removeEntry(possiblePositions, "top");
630
- }
631
- }
632
-
633
- // Check for space to the right
634
- if (targetOffset.width + targetOffset.left + tooltipWidth > windowSize.width) {
635
- _removeEntry(possiblePositions, "right");
636
- }
637
-
638
- // Check for space to the left
639
- if (targetOffset.left - tooltipWidth < 0) {
640
- _removeEntry(possiblePositions, "left");
641
- }
642
-
643
- // At this point, our array only has positions that are valid. Pick the first one, as it remains in order
644
- if (possiblePositions.length > 0) {
645
- calculatedPosition = possiblePositions[0];
646
- }
647
-
648
- // If the requested position is in the list, replace our calculated choice with that
649
- if (desiredTooltipPosition && desiredTooltipPosition != "auto") {
650
- if (possiblePositions.indexOf(desiredTooltipPosition) > -1) {
651
- calculatedPosition = desiredTooltipPosition;
652
- }
653
- }
654
-
655
- return calculatedPosition;
656
- }
657
-
658
- /**
659
- * Remove an entry from a string array if it's there, does nothing if it isn't there.
660
- *
661
- * @param {Array} stringArray
662
- * @param {String} stringToRemove
663
- */
664
- function _removeEntry(stringArray, stringToRemove) {
665
- if (stringArray.indexOf(stringToRemove) > -1) {
666
- stringArray.splice(stringArray.indexOf(stringToRemove), 1);
667
- }
668
- }
669
-
670
- /**
671
- * Update the position of the helper layer on the screen
672
- *
673
- * @api private
674
- * @method _setHelperLayerPosition
675
- * @param {Object} helperLayer
676
- */
677
- function _setHelperLayerPosition(helperLayer) {
678
- if (helperLayer) {
679
- //prevent error when `this._currentStep` in undefined
680
- if (!this._introItems[this._currentStep]) return;
681
-
682
- var currentElement = this._introItems[this._currentStep],
683
- elementPosition = _getOffset(currentElement.element),
684
- widthHeightPadding = 10;
685
-
686
- if (currentElement.position == 'floating') {
687
- widthHeightPadding = 0;
688
- }
689
-
690
- //set new position to helper layer
691
- helperLayer.setAttribute('style', 'width: ' + (elementPosition.width + widthHeightPadding) + 'px; ' +
692
- 'height:' + (elementPosition.height + widthHeightPadding) + 'px; ' +
693
- 'top:' + (elementPosition.top - 5) + 'px;' +
694
- 'left: ' + (elementPosition.left - 5) + 'px;');
695
-
696
- }
697
- }
698
-
699
- /**
700
- * Add disableinteraction layer and adjust the size and position of the layer
701
- *
702
- * @api private
703
- * @method _disableInteraction
704
- */
705
- function _disableInteraction () {
706
- var disableInteractionLayer = document.querySelector('.introjs-disableInteraction');
707
- if (disableInteractionLayer === null) {
708
- disableInteractionLayer = document.createElement('div');
709
- disableInteractionLayer.className = 'introjs-disableInteraction';
710
- this._targetElement.appendChild(disableInteractionLayer);
711
- }
712
-
713
- _setHelperLayerPosition.call(this, disableInteractionLayer);
714
- }
715
-
716
- /**
717
- * Show an element on the page
718
- *
719
- * @api private
720
- * @method _showElement
721
- * @param {Object} targetElement
722
- */
723
- function _showElement(targetElement) {
724
-
725
- if (typeof (this._introChangeCallback) !== 'undefined') {
726
- this._introChangeCallback.call(this, targetElement.element);
727
- }
728
-
729
- var self = this,
730
- oldHelperLayer = document.querySelector('.introjs-helperLayer'),
731
- oldReferenceLayer = document.querySelector('.introjs-tooltipReferenceLayer'),
732
- highlightClass = 'introjs-helperLayer',
733
- elementPosition = _getOffset(targetElement.element);
734
-
735
- //check for a current step highlight class
736
- if (typeof (targetElement.highlightClass) === 'string') {
737
- highlightClass += (' ' + targetElement.highlightClass);
738
- }
739
- //check for options highlight class
740
- if (typeof (this._options.highlightClass) === 'string') {
741
- highlightClass += (' ' + this._options.highlightClass);
742
- }
743
-
744
- if (oldHelperLayer != null) {
745
- var oldHelperNumberLayer = oldReferenceLayer.querySelector('.introjs-helperNumberLayer'),
746
- oldtooltipLayer = oldReferenceLayer.querySelector('.introjs-tooltiptext'),
747
- oldArrowLayer = oldReferenceLayer.querySelector('.introjs-arrow'),
748
- oldtooltipContainer = oldReferenceLayer.querySelector('.introjs-tooltip'),
749
- skipTooltipButton = oldReferenceLayer.querySelector('.introjs-skipbutton'),
750
- prevTooltipButton = oldReferenceLayer.querySelector('.introjs-prevbutton'),
751
- nextTooltipButton = oldReferenceLayer.querySelector('.introjs-nextbutton');
752
-
753
- //update or reset the helper highlight class
754
- oldHelperLayer.className = highlightClass;
755
- //hide the tooltip
756
- oldtooltipContainer.style.opacity = 0;
757
- oldtooltipContainer.style.display = "none";
758
-
759
- if (oldHelperNumberLayer != null) {
760
- var lastIntroItem = this._introItems[(targetElement.step - 2 >= 0 ? targetElement.step - 2 : 0)];
761
-
762
- if (lastIntroItem != null && (this._direction == 'forward' && lastIntroItem.position == 'floating') || (this._direction == 'backward' && targetElement.position == 'floating')) {
763
- oldHelperNumberLayer.style.opacity = 0;
764
- }
765
- }
766
-
767
- //set new position to helper layer
768
- _setHelperLayerPosition.call(self, oldHelperLayer);
769
- _setHelperLayerPosition.call(self, oldReferenceLayer);
770
-
771
- //remove `introjs-fixParent` class from the elements
772
- var fixParents = document.querySelectorAll('.introjs-fixParent');
773
- if (fixParents && fixParents.length > 0) {
774
- for (var i = fixParents.length - 1; i >= 0; i--) {
775
- fixParents[i].className = fixParents[i].className.replace(/introjs-fixParent/g, '').replace(/^\s+|\s+$/g, '');
776
- };
777
- }
778
-
779
- //remove old classes
780
- var oldShowElement = document.querySelector('.introjs-showElement');
781
- oldShowElement.className = oldShowElement.className.replace(/introjs-[a-zA-Z]+/g, '').replace(/^\s+|\s+$/g, '');
782
-
783
- //we should wait until the CSS3 transition is competed (it's 0.3 sec) to prevent incorrect `height` and `width` calculation
784
- if (self._lastShowElementTimer) {
785
- clearTimeout(self._lastShowElementTimer);
786
- }
787
- self._lastShowElementTimer = setTimeout(function() {
788
- //set current step to the label
789
- if (oldHelperNumberLayer != null) {
790
- oldHelperNumberLayer.innerHTML = targetElement.step;
791
- }
792
- //set current tooltip text
793
- oldtooltipLayer.innerHTML = targetElement.intro;
794
- //set the tooltip position
795
- oldtooltipContainer.style.display = "block";
796
- _placeTooltip.call(self, targetElement.element, oldtooltipContainer, oldArrowLayer, oldHelperNumberLayer);
797
-
798
- //change active bullet
799
- oldReferenceLayer.querySelector('.introjs-bullets li > a.active').className = '';
800
- oldReferenceLayer.querySelector('.introjs-bullets li > a[data-stepnumber="' + targetElement.step + '"]').className = 'active';
801
-
802
- oldReferenceLayer.querySelector('.introjs-progress .introjs-progressbar').setAttribute('style', 'width:' + _getProgress.call(self) + '%;');
803
-
804
- //show the tooltip
805
- oldtooltipContainer.style.opacity = 1;
806
- if (oldHelperNumberLayer) oldHelperNumberLayer.style.opacity = 1;
807
-
808
- //reset button focus
809
- if (nextTooltipButton.tabIndex === -1) {
810
- //tabindex of -1 means we are at the end of the tour - focus on skip / done
811
- skipTooltipButton.focus();
812
- } else {
813
- //still in the tour, focus on next
814
- nextTooltipButton.focus();
815
- }
816
- }, 350);
817
-
818
- } else {
819
- var helperLayer = document.createElement('div'),
820
- referenceLayer = document.createElement('div'),
821
- arrowLayer = document.createElement('div'),
822
- tooltipLayer = document.createElement('div'),
823
- tooltipTextLayer = document.createElement('div'),
824
- bulletsLayer = document.createElement('div'),
825
- progressLayer = document.createElement('div'),
826
- buttonsLayer = document.createElement('div');
827
-
828
- helperLayer.className = highlightClass;
829
- referenceLayer.className = 'introjs-tooltipReferenceLayer';
830
-
831
- //set new position to helper layer
832
- _setHelperLayerPosition.call(self, helperLayer);
833
- _setHelperLayerPosition.call(self, referenceLayer);
834
-
835
- //add helper layer to target element
836
- this._targetElement.appendChild(helperLayer);
837
- this._targetElement.appendChild(referenceLayer);
838
-
839
- arrowLayer.className = 'introjs-arrow';
840
-
841
- tooltipTextLayer.className = 'introjs-tooltiptext';
842
- tooltipTextLayer.innerHTML = targetElement.intro;
843
-
844
- bulletsLayer.className = 'introjs-bullets';
845
-
846
- if (this._options.showBullets === false) {
847
- bulletsLayer.style.display = 'none';
848
- }
849
-
850
- var ulContainer = document.createElement('ul');
851
-
852
- for (var i = 0, stepsLength = this._introItems.length; i < stepsLength; i++) {
853
- var innerLi = document.createElement('li');
854
- var anchorLink = document.createElement('a');
855
-
856
- anchorLink.onclick = function() {
857
- self.goToStep(this.getAttribute('data-stepnumber'));
858
- };
859
-
860
- if (i === (targetElement.step-1)) anchorLink.className = 'active';
861
-
862
- anchorLink.href = 'javascript:void(0);';
863
- anchorLink.innerHTML = "&nbsp;";
864
- anchorLink.setAttribute('data-stepnumber', this._introItems[i].step);
865
-
866
- innerLi.appendChild(anchorLink);
867
- ulContainer.appendChild(innerLi);
868
- }
869
-
870
- bulletsLayer.appendChild(ulContainer);
871
-
872
- progressLayer.className = 'introjs-progress';
873
-
874
- if (this._options.showProgress === false) {
875
- progressLayer.style.display = 'none';
876
- }
877
- var progressBar = document.createElement('div');
878
- progressBar.className = 'introjs-progressbar';
879
- progressBar.setAttribute('style', 'width:' + _getProgress.call(this) + '%;');
880
-
881
- progressLayer.appendChild(progressBar);
882
-
883
- buttonsLayer.className = 'introjs-tooltipbuttons';
884
- if (this._options.showButtons === false) {
885
- buttonsLayer.style.display = 'none';
886
- }
887
-
888
- tooltipLayer.className = 'introjs-tooltip';
889
- tooltipLayer.appendChild(tooltipTextLayer);
890
- tooltipLayer.appendChild(bulletsLayer);
891
- tooltipLayer.appendChild(progressLayer);
892
-
893
- //add helper layer number
894
- if (this._options.showStepNumbers == true) {
895
- var helperNumberLayer = document.createElement('span');
896
- helperNumberLayer.className = 'introjs-helperNumberLayer';
897
- helperNumberLayer.innerHTML = targetElement.step;
898
- referenceLayer.appendChild(helperNumberLayer);
899
- }
900
-
901
- tooltipLayer.appendChild(arrowLayer);
902
- referenceLayer.appendChild(tooltipLayer);
903
-
904
- //next button
905
- var nextTooltipButton = document.createElement('a');
906
-
907
- nextTooltipButton.onclick = function() {
908
- if (self._introItems.length - 1 != self._currentStep) {
909
- _nextStep.call(self);
910
- }
911
- };
912
-
913
- nextTooltipButton.href = 'javascript:void(0);';
914
- nextTooltipButton.innerHTML = this._options.nextLabel;
915
-
916
- //previous button
917
- var prevTooltipButton = document.createElement('a');
918
-
919
- prevTooltipButton.onclick = function() {
920
- if (self._currentStep != 0) {
921
- _previousStep.call(self);
922
- }
923
- };
924
-
925
- prevTooltipButton.href = 'javascript:void(0);';
926
- prevTooltipButton.innerHTML = this._options.prevLabel;
927
-
928
- //skip button
929
- var skipTooltipButton = document.createElement('a');
930
- skipTooltipButton.className = 'introjs-button introjs-skipbutton btn';
931
- skipTooltipButton.id = 'introjs_skipbutton';
932
- skipTooltipButton.href = 'javascript:void(0);';
933
- skipTooltipButton.innerHTML = this._options.skipLabel;
934
-
935
- skipTooltipButton.onclick = function() {
936
- if (self._introItems.length - 1 == self._currentStep && typeof (self._introCompleteCallback) === 'function') {
937
- self._introCompleteCallback.call(self);
938
- }
939
-
940
- if (self._introItems.length - 1 != self._currentStep && typeof (self._introExitCallback) === 'function') {
941
- self._introExitCallback.call(self);
942
- }
943
-
944
- _exitIntro.call(self, self._targetElement);
945
- };
946
-
947
- buttonsLayer.appendChild(skipTooltipButton);
948
-
949
- //in order to prevent displaying next/previous button always
950
- if (this._introItems.length > 1) {
951
- buttonsLayer.appendChild(prevTooltipButton);
952
- buttonsLayer.appendChild(nextTooltipButton);
953
- }
954
-
955
- tooltipLayer.appendChild(buttonsLayer);
956
-
957
- //set proper position
958
- _placeTooltip.call(self, targetElement.element, tooltipLayer, arrowLayer, helperNumberLayer);
959
- }
960
-
961
- //disable interaction
962
- if (this._options.disableInteraction === true) {
963
- _disableInteraction.call(self);
964
- }
965
-
966
- prevTooltipButton.removeAttribute('tabIndex');
967
- nextTooltipButton.removeAttribute('tabIndex');
968
-
969
- if (this._currentStep == 0 && this._introItems.length > 1) {
970
- prevTooltipButton.className = 'introjs-button introjs-prevbutton introjs-disabled disabled btn btn-success';
971
- prevTooltipButton.tabIndex = '-1';
972
- nextTooltipButton.className = 'introjs-button introjs-nextbutton btn btn-primary';
973
- skipTooltipButton.innerHTML = this._options.skipLabel;
974
- } else if (this._introItems.length - 1 == this._currentStep || this._introItems.length == 1) {
975
- skipTooltipButton.innerHTML = this._options.doneLabel;
976
- prevTooltipButton.className = 'introjs-button introjs-prevbutton btn btn-success';
977
- nextTooltipButton.className = 'introjs-button introjs-nextbutton introjs-disabled disabled btn btn-primary';
978
- nextTooltipButton.tabIndex = '-1';
979
- } else {
980
- prevTooltipButton.className = 'introjs-button introjs-prevbutton btn btn-success';
981
- nextTooltipButton.className = 'introjs-button introjs-nextbutton btn btn-primary';
982
- skipTooltipButton.innerHTML = this._options.skipLabel;
983
- }
984
-
985
- //Set focus on "next" button, so that hitting Enter always moves you onto the next step
986
- nextTooltipButton.focus();
987
-
988
- //add target element position style
989
- targetElement.element.className += ' introjs-showElement';
990
-
991
- var currentElementPosition = _getPropValue(targetElement.element, 'position');
992
- if (currentElementPosition !== 'absolute' &&
993
- currentElementPosition !== 'relative') {
994
- //change to new intro item
995
- targetElement.element.className += ' introjs-relativePosition';
996
- }
997
-
998
- var parentElm = targetElement.element.parentNode;
999
- while (parentElm != null) {
1000
- if (parentElm.tagName.toLowerCase() === 'body') break;
1001
-
1002
- //fix The Stacking Contenxt problem.
1003
- //More detail: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context
1004
- var zIndex = _getPropValue(parentElm, 'z-index');
1005
- var opacity = parseFloat(_getPropValue(parentElm, 'opacity'));
1006
- var transform = _getPropValue(parentElm, 'transform') || _getPropValue(parentElm, '-webkit-transform') || _getPropValue(parentElm, '-moz-transform') || _getPropValue(parentElm, '-ms-transform') || _getPropValue(parentElm, '-o-transform');
1007
- if (/[0-9]+/.test(zIndex) || opacity < 1 || (transform !== 'none' && transform !== undefined)) {
1008
- parentElm.className += ' introjs-fixParent';
1009
- }
1010
-
1011
- parentElm = parentElm.parentNode;
1012
- }
1013
-
1014
- if (!_elementInViewport(targetElement.element) && this._options.scrollToElement === true) {
1015
- var rect = targetElement.element.getBoundingClientRect(),
1016
- winHeight = _getWinSize().height,
1017
- top = rect.bottom - (rect.bottom - rect.top),
1018
- bottom = rect.bottom - winHeight;
1019
-
1020
- //Scroll up
1021
- if (top < 0 || targetElement.element.clientHeight > winHeight) {
1022
- window.scrollBy(0, top - 30); // 30px padding from edge to look nice
1023
-
1024
- //Scroll down
1025
- } else {
1026
- window.scrollBy(0, bottom + 100); // 70px + 30px padding from edge to look nice
1027
- }
1028
- }
1029
-
1030
- if (typeof (this._introAfterChangeCallback) !== 'undefined') {
1031
- this._introAfterChangeCallback.call(this, targetElement.element);
1032
- }
1033
- }
1034
-
1035
- /**
1036
- * Get an element CSS property on the page
1037
- * Thanks to JavaScript Kit: http://www.javascriptkit.com/dhtmltutors/dhtmlcascade4.shtml
1038
- *
1039
- * @api private
1040
- * @method _getPropValue
1041
- * @param {Object} element
1042
- * @param {String} propName
1043
- * @returns Element's property value
1044
- */
1045
- function _getPropValue (element, propName) {
1046
- var propValue = '';
1047
- if (element.currentStyle) { //IE
1048
- propValue = element.currentStyle[propName];
1049
- } else if (document.defaultView && document.defaultView.getComputedStyle) { //Others
1050
- propValue = document.defaultView.getComputedStyle(element, null).getPropertyValue(propName);
1051
- }
1052
-
1053
- //Prevent exception in IE
1054
- if (propValue && propValue.toLowerCase) {
1055
- return propValue.toLowerCase();
1056
- } else {
1057
- return propValue;
1058
- }
1059
- }
1060
-
1061
- /**
1062
- * Provides a cross-browser way to get the screen dimensions
1063
- * via: http://stackoverflow.com/questions/5864467/internet-explorer-innerheight
1064
- *
1065
- * @api private
1066
- * @method _getWinSize
1067
- * @returns {Object} width and height attributes
1068
- */
1069
- function _getWinSize() {
1070
- if (window.innerWidth != undefined) {
1071
- return { width: window.innerWidth, height: window.innerHeight };
1072
- } else {
1073
- var D = document.documentElement;
1074
- return { width: D.clientWidth, height: D.clientHeight };
1075
- }
1076
- }
1077
-
1078
- /**
1079
- * Add overlay layer to the page
1080
- * http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
1081
- *
1082
- * @api private
1083
- * @method _elementInViewport
1084
- * @param {Object} el
1085
- */
1086
- function _elementInViewport(el) {
1087
- var rect = el.getBoundingClientRect();
1088
-
1089
- return (
1090
- rect.top >= 0 &&
1091
- rect.left >= 0 &&
1092
- (rect.bottom+80) <= window.innerHeight && // add 80 to get the text right
1093
- rect.right <= window.innerWidth
1094
- );
1095
- }
1096
-
1097
- /**
1098
- * Add overlay layer to the page
1099
- *
1100
- * @api private
1101
- * @method _addOverlayLayer
1102
- * @param {Object} targetElm
1103
- */
1104
- function _addOverlayLayer(targetElm) {
1105
- var overlayLayer = document.createElement('div'),
1106
- styleText = '',
1107
- self = this;
1108
-
1109
- //set css class name
1110
- overlayLayer.className = 'introjs-overlay';
1111
-
1112
- //check if the target element is body, we should calculate the size of overlay layer in a better way
1113
- if (targetElm.tagName.toLowerCase() === 'body') {
1114
- styleText += 'top: 0;bottom: 0; left: 0;right: 0;position: fixed;';
1115
- overlayLayer.setAttribute('style', styleText);
1116
- } else {
1117
- //set overlay layer position
1118
- var elementPosition = _getOffset(targetElm);
1119
- if (elementPosition) {
1120
- styleText += 'width: ' + elementPosition.width + 'px; height:' + elementPosition.height + 'px; top:' + elementPosition.top + 'px;left: ' + elementPosition.left + 'px;';
1121
- overlayLayer.setAttribute('style', styleText);
1122
- }
1123
- }
1124
-
1125
- targetElm.appendChild(overlayLayer);
1126
-
1127
- overlayLayer.onclick = function() {
1128
- if (self._options.exitOnOverlayClick == true) {
1129
-
1130
- //check if any callback is defined
1131
- if (self._introExitCallback != undefined) {
1132
- self._introExitCallback.call(self);
1133
- }
1134
- _exitIntro.call(self, targetElm);
1135
- }
1136
- };
1137
-
1138
- setTimeout(function() {
1139
- styleText += 'opacity: ' + self._options.overlayOpacity.toString() + ';';
1140
- overlayLayer.setAttribute('style', styleText);
1141
- }, 10);
1142
-
1143
- return true;
1144
- }
1145
-
1146
- /**
1147
- * Get an element position on the page
1148
- * Thanks to `meouw`: http://stackoverflow.com/a/442474/375966
1149
- *
1150
- * @api private
1151
- * @method _getOffset
1152
- * @param {Object} element
1153
- * @returns Element's position info
1154
- */
1155
- function _getOffset(element) {
1156
- var elementPosition = {};
1157
-
1158
- //set width
1159
- elementPosition.width = element.offsetWidth;
1160
-
1161
- //set height
1162
- elementPosition.height = element.offsetHeight;
1163
-
1164
- //calculate element top and left
1165
- var _x = 0;
1166
- var _y = 0;
1167
- while (element && !isNaN(element.offsetLeft) && !isNaN(element.offsetTop)) {
1168
- _x += element.offsetLeft;
1169
- _y += element.offsetTop;
1170
- element = element.offsetParent;
1171
- }
1172
- //set top
1173
- elementPosition.top = _y;
1174
- //set left
1175
- elementPosition.left = _x;
1176
-
1177
- return elementPosition;
1178
- }
1179
-
1180
- /**
1181
- * Gets the current progress percentage
1182
- *
1183
- * @api private
1184
- * @method _getProgress
1185
- * @returns current progress percentage
1186
- */
1187
- function _getProgress() {
1188
- // Steps are 0 indexed
1189
- var currentStep = parseInt((this._currentStep + 1), 10);
1190
- return ((currentStep / this._introItems.length) * 100);
1191
- }
1192
-
1193
- /**
1194
- * Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
1195
- * via: http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically
1196
- *
1197
- * @param obj1
1198
- * @param obj2
1199
- * @returns obj3 a new object based on obj1 and obj2
1200
- */
1201
- function _mergeOptions(obj1,obj2) {
1202
- var obj3 = {};
1203
- for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
1204
- for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
1205
- return obj3;
1206
- }
1207
-
1208
- var introJs = function (targetElm) {
1209
- if (typeof (targetElm) === 'object') {
1210
- //Ok, create a new instance
1211
- return new IntroJs(targetElm);
1212
-
1213
- } else if (typeof (targetElm) === 'string') {
1214
- //select the target element with query selector
1215
- var targetElement = document.querySelector(targetElm);
1216
-
1217
- if (targetElement) {
1218
- return new IntroJs(targetElement);
1219
- } else {
1220
- throw new Error('There is no element with given selector.');
1221
- }
1222
- } else {
1223
- return new IntroJs(document.body);
1224
- }
1225
- };
1226
-
1227
- /**
1228
- * Current IntroJs version
1229
- *
1230
- * @property version
1231
- * @type String
1232
- */
1233
- introJs.version = VERSION;
1234
-
1235
- //Prototype
1236
- introJs.fn = IntroJs.prototype = {
1237
- clone: function () {
1238
- return new IntroJs(this);
1239
- },
1240
- setOption: function(option, value) {
1241
- this._options[option] = value;
1242
- return this;
1243
- },
1244
- setOptions: function(options) {
1245
- this._options = _mergeOptions(this._options, options);
1246
- return this;
1247
- },
1248
- start: function () {
1249
- _introForElement.call(this, this._targetElement);
1250
- return this;
1251
- },
1252
- goToStep: function(step) {
1253
- _goToStep.call(this, step);
1254
- return this;
1255
- },
1256
- nextStep: function() {
1257
- _nextStep.call(this);
1258
- return this;
1259
- },
1260
- previousStep: function() {
1261
- _previousStep.call(this);
1262
- return this;
1263
- },
1264
- exit: function() {
1265
- _exitIntro.call(this, this._targetElement);
1266
- return this;
1267
- },
1268
- refresh: function() {
1269
- _setHelperLayerPosition.call(this, document.querySelector('.introjs-helperLayer'));
1270
- _setHelperLayerPosition.call(this, document.querySelector('.introjs-tooltipReferenceLayer'));
1271
- return this;
1272
- },
1273
- onbeforechange: function(providedCallback) {
1274
- if (typeof (providedCallback) === 'function') {
1275
- this._introBeforeChangeCallback = providedCallback;
1276
- } else {
1277
- throw new Error('Provided callback for onbeforechange was not a function');
1278
- }
1279
- return this;
1280
- },
1281
- onchange: function(providedCallback) {
1282
- if (typeof (providedCallback) === 'function') {
1283
- this._introChangeCallback = providedCallback;
1284
- } else {
1285
- throw new Error('Provided callback for onchange was not a function.');
1286
- }
1287
- return this;
1288
- },
1289
- onafterchange: function(providedCallback) {
1290
- if (typeof (providedCallback) === 'function') {
1291
- this._introAfterChangeCallback = providedCallback;
1292
- } else {
1293
- throw new Error('Provided callback for onafterchange was not a function');
1294
- }
1295
- return this;
1296
- },
1297
- oncomplete: function(providedCallback) {
1298
- if (typeof (providedCallback) === 'function') {
1299
- this._introCompleteCallback = providedCallback;
1300
- } else {
1301
- throw new Error('Provided callback for oncomplete was not a function.');
1302
- }
1303
- return this;
1304
- },
1305
- onexit: function(providedCallback) {
1306
- if (typeof (providedCallback) === 'function') {
1307
- this._introExitCallback = providedCallback;
1308
- } else {
1309
- throw new Error('Provided callback for onexit was not a function.');
1310
- }
1311
- return this;
1312
- }
1313
- };
1314
-
1315
- exports.introJs = introJs;
1316
- return introJs;
1317
- }));