GithubHelp home page GithubHelp logo

fleather-editor / fleather Goto Github PK

View Code? Open in Web Editor NEW
176.0 4.0 28.0 13.75 MB

Soft and gentle rich text editing for Flutter applications.

Home Page: https://fleather-editor.github.io

License: Other

Dart 95.93% Kotlin 0.01% Ruby 0.25% Swift 0.13% Objective-C 0.01% CMake 1.57% C++ 1.86% C 0.13% HTML 0.10%
dart flutter rich-text-editor wysiwyg

fleather's Introduction

Fleather & Parchment codecov pub package

Fleather

banner Soft and gentle rich text editing for Flutter applications based on Zefyr. It uses a document model named Parchment based on Notus.

πŸ‘‰ Live demo here.

Features

  • Works on Android, iOS, Web, macOS, Linux and Windows
  • Inline attributes like bold, italic, strikethrough and etc.
  • Line attributes like direction, alignment, heading, number and bullet list and etc.
  • Block attributes like code, quote and etc.
  • Supports inline and block embeds
  • Markdown-inspired semantics
  • Supports markdown shortcuts
  • Using Quill.js Delta as underlying data format by Parchment, Fleather is ready for collaborative editing using OT (Not provided as a built-in functionality)

Full documentation can be found here.

Get started

Add Fleather to your dependencies.

dependencies:
  flutter:
    sdk: flutter
  fleather: ^1.16.0

Usage

For a complete working project using Fleather, check our example.

  1. Create a FleatherController
document = ParchmentDocument.fromJson(json);
controller = FleatherController(document);
  1. Add FleatherEditor or FleatherField with a FleatherToolbar to your widgets.
Column(
  children: [
    FleatherToolbar.basic(controller: _controller!),
    Expanded(
      child: FleatherEditor(controller: controller),
    ),
    //or
    FleatherField(controller: controller)
  ],
),

Migration

For migration guides check out MIGRATION.md.

Credits

fleather's People

Contributors

ahmadre avatar albert-jan avatar amantoux avatar amir-p avatar britannio avatar canrau avatar cgestes avatar dsyrstad avatar equweiyu avatar gaganyadav80 avatar glynskyi avatar gyurimajercsik avatar jacquetc avatar jolancornevin avatar kontrano avatar maelchiotti avatar pulyaevskiy avatar simonbengtsson avatar zaynetro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

fleather's Issues

[Web] Cannot select color from toolbar

Steps to Reproduce

On web environment, attempting to select a color from toolbar will have to effect

Logs

Error: Unsupported operation: Platform._operatingSystem
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 288:49      throw_
dart-sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart 244:5                   _operatingSystem
dart-sdk/lib/io/platform_impl.dart 56:40                                          get operatingSystem
dart-sdk/lib/io/platform.dart 66:45                                               get _operatingSystem
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 941:8   get
dart-sdk/lib/io/platform.dart 157:51                                              get isAndroid
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 941:8   get
packages/fleather/src/widgets/editor_toolbar.dart 394:41                          _defaultSelectColor

How to customize a existed widget's style?

Is your feature request related to a problem? Please describe.
Is there a ability to customize a existed widget's style, such as change the color of h1?

Describe the solution you'd like
Export a api to customize the style to widgets or rules.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Markdown Serialization can't handle ordered lists

Steps to Reproduce

  1. Create a ParchmentDocument containing an ordered list like this:
1. Hello
2. This is a
3. List
  1. Serialize it as markdown
  2. see that it looks like this now: 1. Hello1. This is a1. List

Logs

The list also can't be deserialized anymore:

flutter: 'package:parchment/src/document/leaf.dart': Failed assertion: line 115 pos 12: 'value.isInline || value.isEmpty': Style cannot be applied to this leaf node: {block: ol}
leaf.dart:115
flutter: #2      LeafNode.applyStyle
leaf.dart:115
flutter: #3      LeafNode.formatAndOptimize
leaf.dart:108
flutter: #4      LineNode._insertSafe
line.dart:351
flutter: #5      LineNode.insert
line.dart:219
flutter: #6      ContainerNode.insert
node.dart:241
flutter: #7      ParchmentDocument._loadDocument
document.dart:322
flutter: #8      new ParchmentDocument.fromDelta
document.dart:64

