index.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.DataUri = void 0;
  4. var DataUri;
  5. (function (DataUri) {
  6. function isDataUrl(url) {
  7. const prefix = 'data:';
  8. return url.substr(0, prefix.length) === prefix;
  9. }
  10. DataUri.isDataUrl = isDataUrl;
  11. /**
  12. * Converts an image at `url` to base64-encoded data uri.
  13. * The mime type of the image is inferred from the `url` file extension.
  14. */
  15. function imageToDataUri(url, callback) {
  16. // No need to convert to data uri if it is already in data uri.
  17. if (!url || isDataUrl(url)) {
  18. // Keep the async nature of the function.
  19. setTimeout(() => callback(null, url));
  20. return;
  21. }
  22. const onError = () => {
  23. callback(new Error(`Failed to load image: ${url}`));
  24. };
  25. const onLoad = window.FileReader
  26. ? // chrome, IE10+
  27. (xhr) => {
  28. if (xhr.status === 200) {
  29. const reader = new FileReader();
  30. reader.onload = (evt) => {
  31. const dataUri = evt.target.result;
  32. callback(null, dataUri);
  33. };
  34. reader.onerror = onError;
  35. reader.readAsDataURL(xhr.response);
  36. }
  37. else {
  38. onError();
  39. }
  40. }
  41. : (xhr) => {
  42. const toString = (u8a) => {
  43. const CHUNK_SZ = 0x8000;
  44. const c = [];
  45. for (let i = 0; i < u8a.length; i += CHUNK_SZ) {
  46. c.push(String.fromCharCode.apply(null, u8a.subarray(i, i + CHUNK_SZ)));
  47. }
  48. return c.join('');
  49. };
  50. if (xhr.status === 200) {
  51. let suffix = url.split('.').pop() || 'png';
  52. if (suffix === 'svg') {
  53. suffix = 'svg+xml';
  54. }
  55. const meta = `data:image/${suffix};base64,`;
  56. const bytes = new Uint8Array(xhr.response);
  57. const base64 = meta + btoa(toString(bytes));
  58. callback(null, base64);
  59. }
  60. else {
  61. onError();
  62. }
  63. };
  64. const xhr = new XMLHttpRequest();
  65. xhr.responseType = window.FileReader ? 'blob' : 'arraybuffer';
  66. xhr.open('GET', url, true);
  67. xhr.addEventListener('error', onError);
  68. xhr.addEventListener('load', () => onLoad(xhr));
  69. xhr.send();
  70. }
  71. DataUri.imageToDataUri = imageToDataUri;
  72. function dataUriToBlob(dataUrl) {
  73. let uri = dataUrl.replace(/\s/g, '');
  74. uri = decodeURIComponent(uri);
  75. const index = uri.indexOf(',');
  76. const dataType = uri.slice(0, index); // e.g. 'data:image/jpeg;base64'
  77. const mime = dataType.split(':')[1].split(';')[0]; // e.g. 'image/jpeg'
  78. const data = uri.slice(index + 1);
  79. let decodedString;
  80. if (dataType.indexOf('base64') >= 0) {
  81. // data may be encoded in base64
  82. decodedString = atob(data);
  83. }
  84. else {
  85. // convert the decoded string to UTF-8
  86. decodedString = unescape(encodeURIComponent(data));
  87. }
  88. // write the bytes of the string to a typed array
  89. const ia = new Uint8Array(decodedString.length);
  90. for (let i = 0; i < decodedString.length; i += 1) {
  91. ia[i] = decodedString.charCodeAt(i);
  92. }
  93. return new Blob([ia], { type: mime });
  94. }
  95. DataUri.dataUriToBlob = dataUriToBlob;
  96. function downloadBlob(blob, fileName) {
  97. const msSaveBlob = window.navigator.msSaveBlob;
  98. if (msSaveBlob) {
  99. // requires IE 10+
  100. // pulls up a save dialog
  101. msSaveBlob(blob, fileName);
  102. }
  103. else {
  104. // other browsers
  105. // downloads directly in Chrome and Safari
  106. // presents a save/open dialog in Firefox
  107. // Firefox bug: `from` field in save dialog always shows `from:blob:`
  108. // https://bugzilla.mozilla.org/show_bug.cgi?id=1053327
  109. const url = window.URL.createObjectURL(blob);
  110. const link = document.createElement('a');
  111. link.href = url;
  112. link.download = fileName;
  113. document.body.appendChild(link);
  114. link.click();
  115. document.body.removeChild(link);
  116. // mark the url for garbage collection
  117. window.URL.revokeObjectURL(url);
  118. }
  119. }
  120. DataUri.downloadBlob = downloadBlob;
  121. function downloadDataUri(dataUrl, fileName) {
  122. const blob = dataUriToBlob(dataUrl);
  123. downloadBlob(blob, fileName);
  124. }
  125. DataUri.downloadDataUri = downloadDataUri;
  126. function parseViewBox(svg) {
  127. const matches = svg.match(/<svg[^>]*viewBox\s*=\s*(["']?)(.+?)\1[^>]*>/i);
  128. if (matches && matches[2]) {
  129. return matches[2].replace(/\s+/, ' ').split(' ');
  130. }
  131. return null;
  132. }
  133. function getNumber(str) {
  134. const ret = parseFloat(str);
  135. return Number.isNaN(ret) ? null : ret;
  136. }
  137. function svgToDataUrl(svg, options = {}) {
  138. let viewBox = null;
  139. const getNumberFromViewBox = (index) => {
  140. if (viewBox == null) {
  141. viewBox = parseViewBox(svg);
  142. }
  143. if (viewBox != null) {
  144. return getNumber(viewBox[index]);
  145. }
  146. return null;
  147. };
  148. const getNumberFromMatches = (reg) => {
  149. const matches = svg.match(reg);
  150. if (matches && matches[2]) {
  151. return getNumber(matches[2]);
  152. }
  153. return null;
  154. };
  155. let w = options.width;
  156. if (w == null) {
  157. w = getNumberFromMatches(/<svg[^>]*width\s*=\s*(["']?)(.+?)\1[^>]*>/i);
  158. }
  159. if (w == null) {
  160. w = getNumberFromViewBox(2);
  161. }
  162. if (w == null) {
  163. throw new Error('Can not parse width from svg string');
  164. }
  165. let h = options.height;
  166. if (h == null) {
  167. h = getNumberFromMatches(/<svg[^>]*height\s*=\s*(["']?)(.+?)\1[^>]*>/i);
  168. }
  169. if (h == null) {
  170. h = getNumberFromViewBox(3);
  171. }
  172. if (h == null) {
  173. throw new Error('Can not parse height from svg string');
  174. }
  175. const decoded = encodeURIComponent(svg)
  176. .replace(/'/g, '%27')
  177. .replace(/"/g, '%22');
  178. const header = 'data:image/svg+xml';
  179. const dataUrl = `${header},${decoded}`;
  180. return dataUrl;
  181. }
  182. DataUri.svgToDataUrl = svgToDataUrl;
  183. })(DataUri = exports.DataUri || (exports.DataUri = {}));
  184. //# sourceMappingURL=index.js.map