Move popover logic to separate class
Browse files- assets/scripts/src/element.js +9 -54
- assets/scripts/src/popover.js +71 -0
- assets/scripts/src/sholo.js +9 -2
assets/scripts/src/element.js
CHANGED
@@ -1,21 +1,26 @@
|
|
1 |
import Position from './position';
|
2 |
|
|
|
|
|
|
|
|
|
3 |
export default class Element {
|
4 |
/**
|
5 |
* DOM element object
|
6 |
* @param node
|
7 |
* @param options
|
|
|
8 |
* @param overlay
|
9 |
* @param window
|
10 |
* @param document
|
11 |
*/
|
12 |
-
constructor(node, options, overlay, window, document) {
|
13 |
this.node = node;
|
14 |
this.document = document;
|
15 |
this.window = window;
|
16 |
this.options = options;
|
17 |
this.overlay = overlay;
|
18 |
-
this.popover =
|
19 |
}
|
20 |
|
21 |
/**
|
@@ -99,7 +104,7 @@ export default class Element {
|
|
99 |
|
100 |
onDeselected() {
|
101 |
// Will be called when element is about to be deselected
|
102 |
-
this.
|
103 |
}
|
104 |
|
105 |
onHighlightStarted() {
|
@@ -125,42 +130,9 @@ export default class Element {
|
|
125 |
}
|
126 |
|
127 |
showPopover() {
|
128 |
-
this.resetPopover();
|
129 |
-
|
130 |
-
// Position at which the element is
|
131 |
const position = this.getCalculatedPosition();
|
132 |
|
133 |
-
|
134 |
-
|
135 |
-
const pageHeight = this.getFullPageSize().height;
|
136 |
-
const popoverHeight = this.getPopoverHeight();
|
137 |
-
const popoverMargin = this.options.padding + 10;
|
138 |
-
|
139 |
-
this.popover.style.left = `${position.left - this.options.padding}px`;
|
140 |
-
|
141 |
-
// Calculate different dimensions after attaching popover
|
142 |
-
const pageHeightAfterPopOver = position.bottom + popoverHeight + popoverMargin;
|
143 |
-
|
144 |
-
// If adding popover would go out of the window height, then show it to the top
|
145 |
-
if (pageHeightAfterPopOver >= pageHeight) {
|
146 |
-
this.popover.style.top = `${position.top - popoverHeight - popoverMargin}px`;
|
147 |
-
popoverTip.classList.add('bottom');
|
148 |
-
} else {
|
149 |
-
this.popover.style.top = `${position.bottom + popoverMargin}px`;
|
150 |
-
popoverTip.classList.add('top');
|
151 |
-
}
|
152 |
-
}
|
153 |
-
|
154 |
-
getPopover() {
|
155 |
-
// @todo: Create if not there
|
156 |
-
const popover = this.document.getElementById('sholo-popover-item');
|
157 |
-
popover.style.position = 'absolute';
|
158 |
-
|
159 |
-
return popover;
|
160 |
-
}
|
161 |
-
|
162 |
-
hidePopover() {
|
163 |
-
this.popover.style.display = 'none';
|
164 |
}
|
165 |
|
166 |
getFullPageSize() {
|
@@ -173,21 +145,4 @@ export default class Element {
|
|
173 |
width: Math.max(body.scrollWidth, body.offsetWidth, html.scrollWidth, html.offsetWidth),
|
174 |
};
|
175 |
}
|
176 |
-
|
177 |
-
getPopoverHeight() {
|
178 |
-
return Math.max(this.popover.scrollHeight, this.popover.offsetHeight);
|
179 |
-
}
|
180 |
-
|
181 |
-
resetPopover() {
|
182 |
-
this.popover.style.display = 'block';
|
183 |
-
this.popover.style.left = '';
|
184 |
-
this.popover.style.top = '';
|
185 |
-
this.popover.style.bottom = '';
|
186 |
-
this.popover.style.right = '';
|
187 |
-
|
188 |
-
// Remove the positional classes from tip
|
189 |
-
this.popover
|
190 |
-
.querySelector('.sholo-popover-tip')
|
191 |
-
.className = 'sholo-popover-tip';
|
192 |
-
}
|
193 |
}
|
|
|
1 |
import Position from './position';
|
2 |
|
3 |
+
/**
|
4 |
+
* Wrapper around DOMElements to enrich them
|
5 |
+
* with the functionality necessary
|
6 |
+
*/
|
7 |
export default class Element {
|
8 |
/**
|
9 |
* DOM element object
|
10 |
* @param node
|
11 |
* @param options
|
12 |
+
* @param popover
|
13 |
* @param overlay
|
14 |
* @param window
|
15 |
* @param document
|
16 |
*/
|
17 |
+
constructor(node, options, popover, overlay, window, document) {
|
18 |
this.node = node;
|
19 |
this.document = document;
|
20 |
this.window = window;
|
21 |
this.options = options;
|
22 |
this.overlay = overlay;
|
23 |
+
this.popover = popover;
|
24 |
}
|
25 |
|
26 |
/**
|
|
|
104 |
|
105 |
onDeselected() {
|
106 |
// Will be called when element is about to be deselected
|
107 |
+
this.popover.hide();
|
108 |
}
|
109 |
|
110 |
onHighlightStarted() {
|
|
|
130 |
}
|
131 |
|
132 |
showPopover() {
|
|
|
|
|
|
|
133 |
const position = this.getCalculatedPosition();
|
134 |
|
135 |
+
this.popover.show(position);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
}
|
137 |
|
138 |
getFullPageSize() {
|
|
|
145 |
width: Math.max(body.scrollWidth, body.offsetWidth, html.scrollWidth, html.offsetWidth),
|
146 |
};
|
147 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
}
|
assets/scripts/src/popover.js
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Popover that is displayed on top of the highlighted element
|
3 |
+
*/
|
4 |
+
import Element from './element';
|
5 |
+
|
6 |
+
export default class Popover extends Element {
|
7 |
+
constructor(options = {
|
8 |
+
padding: 10,
|
9 |
+
}, window, document) {
|
10 |
+
super();
|
11 |
+
|
12 |
+
this.options = options;
|
13 |
+
this.window = window;
|
14 |
+
this.document = document;
|
15 |
+
|
16 |
+
this.node = this.getPopover();
|
17 |
+
}
|
18 |
+
|
19 |
+
getPopover() {
|
20 |
+
// @todo: Create if not there
|
21 |
+
const popover = this.document.getElementById('sholo-popover-item');
|
22 |
+
popover.style.position = 'absolute';
|
23 |
+
|
24 |
+
return popover;
|
25 |
+
}
|
26 |
+
|
27 |
+
getHeight() {
|
28 |
+
return Math.max(this.node.scrollHeight, this.node.offsetHeight);
|
29 |
+
}
|
30 |
+
|
31 |
+
hide() {
|
32 |
+
this.node.style.display = 'none';
|
33 |
+
}
|
34 |
+
|
35 |
+
reset() {
|
36 |
+
this.node.style.display = 'block';
|
37 |
+
this.node.style.left = '';
|
38 |
+
this.node.style.top = '';
|
39 |
+
this.node.style.bottom = '';
|
40 |
+
this.node.style.right = '';
|
41 |
+
|
42 |
+
// Remove the positional classes from tip
|
43 |
+
this.node
|
44 |
+
.querySelector('.sholo-popover-tip')
|
45 |
+
.className = 'sholo-popover-tip';
|
46 |
+
}
|
47 |
+
|
48 |
+
show(position) {
|
49 |
+
this.reset();
|
50 |
+
|
51 |
+
const popoverTip = this.node.querySelector('.sholo-popover-tip');
|
52 |
+
|
53 |
+
const pageHeight = this.getFullPageSize().height;
|
54 |
+
const popoverHeight = this.getHeight();
|
55 |
+
const popoverMargin = this.options.padding + 10;
|
56 |
+
|
57 |
+
this.node.style.left = `${position.left - this.options.padding}px`;
|
58 |
+
|
59 |
+
// Calculate different dimensions after attaching popover
|
60 |
+
const pageHeightAfterPopOver = position.bottom + popoverHeight + popoverMargin;
|
61 |
+
|
62 |
+
// If adding popover would go out of the window height, then show it to the top
|
63 |
+
if (pageHeightAfterPopOver >= pageHeight) {
|
64 |
+
this.node.style.top = `${position.top - popoverHeight - popoverMargin}px`;
|
65 |
+
popoverTip.classList.add('bottom');
|
66 |
+
} else {
|
67 |
+
this.node.style.top = `${position.bottom + popoverMargin}px`;
|
68 |
+
popoverTip.classList.add('top');
|
69 |
+
}
|
70 |
+
}
|
71 |
+
}
|
assets/scripts/src/sholo.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
import Overlay from './overlay';
|
2 |
import Element from './element';
|
3 |
import './polyfill';
|
|
|
4 |
|
5 |
/**
|
6 |
* Plugin class that drives the plugin
|
@@ -172,7 +173,11 @@ export default class Sholo {
|
|
172 |
return;
|
173 |
}
|
174 |
|
175 |
-
|
|
|
|
|
|
|
|
|
176 |
|
177 |
this.steps.push(element);
|
178 |
});
|
@@ -199,7 +204,9 @@ export default class Sholo {
|
|
199 |
return;
|
200 |
}
|
201 |
|
202 |
-
|
|
|
|
|
203 |
this.overlay.highlight(element);
|
204 |
}
|
205 |
}
|
|
|
1 |
import Overlay from './overlay';
|
2 |
import Element from './element';
|
3 |
import './polyfill';
|
4 |
+
import Popover from './popover';
|
5 |
|
6 |
/**
|
7 |
* Plugin class that drives the plugin
|
|
|
173 |
return;
|
174 |
}
|
175 |
|
176 |
+
// @todo pass the options such as position, button text etc
|
177 |
+
const popover = new Popover({
|
178 |
+
padding: this.options.padding,
|
179 |
+
}, this.window, this.document);
|
180 |
+
const element = new Element(domElement, elementOptions, popover, this.overlay, this.window, this.document);
|
181 |
|
182 |
this.steps.push(element);
|
183 |
});
|
|
|
204 |
return;
|
205 |
}
|
206 |
|
207 |
+
// @todo add options such as position, button texts, additional classes etc
|
208 |
+
const popover = new Popover({}, this.window, this.document);
|
209 |
+
const element = new Element(domElement, this.options, popover, this.overlay, this.window, this.document);
|
210 |
this.overlay.highlight(element);
|
211 |
}
|
212 |
}
|