visibilityHandlerStore.js (2355B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 /** 8 * Redux store object wrapper to temporarily disable the store update notifications 9 * while the panel is hidden. The Redux actions are still dispatched and the reducers 10 * will be updating, but the changes are not communicated to connected components. 11 * i.e. redux's `connect` method won't be calling `mapStateToProps` function of all connected components. 12 */ 13 function visibilityHandlerStore(store) { 14 return { 15 /** 16 * Override to pause calling `listener` function while the panel is hidden. 17 * The function will be called once when the panel is shown. 18 * 19 * @param {Function} listener 20 * @param {object} options 21 * @param {boolean} options.ignoreVisibility 22 * If true, bypass this helper to listen to all store updates, 23 * regarless of panel visibility. This is useful for tests. 24 */ 25 subscribe(listener, { ignoreVisibility = false } = {}) { 26 // Test may pass a custom flag to ignore the visibility handler and listener 27 // to all state changes regarless of panel's visibility. 28 if (ignoreVisibility) { 29 return store.subscribe(listener); 30 } 31 32 function onVisibilityChange() { 33 if (document.visibilityState == "visible") { 34 // Force an update to resume updates when the panel becomes visible again 35 listener(); 36 } 37 } 38 document.addEventListener("visibilitychange", onVisibilityChange); 39 const unsubscribe = store.subscribe(function () { 40 // This is the key operation of this class, to prevent notification 41 // when the panel is hidden. 42 if (document.visibilityState == "visible") { 43 listener(); 44 } 45 }); 46 47 // Calling `subscribe` should return an unsubscribe function 48 return function () { 49 unsubscribe(); 50 document.removeEventListener("visibilitychange", onVisibilityChange); 51 }; 52 }, 53 54 // Provide expected default store functions 55 getState() { 56 return store.getState(); 57 }, 58 dispatch(action) { 59 return store.dispatch(action); 60 }, 61 }; 62 } 63 64 exports.visibilityHandlerStore = visibilityHandlerStore;