00001 (function() { 00002 var out$ = typeof exports != 'undefined' && exports || this; 00003 00004 var doctype = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'; 00005 00006 function isExternal(url) { 00007 return url && url.lastIndexOf('http',0) == 0 && url.lastIndexOf(window.location.host) == -1; 00008 } 00009 00010 function inlineImages(el, callback) { 00011 var images = el.querySelectorAll('image'); 00012 var left = images.length; 00013 if (left == 0) { 00014 callback(); 00015 } 00016 for (var i = 0; i < images.length; i++) { 00017 (function(image) { 00018 var href = image.getAttributeNS("http://www.w3.org/1999/xlink", "href"); 00019 if (href) { 00020 if (isExternal(href.value)) { 00021 console.warn("Cannot render embedded images linking to external hosts: "+href.value); 00022 return; 00023 } 00024 } 00025 var canvas = document.createElement('canvas'); 00026 var ctx = canvas.getContext('2d'); 00027 var img = new Image(); 00028 href = href || image.getAttribute('href'); 00029 img.src = href; 00030 img.onload = function() { 00031 canvas.width = img.width; 00032 canvas.height = img.height; 00033 ctx.drawImage(img, 0, 0); 00034 image.setAttributeNS("http://www.w3.org/1999/xlink", "href", canvas.toDataURL('image/png')); 00035 left--; 00036 if (left == 0) { 00037 callback(); 00038 } 00039 } 00040 img.onerror = function() { 00041 console.log("Could not load "+href); 00042 left--; 00043 if (left == 0) { 00044 callback(); 00045 } 00046 } 00047 })(images[i]); 00048 } 00049 } 00050 00051 function styles(el, selectorRemap) { 00052 var css = ""; 00053 var sheets = document.styleSheets; 00054 for (var i = 0; i < sheets.length; i++) { 00055 try { 00056 var rules = sheets[i].cssRules; 00057 } catch (e) { 00058 console.warn("Stylesheet could not be loaded: "+sheets[i].href); 00059 continue; 00060 } 00061 00062 if (rules != null) { 00063 for (var j = 0; j < rules.length; j++) { 00064 var rule = rules[j]; 00065 if (typeof(rule.style) != "undefined") { 00066 var match = null; 00067 try { 00068 match = el.querySelector(rule.selectorText); 00069 } catch(err) { 00070 console.warn('Invalid CSS selector "' + rule.selectorText + '"', err); 00071 } 00072 if (match) { 00073 var selector = selectorRemap ? selectorRemap(rule.selectorText) : rule.selectorText; 00074 css += selector + " { " + rule.style.cssText + " }\n"; 00075 } else if(rule.cssText.match(/^@font-face/)) { 00076 css += rule.cssText + '\n'; 00077 } 00078 } 00079 } 00080 } 00081 } 00082 return css; 00083 } 00084 00085 function getDimension(el, clone, dim) { 00086 var v = (el.viewBox.baseVal && el.viewBox.baseVal[dim]) || 00087 (clone.getAttribute(dim) !== null && !clone.getAttribute(dim).match(/%$/) && parseInt(clone.getAttribute(dim))) || 00088 el.getBoundingClientRect()[dim] || 00089 parseInt(clone.style[dim]) || 00090 parseInt(window.getComputedStyle(el).getPropertyValue(dim)); 00091 return (typeof v === 'undefined' || v === null || isNaN(parseFloat(v))) ? 0 : v; 00092 } 00093 00094 function reEncode(data) { 00095 data = encodeURIComponent(data); 00096 data = data.replace(/%([0-9A-F]{2})/g, function(match, p1) { 00097 var c = String.fromCharCode('0x'+p1); 00098 return c === '%' ? '%25' : c; 00099 }); 00100 return decodeURIComponent(data); 00101 } 00102 00103 out$.svgAsDataUri = function(el, options, cb) { 00104 options = options || {}; 00105 options.scale = options.scale || 1; 00106 var xmlns = "http://www.w3.org/2000/xmlns/"; 00107 00108 inlineImages(el, function() { 00109 var outer = document.createElement("div"); 00110 var clone = el.cloneNode(true); 00111 var width, height; 00112 if(el.tagName == 'svg') { 00113 width = options.width || getDimension(el, clone, 'width'); 00114 height = options.height || getDimension(el, clone, 'height'); 00115 } else if(el.getBBox) { 00116 var box = el.getBBox(); 00117 width = box.x + box.width; 00118 height = box.y + box.height; 00119 clone.setAttribute('transform', clone.getAttribute('transform').replace(/translate\(.*?\)/, '')); 00120 00121 var svg = document.createElementNS('http://www.w3.org/2000/svg','svg') 00122 svg.appendChild(clone) 00123 clone = svg; 00124 } else { 00125 console.error('Attempted to render non-SVG element', el); 00126 return; 00127 } 00128 00129 clone.setAttribute("version", "1.1"); 00130 clone.setAttributeNS(xmlns, "xmlns", "http://www.w3.org/2000/svg"); 00131 clone.setAttributeNS(xmlns, "xmlns:xlink", "http://www.w3.org/1999/xlink"); 00132 clone.setAttribute("width", width * options.scale); 00133 clone.setAttribute("height", height * options.scale); 00134 clone.setAttribute("viewBox", [ 00135 options.left || 0, 00136 options.top || 0, 00137 width, 00138 height 00139 ].join(" ")); 00140 00141 outer.appendChild(clone); 00142 00143 var css = styles(el, options.selectorRemap); 00144 var s = document.createElement('style'); 00145 s.setAttribute('type', 'text/css'); 00146 s.innerHTML = "<![CDATA[\n" + css + "\n]]>"; 00147 var defs = document.createElement('defs'); 00148 defs.appendChild(s); 00149 clone.insertBefore(defs, clone.firstChild); 00150 00151 var svg = doctype + outer.innerHTML; 00152 var uri = 'data:image/svg+xml;base64,' + window.btoa(reEncode(svg)); 00153 if (cb) { 00154 cb(uri); 00155 } 00156 }); 00157 } 00158 00159 out$.svgAsPngUri = function(el, options, cb) { 00160 out$.svgAsDataUri(el, options, function(uri) { 00161 var image = new Image(); 00162 image.onload = function() { 00163 var canvas = document.createElement('canvas'); 00164 canvas.width = image.width; 00165 canvas.height = image.height; 00166 var context = canvas.getContext('2d'); 00167 if(options && options.backgroundColor){ 00168 context.fillStyle = options.backgroundColor; 00169 context.fillRect(0, 0, canvas.width, canvas.height); 00170 } 00171 context.drawImage(image, 0, 0); 00172 var a = document.createElement('a'); 00173 cb(canvas.toDataURL('image/png')); 00174 } 00175 image.src = uri; 00176 }); 00177 } 00178 00179 out$.saveSvgAsPng = function(el, name, options) { 00180 options = options || {}; 00181 out$.svgAsPngUri(el, options, function(uri) { 00182 var a = document.createElement('a'); 00183 a.download = name; 00184 a.href = uri; 00185 document.body.appendChild(a); 00186 a.addEventListener("click", function(e) { 00187 a.parentNode.removeChild(a); 00188 }); 00189 a.click(); 00190 }); 00191 } 00192 })();