embed.ts 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // transplanted from https://github.com/jgraph/drawio-tools/blob/d46977060ffad70cae5a9059a2cbfcd8bcf420de/tools/convert.html
  2. import pako from 'pako';
  3. const unconpressedDataRegexp = /<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. } catch (e) {
  12. throw new Error(`Base64 to binary failed: ${e}`);
  13. }
  14. if (data.length > 0) {
  15. try {
  16. data = pako.inflateRaw(
  17. Uint8Array.from(data, (c) => c.charCodeAt(0)),
  18. { to: 'string' },
  19. );
  20. } catch (e) {
  21. throw new Error(`inflateRaw failed: ${e}`);
  22. }
  23. }
  24. try {
  25. data = decodeURIComponent(data);
  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. {
  38. '&': '&amp;',
  39. "'": '&#x27;',
  40. '`': '&#x60;',
  41. '"': '&quot;',
  42. '<': '&lt;',
  43. '>': '&gt;',
  44. }[match] ?? match
  45. );
  46. });
  47. };
  48. export const generateMxgraphData = (code: string): string => {
  49. const trimedCode = code.trim();
  50. if (!trimedCode) {
  51. return '';
  52. }
  53. // Evaluate the code is whether uncompressed data that are generated by v21.1.0 or above
  54. // see: https://github.com/jgraph/drawio/issues/3106#issuecomment-1479352026
  55. const isUncompressedData = validateUncompressedData(trimedCode);
  56. if (!isUncompressedData) {
  57. validateCompressedData(trimedCode);
  58. }
  59. const xml = `
  60. <mxfile version="6.8.9" editor="www.draw.io" type="atlas">
  61. <mxAtlasLibraries/>
  62. <diagram>${trimedCode}</diagram>
  63. </mxfile>
  64. `;
  65. const mxGraphData = {
  66. editable: false,
  67. highlight: '#0000ff',
  68. nav: false,
  69. toolbar: null,
  70. edit: null,
  71. resize: true,
  72. lightbox: 'false',
  73. xml,
  74. 'dark-mode': 'auto',
  75. };
  76. return escapeHTML(JSON.stringify(mxGraphData));
  77. };