Browser compatibility and refactor
Browse files- demo/scripts/demo.js +1 -0
- readme.md +0 -1
- src/core/element.js +0 -10
- src/core/overlay.js +13 -9
- src/core/popover.js +6 -5
- src/core/stage.js +12 -1
- src/driver.scss +6 -1
- src/index.js +2 -3
demo/scripts/demo.js
CHANGED
|
@@ -331,6 +331,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
|
| 331 |
document.querySelector('#run-multi-element-popovers')
|
| 332 |
.addEventListener('click', (e) => {
|
| 333 |
e.preventDefault();
|
|
|
|
| 334 |
featureIntroductionDriver.start();
|
| 335 |
});
|
| 336 |
|
|
|
|
| 331 |
document.querySelector('#run-multi-element-popovers')
|
| 332 |
.addEventListener('click', (e) => {
|
| 333 |
e.preventDefault();
|
| 334 |
+
e.stopPropagation();
|
| 335 |
featureIntroductionDriver.start();
|
| 336 |
});
|
| 337 |
|
readme.md
CHANGED
|
@@ -153,7 +153,6 @@ Here are the options that Driver understands
|
|
| 153 |
|
| 154 |
```javascript
|
| 155 |
const driver = new Driver({
|
| 156 |
-
animate: true, // Animate while changing highlighted element
|
| 157 |
opacity: 0.75, // Background opacity (0 means only popovers and without overlay)
|
| 158 |
padding: 10, // Distance of element from around the edges
|
| 159 |
onHighlightStarted: (Element) {}, // Called when element is about to be highlighted
|
|
|
|
| 153 |
|
| 154 |
```javascript
|
| 155 |
const driver = new Driver({
|
|
|
|
| 156 |
opacity: 0.75, // Background opacity (0 means only popovers and without overlay)
|
| 157 |
padding: 10, // Distance of element from around the edges
|
| 158 |
onHighlightStarted: (Element) {}, // Called when element is about to be highlighted
|
src/core/element.js
CHANGED
|
@@ -34,8 +34,6 @@ export default class Element {
|
|
| 34 |
this.stage = stage;
|
| 35 |
|
| 36 |
this.animationTimeout = null;
|
| 37 |
-
|
| 38 |
-
this.highlightFinished = false; // To track when the element has fully highlighted
|
| 39 |
}
|
| 40 |
|
| 41 |
/**
|
|
@@ -161,8 +159,6 @@ export default class Element {
|
|
| 161 |
// If there was any animation in progress, cancel that
|
| 162 |
this.window.clearTimeout(this.animationTimeout);
|
| 163 |
|
| 164 |
-
this.highlightFinished = false;
|
| 165 |
-
|
| 166 |
if (this.options.onDeselected) {
|
| 167 |
this.options.onDeselected(this);
|
| 168 |
}
|
|
@@ -187,10 +183,6 @@ export default class Element {
|
|
| 187 |
* this element of has just decided to highlight it
|
| 188 |
*/
|
| 189 |
onHighlightStarted() {
|
| 190 |
-
// Because element has just started highlighting
|
| 191 |
-
// and hasn't completely highlighted
|
| 192 |
-
this.highlightFinished = false;
|
| 193 |
-
|
| 194 |
if (this.options.onHighlightStarted) {
|
| 195 |
this.options.onHighlightStarted(this);
|
| 196 |
}
|
|
@@ -205,8 +197,6 @@ export default class Element {
|
|
| 205 |
|
| 206 |
this.node.classList.add(CLASS_DRIVER_HIGHLIGHTED_ELEMENT);
|
| 207 |
|
| 208 |
-
this.highlightFinished = true;
|
| 209 |
-
|
| 210 |
const highlightedElement = this;
|
| 211 |
const popoverElement = this.popover;
|
| 212 |
|
|
|
|
| 34 |
this.stage = stage;
|
| 35 |
|
| 36 |
this.animationTimeout = null;
|
|
|
|
|
|
|
| 37 |
}
|
| 38 |
|
| 39 |
/**
|
|
|
|
| 159 |
// If there was any animation in progress, cancel that
|
| 160 |
this.window.clearTimeout(this.animationTimeout);
|
| 161 |
|
|
|
|
|
|
|
| 162 |
if (this.options.onDeselected) {
|
| 163 |
this.options.onDeselected(this);
|
| 164 |
}
|
|
|
|
| 183 |
* this element of has just decided to highlight it
|
| 184 |
*/
|
| 185 |
onHighlightStarted() {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
if (this.options.onHighlightStarted) {
|
| 187 |
this.options.onHighlightStarted(this);
|
| 188 |
}
|
|
|
|
| 197 |
|
| 198 |
this.node.classList.add(CLASS_DRIVER_HIGHLIGHTED_ELEMENT);
|
| 199 |
|
|
|
|
|
|
|
| 200 |
const highlightedElement = this;
|
| 201 |
const popoverElement = this.popover;
|
| 202 |
|
src/core/overlay.js
CHANGED
|
@@ -22,8 +22,6 @@ export default class Overlay {
|
|
| 22 |
|
| 23 |
this.window = window;
|
| 24 |
this.document = document;
|
| 25 |
-
|
| 26 |
-
this.makeNode();
|
| 27 |
}
|
| 28 |
|
| 29 |
/**
|
|
@@ -37,12 +35,12 @@ export default class Overlay {
|
|
| 37 |
}
|
| 38 |
|
| 39 |
this.node = pageOverlay;
|
|
|
|
| 40 |
}
|
| 41 |
|
| 42 |
/**
|
| 43 |
* Highlights the dom element on the screen
|
| 44 |
* @param {Element} element
|
| 45 |
-
* @param {boolean} animate
|
| 46 |
*/
|
| 47 |
highlight(element) {
|
| 48 |
if (!element || !element.node) {
|
|
@@ -84,12 +82,16 @@ export default class Overlay {
|
|
| 84 |
}
|
| 85 |
|
| 86 |
showOverlay() {
|
| 87 |
-
this.
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
}
|
| 94 |
|
| 95 |
hideOverlay() {
|
|
@@ -101,6 +103,8 @@ export default class Overlay {
|
|
| 101 |
this.node.style.top = '';
|
| 102 |
this.node.style.bottom = '';
|
| 103 |
this.node.style.right = '';
|
|
|
|
|
|
|
| 104 |
}, ANIMATION_DURATION_MS);
|
| 105 |
}
|
| 106 |
|
|
|
|
| 22 |
|
| 23 |
this.window = window;
|
| 24 |
this.document = document;
|
|
|
|
|
|
|
| 25 |
}
|
| 26 |
|
| 27 |
/**
|
|
|
|
| 35 |
}
|
| 36 |
|
| 37 |
this.node = pageOverlay;
|
| 38 |
+
this.node.style.opacity = '0';
|
| 39 |
}
|
| 40 |
|
| 41 |
/**
|
| 42 |
* Highlights the dom element on the screen
|
| 43 |
* @param {Element} element
|
|
|
|
| 44 |
*/
|
| 45 |
highlight(element) {
|
| 46 |
if (!element || !element.node) {
|
|
|
|
| 82 |
}
|
| 83 |
|
| 84 |
showOverlay() {
|
| 85 |
+
this.makeNode();
|
| 86 |
+
|
| 87 |
+
window.setTimeout(() => {
|
| 88 |
+
this.node.style.opacity = `${this.options.opacity}`;
|
| 89 |
+
this.node.style.position = 'fixed';
|
| 90 |
+
this.node.style.left = '0';
|
| 91 |
+
this.node.style.top = '0';
|
| 92 |
+
this.node.style.bottom = '0';
|
| 93 |
+
this.node.style.right = '0';
|
| 94 |
+
});
|
| 95 |
}
|
| 96 |
|
| 97 |
hideOverlay() {
|
|
|
|
| 103 |
this.node.style.top = '';
|
| 104 |
this.node.style.bottom = '';
|
| 105 |
this.node.style.right = '';
|
| 106 |
+
|
| 107 |
+
this.node.parentElement.removeChild(this.node);
|
| 108 |
}, ANIMATION_DURATION_MS);
|
| 109 |
}
|
| 110 |
|
src/core/popover.js
CHANGED
|
@@ -3,9 +3,11 @@ import {
|
|
| 3 |
CLASS_BTN_DISABLED,
|
| 4 |
CLASS_CLOSE_BTN,
|
| 5 |
CLASS_NEXT_STEP_BTN,
|
| 6 |
-
CLASS_POPOVER_DESCRIPTION,
|
|
|
|
| 7 |
CLASS_POPOVER_TIP,
|
| 8 |
-
CLASS_POPOVER_TITLE,
|
|
|
|
| 9 |
ID_POPOVER,
|
| 10 |
POPOVER_HTML,
|
| 11 |
} from '../common/constants';
|
|
@@ -53,7 +55,6 @@ export default class Popover extends Element {
|
|
| 53 |
document.body.appendChild(popover);
|
| 54 |
}
|
| 55 |
|
| 56 |
-
|
| 57 |
this.node = popover;
|
| 58 |
this.tipNode = popover.querySelector(`.${CLASS_POPOVER_TIP}`);
|
| 59 |
this.titleNode = popover.querySelector(`.${CLASS_POPOVER_TITLE}`);
|
|
@@ -68,7 +69,7 @@ export default class Popover extends Element {
|
|
| 68 |
this.node.style.display = 'none';
|
| 69 |
}
|
| 70 |
|
| 71 |
-
|
| 72 |
this.node.style.display = 'block';
|
| 73 |
this.node.style.left = '0';
|
| 74 |
this.node.style.top = '0';
|
|
@@ -86,7 +87,7 @@ export default class Popover extends Element {
|
|
| 86 |
* @param {Position} position
|
| 87 |
*/
|
| 88 |
show(position) {
|
| 89 |
-
this.
|
| 90 |
|
| 91 |
// Set the title and descriptions
|
| 92 |
this.titleNode.innerHTML = this.options.title;
|
|
|
|
| 3 |
CLASS_BTN_DISABLED,
|
| 4 |
CLASS_CLOSE_BTN,
|
| 5 |
CLASS_NEXT_STEP_BTN,
|
| 6 |
+
CLASS_POPOVER_DESCRIPTION,
|
| 7 |
+
CLASS_POPOVER_FOOTER,
|
| 8 |
CLASS_POPOVER_TIP,
|
| 9 |
+
CLASS_POPOVER_TITLE,
|
| 10 |
+
CLASS_PREV_STEP_BTN,
|
| 11 |
ID_POPOVER,
|
| 12 |
POPOVER_HTML,
|
| 13 |
} from '../common/constants';
|
|
|
|
| 55 |
document.body.appendChild(popover);
|
| 56 |
}
|
| 57 |
|
|
|
|
| 58 |
this.node = popover;
|
| 59 |
this.tipNode = popover.querySelector(`.${CLASS_POPOVER_TIP}`);
|
| 60 |
this.titleNode = popover.querySelector(`.${CLASS_POPOVER_TITLE}`);
|
|
|
|
| 69 |
this.node.style.display = 'none';
|
| 70 |
}
|
| 71 |
|
| 72 |
+
setInitialState() {
|
| 73 |
this.node.style.display = 'block';
|
| 74 |
this.node.style.left = '0';
|
| 75 |
this.node.style.top = '0';
|
|
|
|
| 87 |
* @param {Position} position
|
| 88 |
*/
|
| 89 |
show(position) {
|
| 90 |
+
this.setInitialState();
|
| 91 |
|
| 92 |
// Set the title and descriptions
|
| 93 |
this.titleNode.innerHTML = this.options.title;
|
src/core/stage.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import { ID_STAGE,
|
| 2 |
import { createNodeFromString } from '../common/utils';
|
| 3 |
import Element from './element';
|
| 4 |
|
|
@@ -36,11 +36,20 @@ export default class Stage extends Element {
|
|
| 36 |
this.node = stage;
|
| 37 |
}
|
| 38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
/**
|
| 40 |
* Simply hides the stage
|
| 41 |
*/
|
| 42 |
hide() {
|
| 43 |
this.node.style.display = 'none';
|
|
|
|
| 44 |
}
|
| 45 |
|
| 46 |
/**
|
|
@@ -55,6 +64,8 @@ export default class Stage extends Element {
|
|
| 55 |
}
|
| 56 |
|
| 57 |
show(position) {
|
|
|
|
|
|
|
| 58 |
this.setInitialStyle();
|
| 59 |
|
| 60 |
// Make it two times the padding because, half will be given on left and half on right
|
|
|
|
| 1 |
+
import { ID_STAGE, STAGE_HTML } from '../common/constants';
|
| 2 |
import { createNodeFromString } from '../common/utils';
|
| 3 |
import Element from './element';
|
| 4 |
|
|
|
|
| 36 |
this.node = stage;
|
| 37 |
}
|
| 38 |
|
| 39 |
+
removeNode() {
|
| 40 |
+
if (!this.node) {
|
| 41 |
+
return;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
this.node.parentElement.removeChild(this.node);
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
/**
|
| 48 |
* Simply hides the stage
|
| 49 |
*/
|
| 50 |
hide() {
|
| 51 |
this.node.style.display = 'none';
|
| 52 |
+
this.removeNode();
|
| 53 |
}
|
| 54 |
|
| 55 |
/**
|
|
|
|
| 64 |
}
|
| 65 |
|
| 66 |
show(position) {
|
| 67 |
+
this.makeNode();
|
| 68 |
+
|
| 69 |
this.setInitialStyle();
|
| 70 |
|
| 71 |
// Make it two times the padding because, half will be given on left and half on right
|
src/driver.scss
CHANGED
|
@@ -110,7 +110,12 @@ div#driver-popover-item {
|
|
| 110 |
div#driver-page-overlay {
|
| 111 |
background: black;
|
| 112 |
position: absolute;
|
| 113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
z-index: 100002 !important;
|
| 115 |
|
| 116 |
// If you update this duration, make sure to update `ANIMATION_DURATION_MS` constant
|
|
|
|
| 110 |
div#driver-page-overlay {
|
| 111 |
background: black;
|
| 112 |
position: absolute;
|
| 113 |
+
display: block;
|
| 114 |
+
width: 100%;
|
| 115 |
+
height: 100%;
|
| 116 |
+
zoom: 1;
|
| 117 |
+
filter: alpha(opacity=75);
|
| 118 |
+
opacity: 0.75;
|
| 119 |
z-index: 100002 !important;
|
| 120 |
|
| 121 |
// If you update this duration, make sure to update `ANIMATION_DURATION_MS` constant
|
src/index.js
CHANGED
|
@@ -156,7 +156,7 @@ export default class Driver {
|
|
| 156 |
*/
|
| 157 |
hasHighlightedElement() {
|
| 158 |
const highlightedElement = this.overlay.getHighlightedElement();
|
| 159 |
-
return highlightedElement && highlightedElement.node
|
| 160 |
}
|
| 161 |
|
| 162 |
/**
|
|
@@ -177,8 +177,7 @@ export default class Driver {
|
|
| 177 |
|
| 178 |
/**
|
| 179 |
* Handler for the onResize DOM event
|
| 180 |
-
*
|
| 181 |
-
* the highlighted part travels with the width change of window
|
| 182 |
*/
|
| 183 |
onResize() {
|
| 184 |
if (!this.isActivated) {
|
|
|
|
| 156 |
*/
|
| 157 |
hasHighlightedElement() {
|
| 158 |
const highlightedElement = this.overlay.getHighlightedElement();
|
| 159 |
+
return highlightedElement && highlightedElement.node;
|
| 160 |
}
|
| 161 |
|
| 162 |
/**
|
|
|
|
| 177 |
|
| 178 |
/**
|
| 179 |
* Handler for the onResize DOM event
|
| 180 |
+
* Makes sure highlighted element stays at valid position
|
|
|
|
| 181 |
*/
|
| 182 |
onResize() {
|
| 183 |
if (!this.isActivated) {
|