Support document history

While editing document, it should be possible to navigate through the different versions of the document via an Undo/Redo functionality including Ctrl+Z / Ctrl+Shift+Z.

This history of the document will not be persisted so will only cover the current edition session of the document

Screenshots are very important

I always check the showcases and if I don't see one I go to next πŸ˜€

of course I read the feature list but not eye catchy.

sorry for the disruption!

Incorrect style when cursor is at start of line

Steps to Reproduce

  1. Run the example
  2. Set cursor here
image
  1. Although cursor is in front of a unordered list and not in a code block, the FleatherController returns style with code block and no list

Line height doesn't account for `SpanEmbed`s height

Considering the following embed

SpanEmbed square() => SpanEmbed('square');

with the embed builder

if (node.value.type == 'square') {
  return SizedBox(
    width: 120,
    height: 50,
    child: Container(
      color: Colors.red,
    ),
  );
}

and this input

{
  "insert": "Some text"
},
{
  "insert": {
    "_type": "square",
    "_inline": true
  }
},
{
  "insert": {
    "_type": "square",
    "_inline": true
  }
},
{
  "insert": "some other text\n"
}

results in

Capture d’écran 2022-12-11 aΜ€ 19 28 46

and with softwrap

image

Support text background color

I should be possible to define the background color of any selection within the editor.
Selection rectangle should be drawn over the background rectangle

Support for markdown decoding

Hi,

We need a wysiwyg markdown editor in our app and we are considering using Fleather package.
For this we need to initialize the editor with pre-existing markdown data and also extract markdown from the editor data.
We only need basic markdown for now.

I've spotted the ParchmentMarkdownCodec.encode function that let us convert deltas to markdown formatted text, but the ParchmentMarkdownCodec.decode isn't implemented yet and if I'm right it's needed to load markdown formatted text inside the editor.

Is there any way to do this actually?

Rich clipboard

When copy some text (including embeds), pasting it back in the same Fleather widget should preserve format & embeds.

Three use-cases are foreseen:

  1. Copy/paste from/to a Fleather editor to/from an external app.

    We assume that the OS clipboard holds HTML or plain text. The content should be converted to Delta thanks to HTML codec. Copying some text from Fleather to the clipboard will convert ParchmentDocument Deltas to HTML prior to setting it to the clipboard.
  2. Copy from a Fleather editor to another Fleather editor.

    Copying from one Fleather editor to another Fleather editor should be using Delta format
  3. Copy from a position to another position within a same Fleather editor

    Same as 2.

How to write Integration Tests targeting `Fleather Editor` and entering text in it.

Steps to Reproduce

  1. Target RawEditor using final editor = find.byType(RawEditor)
  2. Tap on FleatherField using tester.tap(editor)
  3. Enter text using tester.enterText("Hey there")

Logs

Nothing happens after tester.enterText is called and test is completed, no text in the FleatherField

[βœ“] Flutter (Channel stable, 3.7.11, on Ubuntu 20.04.6 LTS 5.15.0-69-generic, locale en_US.UTF-8)
    β€’ Flutter version 3.7.11 on channel stable at /home/nitesh/snap/flutter/common/flutter
    β€’ Upstream repository [email protected]:flutter/flutter.git
    β€’ Framework revision f72efea43c (3 weeks ago), 2023-04-11 11:57:21 -0700
    β€’ Engine revision 1a65d409c7
    β€’ Dart version 2.19.6
    β€’ DevTools version 2.20.1

[βœ“] Android toolchain - develop for Android devices (Android SDK version 33.0.0-rc4)
    β€’ Android SDK at /home/nitesh/Android/Sdk
    β€’ Platform android-33, build-tools 33.0.0-rc4
    β€’ ANDROID_HOME = /home/nitesh/Android/Sdk
    β€’ Java binary at: /snap/android-studio/125/android-studio/jre/bin/java
    β€’ Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)
    β€’ All Android licenses accepted.

