rich_editor 0.5.0
rich_editor: ^0.5.0 copied to clipboard
WYSIWYG editor for Flutter with a rich set of supported formatting options.
0.5.0 #
Added #
- The editor runs on Tiptap (ProseMirror) instead of the
browser's
contenteditablecommands, so it behaves the same on Android and iOS and its HTML is clean and stable: no<p><ol>lists, leaked styles or zero-width spaces. The Dart API, toolbar and command states are unchanged. - JSON output:
controller.getJson()/setJson()(and on the executor andRichEditorState) read and set the content as a Tiptap / ProseMirror JSON document (#33). - Typed and pasted web addresses become links.
- Indent nests list items; elsewhere it indents paragraphs and headings.
onChangedcallback: the editor now reports every content change to Flutter.RichEditorController: read and set HTML, focus, clear and run commands (controller.executor) without aGlobalKey. It is aValueListenableofRichEditorValue, which carries the HTML and the formatting at the cursor.- The toolbar highlights active formatting (bold, italic, lists, alignment, headings, ...).
RichEditorOptions.toolbarItemschooses and orders the toolbar buttons,toolbarHeightsets its height, andRichEditor.toolbarBuilderreplaces it.RichEditorOptions.labels(RichEditorLabels) localizes every toolbar and dialog text.RichEditor.onUploadErroris called whengetImageUrl/getVideoUrlthrows; nothing is inserted then.- The placeholder is shown while the editor is empty.
RichEditor.readOnlyshows the content without the toolbar and without letting the user edit it;RichEditor.autofocusfocuses the editor once it has loaded.- Pasted and dropped images are uploaded with
getImageUrl(or inserted asdata:URLs without it), at the caret and without distortion. - Undo and Redo are greyed out when there is nothing to undo or redo.
- Links can be edited and removed: the Link button is highlighted while the caret is
in a link and opens it for editing.
executor.editLink/removeLink, andEditorCommand.linkreports the link at the caret. controller.getText()returns the content as plain text.- The editor follows the app's light or dark theme unless
backgroundColor/baseTextColorare set, and colors links, checkboxes and the caret to match. - The editor follows the app's text direction, so Arabic, Hebrew and other
right-to-left apps get a right-to-left editor (wrap it in a
Directionalityto choose).executor.setTextDirectionsets it directly. - The editor page has a Content-Security-Policy that only runs the editor's own scripts, so scripts and inline handlers in the content never run.
- Colors keep their transparency; the color picker opens at the color under the cursor and has a Cancel button.
Fixed #
- On iOS, inserted links, images and the text around them no longer get a
style="-webkit-text-size-adjust: 100%;"attribute in the HTML. - On Android, links and images inserted at the end of a paragraph no longer get the
editor's background color as a
styleattribute in the HTML. - The Quote button removes the quote when the caret is in one, instead of nesting another quote inside it.
- On Android, lists no longer come out as
<p><ol>...</ol></p>, which is not valid HTML and gained an empty paragraph before and after the list every time it was loaded again. - Checkboxes can no longer be ticked while the editor is
readOnly. - Text containing
+(e.g. "C++") lost characters when set withsetHtml. getHtmlno longer decodes HTML entities, which turned typed text like<b>into real markup.- Strings with quotes or backslashes (fonts, placeholder, checkbox text,
insertHtml, ...) no longer break or inject JavaScript; every argument is passed withjsonEncode. - Links, checkboxes, images and videos are built with the DOM instead of string
concatenation;
javascript:and other unsafe URLs are rejected. - Checkboxes no longer store an inline
onclickhandler in the HTML, and their label text is shown. - Pasted HTML is sanitized (scripts, event handlers, unsafe URLs and Word markup removed);
setHtml/insertHtmlstrip scripts and event handlers. - The editor HTML no longer contains zero-width spaces, and is empty when the editor is.
isEmpty()works for any empty content, not one exact string.- Backspace could not delete the last character.
- Deleting everything left the editor without a paragraph to type into.
- Crash in the paste handler when pasted text was inserted late.
- YouTube links in any form (youtu.be, shorts, live, extra parameters) are embedded;
other video links play in a
<video>element. - Background colors were applied without CSS (
styleWithCSSwas never enabled). - The Android font list skipped aliases, mis-parsed one fallback font and could crash; it is now read once, off the UI thread.
- Image resizing stores numeric sizes, rotation applies per image, and the broken drag-to-move was removed.
- A
//comment in style.css disabled thesuprule. RichEditor()crashed withouteditorOptions, and on macOS when disposed.- iOS: the asset server could be requested before it started, never finished starting when its port was taken, used a fixed port shared by all editors, and served every app asset. It now uses a free port and only serves the editor files.
- Changing
valueoreditorOptionsafter the first build had no effect. focus()opened the keyboard for Flutter's own text input, which had no text field, instead of the editor. This is behind reports of the cursor disappearing (#13), Samsung keyboards failing with Vietnamese (#15) and crashes inonCreateInputConnection(#22). The keyboard is now opened for the editor itself, on Android once the user has interacted with the editor.- The editor no longer changes the page while the keyboard composes a word, which cancelled composing input (Vietnamese, Chinese, Japanese, swipe typing).
- Dragging across an image didn't scroll the editor. Images now take touches for resizing and rotating only once tapped, and are outlined then.
- Android: YouTube embeds failed with "Error 153", because the editor page had no
origin. Android now serves the editor under
https://appassets.androidplatform.netwithWebViewAssetLoader, instead of loading it fromfile:///android_asset. - Typing in large documents sent the whole HTML to Flutter on every keystroke and selection change; reports are now batched (at most every 50 ms, less often for large documents).
setStateafter dispose when an upload finished late.- Dialog text fields leaked their controllers.
- The editor no longer forces mixed content on, and only logs WebView console messages in debug builds.
Breaking #
- HTML is parsed into the editor's document, so
getHtmlreturns the editor's own form of what was set:<b>becomes<strong>,<i><em>,<strike><s>,<font>a styled<span>,<pre><pre><code>, list items hold paragraphs, and markup the editor has no formatting for (tables, classes, most inline styles) is dropped. HTML saved by earlier versions loads with its formatting, including images' size and rotation, checkboxes, videos and indents (which becomemargin-inline-startinstead of a blockquote). setHtmlcannot be undone, and font sizes are CSS keywords (x-large) rather than<font size>; thefontSizecommand state still reports 1 - 7.- Needs iOS 14.5 or later and Android System WebView 80 or later.
RichEditorController.markReady(internal) returns the pending content as an HTMLStringor a JSONMap.- Without
getImageUrl, picked images are embedded asdata:URLs instead of being inserted by their file path, which the editor page can no longer load (and never could on iOS). Picking videos needsgetVideoUrl; without it the video dialog only takes links. RichEditor.editorOptionsandRichEditor.disableVideoare non-nullable;RichEditorOptionsis immutable withbarPositiondefaulting toBarPosition.top.- Executor methods return
Future<void>(getCurrentHtmlreturnsFuture<String>), color setters take a non-nullColor,setFontSize/setHeadingthrowArgumentErrorfor out-of-range values. - Removed
JavascriptExecutorBase.encodeHtml,decodeHtml,getCachedHtmland its unused listener fields, and the unused callback and model classes. RichEditorStatefieldsport,html,assetPathandlocalServerare private;javascriptExecutoris read-only.TabButton.onTapis aVoidCallback;disablednow fades the button.getHtml()returns an empty string for an empty editor instead of<p></p>.- Requires Flutter 3.27 and Dart 3.6. Depends on stable
flutter_inappwebview6.1.5; droppedmime,path,xml2jsonandflutter_widget_from_html_core. - Declares Android and iOS as the supported platforms.
0.3.0 #
- Encode HTML correctly before setting it.
0.2.4 0.2.5 #
- Fix HTML encoding/decoding and URL escaping.
0.2.0 0.2.3 #
- Add lint rules and refactor.
- Show a loading indicator while the editor loads and while media uploads.
- Prevent the editor from getting stuck on loading.
- Escape special characters in commands.
0.1.1 #
- Encode HTML before injecting it into JavaScript.
0.1.0 #
- Update dependencies.
0.0.7 #
- Update flutter_inappwebview and flutter_widget_from_html_core.
0.0.6 #
- Refactor for flutter 3.10
0.0.5 #
- Update dependencies; fix
Platform._operatingSystemerror on web.
0.0.3 #
- Editor specific settings
- Video addition feature
0.0.1 #
- Initial release with basic features