# All files / helpers fid-changed.ts

95.24% Statements 40/42
83.33% Branches 15/18
100% Functions 8/8
95.12% Lines 39/41

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111

    17x

    17x

    17x
    96x

    96x
    96x

    17x

    7x

    7x

    7x
    7x
    2x
    2x

    7x

    17x

    3x

    3x

    3x

    3x
    3x

    3x

    148x
    148x
    105x

    166x
    166x

    96x
    96x
    96x

    96x

    17x

    103x
    92x
    92x
    52x

    103x

    99x
    91x
    91x

     /**
     * @license
     * Copyright 2019 Google LLC
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */

    import { getKey } from '../util/get-key';
    import { AppConfig } from '../interfaces/app-config';
    import { IdChangeCallbackFn } from '../functions';

    const fidChangeCallbacks: Map<string, Set<IdChangeCallbackFn>> = new Map();

    /**
     * Calls the onIdChange callbacks with the new FID value, and broadcasts the
     * change to other tabs.
     */
    export function fidChanged(appConfig: AppConfig, fid: string): void {
      const key = getKey(appConfig);

      callFidChangeCallbacks(key, fid);
      broadcastFidChange(key, fid);
    }

    export function addCallback(
      appConfig: AppConfig,
      callback: IdChangeCallbackFn
    ): void {
      // Open the broadcast channel if it's not already open,
      // to be able to listen to change events from other tabs.
      getBroadcastChannel();

      const key = getKey(appConfig);

      let callbackSet = fidChangeCallbacks.get(key);
      if (!callbackSet) {
        callbackSet = new Set();
        fidChangeCallbacks.set(key, callbackSet);
      }
      callbackSet.add(callback);
    }

    export function removeCallback(
      appConfig: AppConfig,
      callback: IdChangeCallbackFn
    ): void {
      const key = getKey(appConfig);

      const callbackSet = fidChangeCallbacks.get(key);

      Iif (!callbackSet) {
        return;
      }

      callbackSet.delete(callback);
      Iif (callbackSet.size === 0) {
        fidChangeCallbacks.delete(key);
      }

      // Close broadcast channel if there are no more callbacks.
      closeBroadcastChannel();
    }

    function callFidChangeCallbacks(key: string, fid: string): void {
      const callbacks = fidChangeCallbacks.get(key);
      if (!callbacks) {
        return;
      }

      for (const callback of callbacks) {
        callback(fid);
      }
    }

    function broadcastFidChange(key: string, fid: string): void {
      const channel = getBroadcastChannel();
      Eif (channel) {
        channel.postMessage({ key, fid });
      }
      closeBroadcastChannel();
    }

    let broadcastChannel: BroadcastChannel | null = null;
    /** Opens and returns a BroadcastChannel if it is supported by the browser. */
    function getBroadcastChannel(): BroadcastChannel | null {
      if (!broadcastChannel && 'BroadcastChannel' in self) {
        broadcastChannel = new BroadcastChannel('[Firebase] FID Change');
        broadcastChannel.onmessage = e => {
          callFidChangeCallbacks(e.data.key, e.data.fid);
        };
      }
      return broadcastChannel;
    }

    function closeBroadcastChannel(): void {
      if (fidChangeCallbacks.size === 0 && broadcastChannel) {
        broadcastChannel.close();
        broadcastChannel = null;
      }
    }