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

Provide default native implementation of ClipboardService without external dependencies #2229

Open
1 task done
EchoEllet opened this issue Sep 15, 2024 · 5 comments · May be fixed by #2230
Open
1 task done

Provide default native implementation of ClipboardService without external dependencies #2229

EchoEllet opened this issue Sep 15, 2024 · 5 comments · May be fixed by #2230
Assignees
Labels
enhancement New feature or request in_progress

Comments

@EchoEllet
Copy link
Collaborator

EchoEllet commented Sep 15, 2024

Is there an existing issue for this?

Use case

The functionality of Flutter Clipboard is limited and only supports retrieving the content as plain text since the implementation can be different on each platform, there is no standard.

This leads us to use plugins for accessing the platform APIs we need for some features, such as rich text pasting, which allows the user to copy content from websites and apps and paste them into the editor, with the links, styles, etc...

Why replace pasteboard with super_clipboard?

Previously, we were using pasteboard for accessing the clipboard, I had to replace it with super_clipboard since it lacks support for Android (for all methods), and not all functions support all platforms, the static getter html only supports Windows and Web and it doesn't seem to work on Web either since web require registering the paste event. It also was a bit outdated (2y since the last update on pub.dev), it has been updated recently (8 days ago) to support Flutter/WASM.

Why moved super_clipboardto flutter_quill_extensions?

super_clipboard uses Rust to access platform APIs and a bridge, which seems to be experimental and caused a lot of build failure issues for a lot of users, some of the issues are in runtime and are unexpected, I have tried it out on Linux and macOS without any issues other than it takes long to build the app for the first time. So we had to exclude it from flutter_quill and move it to flutter_quill_extensions, which also requires calling a function manually to use the plugin implementation.

It also requires minSdkVersion to be at least 23 which seems to be an issue since some apps still use 19 or 21.

See #1914 for more details.

Why move super_clipboard into its own package/module?

I initially wanted to move super_clipboard into its own package (quill_super_clipboard) to allow flutter_quill users to use it without flutter_quill_extensions and users of flutter_quill_extensions to use the extensions package without super_clipbaord. We were interested in having fewer dependencies on the user's project.

Since those issues still persist, we will introduce a breaking change and move the super_clipboard outside of flutter_quill_extensions.

What about rich_clipboard?

It has been discontinued.

What would be the replacement?

As a replacement, we will provide a default native implementation for the functionalities we need instead of relying on third-party plugins. We have introduced quill_native_bridge in #2194 and removed device_info_plus to have more control over the implementation, only the functionalities we need which result in a more lightweight package, and fewer issues and conflicts with the user dependencies if a major breaking release introduced in a dependency, you can update directly without having to update the Flutter Quill project first, when a new feature comes out in Flutter, like a major breaking release such as support for Flutter/WASM or breaking changes in Dart or updating Android Gradle Plugin, we can update the project directly from this repo.

If we manage to get this feature working on all platforms, you probably won't need pasteboard or super_clipboard for this feature anymore.

We only need a way to access the HTML and Markdown from the system clipboard (regardless if it was a file or a text copied from an app or website).

Web

we have already introduced support for this feature in #2009 using paste_event,. There seems to be an issue, see #2220.

Mobile (Android and iOS)

  • iOS: UIPasteboard
  • Android: android.content.ClipboardManager

Desktop

it will take longer since I'm less familiar with the native desktop than the native mobile, as such I will have to delay this until some other time (probably don't have plans), so you will have to provide your own implementation, or use super_clipboard. If anyone is familiar with those APIs on desktop, feel free to submit a PR

  • macOS: NSPasteboard

Proposal

Already implemented this feature on Android, iOS, and macOS.

QuillNativeBridgeAndroidDemo.mov
QuillNativeBridgeIosDemo.mov
Screenshot

image

