File size: 4,103 Bytes
22c7264 3dfa288 b4b2753 22c7264 8755ee2 0c119f7 8755ee2 0c119f7 31d8a1a bb8be8c 5aa283f bb8be8c d5e94aa 5aa283f bb8be8c 8755ee2 bb8be8c d5e94aa 5aa283f 22fca24 ede8cb9 5aa283f 22fca24 5aa283f ede8cb9 22fca24 ede8cb9 22fca24 5aa283f 22fca24 bb8be8c 5aa283f 8755ee2 bb8be8c 8755ee2 bb8be8c b4b2753 8755ee2 d5e94aa 5aa283f 8755ee2 22c7264 5aa283f b4b2753 5aa283f 22c7264 5aa283f 22c7264 b4b2753 5aa283f 37f5ac4 5aa283f b4b2753 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
import Overlay from './overlay';
import Element from './element';
import './polyfill';
/**
* Plugin class that drives the plugin
*/
export default class Sholo {
/**
* @param options
*/
constructor(options = {}) {
this.options = Object.assign({
padding: 10,
animate: true,
opacity: 0.75,
}, options);
this.overlay = new Overlay(options);
this.document = document;
this.window = window;
this.steps = []; // steps to be presented if any
this.currentStep = 0; // index for the currently highlighted step
this.onScroll = this.onScroll.bind(this);
this.onResize = this.onResize.bind(this);
this.onKeyUp = this.onKeyUp.bind(this);
this.onClick = this.onClick.bind(this);
// Event bindings
this.bind();
}
/**
* Binds any DOM events listeners
* @todo: add throttling in all the listeners
*/
bind() {
this.document.addEventListener('scroll', this.onScroll, false);
this.document.addEventListener('DOMMouseScroll', this.onScroll, false);
this.window.addEventListener('resize', this.onResize, false);
this.window.addEventListener('keyup', this.onKeyUp, false);
this.window.addEventListener('click', this.onClick, false);
}
/**
* Removes the popover if clicked outside the highlighted element
* or outside the
* @param e
*/
onClick(e) {
if (!this.hasHighlightedElement()) {
// Has no highlighted element so ignore the click
return;
}
const highlightedElement = this.overlay.getHighlightedElement();
const popover = document.getElementById('sholo-popover-item');
const clickedHighlightedElement = highlightedElement.node.contains(e.target);
const clickedPopover = popover && popover.contains(e.target);
// Remove the overlay If clicked outside the highlighted element
if (!clickedHighlightedElement && !clickedPopover) {
this.overlay.clear();
return;
}
const nextClicked = e.target.classList.contains('sholo-next-btn');
if (nextClicked) {
this.currentStep += 1;
this.overlay.highlight(this.steps[this.currentStep]);
}
}
hasHighlightedElement() {
const highlightedElement = this.overlay.getHighlightedElement();
return highlightedElement && highlightedElement.node;
}
/**
* Handler for the onScroll event on document
* Refreshes without animation on scroll to make sure
* that the highlighted part travels with the scroll
*/
onScroll() {
this.overlay.refresh(false);
}
/**
* Handler for the onResize DOM event
* Refreshes with animation on scroll to make sure that
* the highlighted part travels with the width change of window
*/
onResize() {
// Refresh with animation
this.overlay.refresh(true);
}
/**
* Clears the overlay on escape key process
* @param event
*/
onKeyUp(event) {
if (event.keyCode === 27) {
this.overlay.clear();
}
}
defineSteps(steps) {
this.steps = [];
steps.forEach((step, index) => {
if (!step.element) {
throw new Error(`Element (query selector or a dom element) missing in step ${index}`);
}
const domElement = Sholo.findDomElement(step.element);
const element = new Element(domElement, Object.assign({}, this.options, step));
this.steps.push(element);
});
}
start() {
if (!this.steps || this.steps.length === 0) {
throw new Error('There are no steps defined to iterate');
}
this.currentStep = 0;
this.overlay.highlight(this.steps[0]);
}
/**
* Highlights the given selector
* @param selector
*/
highlight(selector) {
const domElement = Sholo.findDomElement(selector);
const element = new Element(domElement, this.options);
this.overlay.highlight(element);
}
static findDomElement(selector) {
if (typeof selector === 'string') {
return document.querySelector(selector);
}
if (typeof selector === 'object') {
return selector;
}
throw new Error('Element can only be string or the dom element');
}
}
|