diff options
Diffstat (limited to 'app/assets/javascripts/smart_interval.js')
-rw-r--r-- | app/assets/javascripts/smart_interval.js | 253 |
1 files changed, 126 insertions, 127 deletions
diff --git a/app/assets/javascripts/smart_interval.js b/app/assets/javascripts/smart_interval.js index d1bdc353be2..2bf7a3a5d61 100644 --- a/app/assets/javascripts/smart_interval.js +++ b/app/assets/javascripts/smart_interval.js @@ -1,158 +1,157 @@ -/* -* Instances of SmartInterval extend the functionality of `setInterval`, make it configurable -* and controllable by a public API. -* -* */ - -(() => { - class SmartInterval { - /** - * @param { function } opts.callback Function to be called on each iteration (required) - * @param { milliseconds } opts.startingInterval `currentInterval` is set to this initially - * @param { milliseconds } opts.maxInterval `currentInterval` will be incremented to this - * @param { milliseconds } opts.hiddenInterval `currentInterval` is set to this - * when the page is hidden - * @param { integer } opts.incrementByFactorOf `currentInterval` is incremented by this factor - * @param { boolean } opts.lazyStart Configure if timer is initialized on - * instantiation or lazily - * @param { boolean } opts.immediateExecution Configure if callback should - * be executed before the first interval. - */ - constructor(opts = {}) { - this.cfg = { - callback: opts.callback, - startingInterval: opts.startingInterval, - maxInterval: opts.maxInterval, - hiddenInterval: opts.hiddenInterval, - incrementByFactorOf: opts.incrementByFactorOf, - lazyStart: opts.lazyStart, - immediateExecution: opts.immediateExecution, - }; - - this.state = { - intervalId: null, - currentInterval: this.cfg.startingInterval, - pageVisibility: 'visible', - }; - - this.initInterval(); - } - /* public */ - - start() { - const cfg = this.cfg; - const state = this.state; - - if (cfg.immediateExecution) { - cfg.immediateExecution = false; - cfg.callback(); - } +/** + * Instances of SmartInterval extend the functionality of `setInterval`, make it configurable + * and controllable by a public API. + */ + +class SmartInterval { + /** + * @param { function } opts.callback Function to be called on each iteration (required) + * @param { milliseconds } opts.startingInterval `currentInterval` is set to this initially + * @param { milliseconds } opts.maxInterval `currentInterval` will be incremented to this + * @param { milliseconds } opts.hiddenInterval `currentInterval` is set to this + * when the page is hidden + * @param { integer } opts.incrementByFactorOf `currentInterval` is incremented by this factor + * @param { boolean } opts.lazyStart Configure if timer is initialized on + * instantiation or lazily + * @param { boolean } opts.immediateExecution Configure if callback should + * be executed before the first interval. + */ + constructor(opts = {}) { + this.cfg = { + callback: opts.callback, + startingInterval: opts.startingInterval, + maxInterval: opts.maxInterval, + hiddenInterval: opts.hiddenInterval, + incrementByFactorOf: opts.incrementByFactorOf, + lazyStart: opts.lazyStart, + immediateExecution: opts.immediateExecution, + }; + + this.state = { + intervalId: null, + currentInterval: this.cfg.startingInterval, + pageVisibility: 'visible', + }; + + this.initInterval(); + } - state.intervalId = window.setInterval(() => { - cfg.callback(); + /* public */ - if (this.getCurrentInterval() === cfg.maxInterval) { - return; - } + start() { + const cfg = this.cfg; + const state = this.state; - this.incrementInterval(); - this.resume(); - }, this.getCurrentInterval()); + if (cfg.immediateExecution) { + cfg.immediateExecution = false; + cfg.callback(); } - // cancel the existing timer, setting the currentInterval back to startingInterval - cancel() { - this.setCurrentInterval(this.cfg.startingInterval); - this.stopTimer(); - } + state.intervalId = window.setInterval(() => { + cfg.callback(); - onVisibilityHidden() { - if (this.cfg.hiddenInterval) { - this.setCurrentInterval(this.cfg.hiddenInterval); - this.resume(); - } else { - this.cancel(); + if (this.getCurrentInterval() === cfg.maxInterval) { + return; } - } - // start a timer, using the existing interval - resume() { - this.stopTimer(); // stop exsiting timer, in case timer was not previously stopped - this.start(); - } + this.incrementInterval(); + this.resume(); + }, this.getCurrentInterval()); + } - onVisibilityVisible() { - this.cancel(); - this.start(); - } + // cancel the existing timer, setting the currentInterval back to startingInterval + cancel() { + this.setCurrentInterval(this.cfg.startingInterval); + this.stopTimer(); + } - destroy() { + onVisibilityHidden() { + if (this.cfg.hiddenInterval) { + this.setCurrentInterval(this.cfg.hiddenInterval); + this.resume(); + } else { this.cancel(); - document.removeEventListener('visibilitychange', this.handleVisibilityChange); - $(document).off('visibilitychange').off('beforeunload'); } + } - /* private */ + // start a timer, using the existing interval + resume() { + this.stopTimer(); // stop exsiting timer, in case timer was not previously stopped + this.start(); + } - initInterval() { - const cfg = this.cfg; + onVisibilityVisible() { + this.cancel(); + this.start(); + } - if (!cfg.lazyStart) { - this.start(); - } + destroy() { + this.cancel(); + document.removeEventListener('visibilitychange', this.handleVisibilityChange); + $(document).off('visibilitychange').off('beforeunload'); + } - this.initVisibilityChangeHandling(); - this.initPageUnloadHandling(); - } + /* private */ - initVisibilityChangeHandling() { - // cancel interval when tab no longer shown (prevents cached pages from polling) - document.addEventListener('visibilitychange', this.handleVisibilityChange.bind(this)); - } + initInterval() { + const cfg = this.cfg; - initPageUnloadHandling() { - // TODO: Consider refactoring in light of turbolinks removal. - // prevent interval continuing after page change, when kept in cache by Turbolinks - $(document).on('beforeunload', () => this.cancel()); + if (!cfg.lazyStart) { + this.start(); } - handleVisibilityChange(e) { - this.state.pageVisibility = e.target.visibilityState; - const intervalAction = this.isPageVisible() ? - this.onVisibilityVisible : - this.onVisibilityHidden; + this.initVisibilityChangeHandling(); + this.initPageUnloadHandling(); + } - intervalAction.apply(this); - } + initVisibilityChangeHandling() { + // cancel interval when tab no longer shown (prevents cached pages from polling) + document.addEventListener('visibilitychange', this.handleVisibilityChange.bind(this)); + } - getCurrentInterval() { - return this.state.currentInterval; - } + initPageUnloadHandling() { + // TODO: Consider refactoring in light of turbolinks removal. + // prevent interval continuing after page change, when kept in cache by Turbolinks + $(document).on('beforeunload', () => this.cancel()); + } - setCurrentInterval(newInterval) { - this.state.currentInterval = newInterval; - } + handleVisibilityChange(e) { + this.state.pageVisibility = e.target.visibilityState; + const intervalAction = this.isPageVisible() ? + this.onVisibilityVisible : + this.onVisibilityHidden; - incrementInterval() { - const cfg = this.cfg; - const currentInterval = this.getCurrentInterval(); - if (cfg.hiddenInterval && !this.isPageVisible()) return; - let nextInterval = currentInterval * cfg.incrementByFactorOf; + intervalAction.apply(this); + } - if (nextInterval > cfg.maxInterval) { - nextInterval = cfg.maxInterval; - } + getCurrentInterval() { + return this.state.currentInterval; + } + + setCurrentInterval(newInterval) { + this.state.currentInterval = newInterval; + } + + incrementInterval() { + const cfg = this.cfg; + const currentInterval = this.getCurrentInterval(); + if (cfg.hiddenInterval && !this.isPageVisible()) return; + let nextInterval = currentInterval * cfg.incrementByFactorOf; - this.setCurrentInterval(nextInterval); + if (nextInterval > cfg.maxInterval) { + nextInterval = cfg.maxInterval; } - isPageVisible() { return this.state.pageVisibility === 'visible'; } + this.setCurrentInterval(nextInterval); + } - stopTimer() { - const state = this.state; + isPageVisible() { return this.state.pageVisibility === 'visible'; } - state.intervalId = window.clearInterval(state.intervalId); - } + stopTimer() { + const state = this.state; + + state.intervalId = window.clearInterval(state.intervalId); } - gl.SmartInterval = SmartInterval; -})(window.gl || (window.gl = {})); +} + +window.gl.SmartInterval = SmartInterval; |