[βœ“] Chrome - develop for the web
    β€’ Chrome at google-chrome

[βœ“] Linux toolchain - develop for Linux desktop
    β€’ clang version 10.0.0-4ubuntu1
    β€’ cmake version 3.16.3
    β€’ ninja version 1.10.0
    β€’ pkg-config version 0.29.1

[βœ“] Android Studio (version 2021.3)
    β€’ Android Studio at /snap/android-studio/125/android-studio
    β€’ Flutter plugin version 72.1.1
    β€’ Dart plugin version 213.7433
    β€’ Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[βœ“] VS Code (version 1.77.1)
    β€’ VS Code at /usr/share/code
    β€’ Flutter extension version 3.62.0

How to change the editor font size

I don't mean Heading attributes, I want to give the font a special font size.
I tried to wrap FleatherEditor with Theme and changed Textheme but It was not successful.

Inserting new line while toolbar being displayed throws exception

Steps to Reproduce

  1. Run the example app
  2. Make toolbar visible (by selecting a part of text or tapping somewhere)
  3. Insert new line (by pressing enter)

Logs

The following assertion was thrown building _OverlayEntryWidget-[LabeledGlobalKey<_OverlayEntryWidgetState>#e1f42](dirty, state: _OverlayEntryWidgetState#c8565):
No child at position TextPosition(offset: 28, affinity: TextAffinity.downstream)
'package:fleather/src/rendering/editable_box.dart':
Failed assertion: line 245 pos 12: 'targetChild != null'

When the exception was thrown, this was the stack: 
#2      RenderEditableContainerBox.childAtPosition (package:fleather/src/rendering/editable_box.dart:245:12)
#3      RenderEditor.getEndpointsForSelection (package:fleather/src/rendering/editor.dart:364:21)
#4      RawEditorState.contextMenuAnchors (package:fleather/src/widgets/editor.dart:1579:22)
#5      defaultContextMenuBuilder (package:fleather/src/widgets/editor.dart:41:34)
#6      RawEditorState._handleSelectionChanged.<anonymous closure> (package:fleather/src/widgets/editor.dart:1121:40)
#7      EditorTextSelectionOverlay._buildToolbar (package:fleather/src/widgets/text_selection.dart:314:35)
#8      _OverlayEntryWidgetState.build (package:flutter/src/widgets/overlay.dart:259:34)
#9      StatefulElement.build (package:flutter/src/widgets/framework.dart:5080:27)
#10     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4968:15)
#11     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5133:11)
#12     Element.rebuild (package:flutter/src/widgets/framework.dart:4690:5)
#13     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2743:19)
#14     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:863:21)
#15     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1289:15)
#16     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1218:9)
(elided 2 frames from class _AssertionError)

Selection toolbar wrong positioning

Steps to Reproduce

  1. Run the example app
  2. Select the heading text ("Fleather")
  3. Instead of displaying it right above or under the selected text, it appears way below it.

Custom text style and line height

Hi guys!

I'm discovering the fleather editor, and it looks perfect ! I have two questions that remain answerless after my researches on the web and this repo.

  • I was wondering how I can customize the different text styles ?
  • And why is the line height so big for the normal text ? It seems we can't have compact normal text lines for paragraphs ?

Below an image of my integration if needed :

image

Thansk for your help!

Emoji handling

This issue is more like a question.

Quill delta uses String.length when calculating the length of inserted string. This works with normal text but with a single emoji it returns the length=2. This works alright when you handle Parchment doc. My problem is that I convert Parchment doc to my own format where I count characters.

Do you have any suggestions how to bridge these two worlds together?

My only thought so far was to replace emojis with inline embeds.

Sample test:

    test('insert after emoji', () {
      final doc = ParchmentDocument();
      doc.insert(0, 'πŸ˜€');
      doc.insert(1, '!');
      final expectedDoc = Delta()
        ..insert('πŸ˜€1\n');
      expect(doc.toDelta(), expectedDoc);
    });

Output:

00:17 +162 -1: parchment/test/document_test.dart: ParchmentDocument insert after emoji [E]
  Expected: Delta:<insert⟨ πŸ˜€1⏎ ⟩>
    Actual: Delta:<insert⟨ �!�⏎ ⟩>

  package:test_api               expect
  test/document_test.dart 403:7  main.<fn>.<fn>

P.S I see that Fleather imports characters package but I don't see where that package is used. Is it used anywhere?

Indentation issues when applied to checklist

Steps to Reproduce

  1. Create a checklist with 3 items
  2. Apply indentation to the second one
  3. Apply indentation twice to third one
    Indentation is heterogenous
  4. de-indent twice third item
    Item isn't in the right place

Updating widget breaks undo/redo

Cause

When updating widget, changes are stacked in old widget's HistoryStack instance while undo/redo is performed on new widget stack

Typing in editor adds the previous typed text after recreating controller

I've only experienced this issue on Android. Only way to prevent it for now is to recreate editor widget state every time controller changes.

Steps to Reproduce

  1. Type something in editor
  2. Recreate controller
  3. Type something in editor

I haven't done any investigations yet but I think this issue roots in our RawEditorStateTextInputClientMixin and its _lastKnownRemoteTextEditingValue. I believe this issue will be solved after upgrading package to support Flutter 3.3 (By using granular text updates)

Recreating a new controller and passing it to editor I'm getting this log:

E/MethodChannel#flutter/textinput(10622): Failed to handle method call
E/MethodChannel#flutter/textinput(10622): java.lang.IndexOutOfBoundsException: invalid composing start: 0
E/MethodChannel#flutter/textinput(10622): 	at io.flutter.embedding.engine.systemchannels.TextInputChannel$TextEditState.<init>(TextInputChannel.java:777)
E/MethodChannel#flutter/textinput(10622): 	at io.flutter.embedding.engine.systemchannels.TextInputChannel$TextEditState.fromJson(TextInputChannel.java:738)
E/MethodChannel#flutter/textinput(10622): 	at io.flutter.embedding.engine.systemchannels.TextInputChannel$1.onMethodCall(TextInputChannel.java:101)
E/MethodChannel#flutter/textinput(10622): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
E/MethodChannel#flutter/textinput(10622): 	at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295)
E/MethodChannel#flutter/textinput(10622): 	at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:319)
E/MethodChannel#flutter/textinput(10622): 	at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
E/MethodChannel#flutter/textinput(10622): 	at android.os.Handler.handleCallback(Handler.java:938)
E/MethodChannel#flutter/textinput(10622): 	at android.os.Handler.dispatchMessage(Handler.java:99)
E/MethodChannel#flutter/textinput(10622): 	at android.os.Looper.loop(Looper.java:246)
E/MethodChannel#flutter/textinput(10622): 	at android.app.ActivityThread.main(ActivityThread.java:8633)
E/MethodChannel#flutter/textinput(10622): 	at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#flutter/textinput(10622): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
E/MethodChannel#flutter/textinput(10622): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
E/flutter (10622): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: PlatformException(error, invalid composing start: 0, null, java.lang.IndexOutOfBoundsException: invalid composing start: 0
E/flutter (10622): 	at io.flutter.embedding.engine.systemchannels.TextInputChannel$TextEditState.<init>(TextInputChannel.java:777)
E/flutter (10622): 	at io.flutter.embedding.engine.systemchannels.TextInputChannel$TextEditState.fromJson(TextInputChannel.java:738)
E/flutter (10622): 	at io.flutter.embedding.engine.systemchannels.TextInputChannel$1.onMethodCall(TextInputChannel.java:101)
E/flutter (10622): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
E/flutter (10622): 	at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295)
E/flutter (10622): 	at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:319)
E/flutter (10622): 	at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
E/flutter (10622): 	at android.os.Handler.handleCallback(Handler.java:938)
E/flutter (10622): 	at android.os.Handler.dispatchMessage(Handler.java:99)
E/flutter (10622): 	at android.os.Looper.loop(Looper.java:246)
E/flutter (10622): 	at android.app.ActivityThread.main(ActivityThread.java:8633)
E/flutter (10622): 	at java.lang.reflect.Method.invoke(Native Method)
E/flutter (10622): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
E/flutter (10622): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
E/flutter (10622): )
E/flutter (10622): #0      JSONMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:164:7)
E/flutter (10622): #1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:167:18)
E/flutter (10622): <asynchronous suspension>

