Skip to content

Preserve formatting when pasting - #62

Merged
janglad merged 5 commits into
mainfrom
fix/web-4052-pen-pasting-content-does-not-preserve-formatting
Sep 25, 2026
Merged

janglad merged 5 commits into
mainfrom
fix/web-4052-pen-pasting-content-does-not-preserve-formatting

Conversation

@janglad

@janglad janglad commented Sep 24, 2026 •

Copy link
Copy Markdown
Member

Before
Bullets, underline, ... lose formatting when pasting in from other rich text editors

Screen.Recording.2026-09-24.at.07.46.55.mov

After
Preserved. Tested with Apple Notes, Blocknote, Raycast notes

Screen.Recording.2026-09-24.at.15.15.36.mov

Summary

Fixes WEB-4052 by preserving common formatting when pasting HTML into Pen:

  • Links, lists, checklists, blockquotes, and text alignment
  • Bold, italic, underline, and strikethrough
  • Formatting expressed through simple stylesheet classes, including Apple Notes clipboard HTML
  • Consistent rendering across DOM, React, and Vue

Keeps CSS support intentionally narrow: .class and tag.class selectors with a closed set of formatting properties.


Note

Medium Risk
Changes the security-sensitive HTML sanitize/import path with new CSS parsing and inlining, though scope is intentionally closed and heavily tested; bundle size for interop also increases materially.

Overview
Fixes WEB-4052 by improving HTML paste/import so block structure, spacing, lists, inline marks, and alignment survive typical rich-text clipboard payloads (including Apple Notes class-based CSS).

Sanitize + import: Before DOMPurify strips <style>, the sanitizer inlines safe declarations from simple .class / tag.class rules onto matching elements; complex selectors and unsafe properties stay dropped. Inline styles now admit mark-bearing font-weight, font-style, and text-decoration* under the same closed filter. parseInlineContent maps those styles (and explicit resets like font-weight: normal) to Pen marks; lone block <br> becomes an empty paragraph while inline <br> becomes \n. domToBlocks maps text-align / align to a new textAlignment block prop.

Schema + renderers: Default text blocks gain optional textAlignment with HTML export round-trip; DOM, React, and Vue apply it via resolveBlockTextAlignment.

Corpus/tests: Apple Notes fixture is hand-captured; Google Docs expectations now keep span bold/italic. @input/pen-interop size budget rises ~13% for the stylesheet pass. Specs (SEC3, interop, empty-blocks EM8) document the narrowed CSS behavior.

Reviewed by Cursor Bugbot for commit b471046. Bugbot is set up for automated code reviews on this repo. Configure here.

This commit introduces functionality to preserve HTML block structure, inline marks, lists, and text alignment when pasting formatted HTML. Key changes include updates to the paste corpus to reflect these enhancements, as well as modifications to the DOM parsing and inline content handling to support text alignment properties. Additionally, tests have been added to ensure the correct preservation of marks and alignment during paste operations.
…ation

This commit introduces several updates to the HTML parsing and sanitization processes. Key changes include the addition of a DOMParser fallback for environments lacking Object.hasOwn, improvements to inline stylesheet handling, and the restructuring of style resolution logic to better support class-based styles. Additionally, the size limit baseline for the @input/pen-interop package has been updated to reflect changes in the handling of safe stylesheet declarations and text alignment properties. These enhancements aim to ensure more consistent preservation of formatting during HTML imports and pastes.
@janglad

janglad commented Sep 24, 2026

Copy link
Copy Markdown
Member Author

bugbot run

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread packages/extensions/interop/src/html/import/sanitize.ts
This commit updates the size limit baseline for the @input/pen-interop package to 118975 bytes, reflecting recent changes in the handling of safe stylesheet declarations. Additionally, it improves the parsing logic to ensure the preservation of the first rule after braceless at-rules in inline stylesheets. A new test has been added to verify this functionality, ensuring consistent formatting during HTML imports.
@janglad

janglad commented Sep 24, 2026

Copy link
Copy Markdown
Member Author

bugbot run

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

This commit improves the handling of pasted HTML by ensuring that blank-line spacing and breaks are preserved in the resulting content structure. Key changes include updates to the inline content parsing logic and the addition of tests to verify the correct preservation of breaks and empty paragraphs during HTML imports. These enhancements aim to provide a more accurate representation of the original formatting when pasting content.
@janglad

janglad commented Sep 24, 2026

Copy link
Copy Markdown
Member Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit b471046. Configure here.

This commit enhances the formatting of the clipboard importer parsing test by restructuring the test data for better clarity. The changes include consistent indentation and formatting of the test cases, ensuring that the structure is more readable and maintainable. This refactor aims to improve the overall quality of the test suite.
Comment thread packages/schema/src/textAlignmentProp.ts
@janglad
janglad merged commit c2208e9 into main Sep 25, 2026
35 checks passed
@janglad
janglad deleted the fix/web-4052-pen-pasting-content-does-not-preserve-formatting branch September 25, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants