Skip to content
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

Add "Paste as plain text" feature #1946

Open
1 task done
Alspb opened this issue Jun 23, 2024 · 8 comments
Open
1 task done

Add "Paste as plain text" feature #1946

Alspb opened this issue Jun 23, 2024 · 8 comments
Labels
enhancement New feature or request

Comments

@Alspb
Copy link
Contributor

Alspb commented Jun 23, 2024

Is there an existing issue for this?

Use case

It would be great to have "Paste as plain text" feature, as e.g. TextField on Android has.
Sometimes format is not needed, like when text is copied from browser.
Also, this should help avoid misunderstanding on when formatted or plain text is pasted, see #1772.

Proposal

Implement "Paste as plain text" feature and add it to the context menu for pasting. Maybe there should be an option on whether "Paste as plain text" should be included into that menu or not.

@Alspb Alspb added the enhancement New feature or request label Jun 23, 2024
@Alspb
Copy link
Contributor Author

Alspb commented Jun 23, 2024

It looks like to paste plain text one should disable the following code blocks from quill_controller.dart:

if (await _pasteHTML()) {
    updateEditor?.call();
    return true;
}
_applyPasteStyleAndEmbed(insertedText, index, containsEmbed);

But adding "Paste as plain text" to the context menu is not that straightforward, since the menu is implemented using EditableText.getEditableButtonItems.

@singerdmx
Copy link
Owner

@ellet0 Do you have any suggestion?

@EchoEllet
Copy link
Collaborator

EchoEllet commented Jun 26, 2024

If the user paste using the paste button above the keyboard, it should alwats paste as text. This behavior is specific to Android and will apply to all apps. As for the paste as plain text, we could also add the option to always paste as plain text and disable rich text pasting feature.

Notice that if you don't use flutter_quill_extensions, it will be displayed by default.

As for paste as plain text, it's might not be common or known by users, I would suggest having this option only if rich text paste is available.

@Alspb
Copy link
Contributor Author

Alspb commented Jul 5, 2024

Indeed, Android keyboards (though, probably no all) allow to paste as plain text, as it in fact stored in the clipboard. So, it's some kind of an option too: "Paste" button pastes rich text while the keyboard pastes the plain one. However, it doesn't help on other OS.

Notice that if you don't use flutter_quill_extensions, it will be displayed by default.

Not quite sure how to check if flutter_quill_extensions is used.
Do you mean that pasting as rich text is only available if flutter_quill_extensions is used? I can double-check but looks like text copied from the editor is always pasted as rich (but not sure about pasting from browser).

As for paste as plain text, it's might not be common or known by users, I would suggest having this option only if rich text paste is available.

Totally agree.
But there're some technical problems I see: adding "Paste as plain text" to the context menu on Android, dynamically identifying if "Paste as plain text" button should be in the toolbar, and finding an appropriate icon for "Paste as plain text" button. Though, maybe there's no real need in "Paste as plain text" in the toolbar...

@EchoEllet
Copy link
Collaborator

EchoEllet commented Jul 5, 2024

Not quite sure how to check if flutter_quill_extensions is used.

There are different ways, one of them is to check the type of ClipboardService static instance.

Do you mean that pasting as rich text is only available if flutter_quill_extensions is used? I can double-check but looks like text copied from the editor is always pasted as rich (but not sure about pasting from browser

Starting from 9.4.0, the usages of super_clipboard have been moved from flutter_quill to flutter_quill_extensions.

The rich text, gif, and image features are disabled by default. You will have to use the extensions package and call a function to override the default implementation.

The example already utilized the extensions package and called the FlutterQuillExtensions.useSuperClipboardPlugin.

@Alspb
Copy link
Contributor Author

Alspb commented Jul 7, 2024

Thanks, I'm able to change clipboard plugins by adding/removing FlutterQuillExtensions.useSuperClipboardPlugin, ClipboardService instance in the code confirms it.
However, for some reason I can't reproduce pasting formatted text copied from the browser, no matter which clipboard plugin I use. I mean that getHTML function inside _pasteHTML method always returns null, not sure why.

Nevertheless, if I copy some inline text from the editor (i.e., several words on the same line), the format is preserved (for example, bold words remain bold) after paste, even for the default clipboard plugin. In fact, it looks like clipboard is not used here since the copied text and it's format are stored in the editor itself, see clipboardSelection method. So, at least pasting from the editor is always rich.
At the same time, if several paragraphs are copied, the format is not preserved after paste. Maybe there's a reason behind this behavior but looks like a bug.

By the way, "instance" is misspelled in the code, we should correct it in the same PR: ClipboardServiceProvider.instacne.

@EchoEllet
Copy link
Collaborator

EchoEllet commented Jul 7, 2024

However, for some reason I can't reproduce pasting formatted text copied from the browser, no matter which clipboard plugin I use. I mean that getHTML function inside _pasteHTML method always returns null, not sure why.

That's usually because of the browser restrictions on using the clipboard on the Web.

Take a look at Super Clipboard Accessing clipboard on Web

Web browsers impose some restrictions when reading from clipboard. If value in clipboard has been copied from another application, user needs to confirm clipboard access (usually in form of popover). Asynchronous clipboard API is unavailable by default on Firefox.
To get around this limitation, super_clipboard provides a way to listen to a browser clipboard event, which is triggered when user presses the appropriate keyboard shortcut in browser window (or selects the option from menu).

Previously the Editor requested permission by default, then later it was disabled by default.

Nevertheless, if I copy some inline text from the editor (i.e., several words on the same line), the format is preserved (for example, bold words remain bold) after paste, even for the default clipboard plugin. In fact, it looks like clipboard is not used here since the copied text and it's format are stored in the editor itself

Yes, this was a feature before ClipboardService and super_clipboard integration. However, we might want to document this to be more specific. Developers might use flutter_quill_extensions for this feature even if they are only interested in it for the Editor itself.

By the way, "instance" is misspelled in the code, we should correct it in the same PR: ClipboardServiceProvider.instacne.

Luckily we haven't exported the ClipboardService or related classes yet, so we can correct and update them at any time, I knew we would make a breaking change after a short time after introducing it in 9.4.0 so I decided not to export them for know.

@EchoEllet
Copy link
Collaborator

By the way, "instance" is misspelled in the code, we should correct it in the same PR: ClipboardServiceProvider.instacne.

class ClipboardServiceProvider {
const ClipboardServiceProvider._();
static ClipboardService _instance = DefaultClipboardService();
static ClipboardService get instacne => _instance;
static void setInstance(ClipboardService service) {
_instance = service;
}
static void setInstanceToDefault() {
_instance = DefaultClipboardService();
}
}

It seems that static ClipboardService get instacne => _instance; is the only typo.

The private _instance is correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants