kamrify commited on
Commit
a174130
·
1 Parent(s): c7fb12b

Refactor and animation fixes

Browse files
demo/styles/demo.scss CHANGED
@@ -14,10 +14,10 @@ img.emoji {
14
  background: white;
15
  padding: 10px 30px;
16
  border-radius: 5px;
17
- color: #333333;
18
 
19
  a, a:visited, a:focus {
20
- color: #333333;
21
  text-decoration: underline;
22
  }
23
 
 
14
  background: white;
15
  padding: 10px 30px;
16
  border-radius: 5px;
17
+ color: #1f1f1f;
18
 
19
  a, a:visited, a:focus {
20
+ color: #1f1f1f;
21
  text-decoration: underline;
22
  }
23
 
src/core/element.js CHANGED
@@ -11,17 +11,27 @@ export default class Element {
11
  * @param {Node|HTMLElement} node
12
  * @param {Object} options
13
  * @param {Popover} popover
 
14
  * @param {Overlay} overlay
15
  * @param {Window} window
16
  * @param {Document} document
17
  */
18
- constructor(node, options, popover, overlay, window, document) {
 
 
 
 
 
 
 
 
19
  this.node = node;
20
  this.document = document;
21
  this.window = window;
22
  this.options = options;
23
  this.overlay = overlay;
24
  this.popover = popover;
 
25
 
26
  this.animationTimeout = null;
27
 
@@ -139,9 +149,13 @@ export default class Element {
139
  * Is called when element is about to be deselected
140
  * i.e. when moving the focus to next element of closing
141
  */
142
- onDeselected() {
143
  this.hidePopover();
144
 
 
 
 
 
145
  this.node.classList.remove(CLASS_DRIVER_HIGHLIGHTED_ELEMENT);
146
 
147
  // If there was any animation in progress, cancel that
@@ -154,6 +168,19 @@ export default class Element {
154
  }
155
  }
156
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  /**
158
  * Is called when the element is about to be highlighted
159
  * i.e. either if overlay has started moving the highlight towards
@@ -174,29 +201,21 @@ export default class Element {
174
  */
175
  onHighlighted() {
176
  this.showPopover();
 
177
 
178
  this.node.classList.add(CLASS_DRIVER_HIGHLIGHTED_ELEMENT);
179
 
180
  this.highlightFinished = true;
181
 
182
  const highlightedElement = this;
183
- const highlightedNode = this.node;
184
 
185
- const lastHighlightedElement = this.overlay.getLastHighlightedElement();
186
- const lastHighlightedNode = lastHighlightedElement && lastHighlightedElement.node;
187
-
188
- // If this element is not already highlighted (because this call could
189
- // be from the resize or scroll) and is not in view
190
- if (highlightedNode !== lastHighlightedNode) {
191
- const popoverElement = this.popover;
192
-
193
- if (popoverElement && !popoverElement.isInView()) {
194
- popoverElement.bringInView();
195
- }
196
 
197
- if (!highlightedElement.isInView()) {
198
- highlightedElement.bringInView();
199
- }
200
  }
201
 
202
  if (this.options.onHighlighted) {
@@ -204,6 +223,13 @@ export default class Element {
204
  }
205
  }
206
 
 
 
 
 
 
 
 
207
  /**
208
  * Gets the DOM Element behind this element
209
  * @returns {Node|HTMLElement|*}
@@ -212,6 +238,10 @@ export default class Element {
212
  return this.node;
213
  }
214
 
 
 
 
 
215
  hidePopover() {
216
  if (!this.popover) {
217
  return;
 
11
  * @param {Node|HTMLElement} node
12
  * @param {Object} options
13
  * @param {Popover} popover
14
+ * @param {Stage} stage
15
  * @param {Overlay} overlay
16
  * @param {Window} window
17
  * @param {Document} document
18
  */
19
+ constructor({
20
+ node,
21
+ options,
22
+ popover,
23
+ stage,
24
+ overlay,
25
+ window,
26
+ document,
27
+ } = {}) {
28
  this.node = node;
29
  this.document = document;
30
  this.window = window;
31
  this.options = options;
32
  this.overlay = overlay;
33
  this.popover = popover;
34
+ this.stage = stage;
35
 
36
  this.animationTimeout = null;
37
 
 
149
  * Is called when element is about to be deselected
150
  * i.e. when moving the focus to next element of closing
151
  */
152
+ onDeselected(hideStage = false) {
153
  this.hidePopover();
154
 
155
+ if (hideStage) {
156
+ this.hideStage();
157
+ }
158
+
159
  this.node.classList.remove(CLASS_DRIVER_HIGHLIGHTED_ELEMENT);
160
 
161
  // If there was any animation in progress, cancel that
 
168
  }
169
  }
170
 
171
+ /**
172
+ * Checks if the given element is same as the current element
173
+ * @param {Element} element
174
+ * @returns {boolean}
175
+ */
176
+ isSame(element) {
177
+ if (!element || !element.node) {
178
+ return false;
179
+ }
180
+
181
+ return element.node === this.node;
182
+ }
183
+
184
  /**
185
  * Is called when the element is about to be highlighted
186
  * i.e. either if overlay has started moving the highlight towards
 
201
  */
202
  onHighlighted() {
203
  this.showPopover();
204
+ this.showStage();
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
 
213
+ if (popoverElement && !popoverElement.isInView()) {
214
+ popoverElement.bringInView();
215
+ }
 
 
 
 
 
 
 
 
216
 
217
+ if (!highlightedElement.isInView()) {
218
+ highlightedElement.bringInView();
 
219
  }
220
 
221
  if (this.options.onHighlighted) {
 
223
  }
224
  }
225
 
226
+ /**
227
+ * Shows the stage behind the element
228
+ */
229
+ showStage() {
230
+ this.stage.show(this.getCalculatedPosition());
231
+ }
232
+
233
  /**
234
  * Gets the DOM Element behind this element
235
  * @returns {Node|HTMLElement|*}
 
238
  return this.node;
239
  }
240
 
241
+ hideStage() {
242
+ this.stage.hide();
243
+ }
244
+
245
  hidePopover() {
246
  if (!this.popover) {
247
  return;
src/core/overlay.js CHANGED
@@ -10,10 +10,9 @@ export default class Overlay {
10
  /**
11
  * @param {Object} options
12
  * @param {Window} window
13
- * @param {Stage} stage
14
  * @param {Document} document
15
  */
16
- constructor(options, stage, window, document) {
17
  this.options = options;
18
 
19
  this.positionToHighlight = new Position({}); // position at which layover is to be patched at
@@ -23,7 +22,6 @@ export default class Overlay {
23
 
24
  this.window = window;
25
  this.document = document;
26
- this.stage = stage;
27
 
28
  this.makeNode();
29
  }
@@ -52,6 +50,11 @@ export default class Overlay {
52
  return;
53
  }
54
 
 
 
 
 
 
55
  // There might be hide timer from last time
56
  // which might be getting triggered
57
  this.window.clearTimeout(this.hideTimer);
@@ -60,7 +63,7 @@ export default class Overlay {
60
  element.onHighlightStarted();
61
 
62
  // Old element has been deselected
63
- if (this.highlightedElement) {
64
  this.highlightedElement.onDeselected();
65
  }
66
 
@@ -76,9 +79,6 @@ export default class Overlay {
76
 
77
  this.showOverlay();
78
 
79
- // Show the stage
80
- this.stage.show(this.positionToHighlight);
81
-
82
  // Element has been highlighted
83
  this.highlightedElement.onHighlighted();
84
  }
@@ -126,14 +126,13 @@ export default class Overlay {
126
  clear() {
127
  this.positionToHighlight = new Position();
128
  if (this.highlightedElement) {
129
- this.highlightedElement.onDeselected();
130
  }
131
 
132
  this.highlightedElement = null;
133
  this.lastHighlightedElement = null;
134
 
135
  this.hideOverlay();
136
- this.stage.hide();
137
  }
138
 
139
  /**
@@ -141,12 +140,13 @@ export default class Overlay {
141
  * And moves the highlight around if necessary
142
  */
143
  refresh() {
144
- // If the highlighted element was there Cancel the
145
- // existing animation frame if any and highlight it again
146
- // as its position might have been changed
147
- if (this.highlightedElement) {
148
- this.highlight(this.highlightedElement);
149
- this.highlightedElement.onHighlighted();
150
  }
 
 
 
 
151
  }
152
  }
 
10
  /**
11
  * @param {Object} options
12
  * @param {Window} window
 
13
  * @param {Document} document
14
  */
15
+ constructor(options, window, document) {
16
  this.options = options;
17
 
18
  this.positionToHighlight = new Position({}); // position at which layover is to be patched at
 
22
 
23
  this.window = window;
24
  this.document = document;
 
25
 
26
  this.makeNode();
27
  }
 
50
  return;
51
  }
52
 
53
+ // If highlighted element is not changed from last time
54
+ if (this.highlightedElement && this.highlightedElement.isSame(this.lastHighlightedElement)) {
55
+ return;
56
+ }
57
+
58
  // There might be hide timer from last time
59
  // which might be getting triggered
60
  this.window.clearTimeout(this.hideTimer);
 
63
  element.onHighlightStarted();
64
 
65
  // Old element has been deselected
66
+ if (this.highlightedElement && !this.highlightedElement.isSame(this.lastHighlightedElement)) {
67
  this.highlightedElement.onDeselected();
68
  }
69
 
 
79
 
80
  this.showOverlay();
81
 
 
 
 
82
  // Element has been highlighted
83
  this.highlightedElement.onHighlighted();
84
  }
 
126
  clear() {
127
  this.positionToHighlight = new Position();
128
  if (this.highlightedElement) {
129
+ this.highlightedElement.onDeselected(true);
130
  }
131
 
132
  this.highlightedElement = null;
133
  this.lastHighlightedElement = null;
134
 
135
  this.hideOverlay();
 
136
  }
137
 
138
  /**
 
140
  * And moves the highlight around if necessary
141
  */
142
  refresh() {
143
+ // If no highlighted element, cancel the refresh
144
+ if (!this.highlightedElement) {
145
+ return;
 
 
 
146
  }
147
+
148
+ // Reposition the stage and show popover
149
+ this.highlightedElement.showPopover();
150
+ this.highlightedElement.showStage();
151
  }
152
  }
src/core/stage.js CHANGED
@@ -46,7 +46,7 @@ export default class Stage extends Element {
46
  /**
47
  * Makes it visible and sets the default properties
48
  */
49
- reset() {
50
  this.node.style.display = 'block';
51
  this.node.style.left = '0';
52
  this.node.style.top = '0';
@@ -55,7 +55,7 @@ export default class Stage extends Element {
55
  }
56
 
57
  show(position) {
58
- this.reset();
59
 
60
  // Make it two times the padding because, half will be given on left and half on right
61
  const requiredPadding = this.options.padding * 2;
 
46
  /**
47
  * Makes it visible and sets the default properties
48
  */
49
+ setInitialStyle() {
50
  this.node.style.display = 'block';
51
  this.node.style.left = '0';
52
  this.node.style.top = '0';
 
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
61
  const requiredPadding = this.options.padding * 2;
src/index.js CHANGED
@@ -43,8 +43,7 @@ export default class Driver {
43
  this.steps = []; // steps to be presented if any
44
  this.currentStep = 0; // index for the currently highlighted step
45
 
46
- const stage = new Stage(this.options, window, document);
47
- this.overlay = new Overlay(this.options, stage, window, document);
48
 
49
  this.onResize = this.onResize.bind(this);
50
  this.onKeyUp = this.onKeyUp.bind(this);
@@ -70,8 +69,7 @@ export default class Driver {
70
  * @param e
71
  */
72
  onClick(e) {
73
- if (!this.hasHighlightedElement() || !this.isActivated) {
74
- // Has no highlighted element so ignore the click
75
  return;
76
  }
77
 
@@ -188,7 +186,7 @@ export default class Driver {
188
  }
189
 
190
  // Refresh with animation
191
- this.overlay.refresh(true);
192
  }
193
 
194
  /**
@@ -278,7 +276,17 @@ export default class Driver {
278
  popover = new Popover(popoverOptions, this.window, this.document);
279
  }
280
 
281
- return new Element(domElement, elementOptions, popover, this.overlay, this.window, this.document);
 
 
 
 
 
 
 
 
 
 
282
  }
283
 
284
  /**
 
43
  this.steps = []; // steps to be presented if any
44
  this.currentStep = 0; // index for the currently highlighted step
45
 
46
+ this.overlay = new Overlay(this.options, window, document);
 
47
 
48
  this.onResize = this.onResize.bind(this);
49
  this.onKeyUp = this.onKeyUp.bind(this);
 
69
  * @param e
70
  */
71
  onClick(e) {
72
+ if (!this.isActivated || !this.hasHighlightedElement()) {
 
73
  return;
74
  }
75
 
 
186
  }
187
 
188
  // Refresh with animation
189
+ this.overlay.refresh();
190
  }
191
 
192
  /**
 
276
  popover = new Popover(popoverOptions, this.window, this.document);
277
  }
278
 
279
+ const stage = new Stage(this.options, this.window, this.document);
280
+
281
+ return new Element({
282
+ node: domElement,
283
+ options: elementOptions,
284
+ popover,
285
+ stage,
286
+ overlay: this.overlay,
287
+ window: this.window,
288
+ document: this.document,
289
+ });
290
  }
291
 
292
  /**