DrawioCommunicationHelper.ts 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import loggerFactory from '~/utils/logger';
  2. const logger = loggerFactory('growi:cli:DrawioCommunicationHelper');
  3. export type DrawioConfig = {
  4. css: string,
  5. customFonts: string[],
  6. compressXml: boolean,
  7. }
  8. export type DrawioCommunicationCallbackOptions = {
  9. onClose?: () => void;
  10. onSave?: (drawioData: string) => void;
  11. }
  12. export class DrawioCommunicationHelper {
  13. drawioUri: string;
  14. drawioConfig: DrawioConfig;
  15. callbackOpts?: DrawioCommunicationCallbackOptions;
  16. constructor(drawioUri: string, drawioConfig: DrawioConfig, callbackOpts?: DrawioCommunicationCallbackOptions) {
  17. this.drawioUri = drawioUri;
  18. this.drawioConfig = drawioConfig;
  19. this.callbackOpts = callbackOpts;
  20. }
  21. onReceiveMessage(event: MessageEvent, drawioMxFile: string): void {
  22. // check origin
  23. if (event.origin != null && this.drawioUri != null) {
  24. const originUrl = new URL(event.origin);
  25. const drawioUrl = new URL(this.drawioUri);
  26. if (originUrl.origin !== drawioUrl.origin) {
  27. logger.debug(`Skipping the event because the origins are mismatched. expected: '${drawioUrl.origin}', actual: '${originUrl.origin}'`);
  28. return;
  29. }
  30. }
  31. // configure
  32. if (event.data === '{"event":"configure"}') {
  33. if (event.source == null) {
  34. return;
  35. }
  36. // refs:
  37. // * https://desk.draw.io/support/solutions/articles/16000103852-how-to-customise-the-draw-io-interface
  38. // * https://desk.draw.io/support/solutions/articles/16000042544-how-does-embed-mode-work-
  39. // * https://desk.draw.io/support/solutions/articles/16000058316-how-to-configure-draw-io-
  40. event.source.postMessage(JSON.stringify({
  41. action: 'configure',
  42. config: this.drawioConfig,
  43. }), { targetOrigin: '*' });
  44. return;
  45. }
  46. // restore diagram data
  47. if (event.data === 'ready') {
  48. event.source?.postMessage(drawioMxFile, { targetOrigin: '*' });
  49. return;
  50. }
  51. if (typeof event.data === 'string' && event.data.match(/mxfile/)) {
  52. if (event.data.length > 0) {
  53. const parser = new DOMParser();
  54. const dom = parser.parseFromString(event.data, 'text/xml');
  55. const drawioData = dom.getElementsByTagName('diagram')[0].innerHTML;
  56. /*
  57. * Saving Drawio will be implemented by the following tasks
  58. * https://redmine.weseek.co.jp/issues/100845
  59. * https://redmine.weseek.co.jp/issues/104507
  60. */
  61. this.callbackOpts?.onSave?.(drawioData);
  62. }
  63. this.callbackOpts?.onClose?.();
  64. return;
  65. }
  66. if (typeof event.data === 'string' && event.data.length === 0) {
  67. this.callbackOpts?.onClose?.();
  68. return;
  69. }
  70. // NOTHING DONE. (Receive unknown iframe message.)
  71. }
  72. }