Skip to content

Conversation

@brianHarder
Copy link
Contributor

@brianHarder brianHarder commented Oct 2, 2025

Contributor checklist:

  • My contribution is not related to translations.
  • My commits are in nice logical chunks with good commit messages
  • My changes are rebased on the latest main branch
  • A pnpm run ready run passes successfully (more about tests here)
  • My changes are ready to be shipped to users

Description

This PR ensures that existing formatting is not inherited when unformatted text is pasted in to replace the existing text. To implement this change, index.ts in the ts/quill/signal-clipboard directory has been modified to add a check for select all. If a paste event happens when all text is selected, no formatting is applied. This PR partially addresses GH issue #6793.

I manually tested this PR by performing paste events in the mock environment. I tested that selecting all and pasting cleared the formatting and that pasting into a partial section kept the formatting. I also added a test file to simulate the paste all event in two scenarios - strikethrough and text with multiple formats applied - and check that no formatting is applied. I did all my testing on my laptop, which runs macOS 10.15.7.

Screen.Recording.2025-10-01.at.3.33.03.PM.mov

@trevor-signal trevor-signal self-requested a review October 2, 2025 15:26
@brianHarder brianHarder changed the title Formatting inheritance Copy-Paste Formatting Inheritance Oct 4, 2025
Copy link
Contributor

@trevor-signal trevor-signal left a comment

Choose a reason for hiding this comment

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

This is great, thank you! Just one question on the behavior difference between signal and external text.


// Check if we're selecting all content
const totalLength = this.quill.getLength();
const isSelectingAll = selection.length >= totalLength - 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, I see that quill.getLength() always includes an additional \n character, nice find!

if (selection.length === 0) {
formats = this.quill.getFormat(selection.index);
} else if (isSelectingAll || !signal) {
// No formatting for select-all or external plain text
Copy link
Contributor

Choose a reason for hiding this comment

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

Not including formats for external text is a departure from current behavior, and I think means:

  1. select formatted section in the compose box (but not the whole selection)
  2. paste behavior of unformatted text now varies:
    • paste with unformatted signal text -> inherits format
    • paste with unformatted external text -> stays unformatted

I'm not sure we want that difference in behavior. Let's preserve the original behavior here, unless there's a reason for the change I'm not thinking of.

import { SignalClipboard } from '../../quill/signal-clipboard/index.js';
import { QuillFormattingStyle } from '../../quill/formatting/menu.js';

class MockQuill {
Copy link
Contributor

Choose a reason for hiding this comment

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

this is very cool and will be useful!

@brianHarder
Copy link
Contributor Author

Thank you for the feedback! I've updated index.dom.ts to not remove formatting when pasting external tests, as well as changed file names as needed.

@trevor-signal trevor-signal self-requested a review October 31, 2025 15:49
@trevor-signal
Copy link
Contributor

Thanks @brianHarder! This has been merged internally and will be included in the next beta release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants