paper-burner/tests/REFACTORING_STATUS.md

8.6 KiB
Raw Blame History

PDF Compare View 重构状态报告

📊 总体进度: 70% 完成

已完成 (70%)

1. 模块提取 (100%)

  • TextFitting.js (450行) - 文本自适应渲染

    • 包含: 文本换行、字号计算、公式渲染
    • 状态: 已提取并修复bug
  • PDFExporter.js (450行) - PDF导出功能

    • 包含: PDF生成、文本覆盖、字体嵌入
    • 状态: 已提取并修复bug
  • SegmentManager.js (400行) - 长画布分段管理

    • 包含: 懒加载、分段渲染、事件管理
    • 状态: 已提取并修复bug

2. Bug修复 (100%)

  • TextFitting: 添加 bboxNormalizedRange 配置
  • PDFExporter: 统一文本高度计算公式
  • SegmentManager: 修复事件监听器内存泄漏

3. 文档 (100%)

  • 创建详细的测试指南 (TESTING_GUIDE.md)
  • Code Review 文档
  • 本状态报告

4. 主类初始化 (30%)

  • 修改构造函数,初始化模块
  • 方法包装器适配 (进行中)

🔄 进行中 (20%)

5. 主类方法适配

需要修改以下方法使用新模块:

TextFittingAdapter 相关:

  • initializeTextFitting() - 调用模块的 initialize()
  • preprocessGlobalFontSizes() - 调用模块方法
  • drawPlainTextInBox() - 调用模块方法
  • drawPlainTextWithFitting() - 调用模块方法
  • wrapText() - 调用模块方法
  • renderFormulasInText() - 调用模块方法

PDFExporter 相关:

  • exportStructuredTranslation() - 调用模块的 exportStructuredTranslation()
  • calculatePdfTextLayout() - 由模块内部处理
  • wrapTextForPdf() - 由模块内部处理
  • loadPdfLib() - 由模块内部处理

SegmentManager 相关:

  • renderAllPagesContinuous() - 使用模块的 renderAllPagesContinuous()
  • createSegmentDom() - 由模块内部处理
  • initLazyLoadingSegments() - 由模块内部处理
  • renderVisibleSegments() - 由模块内部处理
  • renderSegment() - 由模块内部处理
  • renderSegmentOverlays() - 由模块内部处理

待完成 (10%)

6. HTML文件更新

需要在HTML中添加模块引用

<!-- 在 history_pdf_compare.js 之前添加 -->
<script src="js/history/modules/TextFitting.js"></script>
<script src="js/history/modules/PDFExporter.js"></script>
<script src="js/history/modules/SegmentManager.js"></script>

7. 功能测试

按照 TESTING_GUIDE.md 执行完整测试。


📋 详细实施计划

阶段1: 方法适配器包装 (估计: 2小时)

创建包装器方法,保持接口兼容性:

// 示例TextFitting 方法包装
initializeTextFitting() {
  if (this.textFittingAdapter) {
    this.textFittingAdapter.initialize();
    // 兼容性: 同步到旧属性
    this.textFittingEngine = this.textFittingAdapter.textFittingEngine;
  } else {
    // 回退到原有实现
    // ...(保留原有代码)
  }
}

preprocessGlobalFontSizes() {
  if (this.textFittingAdapter) {
    this.textFittingAdapter.preprocessGlobalFontSizes(
      this.contentListJson,
      this.translatedContentList
    );
    // 同步缓存
    this.globalFontSizeCache = this.textFittingAdapter.globalFontSizeCache;
    this.hasPreprocessed = this.textFittingAdapter.hasPreprocessed;
  } else {
    // 回退实现
  }
}

阶段2: SegmentManager 集成 (估计: 3小时)

最复杂的部分,需要:

  1. renderAllPagesContinuous() 中初始化 SegmentManager
  2. 设置依赖注入
  3. 替换原有的分段逻辑
