Core 边界
InkLayer Core 提供文档与批注能力,但不是一个已经完成的 PDF 应用。这一页回答一个实际问题:开发 Viewer 时,哪些工作应该交给 Core,哪些工作应该由应用或框架组件完成?
一个简单的判断方法
如果一项行为在 React、Vue 和原生 JavaScript 中分别实现后,可能改变下面任何一项,就应该放在 Core:
- PDF 的解析结果或页面坐标;
- 批注数据、交互方式或导出结果;
- 文档权限或页面内的直接操作;
- 资源的归属和清理时机。
如果一项行为主要控制布局、品牌、路由、文案、业务流程、登录用户身份或服务端策略,就应该由应用负责。
很多功能会横跨两侧。遇到这种情况,Core 负责保持一致的行为和数据,应用负责控件与界面呈现。
各项功能如何分工
| 功能 | Core 提供 | 应用或框架提供 |
|---|---|---|
| PDF 加载 | URL/字节加载、分段请求、密码处理、取消、错误和文档权限 | PDF 来源、密码对话框、加载/错误界面和访问策略 |
| 页面与缩放 | 单页、连续和对页布局,虚拟渲染、页面绘制、缩放、手势与导航 | 布局容器、模式按钮、页码输入框和外围样式 |
| 缩略图与目录 | 缩略图渲染、目录提取、目标解析和导航接口 | 侧边栏、树形/网格界面、选中状态和展开状态 |
| 搜索与文字选择 | 文字提取、匹配、结果高亮、规范化选择结果和页面坐标矩形 | 搜索框、结果面板和文字选择后的操作菜单 |
| 批注交互 | 工具、命中测试、选择、创建、拖动、缩放、旋转和不同几何类型的编辑 | 工具栏、颜色/外观控件、右键菜单和侧边栏 |
| 批注数据 | 可序列化的规范批注、评论、引用、数据仓库操作和变更事件 | 服务端存储、同步、冲突处理和产品特有的附加数据 |
| 作者与权限 | 根据 currentUser 和批注权限字段执行客户端交互判断 | 可信用户身份、权限配置、提示文案以及服务端的最终权限校验 |
| 水印 | 校验水印配置,并在支持的查看、打印和导出路径中渲染 | 水印中的用户/文档信息,以及决定显示位置的业务策略 |
| 打印与导出 | 校验文档限制,生成 PDF/Excel 内容,并提供浏览器打印和下载辅助函数 | 按钮与选项、原始 PDF 字节、文件名、上传/下载选择和调用时机 |
| 键盘与无障碍 | 文档区域内的焦点、批注键盘交互、语义替代和减弱动态效果 | 无障碍工具栏、菜单和对话框,Core 外围的焦点顺序与本地化标签 |
| 应用服务 | 通过能力插件接入日志、请求、文字输入、数据仓库、ID、时钟、打印和下载 | Provider 的具体实现,以及这些服务需要的应用界面 |
客户端权限不能代替服务端权限
Core 可以阻止用户编辑其他作者的批注,但浏览器中的状态可以被用户修改。加载或保存批注时,服务端仍然必须验证用户身份,并执行最终的读写权限校验。
Core 明确不负责什么
Core 不提供:
- 完整的工具栏、缩略图侧边栏、搜索面板、评论面板或应用外壳;
- 用户登录、文档授权或可信的权限后端;
- 数据库、服务端持久化协议或实时协作传输;
- 应用路由、品牌设计、本地化策略或业务流程;
- 安装能力插件后自动触发的打印或下载。
这些部分会因产品的界面、基础设施和业务策略而不同,因此应该由应用实现。框架接入章节会展示如何组装最小可用的 Viewer,但不会把这些产品选择固化成 Core 默认行为。
扩展功能必须遵守的规则
自定义框架组件、能力插件和批注类型都应该保持下面这些 Core 约定:
core.annotations.repository始终是批注数据源,不持久化渲染节点或 DOM 矩形。- 每条批注都有从 0 开始的
pageIndex和明确的coordinateSpace;适配器不能混用 Stage 坐标与 PDF 用户空间坐标。跨页文字选择会拆分成多个页内片段。 - 文档交互由当前工具决定,文字选择、批注选择和绘制工具不能同时争夺同一组指针事件。
- 密码不能进入日志、普通事件、持久化状态或错误数据。
- 公开接口和事件不能暴露可变的 Konva 节点或 PDF.js 私有状态。
- 替换文档或销毁实例时,必须释放属于该文档的任务、Canvas、文字层、订阅和缩略图缓存。
- 安全打印生成的栅格 PDF 是临时、未加密、仅包含图片的打印文件,不能作为受保护源文档的替代下载。
这些规则可以保证不同框架下的行为和持久化数据保持兼容。模块划分与数据流见架构概览。