Safari fails to replace SVG element with: NoModificationAllowedError: The object can not be modified

283 Views Asked by At

I would like to replace all my SVG’s <rect> elements with foreignObject which does work fine FireFox and Chromium-based Browser but fails in Safari.

MWE:

HTML/SVG

<!DOCTYPE html>
<html lang="en">
  <body>
    <svg>
      <rect id="rect1" width="100" height="100" />
    </svg>
  </body>
</html>

JavaScript

let myRect = document.getElementById("rect1")
myRect.outerHTML = myRect.outerHTML.replace("<rect", "<foreignObject").replace("</rect>", "</foreignObject>")

Safari fails with: NoModificationAllowedError: The object can not be modified.

I know the issue is due to outerHTML is on the HTML namespace while SVG is on XML, yet is there a way to make this work in SVG?

Thanks for any insight into this issue.

1

There are 1 best solutions below

1
On BEST ANSWER

Replacing strings is very error prone

Replace the element .. after copying attributes

<svg id=SVG>
  <rect id="rect1" width="100" height="100" />
  <g>    
    <rect id="rect2" width="100" height="100" />
  </g>
</svg>

<script>
  let svg = SVG;
  svg.querySelectorAll("rect").forEach(rect => {
    let obj = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject");
    [...rect.attributes].map(  ({name,value}) => obj.setAttribute(name, value)  );
    rect.replaceWith(obj);
  });
  console.log(SVG.outerHTML);
</script>

PS unreadable rect.parentNode.replaceChild(obj, rect); for IE11