UNPKG

marbles

Version:

Front-end framework for routing, http, and data handling

124 lines (112 loc) 3.06 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /* @flow weak */ /** * @memberof Marbles * @mixin * @desc Manages a state object. You must define `state` {Object} and `__changeListeners` {Array} on the object this is mixed into. */ var State = { /** * @method * @param {function} handler Function to call when the state object changes */ addChangeListener: function addChangeListener(handler) { this.__changeListeners.push(handler); }, /** * @method * @param {function} handler * @desc Prevents handler from being called for future changes */ removeChangeListener: function removeChangeListener(handler) { this.__changeListeners = this.__changeListeners.filter(function (fn) { return fn !== handler; }); }, /** * @method * @param {function} changeFn * @desc Calls `willChange`, the passed in function, `handleChange`, then `didChange` */ withChange: function withChange(changeFn) { this.willChange(); changeFn.call(this); this.handleChange(); this.didChange(); }, /** * @method * @param {Object} newState * @desc Copies properties of newState to the existing state object */ setState: function setState(newState) { this.withChange(function () { var state = this.state; Object.keys(newState).forEach(function (key) { state[key] = newState[key]; }); }); }, /** * @method * @param {Object} newState * @param {Number} maxTimeout * @desc Same as setState, but waits up to 10ms for more changes to occur before calling change listeners */ setStateWithDelay: function setStateWithDelay(newState, maxTimeout) { this.willChange(); var state = this.state; Object.keys(newState).forEach(function (key) { state[key] = newState[key]; }); this.handleChangeWithDelay(maxTimeout); }, handleChangeWithDelay: function handleChangeWithDelay(maxTimeout) { maxTimeout = maxTimeout || 10; clearTimeout(this.__handleChangeTimeout); this.__handleChangeTimeout = setTimeout((function () { this.handleChangeDelayed(); }).bind(this), 2); if (!this.__handleChangeMaxTimeout) { this.__handleChangeMaxTimeout = setTimeout((function () { this.handleChangeDelayed(); }).bind(this), maxTimeout); } }, handleChangeDelayed: function handleChangeDelayed() { clearTimeout(this.__handleChangeMaxTimeout); clearTimeout(this.__handleChangeTimeout); this.handleChange(); this.didChange(); }, /** * @method * @param {Object} newState * @desc Replaces the existing state object with newState */ replaceState: function replaceState(newState) { this.withChange(function () { this.state = newState; }); }, handleChange: function handleChange() { this.__changeListeners.forEach(function (handler) { handler(); }); }, /** * @method * @desc Called before state object is mutated */ willChange: function willChange() {}, /** * @method * @desc Called after state object is mutated */ didChange: function didChange() {} }; exports["default"] = State; module.exports = exports["default"];