I want to duplicate an embedded SVG in HTML, re-define it's IDs inside.
For example, there is a HTML file like
<html>
<body>
<div id="svgs">
</div>
<!-- Template -->
<div style="display:none;">
<svg xmlns="http://www.w3.org/2000/svg" width="181" height="59" id="type0svg">
<g style="display:inline" transform="translate(0,0)">
<text id="ph1" x="23.6" y="51.7">ph1</text>
<text id="ph2" x="105.1" y="51">ph2</text>
</g>
</svg>
</div>
</body>
</html>
and data [{ph1:'placeholder1',ph2:'placeholder2'},{ph1:'apple',ph2:'orange'}]
. I want to generate a DOM like ...
<html>
<body>
<div id="svgs">
<!-- {ph1:'placeholder1',ph2:'placeholder2'} -->
<svg xmlns="http://www.w3.org/2000/svg" width="181" height="59" id="type0svg1">
<g style="display:inline" transform="translate(0,0)">
<text id="ph1_1" x="23.6" y="51.7">placeholder1</text>
<text id="ph2_1" x="105.1" y="51">placeholder2</text>
</g>
</svg>
<!-- {ph1:'apple',ph2:'orange'} -->
<svg xmlns="http://www.w3.org/2000/svg" width="181" height="59" id="type0svg2">
<g style="display:inline" transform="translate(0,0)">
<text id="ph1_2" x="23.6" y="51.7">apple</text>
<text id="ph2_2" x="105.1" y="51">orange</text>
</g>
</svg>
</div>
<!-- Template -->
<div style="display:none;">
<svg xmlns="http://www.w3.org/2000/svg" width="181" height="59" id="type0svg">
<g style="display:inline" transform="translate(0,0)">
<text id="ph1" x="23.6" y="51.7">ph1</text>
<text id="ph2" x="105.1" y="51">ph2</text>
</g>
</svg>
</div>
</body>
</html>
Notice that all IDs under copied DOM has been re-defined from 'blahblah' to 'blahblah_1' and 'blahblah_2'.
How can this be done smartly using Google closure library?
Here's an approach:
Duplication of node. Use the standard DOM method Node.cloneNode(true)
to create deep clones of a node.
Redefinition of IDs. The goog.ui.Component
framework uses goog.ui.IdGenerator
extensively to generate unique IDs of the form <ID>:<increment>
(there's another implementation in goog.events.getUniqueId
if you don't mind the events baggage). With the same underlying idea you can create your own ID generator.
Tree walking. The goog.dom
namespace has a number of node iterators that can be reliably used to arrive at elements whose IDs must be changed.
I set up a JSBin example that creates as many clones as replacement sets are specified in the data array, uniquifies IDs, and appends the clones to #svgs
.
If DOM methods are undesirable, Closure Library also provides an html SAX parser (goog.string.html.HtmlParser
under "third-party") which can serve as the base of a DOM-less approach (note: the parser doesn't support SVG elements out of the box).