(function (d3Pointers) { var callTemplate = function(callback,sel,d) { sel = (sel) ? 'template' + ( (sel.match(/^[\#|\.|\:|\[]/g)) ? sel : ' ' + sel ) : ''; var serializer = new XMLSerializer(), parser = new DOMParser(), template = d3.select(sel)[0][0], thisSelection = (d) ? this.datum(d) : this, preTemplate = postTemplate = '', templateContent = ( (serializer && template.toString() == '[object HTMLTemplateElement]') ? serializer.serializeToString(template.content) : template.innerHTML ).replace(/\.*?\<\/script\>/gi,''); switch(template.getAttribute('type')) { case 'image/svg+xml': preTemplate = ''; postTemplate = ''; break; case 'text/html': preTemplate = ''; postTemplate = ''; break; case 'text/plain': preTemplate = ''; postTemplate = ''; break; case 'text/javascript': templateContent = ''; break; default: break; } parser.async = false; thisSelection.each(function (d) { var renderedContent = callback(templateContent, d), parsedContent = parser .parseFromString(preTemplate + renderedContent + postTemplate,'text/xml') .documentElement .firstChild; while (parsedContent) { this.appendChild( this.ownerDocument.importNode(parsedContent, true) ); parsedContent = parsedContent.nextSibling; } }); }; while((pointer = d3Pointers.pop())) { pointer.prototype.callTemplate = callTemplate; } })( [d3.selection, d3.selection.enter] );