This solution is generated by ChatGPT, correctness is not guaranteed.

AI solution for JavaScript Coding Question on BFE.dev
113. Virtual DOM I

Solution:

To solve this problem, we can define two functions virtualize and render. virtualize function will take a real DOM tree and return an object literal that represents the same tree structure. The render function will take this object literal presentation and recreate a DOM tree.

function virtualize(node) {
  // Base case: if node is TextNode
  if (node.nodeType === Node.TEXT_NODE) {
    return node.textContent;
  }

  // Otherwise, create object for element node
  const obj = {
    type: node.nodeName.toLowerCase(),
    props: {},
    children: [],
  };

  // Add properties
  for (const prop of node.attributes) {
    obj.props[prop.name] = prop.value;
  }

  // Add children
  for (const child of node.childNodes) {
    obj.children.push(virtualize(child));
  }

  return obj;
}

function render(obj) {
  // Base case: if obj is TextNode
  if (typeof obj === "string") {
    return document.createTextNode(obj);
  }

  // Create element node
  const node = document.createElement(obj.type);

  // Set properties
  for (const prop in obj.props) {
    node.setAttribute(prop, obj.props[prop]);
  }

  // Add children
  for (const child of obj.children) {
    node.appendChild(render(child));
  }

  return node;
}

Let's test our solution:

// Create real DOM tree
const root = document.createElement("div");
root.innerHTML = `
  <h1> this is </h1>
  <p class="paragraph">a <button>button</button> from <a href="https://bfe.dev"><b>BFE</b>.dev</a></p>
`;

// Virtualize DOM tree
const obj = virtualize(root);

console.log(obj);
/*
{
  type: 'div',
  props: {},
  children: [
    {
      type: 'h1',
      props: {},
      children: [' this is ']
    },
    {
      type: 'p',
      props: { class: 'paragraph' },
      children: [
        'a ',
        {
          type: 'button',
          props: {},
          children: ['button']
        },
        ' from ',
        {
          type: 'a',
          props: { href: 'https://bfe.dev' },
          children: [{ type: 'b', props: {}, children: ['BFE'] }, '.dev']
        }
      ]
    }
  ]
}
*/

// Render object literal as DOM tree
const newRoot = render(obj);

console.log(newRoot.outerHTML);
/*
<div>
  <h1> this is </h1>
  <p class="paragraph">a <button>button</button> from <a href="https://bfe.dev"><b>BFE</b>.dev</a></p>
</div>
*/

As we can see from the console output, the virtualized object and the rendered DOM tree are the same as the original. Therefore, our solution works as expected.