Planning Future Development Flutter Quill #2270
Replies: 5 comments 1 reply
-
Unfortunately, in Dart there is only a private and public scope. The most similar to Java's protected, or TypeScript, is the
|
Beta Was this translation helpful? Give feedback.
-
I had the same question since 2023, created an issue recently (#2250) to see if there are any developers who have the answer. The issue is that the reason is not documented enough, so even if there is a good reason it should be clear for future developers.
Sound like a better solution, we need to discuss this further but the only issue is that we need a good plan for fixing those issues since they introduce breaking changes, there are a number of issues, and fixing them is not backward compatible, the project is not in a state where we provide workarounds to make it backward compatible. See my suggestion in #2269. In short, we need a pre-release and Maybe a website for docs since users do want to search and have answers quickly, and even if everything is documented but we don't have a website, they will ask questions that are already answered in the
For code to be tree shaken in production mode or depending on the platform check, it's simple to solve as it's documented, but I'm still not sure about some cases and searched in Dart and Flutter repositories to find relevant questions but didn't find any. Need to ask Dart expert who do know how such features work internally and have worked with the Dart team or look at the code and test ourselves.
As @CatHood0 mentioned, it doesn't work as Java, Kotlin, and other languages, it will only give them a warning and doesn't require opt-in (otherwise causes a compilation error). We need to mention this in docs of anything that's experimental instead of annotating it, also give them a note about breaking changes in As for the We should consider a solution that ensures the developer will not be able to use those directly without knowing this is an internal API or experimental. Such as having a file that's not exported that does provide an extension for a class, or private member, or use the
LGTM. We also need to clean up all PRs since the start of the library until now. For #2251 attempt to cleanup #2026. Since I don't have any information about some of the decisions that were made, I was unable to complete the cleanup. I will probably have to change some things, introduce a breaking change, and possibly a regression or a design issue. |
Beta Was this translation helpful? Give feedback.
-
I believe that it was simply a premature design that was had at the beginning while the project was being created and then it was simply left as an immovable part. Probably just a mistake that was not taken into account and now we are seeing the problem. But, it would be better if someone knew why exactly |
Beta Was this translation helpful? Give feedback.
-
Update: See this comment. |
Beta Was this translation helpful? Give feedback.
-
I think |
Beta Was this translation helpful? Give feedback.
-
@singerdmx @EchoEllet @CatHood0 + other interested partners.
This starts a discussion on how to proceed to provide a stable and reliable rich text editor with a code base that is easy to understand, easy to fix problems, easy to introduce improvements and new features.
This is a first draft that is designed to provoke discussion and identify conceptual problems. There will be lots that are wrong and need rewriting. But, if we can organize how to approach this task, it will save us all a lot of time (we all know that time is always limited!).
Interface/API
The concept of an API (C# like languages use 'interface' keyword, dart has abstract classes) is used to separate design from implementation. 'Design' provides a documented definition of what is expected to be done. 'Implementation' provides how it is done and allows others to rewrite the implementation if the default does not do what they want.
For example:
Complex classes (such as QuillEditor) need to use external functions (such as QuillController). By using a QuillControllerAPI parameter, calls from QuillEditor are more easily understood since the API defined functions are explicitly documented and their purpose easily understood. Users would create a QuillEditor instance by providing an instance of QuillController that would be the class that implements the functions of the QuillControllerAPI (dart: class QuillController implements QuillControllerAPI).
Separation of design and implementation allows us to identify which functions are actually needed and explain their intent without being obscured by a mass of implementation code.
This allows class parameters to be defined as easy to understand function providers with good documentation on what each method does. Ideally, the implementation of each method should have no side-effects and functions should be testable. Mocks can be used to test classes dependent on the API design function without using actual implementation code that could change in future updates and result in breaking changes and test failures. This increases stability of the code and makes maintenance easier.
There are a number of areas that are mysterious
Currently we have QuillEditor and QuillRawEditor. It is not clear why QuillRawEditor is needed. It should be a low level implementation of the editor. But, in cases I have looked into, QuillEditor simply duplicates its own configuration options to create a QuillRawEditor with the same set of configuration options. There may be a good reason for this but it would be good to find out what the reason is!
Design possibilities
In reviewing other editor projects and forks, one feature that struck me as very useful is the concept of a simpler text field in addition to the full editor. In reading many of our issues, it appears that many of our users are using the complex editor when all they really need is a simple text box with simple formatting. This would greatly simplify the code and allow us to optimize performance. (For example, some operations require converting the entire document to plain text and then referencing 1 character! - no problem for simple one line documents but for large hundred page documents this makes no sense.)
We have many issues relating to users trying to use more than one editor field on a page. This would give us an opportunity to review the hard toolbar-controller-editor connection and simplify the support logic. Perhaps, the controller could provide a separation between actions and the actual document data. This might make it easy for a single controller to handle multiple editor instances.
Clipboard
Many issues relate to clipboard usage. We could consider an API:
This would identify which clipboard formats would be accepted (users can pick which formats they want to enable) as well as the order in which they should be applied (again, users can pick the order and easily change). We would provide default handlers for the most common formats, but users could easily provide their own (including custom formats) or extend the defaults. Issues with a format will be contained to that handler and will have no impact on any other part of the editor. (Great for maintainability.)
Tree-shaking
This is an area that I have no expertise with. Project organization would ideally have a core implementation with optional modules that could be included to meet a user's requirement. Coming from the win32 world, I do not include extension libraries because to include a library is to include the entire code! (Using 1 simple function from a 50MB library would include the entire library!!)
@EchoEllet this is an area that you understand, and it will be invaluable if we knew that my bad example from the win32 world does not apply here. In my simple example, would my final app include the full 50MB or only the <1MB for the code block I am calling? This would affect how we organize the add-on libraries.
Breaking changes
I am optimistic that this kind of reorganization can be achieved without introducing breaking changes for the majority of our users. There will be breaking changes for users who are calling internal methods of classes that should be internal to the editor. Their reports will enable us to better understand what the core editor needs to be able to do.
One aspect I miss from the C-family of languages is the concept of scope. Classes, methods and properties can be marked as private, protected, public and also internal. In dart, we have private and public which does not prevent users from calling methods that should be only used within the editor.
@EchoEllet, you introduced me to
@visibleForTesting
and I see there is also an@internal
. Are these something we could use to prevent future programmers directly calling methods that they should not be calling? This goes to the concept of testability of APIs. When we call a function through an API, we must assume that the API implementation might be wrong and must trap for such errors to prevent the error causing the app to crash. Enforcing internal-only usage limits the amount of such safety code.Folder structure during the process:
It would be good to have a folder structure to distinguish classes that have been processed to the new API model ('clean'?) from code that needs to be reviewed and streamlined ('dirty'?). That way we would know what still needs to be done. (Maybe top level 'api' and 'implementation' folders would be better?)
Summary
I have tried to quickly outline some possibilities. Our overriding goal should be to simplify, understand, test and make this useful to many people. I also hope that we will come to feel satisfaction and be proud of what we can accomplish.
Beta Was this translation helpful? Give feedback.
All reactions