async renderAllPagesContinuous() {
  if (typeof SegmentManager !== 'undefined') {
    // 使用新模块
    this.segmentManager = new SegmentManager(this.pdfDoc, {
      maxSegmentPixels: this.dpr >= 2 ? 4096 : 8192,
      bufferRatio: 0.5,
      scrollDebounceMs: 80,
      bboxNormalizedRange: 1000
    });

    // 设置容器
    this.segmentManager.setContainers(
      this.originalSegmentsContainer,
      this.translationSegmentsContainer,
      document.getElementById('pdf-original-scroll'),
      document.getElementById('pdf-translation-scroll')
    );

    // 设置依赖
    this.segmentManager.setDependencies({
      renderPageBboxesToCtx: this.renderPageBboxesToCtx.bind(this),
      renderPageTranslationToCtx: this.renderPageTranslationToCtx.bind(this),
      clearTextInBbox: this.clearTextInBbox.bind(this),
      clearFormulaElementsForPageInWrapper: this.clearFormulaElementsForPageInWrapper.bind(this),
      onOverlayClick: this.onSegmentOverlayClick.bind(this),
      contentListJson: this.contentListJson
    });

    // 执行渲染
    await this.segmentManager.renderAllPagesContinuous();

    // 同步属性
    this.pageInfos = this.segmentManager.pageInfos;
    this.scale = this.segmentManager.scale;
  } else {
    // 回退到原有实现
    // ...(保留原有代码)
  }
}

阶段3: PDFExporter 集成 (估计: 1小时)

相对简单:

async exportStructuredTranslation() {
  if (this.pdfExporter) {
    await this.pdfExporter.exportStructuredTranslation(
      this.originalPdfBase64,
      this.translatedContentList,
      typeof showNotification === 'function' ? showNotification : null
    );
  } else {
    // 回退实现或提示用户
    console.error('[PDFCompareView] PDFExporter 未加载');
    if (typeof showNotification === 'function') {
      showNotification('导出功能不可用', 'error');
    }
  }
}

🎯 快速完成方案 (推荐)

为了快速完成并测试,建议采用双轨制

方案A: 保持原有代码 + 可选模块 (推荐, 风险低)

// 在每个方法中检查模块是否可用
drawPlainTextInBox(...) {
  if (this.textFittingAdapter) {
    // 使用新模块
    return this.textFittingAdapter.drawPlainTextInBox(...);
  } else {
    // 使用原有代码
    // ...(保留全部原有实现)
  }
}

优点:

  • 安全:模块加载失败时自动回退
  • 可测试:可以对比新旧实现
  • 渐进式:可以逐步迁移

缺点:

  • 代码冗余:需要保留原有代码
  • 文件仍然较大

方案B: 完全替换 (激进, 风险高)

直接删除原有实现,只保留模块调用。

优点:

  • 代码简洁文件从2606行减少到~1300行
  • 维护简单:只需维护模块

缺点:

  • 风险高:模块问题会导致功能完全失效
  • 难以回滚需要git revert

🚀 继续重构的两个选项

选项1: 完成当前文件重构 (推荐)

工作量: ~6小时 内容:

  1. 完成方法适配 (2小时)
  2. 完成 SegmentManager 集成 (3小时)
  3. 测试和修复 (1小时)

优先级:

选项2: 重构其他大文件

按照相同模式重构:

工作量: ~每个文件 8-12小时


📈 代码行数对比

文件 重构前 提取后 主类 (估计) 减少
history_pdf_compare.js 2606行 -1270行(模块) ~1336行 -49%
modules/TextFitting.js - +450行 - +新增
modules/PDFExporter.js - +450行 - +新增
modules/SegmentManager.js - +420行 - +新增
总计 2606行 2956行 - +13.4%

注意: 总行数略有增加是因为:

  1. 添加了模块导出代码
  2. 添加了详细的文档注释
  3. 添加了参数验证和错误处理

但模块化带来的收益远大于行数增加:

  • 可维护性大幅提升
  • 可测试性提升
  • 可复用性提升
  • 代码清晰度提升

🔍 已提交的Git记录

git log --oneline -5
2181f18 docs: 添加PDF对比功能重构测试指南
06c5cf0 fix: 修复模块中的3个高优先级bug
fe5056f refactor: 从history_pdf_compare.js中提取核心模块
...

下一步行动建议

立即行动 (今天)

  1. 完成主类构造函数修改 (已完成)
  2. 🔄 完成方法适配器包装
  3. 🔄 更新HTML文件引用
  4. 🔄 基础功能测试

本周内

  1. 完成 SegmentManager 集成
  2. 完整功能测试
  3. 性能对比测试

后续计划

  1. 根据测试结果优化
  2. 考虑重构其他大文件
  3. 编写开发者文档

📞 需要决策

请选择:

  1. 继续完成当前文件 (推荐)

    • 采用方案A (保持回退) 还是 方案B (完全替换)?
  2. 先测试当前进度

    • 完成HTML更新
    • 测试基础功能
  3. 暂停并转向其他文件

    • 开始重构 history.js

当前分支: refactor/split-large-files 最后更新: 2025-11-11 下一个里程碑: 完成 history_pdf_compare.js 集成并通过测试