Skip to content

Commit 485163f

Browse files
committed
Improved universal reactivity to parent element changes, refactoring
1 parent 74b39ed commit 485163f

File tree

1 file changed

+51
-85
lines changed

1 file changed

+51
-85
lines changed

lib/components/popover.vue

Lines changed: 51 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@
155155
/**
156156
* Class property to be used for Popover rendering
157157
*
158-
* @return string
158+
* @return String
159159
*/
160160
popoverAlignment() {
161161
return !this.placement || this.placement === `default` ? `popover-top` : `popover-${this.placement}`;
@@ -164,75 +164,56 @@
164164
/**
165165
* Determine if the Popover should be shown.
166166
*
167-
* @return boolean
167+
* @return Boolean
168168
*/
169169
showState() {
170170
return this.show !== false && (this.triggerState || this.show);
171-
},
172-
173-
/**
174-
* Tether construct params for each show event.
175-
*
176-
* @return Object
177-
*/
178-
tetherOptions() {
179-
return {
180-
element: this._popover,
181-
target: this._trigger,
182-
offset: this.offset,
183-
constraints: this.constraints,
184-
attachment: placementParams[this.placement].attachment,
185-
targetAttachment: placementParams[this.placement].targetAttachment
186-
};
187-
},
188-
189-
/**
190-
* Determine if debounce should be used.
191-
*
192-
* @return boolean
193-
*/
194-
useDebounce() {
195-
return this.normalizedTriggers.length > 1;
196171
}
197172
},
198173
199174
watch: {
175+
/**
176+
* Refresh Tether display properties
177+
*/
200178
constraints() {
201179
this.setOptions();
202180
},
203181
204-
content() {
205-
this.refreshPosition();
206-
},
207-
182+
/**
183+
* Refresh Popover event triggers
184+
* @param {Array} newTriggers
185+
* @param {Array} oldTriggers
186+
*/
208187
normalizedTriggers(newTriggers, oldTriggers) {
209188
this.updateListeners(newTriggers, oldTriggers);
210189
},
211190
191+
/**
192+
* Refresh Tether display properties
193+
*/
212194
offset() {
213195
this.setOptions();
214196
},
215197
198+
/**
199+
* Refresh Tether display properties
200+
*/
216201
placement() {
217202
this.setOptions();
218203
},
219204
220205
/**
221206
* Affect 'show' state in response to status change
222-
* @param {Boolean} newShowState
207+
* @param {Boolean} val
223208
*/
224209
showState(val) {
225210
clearTimeout(this._timeout);
226211
let delay = this.getDelay(val);
227212
228213
if (delay)
229-
this._timeout = setTimeout(() => {this.togglePopover(val)}, delay);
214+
this._timeout = setTimeout(() => this.togglePopover(val), delay);
230215
else
231216
this.togglePopover(val);
232-
},
233-
234-
title() {
235-
this.refreshPosition();
236217
}
237218
},
238219
@@ -249,20 +230,8 @@
249230
},
250231
251232
/**
252-
* Cleanup component listeners
233+
* Tidy removal of Tether object from the DOM
253234
*/
254-
cleanup() {
255-
// Remove all event listeners
256-
// eslint-disable-next-line guard-for-in
257-
for (const trigger in this.normalizedTriggers) {
258-
this.removeListener(trigger);
259-
}
260-
261-
clearTimeout(this._timeout);
262-
this._timeout = null;
263-
this.hidePopover();
264-
},
265-
266235
destroyTether() {
267236
if (this._tether) {
268237
this._tether.destroy();
@@ -275,8 +244,8 @@
275244
* @param {Object} e
276245
*/
277246
eventHandler(e) {
278-
// If this event is right after a previous successful event, ignore it
279-
if (this.useDebounce && this.debounce > 0 && this.lastEvent !== null && e.timeStamp <= this.lastEvent + this.debounce) {
247+
// If this event is right after a previous successful event, ignore it (debounce)
248+
if (this.normalizedTriggers.length > 1 && this.debounce > 0 && this.lastEvent !== null && e.timeStamp <= this.lastEvent + this.debounce) {
280249
return;
281250
}
282251
@@ -311,13 +280,27 @@
311280
return this.delay;
312281
},
313282
283+
/**
284+
* Tether construct params for each show event.
285+
*
286+
* @return Object
287+
*/
288+
getTetherOptions() {
289+
return {
290+
element: this._popover,
291+
target: this._trigger,
292+
offset: this.offset,
293+
constraints: this.constraints,
294+
attachment: placementParams[this.placement].attachment,
295+
targetAttachment: placementParams[this.placement].targetAttachment
296+
};
297+
},
298+
314299
/**
315300
* Hide popover and fire event
316301
*/
317302
hidePopover() {
318303
this._popover.style.display = 'none';
319-
this.$root.$emit('hidden::popover');
320-
321304
this.destroyTether();
322305
},
323306
@@ -326,7 +309,7 @@
326309
*/
327310
refreshPosition() {
328311
if (this._tether) {
329-
this.$nextTick(() => { this._tether.position(); });
312+
this.$nextTick(() => {this._tether.position()});
330313
}
331314
},
332315
@@ -346,7 +329,7 @@
346329
*/
347330
setOptions() {
348331
if (this._tether) {
349-
this._tether.setOptions(this.tetherOptions);
332+
this._tether.setOptions(this.getTetherOptions());
350333
}
351334
},
352335
@@ -359,20 +342,23 @@
359342
360343
// Let tether do the magic, after element is shown
361344
this._popover.style.display = 'block';
362-
this._tether = new Tether(this.tetherOptions);
345+
this._tether = new Tether(this.getTetherOptions());
363346
364347
// Make sure the popup is rendered in the correct location
365348
this.refreshPosition();
366-
367-
this.$root.$emit('shown::popover');
368349
},
369350
351+
/**
352+
* Handle Popover show or hide instruction
353+
*/
370354
togglePopover(newShowState) {
371355
this.$emit('showChange', newShowState);
372356
if (newShowState) {
373357
this.showPopover();
358+
this.$root.$emit('shown::popover');
374359
} else {
375360
this.hidePopover();
361+
this.$root.$emit('hidden::popover');
376362
}
377363
},
378364
@@ -406,25 +392,9 @@
406392
},
407393
408394
created() {
409-
const hub = this.$root;
410-
hub.$on('hide::popover', () => {
395+
this.$root.$on('hide::popover', () => {
411396
this.triggerState = false;
412397
});
413-
414-
// Workaround to resolve issues like #151
415-
if (this.$router) {
416-
this.$router.beforeEach((to, from, next) => {
417-
next();
418-
this.cleanup();
419-
});
420-
}
421-
422-
const cleanup = () => {
423-
this.cleanup();
424-
};
425-
426-
hub.$on('hide::modal', cleanup);
427-
hub.$on('changed::tab', cleanup);
428398
},
429399
430400
mounted() {
@@ -443,18 +413,14 @@
443413
}
444414
},
445415
446-
/*
447-
beforeUpdate() {
448-
console.log('called beforeUpdate');
449-
},
450-
451416
updated() {
452-
console.log('called update');
453-
}
454-
*/
417+
this.refreshPosition();
418+
},
455419
456420
beforeDestroy() {
457-
this.cleanup();
421+
this.normalizedTriggers.forEach(item => this.removeListener(item));
422+
clearTimeout(this._timeout);
423+
this.destroyTether();
458424
}
459425
};
460426

0 commit comments

Comments
 (0)