download.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. /**
  2. * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. function openUrl(url: string) {
  7. const opened = window.open(url, '_blank');
  8. if (!opened) {
  9. window.location.href = url;
  10. }
  11. }
  12. function click(node: HTMLAnchorElement) {
  13. try {
  14. node.dispatchEvent(new MouseEvent('click'));
  15. } catch (e) {
  16. const evt = document.createEvent('MouseEvents');
  17. evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
  18. node.dispatchEvent(evt);
  19. }
  20. }
  21. export function download(data: Blob | string, downloadName = 'download') {
  22. // using ideas from https://github.com/eligrey/FileSaver.js/blob/master/FileSaver.js
  23. if (!data) return;
  24. if ('download' in HTMLAnchorElement.prototype) {
  25. const a = document.createElement('a');
  26. a.download = downloadName;
  27. a.rel = 'noopener';
  28. if (typeof data === 'string') {
  29. a.href = data;
  30. click(a);
  31. } else {
  32. a.href = URL.createObjectURL(data);
  33. setTimeout(() => URL.revokeObjectURL(a.href), 4E4); // 40s
  34. setTimeout(() => click(a));
  35. }
  36. } else if (typeof navigator !== 'undefined' && (navigator as any).msSaveOrOpenBlob) {
  37. // native saveAs in IE 10+
  38. (navigator as any).msSaveOrOpenBlob(data, downloadName);
  39. } else {
  40. const ua = window.navigator.userAgent;
  41. const isSafari = /Safari/i.test(ua);
  42. const isChromeIos = /CriOS\/[\d]+/.test(ua);
  43. const open = (str: string) => {
  44. openUrl(isChromeIos ? str : str.replace(/^data:[^;]*;/, 'data:attachment/file;'));
  45. };
  46. if ((isSafari || isChromeIos) && FileReader) {
  47. if (data instanceof Blob) {
  48. // no downloading of blob urls in Safari
  49. const reader = new FileReader();
  50. reader.onloadend = () => open(reader.result as string);
  51. reader.readAsDataURL(data);
  52. } else {
  53. open(data);
  54. }
  55. } else {
  56. const url = URL.createObjectURL(typeof data === 'string' ? new Blob([data]) : data);
  57. location.href = url;
  58. setTimeout(() => URL.revokeObjectURL(url), 4E4); // 40s
  59. }
  60. }
  61. }