All files / lib release.js

100% Statements 57/57
100% Branches 14/14
100% Functions 1/1
100% Lines 57/57

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 582x 2x 2x 2x 2x 2x 2x 2x 2x 981x 981x 981x 338x 338x 338x 338x 338x 338x 338x 338x 10x 10x 10x 338x 338x 338x 981x 981x 981x 981x 18x 18x 963x 963x 963x 963x 981x 411x 520x 520x 411x 963x 963x 963x 981x 1x 1x 981x 981x 981x 981x 1390x 522x 522x 522x 981x 981x  
import { unprotectVTree } from './util/memory';
import { StateCache, NodeCache, ReleaseHookCache, Mount } from './util/types';
 
/**
 * Releases state and memory associated to a DOM Node.
 *
 * @param {Mount} mount - Valid input node
 */
export default function release(mount) {
  // If this was a top-level rendered element, deallocate the VTree and remove
  // the StateCache reference.
  if (StateCache.has(mount)) {
    const { mutationObserver, oldTree } = StateCache.get(mount);
 
    // Ensure the mutation observer is cleaned up.
    mutationObserver && mutationObserver.disconnect();
 
    // If there is a known root association that is not in the NodeCache,
    // remove this VTree.
    if (oldTree && !NodeCache.has(oldTree)) {
      ReleaseHookCache.forEach(fn => fn(oldTree));
      unprotectVTree(oldTree);
    }
 
    StateCache.delete(mount);
  }
 
  // The rest of this function only pertains to real HTML element nodes. If
  // this is undefined, then it isn't one.
  if (!mount) {
    return;
  }
 
  const asHTMLElement = /** @type {HTMLElement} */(mount);
 
  // Crawl the childNodes if this is an HTMLElement for state trees.
  if (asHTMLElement.childNodes && asHTMLElement.childNodes.length) {
    for (let i = 0; i < asHTMLElement.childNodes.length; i++) {
      release(asHTMLElement.childNodes[i]);
    }
  }
 
  // If there is a shadowRoot attached to the DOM node, attempt to release this
  // as well.
  if (asHTMLElement.shadowRoot) {
    release(asHTMLElement.shadowRoot);
  }
 
  // Do a thorough check within the NodeCache to fully deallocate all
  // references to the associated trees.
  NodeCache.forEach((domNode, vTree) => {
    if (domNode === asHTMLElement) {
      ReleaseHookCache.forEach(fn => fn(vTree));
      unprotectVTree(vTree);
    }
  });
}