export-view-manager.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /**
  2. * 导出动画弹出框管理器
  3. * 负责管理 export-view iframe 的显示和隐藏
  4. */
  5. class ExportViewManager {
  6. constructor() {
  7. this.frame = null;
  8. this.isShowing = false;
  9. this.resolveCallback = null;
  10. this.init();
  11. }
  12. init() {
  13. this.frame = document.getElementById('exportViewFrame');
  14. if (!this.frame) {
  15. // console.error('[ExportViewManager] exportViewFrame 未找到');
  16. return;
  17. }
  18. // 监听来自 export-view 的消息
  19. window.addEventListener('message', (event) => {
  20. if (event.origin !== window.location.origin) {
  21. return;
  22. }
  23. const { data } = event;
  24. if (data && data.type === 'close-export-view') {
  25. // console.log('[ExportViewManager] 收到关闭消息');
  26. this.hide();
  27. } else if (data && data.type === 'export-confirmed') {
  28. // console.log('[ExportViewManager] 用户确认导出');
  29. this.handleExportConfirmed(data);
  30. }
  31. });
  32. }
  33. /**
  34. * 显示导出弹出框
  35. * @param {string} folderName - 文件夹名称
  36. * @returns {Promise<boolean>} - 返回用户是否确认导出
  37. */
  38. async show(folderName) {
  39. // console.log('[ExportViewManager] → show() 被调用');
  40. // console.log('[ExportViewManager] 文件夹名称:', folderName);
  41. if (!this.frame) {
  42. // console.error('[ExportViewManager] frame 未初始化');
  43. return false;
  44. }
  45. return new Promise((resolve) => {
  46. this.resolveCallback = resolve;
  47. this.isShowing = true;
  48. // 显示 iframe
  49. this.frame.style.display = 'block';
  50. // 等待 iframe 加载完成后发送文件夹名称
  51. const sendFolderName = () => {
  52. if (this.frame.contentWindow) {
  53. this.frame.contentWindow.postMessage({
  54. type: 'generate-export-preview',
  55. folderName: folderName
  56. }, '*');
  57. // console.log('[ExportViewManager] ✓ 已发送文件夹名称到 export-view');
  58. } else {
  59. // 如果 iframe 还没加载完,等待一下再试
  60. setTimeout(sendFolderName, 100);
  61. }
  62. };
  63. // 监听 iframe 加载完成
  64. const handleLoad = () => {
  65. // console.log('[ExportViewManager] ✓ iframe 加载完成');
  66. // 等待一小段时间确保 iframe 内容完全初始化
  67. setTimeout(() => {
  68. sendFolderName();
  69. }, 100);
  70. };
  71. this.frame.onload = handleLoad;
  72. // 如果 iframe 已经加载,立即发送
  73. if (this.frame.contentDocument && this.frame.contentDocument.readyState === 'complete') {
  74. handleLoad();
  75. } else {
  76. // 重新加载 iframe 以确保它处于干净状态
  77. this.frame.src = this.frame.src;
  78. }
  79. });
  80. }
  81. /**
  82. * 隐藏导出弹出框
  83. */
  84. hide() {
  85. // console.log('[ExportViewManager] → hide() 被调用');
  86. if (this.frame) {
  87. this.frame.style.display = 'none';
  88. }
  89. this.isShowing = false;
  90. // 如果还有未完成的 Promise,返回 false(取消)
  91. if (this.resolveCallback) {
  92. this.resolveCallback(false);
  93. this.resolveCallback = null;
  94. }
  95. }
  96. /**
  97. * 处理用户确认导出
  98. * @param {Object} data - 导出数据
  99. */
  100. handleExportConfirmed(data) {
  101. // console.log('[ExportViewManager] 处理导出确认');
  102. if (this.resolveCallback) {
  103. this.resolveCallback(true);
  104. this.resolveCallback = null;
  105. }
  106. // 关闭弹出框
  107. this.hide();
  108. }
  109. }
  110. // 全局单例
  111. // console.log('[ExportViewManager] 创建全局实例...');
  112. window.ExportViewManager = new ExportViewManager();
  113. // console.log('[ExportViewManager] ✓ 全局实例已创建');