embed.ts 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // transplanted from https://github.com/jgraph/drawio-tools/blob/d46977060ffad70cae5a9059a2cbfcd8bcf420de/tools/convert.html
  2. import pako from 'pako';
  3. const unconpressedDataRegexp = new RegExp('<mxGraphModel');
  4. const validateUncompressedData = (input: string): boolean => {
  5. return unconpressedDataRegexp.test(input);
  6. };
  7. const validateCompressedData = (input: string): boolean => {
  8. let data = input;
  9. try {
  10. data = Buffer.from(data, 'base64').toString('binary');
  11. }
  12. catch (e) {
  13. throw new Error(`Base64 to binary failed: ${e}`);
  14. }
  15. if (data.length > 0) {
  16. try {
  17. data = pako.inflateRaw(Uint8Array.from(data, c => c.charCodeAt(0)), { to: 'string' });
  18. }
  19. catch (e) {
  20. throw new Error(`inflateRaw failed: ${e}`);
  21. }
  22. }
  23. try {
  24. data = decodeURIComponent(data);
  25. }
  26. catch (e) {
  27. throw new Error(`decodeURIComponent failed: ${e}`);
  28. }
  29. return true;
  30. };
  31. const escapeHTML = (string): string => {
  32. if (typeof string !== 'string') {
  33. return string;
  34. }
  35. return string.replace(/[&'`"<>]/g, (match): string => {
  36. return {
  37. '&': '&amp;',
  38. "'": '&#x27;',
  39. '`': '&#x60;',
  40. '"': '&quot;',
  41. '<': '&lt;',
  42. '>': '&gt;',
  43. }[match] ?? match;
  44. });
  45. };
  46. export const generateMxgraphData = (code: string): string => {
  47. const trimedCode = code.trim();
  48. if (!trimedCode) {
  49. return '';
  50. }
  51. // Evaluate the code is whether uncompressed data that are generated by v21.1.0 or above
  52. // see: https://github.com/jgraph/drawio/issues/3106#issuecomment-1479352026
  53. const isUncompressedData = validateUncompressedData(trimedCode);
  54. if (!isUncompressedData) {
  55. validateCompressedData(trimedCode);
  56. }
  57. const xml = `
  58. <mxfile version="6.8.9" editor="www.draw.io" type="atlas">
  59. <mxAtlasLibraries/>
  60. <diagram>${trimedCode}</diagram>
  61. </mxfile>
  62. `;
  63. // see options: https://drawio.freshdesk.com/support/solutions/articles/16000042542-embed-html
  64. const mxGraphData = {
  65. editable: false,
  66. highlight: '#0000ff',
  67. nav: false,
  68. toolbar: null,
  69. edit: null,
  70. resize: true,
  71. lightbox: 'false',
  72. xml,
  73. };
  74. return escapeHTML(JSON.stringify(mxGraphData));
  75. };