How to update DOM after Maquette modifies it

300 Views Asked by At

As mentioned previously, I want to use Maquette as a basic hyperscript language. Consequently, I don't want to use the maquette.projector. However, despite being able to append SVG objects made with Maquette to the DOM, the DOM does not seem to be updating. For example, in the code below, I expect to be able to click a button to create a circle. If I inspect the DOM by using Chrome Dev tools, I can the the SVG circle object was added to the DOM, but the DOM hasn't been updated. How I am supposed to update the DOM?

var h = maquette.h;
var dom = maquette.dom;
var svg;
var svgNode;
var root;
var rootDiv;

function addCircle(evt) {
  console.log("adding circle");
  const c = h('g', [
              h('circle#cool.sweet', {cx: '100', cy: '100', r: '100', fill: 'red'}),
            ]);
  const g = dom.create(c).domNode;
  svgNode.appendChild(g);
}

document.addEventListener('DOMContentLoaded', function () {
  svg = h('svg', {styles: {height: "200px", width: "200px"}})
  rootDiv = h('div.sweet', [
    svg,
  ]);
  root = dom.create(rootDiv).domNode;
  document.body.appendChild(root);
  svgNode = root.querySelector("svg");
  
  const button = h('button', {
    onclick: addCircle,
  }, ["Add circle"]);
  
  const buttonNode = dom.create(button).domNode;
  root.appendChild(buttonNode);
});
<script src="//cdnjs.cloudflare.com/ajax/libs/maquette/2.4.1/maquette.min.js"></script>

Why is appendChild not rendering anything?

1

There are 1 best solutions below

0
On BEST ANSWER

This was a tough one. The reason the circle does not appear on the screen (although it is added to the DOM) has to do with XML-namespaces.

SVG Elements and descendents thereof should get the SVG XML namespace. When you use maquette to render nodes that start in HTML with embedded SVG, you do not have to worry about this.

But now you start inside an SVG by creating a <g> node. Maquette assumes that you need a 'nonstandard' HTML <g> Node, because it does not know you were inside an SVG.

This is why maquette provides a second argument to its DOM.create method which you can use as follows to fix your problem:

const g = dom.create(c, {namespace: 'http://www.w3.org/2000/svg'}).domNode;