flutter doctor -v:

[βœ“] Flutter (Channel stable, 3.0.4, on macOS 12.4 21F79 darwin-arm, locale
    en-US)
    β€’ Flutter version 3.0.4 at /Users/amirpanahandeh/flutter
    β€’ Upstream repository https://github.com/flutter/flutter.git
    β€’ Framework revision 85684f9300 (9 weeks ago), 2022-06-30 13:22:47 -0700
    β€’ Engine revision 6ba2af10bb
    β€’ Dart version 2.17.5
    β€’ DevTools version 2.12.2

[βœ“] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    β€’ Android SDK at /Users/amirpanahandeh/SDK
    β€’ Platform android-32, build-tools 30.0.3
    β€’ ANDROID_HOME = /Users/amirpanahandeh/SDK
    β€’ Java binary at: /Applications/Android
      Studio.app/Contents/jre/Contents/Home/bin/java
    β€’ Java version OpenJDK Runtime Environment (build
      11.0.12+0-b1504.28-7817840)
    β€’ All Android licenses accepted.

[βœ“] Xcode - develop for iOS and macOS (Xcode 13.4.1)
    β€’ Xcode at /Applications/Xcode.app/Contents/Developer
    β€’ CocoaPods version 1.11.3

[βœ“] Chrome - develop for the web
    β€’ Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[βœ“] Android Studio (version 2021.2)
    β€’ Android Studio at /Applications/Android Studio.app/Contents
    β€’ Flutter plugin can be installed from:
      πŸ”¨ https://plugins.jetbrains.com/plugin/9212-flutter
    β€’ Dart plugin can be installed from:
      πŸ”¨ https://plugins.jetbrains.com/plugin/6351-dart
    β€’ Java version OpenJDK Runtime Environment (build
      11.0.12+0-b1504.28-7817840)

