Releases: gibsonchan-5/fleur-pdf
Releases · gibsonchan-5/fleur-pdf
Release list
1.4.0 — Text-anchored annotation rewrite
1.4.0 — Text-anchored annotation rewrite
Highlights
- Complete rewrite of the annotation engine: every highlight is now identified by page range + text content instead of fragile DOM Range/Node references.
- Initial highlighting and restore now share the same text-locating pipeline — what can be highlighted can always be restored.
Bug Fixes
- Cross-page highlight could not locate selected text on restore — root cause: per-page restore was matching the full cross-page string against a single page's textLayer, which can never match.
- Same-page highlight occasionally failed when selection overlapped existing highlights — root cause:
collectSegmentsDirectskipped nodes already marked withfleurSel, so an entirely-in-old-highlight selection produced zero segments. compareBoundaryPointsbranch logic was inverted, so the actual start/end offsets were never applied.- Selection endpoints outside the
.pageelement returned immediately — cross-page drag-selection commonly starts from a container-level node.
New
- New command: FleurPDF: 重新渲染当前 PDF 的标注
- New command: FleurPDF: 诊断当前 PDF 结构 (shows page layout, selection page-range, per-page text split in a Notice)
- Five-level in-page text matching with NFKC normalization as fallback when DOM intersection fails
splitAnnotationTextByPagefor restoring cross-page annotations (greedy per-page split: first page = start → page-tail, last page = remainder)
Notes for reviewers
main.jsis now tracked in git (required by Obsidian community plugin review)versions.jsonupdated for 1.4.0 → minAppVersion 1.7.2
Upgrade in Obsidian → Settings → Community plugins → FleurPDF.
1.3.2 — Fix PDF annotation persistence
1.3.2 — Fix PDF annotation persistence
Bug Fixes
- Fix: PDF annotations disappear after closing/reopening — The core issue was text matching failure in the textLayer
- Root cause: Kangxi Radicals (U+2F00–U+2FD5) vs standard CJK (U+4E00–U+9FFF) encoding mismatch — PDF.js returns Kangxi Radicals for some Chinese text, while saved annotation text uses standard CJK characters
- Fix: Use NFKC Unicode normalization for cross-encoding text matching
- Fix: Remove space insertion between text nodes (broke CJK matching — Chinese text has no inter-word spaces)
- Fix: Add retry mechanism with exponential backoff (500ms → 1s → 2s → 3s → 5s, max 6 attempts)
- Fix: Async wait for textLayer to be rendered before matching
Community Review Compliance
- All
style.xxx =→setCssStyles()/setCssProps() - All
eslint-disablecomments have descriptions - All
setTimeout→window.setTimeout localStorage→plugin.settingsvault.delete→vault.trash
Security
- Added
data.jsonto.gitignoreto prevent API key leaks
1.3.1
v1.3.1: Fix community review warnings
- Replace style.setProperty with direct assignment (standard CSS properties)
- Add eslint-disable comments for custom CSS variables
- Replace localStorage with plugin.settings
- Replace vault.delete with vault.trash
- Add .fleur-underline-wavy and .fleur-underline-solid CSS classes (fix missing underline styles)
- Add void to unhandled Promises
- Add eslint-disable comment for fetch (SSE streaming)
- All setTimeout → window.setTimeout
- All as any → proper type checks
1.3.0
feat: 右键菜单改为彩色图标面板 + 设置界面优化
- 高亮改为 3 个马卡龙色圆点图标(金黄/天蓝/红粉)
- 划线改为直线和波浪两个 SVG 图标(固定深红)
- 设置界面:3 个高亮颜色选择器 + 下划线颜色选择器
- 下划线改用 text-decoration 实现(回退绝对定位方案)
- 加深所有默认颜色(深色系更明显)
- 导出笔记默认文件夹 FleurReader
v1.2.0
侧边栏标注文本点击展开/收起全文
- 新增:侧边栏高亮/划线文本默认显示 3 行,点击可展开查看完整内容,再次点击收起
v1.1.9: 彻底修复侧边栏重复注册
修复\n\n- 彻底修复侧边栏重复注册问题(不再在 onLayoutReady 中主动创建叶子,改为监听 layout-change 事件去重)\n- 解决插件更新/重启后出现两个「批注总览」的问题\n- 符合 Obsidian 社区审核规则
v1.1.8: 彻底修复侧边栏重复注册
修复
- 彻底修复侧边栏重复注册问题(激活侧边栏时先 detach 所有旧叶子,再创建新的)
- 修复插件更新时出现两个「批注总览」的问题
技术细节
- activateSidebar 现在采用激进去重策略:先 detach 所有已有叶子,等待 50ms 后创建新叶子
- 不再使用 detachLeavesOfType(符合社区审核规则)
- 符合 Obsidian 社区审核规则
v1.1.7: 修复侧边栏重复注册和批注重复保存
修复
- 修复侧边栏重复注册问题(热重载时清理旧叶子)
- 修复批注重复保存问题(addAnnotation 增加 id 去重检查)
- 符合 Obsidian 社区审核规则
v1.1.6: 修复右键菜单操作后侧边栏不刷新
修复
- 修复右键菜单操作后侧边栏不刷新的问题(预先捕获 filePath,避免菜单弹出后 PDF 视图失去焦点导致 getActiveFile 返回 null)
- 侧边栏 refresh 方法支持传入 targetPath 参数,不再只依赖 getActiveFile
- 符合 Obsidian 社区审核规则