If we managed to get it working on the web (if issue #2220 is solved), we would be ready to introduce a breaking change.

@EchoEllet
Copy link
Collaborator Author

EchoEllet commented Sep 15, 2024

@CatHood0 Not related to this issue but can you take a look at this issue when you have the time?

Issue Details

Select and copy the following from issue #2009 (an example):

image

Paste it into the editor in the example and you will have this error (on macOS)

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument(s): color format not supported: var(--fgColor-muted, var(--color-fg-muted))
#0      colorToHex (package:flutter_quill_delta_from_html/parser/colors.dart:56:5)
colors.dart:56
#1      validateAndGetColor (package:flutter_quill_delta_from_html/parser/colors.dart:22:10)
colors.dart:22
#2      parseStyleAttribute (package:flutter_quill_delta_from_html/parser/html_utils.dart:54:25)
html_utils.dart:54
#3      processNode (package:flutter_quill_delta_from_html/parser/node_processor.dart:60:13)
node_processor.dart:60
#4      processNode (package:flutter_quill_delta_from_html/parser/node_processor.dart:123:7)
node_processor.dart:123
#5      processNode (package:flutter_quill_delta_from_html/parser/node_processor.dart:123:7)
node_processor.dart:123
#6      HtmlOperations.resolveCurrentElement (package:flutter_quill_delta_from_html/parser/html_to_operation.dart:44:9)
html_to_operation.dart:44
#7      DefaultHtmlToOperations.listToOp (package:flutter_quill_delta_from_html/parser/default_html_to_ops.dart:219:22)
default_html_to_ops.dart:219
#8      HtmlOperations.resolveCurrentElement (package:flutter_quill_delta_from_html/parser/html_to_operation.dart:52:36)
html_to_operation.dart:52
#9      HtmlToDelta.nodeToOperation (package:flutter_quill_delta_from_html/parser/html_to_delta.dart:222:38)
html_to_delta.dart:222
#10     HtmlToDelta.convert (package:flutter_quill_delta_from_html/parser/html_to_delta.dart:129:42)
html_to_delta.dart:129
#11     DeltaX.fromHtml (package:flutter_quill/src/delta/delta_x.dart:50:24)
delta_x.dart:50
#12     QuillControllerRichPaste.pasteHTML (package:flutter_quill/src/controller/quill_controller_rich_paste.dart:40:41)
quill_controller_rich_paste.dart:40
<asynchronous suspension>
#13     QuillController.clipboardPaste (package:flutter_quill/src/controller/quill_controller.dart:577:35)
quill_controller.dart:577
<asynchronous suspension>
#14     QuillRawEditorState.pasteText (package:flutter_quill/src/editor/raw_editor/raw_editor_state.dart:147:9)
raw_editor_state.dart:147
<asynchronous suspension>

On iOS:

Connecting to VM Service at ws://127.0.0.1:57100/B_FJsvoNFPU=/ws
Connected to the VM Service.
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument(s): color format not supported: var(--fgColor-muted, var(--color-fg-muted))
#0      colorToHex (package:flutter_quill_delta_from_html/parser/colors.dart:56:5)
colors.dart:56
#1      validateAndGetColor (package:flutter_quill_delta_from_html/parser/colors.dart:22:10)
colors.dart:22
#2      parseStyleAttribute (package:flutter_quill_delta_from_html/parser/html_utils.dart:54:25)
html_utils.dart:54
#3      processNode (package:flutter_quill_delta_from_html/parser/node_processor.dart:60:13)
node_processor.dart:60
#4      processNode (package:flutter_quill_delta_from_html/parser/node_processor.dart:123:7)
node_processor.dart:123
#5      processNode (package:flutter_quill_delta_from_html/parser/node_processor.dart:123:7)
node_processor.dart:123
#6      HtmlOperations.resolveCurrentElement (package:flutter_quill_delta_from_html/parser/html_to_operation.dart:44:9)
html_to_operation.dart:44
#7      DefaultHtmlToOperations.listToOp (package:flutter_quill_delta_from_html/parser/default_html_to_ops.dart:219:22)
default_html_to_ops.dart:219
#8      HtmlOperations.resolveCurrentElement (package:flut<…>

Same issue on Android:

Unhandled Exception: Invalid argument(s): color format not supported: var(--textTertiary)
E/flutter (29830): #0      colorToHex (package:flutter_quill_delta_from_html/parser/colors.dart:56:5)
E/flutter (29830): #1      validateAndGetColor (package:flutter_quill_delta_from_html/parser/colors.dart:22:10)
E/flutter (29830): #2      parseStyleAttribute (package:flutter_quill_delta_from_html/parser/html_utils.dart:54:25)
E/flutter (29830): #3      processNode (package:flutter_quill_delta_from_html/parser/node_processor.dart:60:13)
E/flutter (29830): #4      processNode (package:flutter_quill_delta_from_html/parser/node_processor.dart:123:7)
E/flutter (29830): #5      processNode (package:flutter_quill_delta_from_html/parser/node_processor.dart:123:7)
E/flutter (29830): #6      HtmlOperations.resolveCurrentElement (package:flutter_quill_delta_from_html/parser/html_to_operation.dart:44:9)
E/flutter (29830): #7      DefaultHtmlToOperations.listToOp (package:flutter_quill_delta_from_html/parser/default_html_to_ops.dart:219:22)
E/flutter (29830): #8      HtmlOperations.resolveCurrentElement (package:flutter_quill_delta_from_html/parser/html_to_operation.dart:52:36)
E/flutter (29830): #9      HtmlToDelta.nodeToOperation (package:flutter_quill_delta_from_html/parser/html_to_delta.dart:222:38)
E/flutter (29830): #10     HtmlToDelta.convert (package:flutter_quill_delta_from_html/parser/html_to_delta.dart:129:42)
E/flutter (29830): #11     DeltaX.fromHtml (package:flutter_quill/src/delta/delta_x.dart:50:24)
E/flutter (29830): #12     QuillControllerRichPaste.pasteHTML (package:flutter_quill/src/controller/quill_controller_rich_paste.dart:40:41)
E/flutter (29830): <asynchronous suspension>
E/flutter (29830): #13     QuillController.clipboardPaste (package:flutter_quill/src/controller/quill_controller.dart:577:35)
E/flutter (29830): <asynchronous suspension>
E/flutter (29830): #14     QuillRawEditorState.pasteText (package:flutter_quill/src/editor/raw_editor/raw_editor_state.dart:147:9)
E/flutter (29830): <asynchronous suspension>
E/flutter (29830): 

For this case, it doesn't seems to be an issue on one specific platform however the HTML content can be very platform-dependent, and not everything can be validated, some attributes need to be ignored without throwing an error, throwing an error is suitable when reading or parsing the HTML to load it as a document. the parsing process itself should not be slightly different based on the platform regardless of the issue.

We might need to have a separate implementation specifically for pasting HTML content into the editor in flutter_quill, especially if fixing this issue affects the users of flutter_quill_delta_from_html who are using the package for a little bit different purpose.

@CatHood0
Copy link
Collaborator

@EchoEllet Thanks for reporting it. Must be an issue with how the package transform the colors from html to a color valid for Delta. I'll fix it soon.

@CatHood0
Copy link
Collaborator

CatHood0 commented Sep 15, 2024

We might need to have a separate implementation specifically for pasting HTML content into the editor

Are you suggesting to have a class that allows us to get the appropriate Delta without directly using the flutter_quill_delta_from_html package? Maybe doing this would allow us to have any other implementation later without having to remove almost any code and we can control any exception from that class.

@EchoEllet
Copy link
Collaborator Author

It's probably what I'm suggesting. We can rewrite the fromHtml specifically and only for this rich pasting feature, or maybe extract the needed parts from flutter_quill_delta_from_html and modify it to adjust the needs, we could also have slightly different implementation in flutter_quill_delta_from_html by having a separate class or provide an option in the package to check if what we want is to paste this Delta into the editor, and then will change the conversation process to fit.

Similarly, how vsc_quill_delta_to_html handle it:

final converter = QuillDeltaToHtmlConverter(
    ops,
    ConverterOptions.forEmail(),
  );

We should have more consideration before making this change. Is this something only needed for flutter_quill or more users interested in this feature?

Meanwhile, I think we're okay with fixing this color parsing issue above.
This shouldn't be a high priority issue.

@EchoEllet EchoEllet changed the title Provide default native implementation of ClipboardService for Android and iOS without external dependencies Provide default native implementation of ClipboardService without external dependencies Sep 15, 2024
@CatHood0
Copy link
Collaborator

CatHood0 commented Sep 15, 2024

Not related to this issue but can you take a look at this issue when you have the time?

This should be fixed already with the new version.

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