[βœ“] IntelliJ IDEA Community Edition (version 2021.1.3)
    β€’ IntelliJ at /Applications/IntelliJ IDEA CE.app
    β€’ Flutter plugin version 58.0.3
    β€’ Dart plugin version 211.7727

[βœ“] VS Code (version 1.70.2)
    β€’ VS Code at /Applications/Visual Studio Code.app/Contents
    β€’ Flutter extension version 3.46.0

[βœ“] Connected device (3 available)
    β€’ SM A015F (mobile) β€’ R9HN60D11QJ β€’ android-arm    β€’ Android 11 (API 30)
    β€’ macOS (desktop)   β€’ macos       β€’ darwin-arm64   β€’ macOS 12.4 21F79
      darwin-arm
    β€’ Chrome (web)      β€’ chrome      β€’ web-javascript β€’ Google Chrome
      104.0.5112.101

[βœ“] HTTP Host Availability
    β€’ All required HTTP hosts are available

β€’ No issues found!

Minimum code to reproduce:

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final focusNode = FocusNode();
  var controller = FleatherController();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: FleatherField(controller: controller, focusNode: focusNode),
        floatingActionButton: FloatingActionButton(
          onPressed: () => setState(() => controller = FleatherController()),
          child: const Icon(Icons.close),
        ),
      ),
    );
  }
}
telegram-cloud-document-4-5802932096037031070.mp4

How to define shortcut for a custom widget

Is your feature request related to a problem? Please describe.
Is there anyway to define shortcut for a custom widget?

