widetext for any row marker

by Henry

HTML

<div>content</div>

<div>
  <span>content</span>
</div>

<div>
  <tspan>
    content <span>test</span>
  </tspan>
  <span>
    content2
  </span>
</div>

<!-- 

want to leave

  div > [content]

as is, and turn

  div > * > [content]
  
into

  div > text > [content]
      
-->

CSS

div,
text,
span {
  outline: 1px solid blue;
  padding: 10px;
  margin: 10px;
}

text,
span {
  display: block;
}

span {
  outline: 1px solid green
}

text {
  outline: 1px solid red
}

JavaScript

function change() {
  
  var wtElems = document.querySelectorAll("div");
  
  for (var i = 0; i < wtElems.length; ++i) {
  
    var wtElem = wtElems[i],
      rows = wtElem.children.length,
      textElem = document.createElementNS("http://www.w3.org/2000/svg", "text"),
      svgElem = document.createElementNS("http://www.w3.org/2000/svg", "svg");
      
    if (rows > 0) {
      for (var j = 0; j < rows; ++j) {
        var row = wtElem.children[j];
        var newRow = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
        if (row.tagName !== "TSPAN") { // don't rewrite nodes if it's already they way we want it
          newRow.innerHTML = row.innerHTML;
          wtElem.replaceChild(newRow, row);
        }
      }
    }
    
    while (wtElem.firstChild)
      textElem.appendChild(wtElem.firstChild);
    svgElem.appendChild(textElem);
    wtElem.appendChild(svgElem);
  }
};

change();

/*

<div><svg><text>content</text></svg></div>

<div><svg><text>
  <tspan>content</tspan>
</text></svg></div>

<div><svg><text>
  <tspan>
    content <span>test</span>
  </tspan>
  <tspan>
    content2
  </tspan>
</text></svg></div>

*/