focusManager.mjs 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import { Subscribable } from './subscribable.mjs';
  2. import { isServer } from './utils.mjs';
  3. class FocusManager extends Subscribable {
  4. constructor() {
  5. super();
  6. this.setup = onFocus => {
  7. // addEventListener does not exist in React Native, but window does
  8. // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
  9. if (!isServer && window.addEventListener) {
  10. const listener = () => onFocus(); // Listen to visibillitychange and focus
  11. window.addEventListener('visibilitychange', listener, false);
  12. window.addEventListener('focus', listener, false);
  13. return () => {
  14. // Be sure to unsubscribe if a new handler is set
  15. window.removeEventListener('visibilitychange', listener);
  16. window.removeEventListener('focus', listener);
  17. };
  18. }
  19. return;
  20. };
  21. }
  22. onSubscribe() {
  23. if (!this.cleanup) {
  24. this.setEventListener(this.setup);
  25. }
  26. }
  27. onUnsubscribe() {
  28. if (!this.hasListeners()) {
  29. var _this$cleanup;
  30. (_this$cleanup = this.cleanup) == null ? void 0 : _this$cleanup.call(this);
  31. this.cleanup = undefined;
  32. }
  33. }
  34. setEventListener(setup) {
  35. var _this$cleanup2;
  36. this.setup = setup;
  37. (_this$cleanup2 = this.cleanup) == null ? void 0 : _this$cleanup2.call(this);
  38. this.cleanup = setup(focused => {
  39. if (typeof focused === 'boolean') {
  40. this.setFocused(focused);
  41. } else {
  42. this.onFocus();
  43. }
  44. });
  45. }
  46. setFocused(focused) {
  47. const changed = this.focused !== focused;
  48. if (changed) {
  49. this.focused = focused;
  50. this.onFocus();
  51. }
  52. }
  53. onFocus() {
  54. this.listeners.forEach(({
  55. listener
  56. }) => {
  57. listener();
  58. });
  59. }
  60. isFocused() {
  61. if (typeof this.focused === 'boolean') {
  62. return this.focused;
  63. } // document global can be unavailable in react native
  64. if (typeof document === 'undefined') {
  65. return true;
  66. }
  67. return [undefined, 'visible', 'prerender'].includes(document.visibilityState);
  68. }
  69. }
  70. const focusManager = new FocusManager();
  71. export { FocusManager, focusManager };
  72. //# sourceMappingURL=focusManager.mjs.map