camaleon_cms 2.8.2 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (40) 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/controllers/camaleon_cms/admin/sessions_controller.rb +1 -1
  26. data/app/helpers/camaleon_cms/uploader_helper.rb +11 -4
  27. data/app/uploaders/camaleon_cms_aws_uploader.rb +10 -1
  28. data/app/uploaders/camaleon_cms_local_uploader.rb +3 -1
  29. data/app/uploaders/camaleon_cms_uploader.rb +2 -4
  30. data/app/views/camaleon_cms/admin/settings/_file_system_settings.html.erb +5 -5
  31. data/app/views/layouts/camaleon_cms/admin.html.erb +7 -1
  32. data/lib/camaleon_cms/version.rb +1 -1
  33. data/lib/plugin_routes.rb +2 -0
  34. metadata +20 -15
  35. data/app/assets/javascripts/camaleon_cms/admin/_underscore.js +0 -1536
  36. data/app/assets/javascripts/camaleon_cms/admin/introjs/_intro.min.js +0 -1317
  37. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/de.js +0 -20
  38. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/it.js +0 -23
  39. data/app/assets/stylesheets/camaleon_cms/admin/introjs/_introjs.min.css +0 -1
  40. /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
- }));