|
| 1 | +(function() { |
| 2 | + var out$ = typeof exports != 'undefined' && exports || typeof define != 'undefined' && {} || this; |
| 3 | + |
| 4 | + var doctype = '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'; |
| 5 | + |
| 6 | + function isExternal(url) { |
| 7 | + return url && url.lastIndexOf('http',0) == 0 && url.lastIndexOf(window.location.host) == -1; |
| 8 | + } |
| 9 | + |
| 10 | + function inlineImages(el, callback) { |
| 11 | + var images = el.querySelectorAll('image'); |
| 12 | + var left = images.length; |
| 13 | + if (left == 0) { |
| 14 | + callback(); |
| 15 | + } |
| 16 | + for (var i = 0; i < images.length; i++) { |
| 17 | + (function(image) { |
| 18 | + var href = image.getAttributeNS("http://www.w3.org/1999/xlink", "href"); |
| 19 | + if (href) { |
| 20 | + if (isExternal(href.value)) { |
| 21 | + console.warn("Cannot render embedded images linking to external hosts: "+href.value); |
| 22 | + return; |
| 23 | + } |
| 24 | + } |
| 25 | + var canvas = document.createElement('canvas'); |
| 26 | + var ctx = canvas.getContext('2d'); |
| 27 | + var img = new Image(); |
| 28 | + href = href || image.getAttribute('href'); |
| 29 | + img.src = href; |
| 30 | + img.onload = function() { |
| 31 | + canvas.width = img.width; |
| 32 | + canvas.height = img.height; |
| 33 | + ctx.drawImage(img, 0, 0); |
| 34 | + image.setAttributeNS("http://www.w3.org/1999/xlink", "href", canvas.toDataURL('image/png')); |
| 35 | + left--; |
| 36 | + if (left == 0) { |
| 37 | + callback(); |
| 38 | + } |
| 39 | + } |
| 40 | + img.onerror = function() { |
| 41 | + console.log("Could not load "+href); |
| 42 | + left--; |
| 43 | + if (left == 0) { |
| 44 | + callback(); |
| 45 | + } |
| 46 | + } |
| 47 | + })(images[i]); |
| 48 | + } |
| 49 | + } |
| 50 | + |
| 51 | + function styles(el, selectorRemap) { |
| 52 | + var css = ""; |
| 53 | + var sheets = document.styleSheets; |
| 54 | + for (var i = 0; i < sheets.length; i++) { |
| 55 | + try { |
| 56 | + var rules = sheets[i].cssRules; |
| 57 | + } catch (e) { |
| 58 | + console.warn("Stylesheet could not be loaded: "+sheets[i].href); |
| 59 | + continue; |
| 60 | + } |
| 61 | + |
| 62 | + if (rules != null) { |
| 63 | + for (var j = 0; j < rules.length; j++) { |
| 64 | + var rule = rules[j]; |
| 65 | + if (typeof(rule.style) != "undefined") { |
| 66 | + var match = null; |
| 67 | + try { |
| 68 | + match = el.querySelector(rule.selectorText); |
| 69 | + } catch(err) { |
| 70 | + console.warn('Invalid CSS selector "' + rule.selectorText + '"', err); |
| 71 | + } |
| 72 | + if (match) { |
| 73 | + var selector = selectorRemap ? selectorRemap(rule.selectorText) : rule.selectorText; |
| 74 | + css += selector + " { " + rule.style.cssText + " }\n"; |
| 75 | + } else if(rule.cssText.match(/^@font-face/)) { |
| 76 | + css += rule.cssText + '\n'; |
| 77 | + } |
| 78 | + } |
| 79 | + } |
| 80 | + } |
| 81 | + } |
| 82 | + return css; |
| 83 | + } |
| 84 | + |
| 85 | + function getDimension(el, clone, dim) { |
| 86 | + var v = (el.viewBox && el.viewBox.baseVal && el.viewBox.baseVal[dim]) || |
| 87 | + (clone.getAttribute(dim) !== null && !clone.getAttribute(dim).match(/%$/) && parseInt(clone.getAttribute(dim))) || |
| 88 | + el.getBoundingClientRect()[dim] || |
| 89 | + parseInt(clone.style[dim]) || |
| 90 | + parseInt(window.getComputedStyle(el).getPropertyValue(dim)); |
| 91 | + return (typeof v === 'undefined' || v === null || isNaN(parseFloat(v))) ? 0 : v; |
| 92 | + } |
| 93 | + |
| 94 | + function reEncode(data) { |
| 95 | + data = encodeURIComponent(data); |
| 96 | + data = data.replace(/%([0-9A-F]{2})/g, function(match, p1) { |
| 97 | + var c = String.fromCharCode('0x'+p1); |
| 98 | + return c === '%' ? '%25' : c; |
| 99 | + }); |
| 100 | + return decodeURIComponent(data); |
| 101 | + } |
| 102 | + |
| 103 | + out$.svgAsDataUri = function(el, options, cb) { |
| 104 | + options = options || {}; |
| 105 | + options.scale = options.scale || 1; |
| 106 | + var xmlns = "http://www.w3.org/2000/xmlns/"; |
| 107 | + |
| 108 | + inlineImages(el, function() { |
| 109 | + var outer = document.createElement("div"); |
| 110 | + var clone = el.cloneNode(true); |
| 111 | + clone.setAttribute('transform', clone.getAttribute('transform').replace(/translate\(.*?\)/, '')); |
| 112 | + var svg = document.createElementNS('http://www.w3.org/2000/svg','svg'); |
| 113 | + svg.appendChild(clone); |
| 114 | + clone = svg; |
| 115 | + |
| 116 | + var box = el.getBBox(); |
| 117 | + var rect = el.getBoundingClientRect(); |
| 118 | + |
| 119 | + clone.setAttribute("version", "1.1"); |
| 120 | + if (clone.getAttribute("xmlns") !== null) { |
| 121 | + clone.removeAttribute("xmlns"); |
| 122 | + } |
| 123 | + if (clone.getAttribute("xmlns:xlink") !== null) { |
| 124 | + clone.removeAttribute("xmlns:xlink"); |
| 125 | + } |
| 126 | + clone.setAttributeNS(xmlns, "xmlns", "http://www.w3.org/2000/svg"); |
| 127 | + clone.setAttributeNS(xmlns, "xmlns:xlink", "http://www.w3.org/1999/xlink"); |
| 128 | + clone.setAttribute("width", rect.width); |
| 129 | + clone.setAttribute("height", rect.height); |
| 130 | + clone.setAttribute("viewBox", [ |
| 131 | + box.x, |
| 132 | + box.y, |
| 133 | + rect.width, |
| 134 | + rect.height |
| 135 | + ].join(" ")); |
| 136 | + |
| 137 | + outer.appendChild(clone); |
| 138 | + |
| 139 | + var css = styles(el, options.selectorRemap); |
| 140 | + var s = document.createElement('style'); |
| 141 | + s.setAttribute('type', 'text/css'); |
| 142 | + s.innerHTML = "<![CDATA[\n" + css + "\n]]>"; |
| 143 | + var defs = document.createElement('defs'); |
| 144 | + defs.appendChild(s); |
| 145 | + clone.insertBefore(defs, clone.firstChild); |
| 146 | + |
| 147 | + var svg = doctype + outer.innerHTML.replace(/ /g, ' '); |
| 148 | + var uri = 'data:image/svg+xml;base64,' + window.btoa(reEncode(svg)); |
| 149 | + if (cb) { |
| 150 | + cb(uri); |
| 151 | + } |
| 152 | + }); |
| 153 | + } |
| 154 | + |
| 155 | + out$.svgAsPngUri = function(el, options, cb) { |
| 156 | + out$.svgAsDataUri(el, options, function(uri) { |
| 157 | + var image = new Image(); |
| 158 | + image.onload = function() { |
| 159 | + var canvas = document.createElement('canvas'); |
| 160 | + canvas.width = image.width; |
| 161 | + canvas.height = image.height; |
| 162 | + var context = canvas.getContext('2d'); |
| 163 | + if(options && options.backgroundColor){ |
| 164 | + context.fillStyle = options.backgroundColor; |
| 165 | + context.fillRect(0, 0, canvas.width, canvas.height); |
| 166 | + } |
| 167 | + context.drawImage(image, 0, 0); |
| 168 | + var a = document.createElement('a'), png; |
| 169 | + try { |
| 170 | + png = canvas.toDataURL('image/png'); |
| 171 | + } catch (e) { |
| 172 | + if ((typeof SecurityError !== 'undefined' && e instanceof SecurityError) || e.name == "SecurityError") { |
| 173 | + console.error("Rendered SVG images cannot be downloaded in this browser."); |
| 174 | + return; |
| 175 | + } else { |
| 176 | + throw e; |
| 177 | + } |
| 178 | + } |
| 179 | + cb(png); |
| 180 | + } |
| 181 | + image.src = uri; |
| 182 | + }); |
| 183 | + } |
| 184 | + |
| 185 | + out$.saveSvgAsPng = function(el, name, options) { |
| 186 | + options = options || {}; |
| 187 | + out$.svgAsPngUri(el, options, function(uri) { |
| 188 | + var a = document.createElement('a'); |
| 189 | + a.download = name; |
| 190 | + a.href = uri; |
| 191 | + document.body.appendChild(a); |
| 192 | + a.addEventListener("click", function(e) { |
| 193 | + a.parentNode.removeChild(a); |
| 194 | + }); |
| 195 | + a.click(); |
| 196 | + }); |
| 197 | + } |
| 198 | + |
| 199 | + // if define is defined create as an AMD module |
| 200 | + if (typeof define !== 'undefined') { |
| 201 | + define(function() { |
| 202 | + return out$; |
| 203 | + }); |
| 204 | + } |
| 205 | + |
| 206 | +})(); |
0 commit comments