-
Notifications
You must be signed in to change notification settings - Fork 467
fix: convert HTML to TipTap JSON format in data migration #2886
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: convert HTML to TipTap JSON format in data migration #2886
Conversation
The data migration for desktop app was not restoring memos and summaries because the importer was converting HTML to plain text, but the frontend expects TipTap JSON format. This change: - Adds html_to_tiptap_json() function to convert HTML content to valid TipTap JSON format - Updates session_to_imported_note() to use the new function for raw_md and enhanced_content fields - Properly handles paragraphs, line breaks, and JSON escaping Co-Authored-By: john@hyprnote.com <john@hyprnote.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
✅ Deploy Preview for hyprnote canceled.
|
✅ Deploy Preview for howto-fix-macos-audio-selection canceled.
|
✅ Deploy Preview for hyprnote-storybook canceled.
|
| fn escape_json_string(s: &str) -> String { | ||
| s.replace('\\', "\\\\") | ||
| .replace('"', "\\\"") | ||
| .replace('\n', "\\n") | ||
| .replace('\r', "\\r") | ||
| .replace('\t', "\\t") | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The escape_json_string() function is missing escape handling for several JSON control characters that could appear in migrated content. Specifically, it doesn't escape:
- Backspace (\b / U+0008)
- Form feed (\f / U+000C)
- Other control characters (U+0000 to U+001F)
If the stripped HTML contains any of these characters (e.g., from malformed data or edge cases), the generated JSON will be invalid and fail to parse in the frontend.
Fix: Add comprehensive control character escaping:
fn escape_json_string(s: &str) -> String {
s.chars()
.map(|c| match c {
'\\' => "\\\\".to_string(),
'"' => "\\\"".to_string(),
'\n' => "\\n".to_string(),
'\r' => "\\r".to_string(),
'\t' => "\\t".to_string(),
'\u{0008}' => "\\b".to_string(),
'\u{000C}' => "\\f".to_string(),
c if c.is_control() => format!("\\u{:04x}", c as u32),
c => c.to_string(),
})
.collect()
}| fn escape_json_string(s: &str) -> String { | |
| s.replace('\\', "\\\\") | |
| .replace('"', "\\\"") | |
| .replace('\n', "\\n") | |
| .replace('\r', "\\r") | |
| .replace('\t', "\\t") | |
| } | |
| fn escape_json_string(s: &str) -> String { | |
| s.chars() | |
| .map(|c| match c { | |
| '\\' => "\\\\".to_string(), | |
| '"' => "\\\"".to_string(), | |
| '\n' => "\\n".to_string(), | |
| '\r' => "\\r".to_string(), | |
| '\t' => "\\t".to_string(), | |
| '\u{0008}' => "\\b".to_string(), | |
| '\u{000C}' => "\\f".to_string(), | |
| c if c.is_control() => format!("\\u{:04x}", c as u32), | |
| c => c.to_string(), | |
| }) | |
| .collect() | |
| } | |
Spotted by Graphite Agent
Is this helpful? React 👍 or 👎 to let us know.
Address Graphite AI review feedback by adding comprehensive control character escaping including backspace, form feed, and other control characters (U+0000 to U+001F) to prevent invalid JSON from malformed data or edge cases. Co-Authored-By: john@hyprnote.com <john@hyprnote.com>
Summary
Fixes data migration for desktop app not restoring memos and summaries.
Root cause: The importer was converting HTML content (
raw_memo_html,enhanced_memo_html) to plain text usingstrip_html_tags(), but the frontend expects TipTap JSON format. When the frontend tries to parse the content as JSON, it fails and falls back to an empty document.Fix: Added
html_to_tiptap_json()function that converts HTML to valid TipTap JSON format:\n\n) and handles line breaks (by\n) withhardBreaknodesUpdates since last revision
escape_json_string()to handle all JSON control characters (backspace, form feed, and other control characters) per Graphite AI review feedbackReview & Testing Checklist for Human
EMPTY_TIPTAP_DOCandmd2json()produce inpackages/tiptap/src/shared/utils.ts- ensure the format is compatibleRecommended Test Plan
Notes
cargo checklocally due to pre-existing workspace issue (missingplugins/export/Cargo.toml)html_to_tiptap_json()Link to Devin run: https://app.devin.ai/sessions/7fd54989cc90491aa17bf18218f7b425
Requested by: @ComputelessComputer