embed.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // transplanted from https://github.com/jgraph/drawio-tools/blob/d46977060ffad70cae5a9059a2cbfcd8bcf420de/tools/convert.html
  2. import pako from 'pako';
  3. import xmldoc from 'xmldoc';
  4. export const extractCodeFromMxfile = (input: string): string => {
  5. const doc = new xmldoc.XmlDocument(input);
  6. return doc.valueWithPath('diagram');
  7. };
  8. const validateInputData = (input: string): boolean => {
  9. let data = input;
  10. try {
  11. data = extractCodeFromMxfile(data);
  12. }
  13. catch (e) {
  14. // ignore
  15. }
  16. try {
  17. data = Buffer.from(data, 'base64').toString('binary');
  18. }
  19. catch (e) {
  20. throw new Error(`Base64 to binary failed: ${e}`);
  21. }
  22. if (data.length > 0) {
  23. try {
  24. data = pako.inflateRaw(Uint8Array.from(data, c => c.charCodeAt(0)), { to: 'string' });
  25. }
  26. catch (e) {
  27. throw new Error(`inflateRaw failed: ${e}`);
  28. }
  29. }
  30. try {
  31. data = decodeURIComponent(data);
  32. }
  33. catch (e) {
  34. throw new Error(`decodeURIComponent failed: ${e}`);
  35. }
  36. return true;
  37. };
  38. const escapeHTML = (string): string => {
  39. if (typeof string !== 'string') {
  40. return string;
  41. }
  42. return string.replace(/[&'`"<>]/g, (match): string => {
  43. return {
  44. '&': '&amp;',
  45. "'": '&#x27;',
  46. '`': '&#x60;',
  47. '"': '&quot;',
  48. '<': '&lt;',
  49. '>': '&gt;',
  50. }[match] ?? match;
  51. });
  52. };
  53. export const generateMxgraphData = (code: string): string => {
  54. const trimedCode = code.trim();
  55. if (!trimedCode) {
  56. return '';
  57. }
  58. validateInputData(trimedCode);
  59. let xml;
  60. try {
  61. // may be XML Format <mxfile><diagram> ... </diagram></mxfile>
  62. const doc = new xmldoc.XmlDocument(trimedCode);
  63. const diagram = doc.valueWithPath('diagram');
  64. if (diagram) {
  65. xml = trimedCode;
  66. }
  67. }
  68. catch (e) {
  69. // may be NOT XML Format
  70. xml = `
  71. <mxfile version="6.8.9" editor="www.draw.io" type="atlas">
  72. <mxAtlasLibraries/>
  73. <diagram>${trimedCode}</diagram>
  74. </mxfile>
  75. `;
  76. }
  77. // see options: https://drawio.freshdesk.com/support/solutions/articles/16000042542-embed-html
  78. const mxGraphData = {
  79. editable: false,
  80. highlight: '#0000ff',
  81. nav: false,
  82. toolbar: null,
  83. edit: null,
  84. resize: true,
  85. lightbox: 'false',
  86. xml,
  87. };
  88. return escapeHTML(JSON.stringify(mxGraphData));
  89. };