Describe the solution you'd like
Is there anyway to define shortcut for a custom widget? For example, when I typed ```json and followed by Enter , it should auto display my custom view with prettied json format.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Light theme inline code wrong color

Steps to Reproduce

  1. Create MaterialApp using Material3
MaterialApp(
  theme: ThemeData(useMaterial3: true)
  ...
);
  1. Observe the foreground color for an inline code span

Simulator Screenshot - iPhone 14 (16 2) - 2023-06-30 at 10 07 08

Environment

  • iOS Simulator
  • Flutter version 3.10.5 stable
  • Fleather version fleather: ^1.9.
Doctor summary (to see all details, run flutter doctor -v):
[βœ“] Flutter (Channel stable, 3.10.5, on macOS 13.4 22F66 darwin-arm64, locale en-US)
[βœ“] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1)
[βœ“] Xcode - develop for iOS and macOS (Xcode 14.3.1)
[βœ“] Chrome - develop for the web
[βœ“] Android Studio (version 2022.1)
[βœ“] VS Code (version 1.79.2)
[βœ“] Connected device (3 available)
[βœ“] Network resources

β€’ No issues found!

Toolbar doesn't appear after a long press while gaining focus

Steps to reproduce

  1. Empty document in example (select all - delete)
  2. Open example menu, then close it
  3. long press on document -> nothing appears (toolbar should appear)

Workaround is to type some text and then the long press (or the double tap) will cause the toolbar to appear.

This is particularly annoying for users who wish to paste something in a new document.
Their impression is that they cannot paste things. They end up not using the product

Video

Test coverage

CI should not allow test coverage regressions.

This include:

  • ability to monitor
  • CI to provide test coverage report
  • CI to succeed only in case of test coverage non regression

Open HTML document

Hey,

I am currently writing a mobile app for a CMS I develop. In the web app I currently use tinyMCE, is it possible to load the HTML into fleather or convert it to open?

Greetings
DerKnerd

Deleting line feed between some block causes an error

Steps to Reproduce

Enregistrement.de.l.ecran.2023-05-12.a.19.47.20.mov
The following assertion was thrown building TextSelectionHandleOverlay(state: _TextSelectionHandleOverlayState#abda9(ticker inactive)):
No child at position TextPosition(offset: 414, affinity: TextAffinity.downstream)
'package:fleather/src/rendering/editable_box.dart':
Failed assertion: line 245 pos 12: 'targetChild != null'

The relevant error-causing widget was: 
  TextSelectionHandleOverlay TextSelectionHandleOverlay:file:///Users/alanmantoux/Coding/fleather/packages/fleather/lib/src/widgets/text_selection.dart:256:12
When the exception was thrown, this was the stack: 
#2      RenderEditableContainerBox.childAtPosition (package:fleather/src/rendering/editable_box.dart:245:12)
#3      RenderEditor.preferredLineHeight (package:fleather/src/rendering/editor.dart:714:19)
#4      _TextSelectionHandleOverlayState.build (package:fleather/src/widgets/text_selection.dart:458:44)
#5      StatefulElement.build (package:flutter/src/widgets/framework.dart:5198:27)
#6      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5086:15)
#7      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5251:11)
#8      Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7)
#9      StatefulElement.update (package:flutter/src/widgets/framework.dart:5274:5)
#10     Element.updateChild (package:flutter/src/widgets/framework.dart:3686:15)
#11     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5111:16)
#12     Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7)
#13     ProxyElement.update (package:flutter/src/widgets/framework.dart:5417:5)
#14     Element.updateChild (package:flutter/src/widgets/framework.dart:3686:15)
#15     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5111:16)
#16     Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7)
#17     ProxyElement.update (package:flutter/src/widgets/framework.dart:5417:5)
#18     Element.updateChild (package:flutter/src/widgets/framework.dart:3686:15)
#19     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5111:16)
#20     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5251:11)
#21     Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7)
#22     StatefulElement.update (package:flutter/src/widgets/framework.dart:5274:5)
#23     Element.updateChild (package:flutter/src/widgets/framework.dart:3686:15)
#24     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5111:16)
#25     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5251:11)
#26     Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7)
#27     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2780:19)
#28     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:903:21)
#29     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:358:5)
#30     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1284:15)
#31     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1214:9)
#32     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1072:5)
#33     _invoke (dart:ui/hooks.dart:142:13)
#34     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:359:5)
#35     _drawFrame (dart:ui/hooks.dart:112:31)
(elided 2 frames from class _AssertionError)
====================================================================================================

(Question) How do I take advantage of the collaborative editing ready features?

I'm trying to develop an OT collaborative text editor, and I think Fleather could help me. In the Pub.dev page it says:

"Using Quill.js Delta as underlying data format by Parchment, Fleather is ready for collaborative editing using OT (Not provided as a built-in functionality)"

As I'm not familiar with such technologies, I'm a bit lost in what Fleather actually provides in that sense.

From my point of view, I'd need a callback for when an operation is performed (insert, remove, ...). The default TextField of Flutter is no use for my use-case since onChanged only gives me the full text, and not the inserted/removed text (or character) and the corresponding index.

I hope I managed to explain my problem. Is there anyone who could point me in the right direction?

Support Flutter 3.3

Flutter 3.3 again has changes in text editing API and now provides granular text changes (deltas).

assign method to text

This isn't problem, I want a new feature,

Can I apply a method to a text, like onLaunchUrl in FleatherEditor Widget , which is executed when we consider a link for a text, but I want to consider another task for the text and have it executed when I click on that part of the text?

Typing Japanese alphabet does not yield correct result

Steps to Reproduce

  1. Open system setting
  2. Select "Keyboard Tab"
  3. Select "Edit" under Text input - Input Sources
  4. Click on the "+" sign at the lower bottom
  5. Select "Japanese - Romaji" and "add"
  6. Make sure "Show input menu in menu bar" is enabled
  7. Click "Done"
  8. On the top right screen, you should see [A] icon. Click on it and change it to [あ]
  9. Click again and uncheck ”Live conversion" because it does some smart conversion but the behavior is inconsistent.
  10. In [あ] Japanese input mode, type "kyouha", hit [space] to convert it to Kanji, and finally hit [enter] key to confirm the conversion.

Expected result:

今ζ—₯は

Actual result:

γγ‚‡γ†γ―δ»Šζ—₯は

Environment

  • Chrome
  • Flutter version: 3.10.5
  • Fleather version: 1.9.0
  • Parchment version: 1.9.0

Logs

There is no error log when the issue happens.

Screen recording

Screen.Recording.2023-07-06.at.10.27.46.AM.mov

Update embed builder API

There are a few issues with the current embed builder API:

  1. It's verbose.
  2. You need to rewrite builder for the built-in embeds (We have only one built-in embed right now but it can change in future) if you want to provide your own builder.

Suppose that I have an embed type of icon. My embedBuilder would be this if I want to support built-in embeds (currently we only have horizontal rule) too.

embedBuilder: (context, node) {
  if (node.value.type == 'hr') {
    final theme = FleatherTheme.of(context);
    return Divider(
      height: theme.paragraph.style.fontSize *
          theme.paragraph.style.height,
      thickness: 2,
      color: Colors.grey.shade200,
    );
  }
  if (node.value.type == 'icon') {
    final data = node.value.data;
    return Icon(
      IconData(int.parse(data['codePoint']),
          fontFamily: data['fontFamily']),
      color: Colors.red,
    );
  }
  throw UnimplementedError();
},

Proposal: Instead of Widget Function(BuildContext context, EmbedNode node) as embed builder, we can have a Map<String, Widget Function(BuildContext context, EmbedNode node)> where the key is EmbedNode.EmbeddableObject.type. This way we can easily merge provided Map with a default internal Map inside editor and there is no need to rewrite built-in embed builders. It's more flexible than the current API.

Previous example can be written to this:

embedBuilder: {
  'icon': (context, node) {
    final data = node.value.data;
    return Icon(
      IconData(int.parse(data['codePoint']),
          fontFamily: data['fontFamily']),
      color: Colors.red,
    );
  }
},

Cons: Using current API we are able to return a default widget in case embed is not supported. With this change we can have a default embed builder too, which will be called if the Map does not contain EmbedNode.EmbeddableObject.type.

fallbackEmbedBuilder: (context, node) {
    return Text('Not Supported');
},

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.