Blog
captureDOM function in snapDOM codebase - part 2

captureDOM function in snapDOM codebase - part 2

In this article, we review captureDOM function in snapDOM codebase. This review is split into 2 parts. We will look at:

  1. embedCustomFonts

  2. collectUsedTagNames

  3. generateDedupedBaseCSS

embedCustomFonts

You will find the following code in modules/fonts.js

/**
 * Embeds custom fonts found in the document as data URLs in CSS.
 *
 * @export
 * @param {Object} options
 * @param {boolean} [options.preCached=false] - Whether to use pre-cached resources
 * @returns {Promise<string>} The inlined CSS for custom fonts
 */

export async function embedCustomFonts({preCached = false } = {}) {
 ...
}

collectUsedTagNames

You will find the following code in utils/cssTools.js

/**
 * Collects all unique tag names used in the DOM tree rooted at the given node.
 *
 * @param {Node} root - The root node to search
 * @returns {string[]} Array of unique tag names
 */
export function collectUsedTagNames(root) {
  const tagSet = new Set();
  if (root.nodeType !== Node.ELEMENT_NODE && root.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) {
    return [];
  }
  if (root.tagName) {
    tagSet.add(root.tagName.toLowerCase());
  }
  if (typeof root.querySelectorAll === 'function') {
    root.querySelectorAll("*").forEach(el => tagSet.add(el.tagName.toLowerCase()));
  }
  return Array.from(tagSet);
}

generateDedupedBaseCSS

You will find the following code in utils/cssTools.js.

/**
 * Generates deduplicated base CSS for the given tag names.
 *
 * @param {string[]} usedTagNames - Array of tag names
 * @returns {string} CSS string
 */
export function generateDedupedBaseCSS(usedTagNames) {
  const groups = new Map();

  for (let tagName of usedTagNames) {
    const styles = cache.defaultStyle.get(tagName);
    if (!styles) continue;

    // Creamos la "firma" del bloque CSS para comparar
    const key = Object.entries(styles)
      .map(([k, v]) => `${k}:${v};`)
      .sort()
      .join('');

    // Agrupamos por firma
    if (!groups.has(key)) {
      groups.set(key, []);
    }
    groups.get(key).push(tagName);
  }

  // Ahora generamos el CSS optimizado
  let css = '';
  for (let [styleBlock, tagList] of groups.entries()) {
    css += `${tagList.join(',')} { ${styleBlock} }\n`;
  }

  return css;
}

About me:

Hey, my name is Ramu Narasinga. I study codebase architecture in large open-source projects.

Email: ramu.narasinga@gmail.com

Want to learn from open-source? Solve challenges inspired by open-source projects.

References:

  1. https://github.com/zumerlab/snapdom/blob/main/src/core/capture.js#L28

  2. https://github.com/zumerlab/snapdom/blob/main/src/modules/fonts.js#L94

  3. https://github.com/zumerlab/snapdom/blob/main/src/utils/cssTools.js#L107

  4. https://github.com/zumerlab/snapdom/blob/main/src/utils/cssTools.js#L127