PluginProbe
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress / 8.5.79
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress v8.5.79
9.1.3 9.1.2 9.1.1 9.1.0 9.0.3 9.0.2 9.0.1 9.0.0 8.5.79 8.5.78 8.5.77 8.5.76 8.5.75 8.5.74 8.5.73 8.5.72 8.5.71 8.5.70 8.5.69 8.5.68 8.5.35 8.5.36 8.5.37 8.5.38 8.5.39 All 222 releases
wpvr / admin / lib / shepherd / tether-shepherd / shepherd.js

shepherd.js in WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress 8.5.79, at admin/lib/shepherd/tether-shepherd/shepherd.js

751 lines 20.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*!
2 * tether-shepherd 1.8.1
3 * https://github.com/shipshapecode/shepherd
4 * Copyright (c) 2015 HubSpot, Inc.
5 * Licensed under the MIT license.
6 */
7
8 (function(root, factory) {
9 if (typeof define === 'function' && define.amd) {
10 define(["tether"], factory);
11 } else if (typeof exports === 'object') {
12 module.exports = factory(require('tether'));
13 } else {
14 root.Shepherd = factory(root.Tether);
15 }
16 }(this, function(Tether) {
17
18 /* global Tether */
19
20 'use strict';
21
22 var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
23
24 var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
25
26 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
27
28 function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
29
30 var _Tether$Utils = Tether.Utils;
31 var Evented = _Tether$Utils.Evented;
32 var addClass = _Tether$Utils.addClass;
33 var extend = _Tether$Utils.extend;
34 var hasClass = _Tether$Utils.hasClass;
35 var removeClass = _Tether$Utils.removeClass;
36 var uniqueId = _Tether$Utils.uniqueId;
37
38 var Shepherd = new Evented();
39
40 function isUndefined(obj) {
41 return typeof obj === 'undefined';
42 };
43
44 function isArray(obj) {
45 return obj && obj.constructor === Array;
46 };
47
48 function isObject(obj) {
49 return obj && obj.constructor === Object;
50 };
51
52 function isObjectLoose(obj) {
53 return typeof obj === 'object';
54 };
55
56 var ATTACHMENT = {
57 'top right': 'bottom left',
58 'top left': 'bottom right',
59 'top center': 'bottom center',
60 'middle right': 'middle left',
61 'middle left': 'middle right',
62 'middle center': 'middle center',
63 'bottom left': 'top right',
64 'bottom right': 'top left',
65 'bottom center': 'top center',
66 'top': 'bottom center',
67 'left': 'middle right',
68 'right': 'middle left',
69 'bottom': 'top center',
70 'center': 'middle center',
71 'middle': 'middle center'
72 };
73
74 function createFromHTML(html) {
75 var el = document.createElement('div');
76 el.innerHTML = html;
77 return el.children[0];
78 }
79
80 function matchesSelector(el, sel) {
81 var matches = undefined;
82 if (!isUndefined(el.matches)) {
83 matches = el.matches;
84 } else if (!isUndefined(el.matchesSelector)) {
85 matches = el.matchesSelector;
86 } else if (!isUndefined(el.msMatchesSelector)) {
87 matches = el.msMatchesSelector;
88 } else if (!isUndefined(el.webkitMatchesSelector)) {
89 matches = el.webkitMatchesSelector;
90 } else if (!isUndefined(el.mozMatchesSelector)) {
91 matches = el.mozMatchesSelector;
92 } else if (!isUndefined(el.oMatchesSelector)) {
93 matches = el.oMatchesSelector;
94 }
95 return matches.call(el, sel);
96 }
97
98 var positionRe = /^(.+) (top|left|right|bottom|center|\[[a-z ]+\])$/;
99
100 function parsePosition(str) {
101 if (isObjectLoose(str)) {
102 if (str.hasOwnProperty("element") && str.hasOwnProperty("on")) {
103 return str;
104 }
105 return null;
106 }
107
108 var matches = positionRe.exec(str);
109 if (!matches) {
110 return null;
111 }
112
113 var on = matches[2];
114 if (on[0] === '[') {
115 on = on.substring(1, on.length - 1);
116 }
117
118 return {
119 'element': matches[1],
120 'on': on
121 };
122 }
123
124 function parseShorthand(obj, props) {
125 if (obj === null || isUndefined(obj)) {
126 return obj;
127 } else if (isObjectLoose(obj)) {
128 return obj;
129 }
130
131 var vals = obj.split(' ');
132 var out = {};
133 var j = props.length - 1;
134 for (var i = vals.length - 1; i >= 0; i--) {
135 if (j === 0) {
136 out[props[j]] = vals.slice(0, i + 1).join(' ');
137 break;
138 } else {
139 out[props[j]] = vals[i];
140 }
141
142 j--;
143 }
144
145 return out;
146 }
147
148 var Step = (function (_Evented) {
149 _inherits(Step, _Evented);
150
151 function Step(tour, options) {
152 _classCallCheck(this, Step);
153
154 _get(Object.getPrototypeOf(Step.prototype), 'constructor', this).call(this, tour, options);
155 this.tour = tour;
156 this.bindMethods();
157 this.setOptions(options);
158 return this;
159 }
160
161 _createClass(Step, [{
162 key: 'bindMethods',
163 value: function bindMethods() {
164 var _this = this;
165
166 var methods = ['_show', 'show', 'hide', 'isOpen', 'cancel', 'complete', 'scrollTo', 'destroy', 'render'];
167 methods.map(function (method) {
168 _this[method] = _this[method].bind(_this);
169 });
170 }
171 }, {
172 key: 'setOptions',
173 value: function setOptions() {
174 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
175
176 this.options = options;
177 this.destroy();
178
179 this.id = this.options.id || this.id || 'step-' + uniqueId();
180
181 var when = this.options.when;
182 if (when) {
183 for (var _event in when) {
184 if (({}).hasOwnProperty.call(when, _event)) {
185 var handler = when[_event];
186 this.on(_event, handler, this);
187 }
188 }
189 }
190
191 // Button configuration
192
193 var buttonsJson = JSON.stringify(this.options.buttons);
194 var buttonsAreDefault = isUndefined(buttonsJson) || buttonsJson === "true";
195
196 var buttonsAreEmpty = buttonsJson === "{}" || buttonsJson === "[]" || buttonsJson === "null" || buttonsJson === "false";
197
198 var buttonsAreArray = !buttonsAreDefault && isArray(this.options.buttons);
199
200 var buttonsAreObject = !buttonsAreDefault && isObject(this.options.buttons);
201
202 // Show default button if undefined or 'true'
203 if (buttonsAreDefault) {
204 this.options.buttons = [{
205 text: 'Next',
206 action: this.tour.next,
207 classes: 'btn'
208 }];
209
210 // Can pass in an object which will assume asingle button
211 } else if (!buttonsAreEmpty && buttonsAreObject) {
212 this.options.buttons = [this.options.buttons];
213
214 // Falsey/empty values or non-object values prevent buttons from rendering
215 } else if (buttonsAreEmpty || !buttonsAreArray) {
216 this.options.buttons = false;
217 }
218 }
219 }, {
220 key: 'getTour',
221 value: function getTour() {
222 return this.tour;
223 }
224 }, {
225 key: 'bindAdvance',
226 value: function bindAdvance() {
227 var _this2 = this;
228
229 // An empty selector matches the step element
230
231 var _parseShorthand = parseShorthand(this.options.advanceOn, ['selector', 'event']);
232
233 var event = _parseShorthand.event;
234 var selector = _parseShorthand.selector;
235
236 var handler = function handler(e) {
237 if (!_this2.isOpen()) {
238 return;
239 }
240
241 if (!isUndefined(selector)) {
242 if (matchesSelector(e.target, selector)) {
243 _this2.tour.next();
244 }
245 } else {
246 if (_this2.el && e.target === _this2.el) {
247 _this2.tour.next();
248 }
249 }
250 };
251
252 // TODO: this should also bind/unbind on show/hide
253 document.body.addEventListener(event, handler);
254 this.on('destroy', function () {
255 return document.body.removeEventListener(event, handler);
256 });
257 }
258 }, {
259 key: 'getAttachTo',
260 value: function getAttachTo() {
261 var opts = parsePosition(this.options.attachTo) || {};
262 var returnOpts = extend({}, opts);
263
264 if (typeof opts.element === 'string') {
265 // Can't override the element in user opts reference because we can't
266 // guarantee that the element will exist in the future.
267 returnOpts.element = document.querySelector(opts.element);
268 if (!returnOpts.element) {
269 console.error('The element for this Shepherd step was not found ' + opts.element);
270 }
271 }
272
273 return returnOpts;
274 }
275 }, {
276 key: 'setupTether',
277 value: function setupTether() {
278 if (isUndefined(Tether)) {
279 throw new Error("Using the attachment feature of Shepherd requires the Tether library");
280 }
281
282 var opts = this.getAttachTo();
283 var attachment = ATTACHMENT[opts.on] || ATTACHMENT.right;
284 if (isUndefined(opts.element)) {
285 opts.element = 'viewport';
286 attachment = 'middle center';
287 }
288
289 var tetherOpts = {
290 classPrefix: 'shepherd',
291 element: this.el,
292 constraints: [{
293 to: 'window',
294 pin: true,
295 attachment: 'together'
296 }],
297 target: opts.element,
298 offset: opts.offset || '0 0',
299 attachment: attachment
300 };
301
302 if (this.tether) {
303 this.tether.destroy();
304 }
305
306 this.tether = new Tether(extend(tetherOpts, this.options.tetherOptions));
307 }
308 }, {
309 key: 'show',
310 value: function show() {
311 var _this3 = this;
312
313 if (!isUndefined(this.options.beforeShowPromise)) {
314 var beforeShowPromise = this.options.beforeShowPromise();
315 if (!isUndefined(beforeShowPromise)) {
316 return beforeShowPromise.then(function () {
317 return _this3._show();
318 });
319 }
320 }
321 this._show();
322 }
323 }, {
324 key: '_show',
325 value: function _show() {
326 var _this4 = this;
327
328 this.trigger('before-show');
329
330 if (!this.el) {
331 this.render();
332 }
333
334 addClass(this.el, 'shepherd-open');
335
336 document.body.setAttribute('data-shepherd-step', this.id);
337
338 this.setupTether();
339
340 if (this.options.scrollTo) {
341 setTimeout(function () {
342 _this4.scrollTo();
343 });
344 }
345
346 this.trigger('show');
347 }
348 }, {
349 key: 'hide',
350 value: function hide() {
351 this.trigger('before-hide');
352
353 removeClass(this.el, 'shepherd-open');
354
355 document.body.removeAttribute('data-shepherd-step');
356
357 if (this.tether) {
358 this.tether.destroy();
359 }
360 this.tether = null;
361
362 this.trigger('hide');
363 }
364 }, {
365 key: 'isOpen',
366 value: function isOpen() {
367 return this.el && hasClass(this.el, 'shepherd-open');
368 }
369 }, {
370 key: 'cancel',
371 value: function cancel() {
372 this.tour.cancel();
373 this.trigger('cancel');
374 }
375 }, {
376 key: 'complete',
377 value: function complete() {
378 this.tour.complete();
379 this.trigger('complete');
380 }
381 }, {
382 key: 'scrollTo',
383 value: function scrollTo() {
384 var _getAttachTo = this.getAttachTo();
385
386 var element = _getAttachTo.element;
387
388 if (!isUndefined(this.options.scrollToHandler)) {
389 this.options.scrollToHandler(element);
390 } else if (!isUndefined(element)) {
391 element.scrollIntoView();
392 }
393 }
394 }, {
395 key: 'destroy',
396 value: function destroy() {
397 if (!isUndefined(this.el) && this.el.parentNode) {
398 this.el.parentNode.removeChild(this.el);
399 delete this.el;
400 }
401
402 if (this.tether) {
403 this.tether.destroy();
404 }
405 this.tether = null;
406
407 this.trigger('destroy');
408 }
409 }, {
410 key: 'render',
411 value: function render() {
412 var _this5 = this;
413
414 if (!isUndefined(this.el)) {
415 this.destroy();
416 }
417
418 this.el = createFromHTML('<div class=\'shepherd-step ' + (this.options.classes || '') + '\' data-id=\'' + this.id + '\' ' + (this.options.idAttribute ? 'id="' + this.options.idAttribute + '"' : '') + '></div>');
419
420 var content = document.createElement('div');
421 content.className = 'shepherd-content';
422 this.el.appendChild(content);
423
424 var header = document.createElement('header');
425 content.appendChild(header);
426
427 if (this.options.title) {
428 header.innerHTML += '<h3 class=\'shepherd-title\'>' + this.options.title + '</h3>';
429 this.el.className += ' shepherd-has-title';
430 }
431
432 if (this.options.showCancelLink) {
433 var link = createFromHTML("<a href class='shepherd-cancel-link'>✕</a>");
434 header.appendChild(link);
435
436 this.el.className += ' shepherd-has-cancel-link';
437
438 this.bindCancelLink(link);
439 }
440
441 if (!isUndefined(this.options.text)) {
442 (function () {
443 var text = createFromHTML("<div class='shepherd-text'></div>");
444 var paragraphs = _this5.options.text;
445
446 if (typeof paragraphs === 'function') {
447 paragraphs = paragraphs.call(_this5, text);
448 }
449
450 if (paragraphs instanceof HTMLElement) {
451 text.appendChild(paragraphs);
452 } else {
453 if (typeof paragraphs === 'string') {
454 paragraphs = [paragraphs];
455 }
456
457 paragraphs.map(function (paragraph) {
458 text.innerHTML += '<p>' + paragraph + '</p>';
459 });
460 }
461
462 content.appendChild(text);
463 })();
464 }
465
466 if (this.options.buttons) {
467 (function () {
468 var footer = document.createElement('footer');
469 var buttons = createFromHTML("<ul class='shepherd-buttons'></ul>");
470
471 _this5.options.buttons.map(function (cfg) {
472 var button = createFromHTML('<li><a class=\'shepherd-button ' + (cfg.classes || '') + '\'>' + cfg.text + '</a>');
473 buttons.appendChild(button);
474 _this5.bindButtonEvents(cfg, button.querySelector('a'));
475 });
476
477 footer.appendChild(buttons);
478 content.appendChild(footer);
479 })();
480 }
481
482 document.body.appendChild(this.el);
483
484 this.setupTether();
485
486 if (this.options.advanceOn) {
487 this.bindAdvance();
488 }
489 }
490 }, {
491 key: 'bindCancelLink',
492 value: function bindCancelLink(link) {
493 var _this6 = this;
494
495 link.addEventListener('click', function (e) {
496 e.preventDefault();
497 _this6.cancel();
498 });
499 }
500 }, {
501 key: 'bindButtonEvents',
502 value: function bindButtonEvents(cfg, el) {
503 var _this7 = this;
504
505 cfg.events = cfg.events || {};
506 if (!isUndefined(cfg.action)) {
507 // Including both a click event and an action is not supported
508 cfg.events.click = cfg.action;
509 }
510
511 for (var _event2 in cfg.events) {
512 if (({}).hasOwnProperty.call(cfg.events, _event2)) {
513 var handler = cfg.events[_event2];
514 if (typeof handler === 'string') {
515 (function () {
516 var page = handler;
517 handler = function () {
518 return _this7.tour.show(page);
519 };
520 })();
521 }
522 el.addEventListener(_event2, handler);
523 }
524 }
525
526 this.on('destroy', function () {
527 for (var _event3 in cfg.events) {
528 if (({}).hasOwnProperty.call(cfg.events, _event3)) {
529 var handler = cfg.events[_event3];
530 el.removeEventListener(_event3, handler);
531 }
532 }
533 });
534 }
535 }]);
536
537 return Step;
538 })(Evented);
539
540 var Tour = (function (_Evented2) {
541 _inherits(Tour, _Evented2);
542
543 function Tour() {
544 var _this8 = this;
545
546 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
547
548 _classCallCheck(this, Tour);
549
550 _get(Object.getPrototypeOf(Tour.prototype), 'constructor', this).call(this, options);
551 this.bindMethods();
552 this.options = options;
553 this.steps = this.options.steps || [];
554
555 // Pass these events onto the global Shepherd object
556 var events = ['complete', 'cancel', 'hide', 'start', 'show', 'active', 'inactive'];
557 events.map(function (event) {
558 (function (e) {
559 _this8.on(e, function (opts) {
560 opts = opts || {};
561 opts.tour = _this8;
562 Shepherd.trigger(e, opts);
563 });
564 })(event);
565 });
566
567 return this;
568 }
569
570 _createClass(Tour, [{
571 key: 'bindMethods',
572 value: function bindMethods() {
573 var _this9 = this;
574
575 var methods = ['next', 'back', 'cancel', 'complete', 'hide'];
576 methods.map(function (method) {
577 _this9[method] = _this9[method].bind(_this9);
578 });
579 }
580 }, {
581 key: 'addStep',
582 value: function addStep(name, step) {
583 if (isUndefined(step)) {
584 step = name;
585 }
586
587 if (!(step instanceof Step)) {
588 if (typeof name === 'string' || typeof name === 'number') {
589 step.id = name.toString();
590 }
591 step = extend({}, this.options.defaults, step);
592 step = new Step(this, step);
593 } else {
594 step.tour = this;
595 }
596
597 this.steps.push(step);
598 return this;
599 }
600 }, {
601 key: 'removeStep',
602 value: function removeStep(name) {
603 var current = this.getCurrentStep();
604
605 for (var i = 0; i < this.steps.length; ++i) {
606 var step = this.steps[i];
607 if (step.id === name) {
608 if (step.isOpen()) {
609 step.hide();
610 }
611 step.destroy();
612 this.steps.splice(i, 1);
613 break;
614 }
615 }
616
617 if (current && current.id === name) {
618 this.currentStep = undefined;
619
620 if (this.steps.length) this.show(0);else this.hide();
621 }
622 }
623 }, {
624 key: 'getById',
625 value: function getById(id) {
626 for (var i = 0; i < this.steps.length; ++i) {
627 var step = this.steps[i];
628 if (step.id === id) {
629 return step;
630 }
631 }
632 }
633 }, {
634 key: 'getCurrentStep',
635 value: function getCurrentStep() {
636 return this.currentStep;
637 }
638 }, {
639 key: 'next',
640 value: function next() {
641 var index = this.steps.indexOf(this.currentStep);
642
643 if (index === this.steps.length - 1) {
644 this.hide(index);
645 this.trigger('complete');
646 this.done();
647 } else {
648 this.show(index + 1, true);
649 }
650 }
651 }, {
652 key: 'back',
653 value: function back() {
654 var index = this.steps.indexOf(this.currentStep);
655 this.show(index - 1, false);
656 }
657 }, {
658 key: 'cancel',
659 value: function cancel() {
660 if (this.currentStep) {
661 this.currentStep.hide();
662 }
663 this.trigger('cancel');
664 this.done();
665 }
666 }, {
667 key: 'complete',
668 value: function complete() {
669 if (this.currentStep) {
670 this.currentStep.hide();
671 }
672 this.trigger('complete');
673 this.done();
674 }
675 }, {
676 key: 'hide',
677 value: function hide() {
678 if (this.currentStep) {
679 this.currentStep.hide();
680 }
681 this.trigger('hide');
682 this.done();
683 }
684 }, {
685 key: 'done',
686 value: function done() {
687 Shepherd.activeTour = null;
688 removeClass(document.body, 'shepherd-active');
689 this.trigger('inactive', { tour: this });
690 }
691 }, {
692 key: 'show',
693 value: function show() {
694 var key = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];
695 var forward = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
696
697 if (this.currentStep) {
698 this.currentStep.hide();
699 } else {
700 addClass(document.body, 'shepherd-active');
701 this.trigger('active', { tour: this });
702 }
703
704 Shepherd.activeTour = this;
705
706 var next = undefined;
707
708 if (typeof key === 'string') {
709 next = this.getById(key);
710 } else {
711 next = this.steps[key];
712 }
713
714 if (next) {
715 if (!isUndefined(next.options.showOn) && !next.options.showOn()) {
716 var index = this.steps.indexOf(next);
717 var nextIndex = forward ? index + 1 : index - 1;
718 this.show(nextIndex, forward);
719 } else {
720 this.trigger('show', {
721 step: next,
722 previous: this.currentStep
723 });
724
725 if (this.currentStep) {
726 this.currentStep.hide();
727 }
728
729 this.currentStep = next;
730 next.show();
731 }
732 }
733 }
734 }, {
735 key: 'start',
736 value: function start() {
737 this.trigger('start');
738
739 this.currentStep = null;
740 this.next();
741 }
742 }]);
743
744 return Tour;
745 })(Evented);
746
747 extend(Shepherd, { Tour: Tour, Step: Step, Evented: Evented });
748 return Shepherd;
749
750 }));
751