Sort constructors first

pull/145/head
Till Friebe 4 years ago
parent 9a29446c97
commit 873bfbcee1
  1. 2
      analysis_options.yaml
  2. 14
      example/lib/widgets/demo_scaffold.dart
  3. 4
      lib/models/documents/attribute.dart
  4. 24
      lib/models/documents/document.dart
  5. 21
      lib/models/documents/history.dart
  6. 4
      lib/models/documents/nodes/container.dart
  7. 4
      lib/models/documents/nodes/embed.dart
  8. 12
      lib/models/documents/nodes/leaf.dart
  9. 4
      lib/models/documents/style.dart
  10. 68
      lib/models/quill_delta.dart
  11. 4
      lib/models/rules/rule.dart
  12. 4
      lib/utils/diff_delta.dart
  13. 8
      lib/widgets/controller.dart
  14. 40
      lib/widgets/cursor.dart
  15. 59
      lib/widgets/default_styles.dart
  16. 4
      lib/widgets/delegate.dart
  17. 126
      lib/widgets/editor.dart
  18. 5
      lib/widgets/keyboard_listener.dart
  19. 30
      lib/widgets/proxy.dart
  20. 66
      lib/widgets/raw_editor.dart
  21. 8
      lib/widgets/responsive_widget.dart
  22. 71
      lib/widgets/text_block.dart
  23. 62
      lib/widgets/text_line.dart
  24. 41
      lib/widgets/text_selection.dart
  25. 134
      lib/widgets/toolbar.dart

@ -29,5 +29,7 @@ linter:
- prefer_interpolation_to_compose_strings
- prefer_relative_imports
- prefer_single_quotes
- sort_constructors_first
- sort_unnamed_constructors_first
- unnecessary_parenthesis
- unnecessary_string_interpolations

@ -11,13 +11,6 @@ typedef DemoContentBuilder = Widget Function(
// Common scaffold for all examples.
class DemoScaffold extends StatefulWidget {
/// Filename of the document to load into the editor.
final String documentFilename;
final DemoContentBuilder builder;
final List<Widget>? actions;
final Widget? floatingActionButton;
final bool showToolbar;
const DemoScaffold({
required this.documentFilename,
required this.builder,
@ -27,6 +20,13 @@ class DemoScaffold extends StatefulWidget {
Key? key,
}) : super(key: key);
/// Filename of the document to load into the editor.
final String documentFilename;
final DemoContentBuilder builder;
final List<Widget>? actions;
final Widget? floatingActionButton;
final bool showToolbar;
@override
_DemoScaffoldState createState() => _DemoScaffoldState();
}

@ -8,12 +8,12 @@ enum AttributeScope {
}
class Attribute<T> {
Attribute(this.key, this.scope, this.value);
final String key;
final AttributeScope scope;
final T value;
Attribute(this.key, this.scope, this.value);
static final Map<String, Attribute> _registry = {
Attribute.bold.key: Attribute.bold,
Attribute.italic.key: Attribute.italic,

@ -15,6 +15,18 @@ import 'style.dart';
/// The rich text document
class Document {
Document() : _delta = Delta()..insert('\n') {
_loadDocument(_delta);
}
Document.fromJson(List data) : _delta = _transform(Delta.fromJson(data)) {
_loadDocument(_delta);
}
Document.fromDelta(Delta delta) : _delta = delta {
_loadDocument(delta);
}
/// The root node of the document tree
final Root _root = Root();
@ -35,18 +47,6 @@ class Document {
Stream<Tuple3<Delta, Delta, ChangeSource>> get changes => _observer.stream;
Document() : _delta = Delta()..insert('\n') {
_loadDocument(_delta);
}
Document.fromJson(List data) : _delta = _transform(Delta.fromJson(data)) {
_loadDocument(_delta);
}
Document.fromDelta(Delta delta) : _delta = delta {
_loadDocument(delta);
}
Delta insert(int index, Object? data) {
assert(index >= 0);
assert(data is String || data is Embeddable);

@ -4,6 +4,14 @@ import '../quill_delta.dart';
import 'document.dart';
class History {
History({
this.ignoreChange = false,
this.interval = 400,
this.maxStack = 100,
this.userOnly = false,
this.lastRecorded = 0,
});
final HistoryStack stack = HistoryStack.empty();
bool get hasUndo => stack.undo.isNotEmpty;
@ -24,13 +32,6 @@ class History {
///record delay
final int interval;
History(
{this.ignoreChange = false,
this.interval = 400,
this.maxStack = 100,
this.userOnly = false,
this.lastRecorded = 0});
void handleDocChange(Tuple3<Delta, Delta, ChangeSource> change) {
if (ignoreChange) return;
if (!userOnly || change.item3 == ChangeSource.LOCAL) {
@ -119,13 +120,13 @@ class History {
}
class HistoryStack {
final List<Delta> undo;
final List<Delta> redo;
HistoryStack.empty()
: undo = [],
redo = [];
final List<Delta> undo;
final List<Delta> redo;
void clear() {
undo.clear();
redo.clear();

@ -116,9 +116,9 @@ abstract class Container<T extends Node?> extends Node {
/// Query of a child in a Container
class ChildQuery {
ChildQuery(this.node, this.offset);
final Node? node; // null if not found
final int offset;
ChildQuery(this.node, this.offset);
}

@ -1,9 +1,9 @@
class Embeddable {
Embeddable(this.type, this.data);
final String type;
final dynamic data;
Embeddable(this.type, this.data);
Map<String, dynamic> toJson() {
final m = <String, String>{type: data};
return m;

@ -8,12 +8,6 @@ import 'node.dart';
/* A leaf node in document tree */
abstract class Leaf extends Node {
Object _value;
Object get value => _value;
Leaf.val(Object val) : _value = val;
factory Leaf(Object data) {
if (data is Embeddable) {
return Embed(data);
@ -23,6 +17,12 @@ abstract class Leaf extends Node {
return Text(text);
}
Leaf.val(Object val) : _value = val;
Object _value;
Object get value => _value;
@override
void applyStyle(Style value) {
assert(value.isInline || value.isIgnored || value.isEmpty,

@ -5,11 +5,11 @@ import 'attribute.dart';
/* Collection of style attributes */
class Style {
final Map<String, Attribute> _attributes;
Style() : _attributes = <String, Attribute>{};
Style.attr(this._attributes);
Style() : _attributes = <String, Attribute>{};
final Map<String, Attribute> _attributes;
static Style fromJson(Map<String, dynamic>? attributes) {
if (attributes == null) {

@ -22,6 +22,29 @@ Object? _passThroughDataDecoder(Object? data) => data;
/// Operation performed on a rich-text document.
class Operation {
Operation._(this.key, this.length, this.data, Map? attributes)
: assert(_validKeys.contains(key), 'Invalid operation key "$key".'),
assert(() {
if (key != Operation.insertKey) return true;
return data is String ? data.length == length : length == 1;
}(), 'Length of insert operation must be equal to the data length.'),
_attributes =
attributes != null ? Map<String, dynamic>.from(attributes) : null;
/// Creates operation which deletes [length] of characters.
factory Operation.delete(int length) =>
Operation._(Operation.deleteKey, length, '', null);
/// Creates operation which inserts [text] with optional [attributes].
factory Operation.insert(dynamic data, [Map<String, dynamic>? attributes]) =>
Operation._(Operation.insertKey, data is String ? data.length : 1, data,
attributes);
/// Creates operation which retains [length] of characters and optionally
/// applies attributes.
factory Operation.retain(int? length, [Map<String, dynamic>? attributes]) =>
Operation._(Operation.retainKey, length, '', attributes);
/// Key of insert operations.
static const String insertKey = 'insert';
@ -50,15 +73,6 @@ class Operation {
_attributes == null ? null : Map<String, dynamic>.from(_attributes!);
final Map<String, dynamic>? _attributes;
Operation._(this.key, this.length, this.data, Map? attributes)
: assert(_validKeys.contains(key), 'Invalid operation key "$key".'),
assert(() {
if (key != Operation.insertKey) return true;
return data is String ? data.length == length : length == 1;
}(), 'Length of insert operation must be equal to the data length.'),
_attributes =
attributes != null ? Map<String, dynamic>.from(attributes) : null;
/// Creates new [Operation] from JSON payload.
///
/// If `dataDecoder` parameter is not null then it is used to additionally
@ -89,20 +103,6 @@ class Operation {
return json;
}
/// Creates operation which deletes [length] of characters.
factory Operation.delete(int length) =>
Operation._(Operation.deleteKey, length, '', null);
/// Creates operation which inserts [text] with optional [attributes].
factory Operation.insert(dynamic data, [Map<String, dynamic>? attributes]) =>
Operation._(Operation.insertKey, data is String ? data.length : 1, data,
attributes);
/// Creates operation which retains [length] of characters and optionally
/// applies attributes.
factory Operation.retain(int? length, [Map<String, dynamic>? attributes]) =>
Operation._(Operation.retainKey, length, '', attributes);
/// Returns value of this operation.
///
/// For insert operations this returns text, for delete and retain - length.
@ -180,6 +180,15 @@ class Operation {
/// "document delta". When delta includes also "retain" or "delete" operations
/// it is a "change delta".
class Delta {
/// Creates new empty [Delta].
factory Delta() => Delta._(<Operation>[]);
Delta._(List<Operation> operations) : _operations = operations;
/// Creates new [Delta] from [other].
factory Delta.from(Delta other) =>
Delta._(List<Operation>.from(other._operations));
/// Transforms two attribute sets.
static Map<String, dynamic>? transformAttributes(
Map<String, dynamic>? a, Map<String, dynamic>? b, bool priority) {
@ -242,15 +251,6 @@ class Delta {
int _modificationCount = 0;
Delta._(List<Operation> operations) : _operations = operations;
/// Creates new empty [Delta].
factory Delta() => Delta._(<Operation>[]);
/// Creates new [Delta] from [other].
factory Delta.from(Delta other) =>
Delta._(List<Operation>.from(other._operations));
/// Creates [Delta] from de-serialized JSON representation.
///
/// If `dataDecoder` parameter is not null then it is used to additionally
@ -599,13 +599,13 @@ class Delta {
/// Specialized iterator for [Delta]s.
class DeltaIterator {
DeltaIterator(this.delta) : _modificationCount = delta._modificationCount;
final Delta delta;
final int _modificationCount;
int _index = 0;
num _offset = 0;
DeltaIterator(this.delta) : _modificationCount = delta._modificationCount;
bool get isNextInsert => nextOperationKey == Operation.insertKey;
bool get isNextDelete => nextOperationKey == Operation.deleteKey;

@ -26,6 +26,8 @@ abstract class Rule {
}
class Rules {
Rules(this._rules);
final List<Rule> _rules;
static final Rules _instance = Rules([
const FormatLinkAtCaretPositionRule(),
@ -45,8 +47,6 @@ class Rules {
const CatchAllDeleteRule(),
]);
Rules(this._rules);
static Rules getInstance() => _instance;
Delta apply(RuleType ruleType, Document document, int index,

@ -33,6 +33,8 @@ const Set<int> WHITE_SPACE = {
// Diff between two texts - old text and new text
class Diff {
Diff(this.start, this.deleted, this.inserted);
// Start index in old text at which changes begin.
final int start;
@ -42,8 +44,6 @@ class Diff {
// The inserted text
final String inserted;
Diff(this.start, this.deleted, this.inserted);
@override
String toString() {
return 'Diff[$start, "$deleted", "$inserted"]';

@ -11,10 +11,6 @@ import '../models/quill_delta.dart';
import '../utils/diff_delta.dart';
class QuillController extends ChangeNotifier {
final Document document;
TextSelection selection;
Style toggledStyle = Style();
QuillController({required this.document, required this.selection});
factory QuillController.basic() {
@ -24,6 +20,10 @@ class QuillController extends ChangeNotifier {
);
}
final Document document;
TextSelection selection;
Style toggledStyle = Style();
// item1: Document state before [change].
//
// item2: Change delta applied to the document.

@ -8,15 +8,6 @@ import 'box.dart';
const Duration _FADE_DURATION = Duration(milliseconds: 250);
class CursorStyle {
final Color color;
final Color backgroundColor;
final double width;
final double? height;
final Radius? radius;
final Offset? offset;
final bool opacityAnimates;
final bool paintAboveText;
const CursorStyle({
required this.color,
required this.backgroundColor,
@ -28,6 +19,15 @@ class CursorStyle {
this.paintAboveText = false,
});
final Color color;
final Color backgroundColor;
final double width;
final double? height;
final Radius? radius;
final Offset? offset;
final bool opacityAnimates;
final bool paintAboveText;
@override
bool operator ==(Object other) =>
identical(this, other) ||
@ -55,14 +55,6 @@ class CursorStyle {
}
class CursorCont extends ChangeNotifier {
final ValueNotifier<bool> show;
final ValueNotifier<bool> _blink;
final ValueNotifier<Color> color;
late AnimationController _blinkOpacityCont;
Timer? _cursorTimer;
bool _targetCursorVisibility = false;
CursorStyle _style;
CursorCont({
required this.show,
required CursorStyle style,
@ -75,6 +67,14 @@ class CursorCont extends ChangeNotifier {
_blinkOpacityCont.addListener(_onColorTick);
}
final ValueNotifier<bool> show;
final ValueNotifier<bool> _blink;
final ValueNotifier<Color> color;
late AnimationController _blinkOpacityCont;
Timer? _cursorTimer;
bool _targetCursorVisibility = false;
CursorStyle _style;
ValueNotifier<bool> get cursorBlink => _blink;
ValueNotifier<Color> get cursorColor => color;
@ -156,15 +156,15 @@ class CursorCont extends ChangeNotifier {
}
class CursorPainter {
CursorPainter(this.editable, this.style, this.prototype, this.color,
this.devicePixelRatio);
final RenderContentProxyBox? editable;
final CursorStyle style;
final Rect? prototype;
final Color color;
final double devicePixelRatio;
CursorPainter(this.editable, this.style, this.prototype, this.color,
this.devicePixelRatio);
void paint(Canvas canvas, Offset offset, TextPosition position) {
assert(prototype != null);

@ -3,14 +3,14 @@ import 'package:flutter/widgets.dart';
import 'package:tuple/tuple.dart';
class QuillStyles extends InheritedWidget {
final DefaultStyles data;
const QuillStyles({
required this.data,
required Widget child,
Key? key,
}) : super(key: key, child: child);
final DefaultStyles data;
@override
bool updateShouldNotify(QuillStyles oldWidget) {
return data != oldWidget.data;
@ -27,6 +27,13 @@ class QuillStyles extends InheritedWidget {
}
class DefaultTextBlockStyle {
DefaultTextBlockStyle(
this.style,
this.verticalSpacing,
this.lineSpacing,
this.decoration,
);
final TextStyle style;
final Tuple2<double, double> verticalSpacing;
@ -34,12 +41,32 @@ class DefaultTextBlockStyle {
final Tuple2<double, double> lineSpacing;
final BoxDecoration? decoration;
DefaultTextBlockStyle(
this.style, this.verticalSpacing, this.lineSpacing, this.decoration);
}
class DefaultStyles {
DefaultStyles({
this.h1,
this.h2,
this.h3,
this.paragraph,
this.bold,
this.italic,
this.underline,
this.strikeThrough,
this.link,
this.color,
this.placeHolder,
this.lists,
this.quote,
this.code,
this.indent,
this.align,
this.leading,
this.sizeSmall,
this.sizeLarge,
this.sizeHuge,
});
final DefaultTextBlockStyle? h1;
final DefaultTextBlockStyle? h2;
final DefaultTextBlockStyle? h3;
@ -61,28 +88,6 @@ class DefaultStyles {
final DefaultTextBlockStyle? align;
final DefaultTextBlockStyle? leading;
DefaultStyles(
{this.h1,
this.h2,
this.h3,
this.paragraph,
this.bold,
this.italic,
this.underline,
this.strikeThrough,
this.link,
this.color,
this.placeHolder,
this.lists,
this.quote,
this.code,
this.indent,
this.align,
this.leading,
this.sizeSmall,
this.sizeLarge,
this.sizeHuge});
static DefaultStyles getInstance(BuildContext context) {
final themeData = Theme.of(context);
final defaultTextStyle = DefaultTextStyle.of(context);

@ -18,11 +18,11 @@ abstract class EditorTextSelectionGestureDetectorBuilderDelegate {
}
class EditorTextSelectionGestureDetectorBuilder {
EditorTextSelectionGestureDetectorBuilder(this.delegate);
final EditorTextSelectionGestureDetectorBuilderDelegate delegate;
bool shouldShowSelectionToolbar = true;
EditorTextSelectionGestureDetectorBuilder(this.delegate);
EditorState? getEditor() {
return delegate.getEditableTextKey().currentState;
}

@ -114,6 +114,43 @@ Widget _defaultEmbedBuilder(BuildContext context, leaf.Embed node) {
}
class QuillEditor extends StatefulWidget {
const QuillEditor({
required this.controller,
required this.focusNode,
required this.scrollController,
required this.scrollable,
required this.padding,
required this.autoFocus,
required this.readOnly,
required this.expands,
this.showCursor,
this.placeholder,
this.enableInteractiveSelection = true,
this.minHeight,
this.maxHeight,
this.customStyles,
this.textCapitalization = TextCapitalization.sentences,
this.keyboardAppearance = Brightness.light,
this.scrollPhysics,
this.onLaunchUrl,
this.embedBuilder = _defaultEmbedBuilder,
});
factory QuillEditor.basic({
required QuillController controller,
required bool readOnly,
}) {
return QuillEditor(
controller: controller,
scrollController: ScrollController(),
scrollable: true,
focusNode: FocusNode(),
autoFocus: true,
readOnly: readOnly,
expands: false,
padding: EdgeInsets.zero);
}
final QuillController controller;
final FocusNode focusNode;
final ScrollController scrollController;
@ -134,40 +171,6 @@ class QuillEditor extends StatefulWidget {
final ValueChanged<String>? onLaunchUrl;
final EmbedBuilder embedBuilder;
const QuillEditor(
{required this.controller,
required this.focusNode,
required this.scrollController,
required this.scrollable,
required this.padding,
required this.autoFocus,
required this.readOnly,
required this.expands,
this.showCursor,
this.placeholder,
this.enableInteractiveSelection = true,
this.minHeight,
this.maxHeight,
this.customStyles,
this.textCapitalization = TextCapitalization.sentences,
this.keyboardAppearance = Brightness.light,
this.scrollPhysics,
this.onLaunchUrl,
this.embedBuilder = _defaultEmbedBuilder});
factory QuillEditor.basic(
{required QuillController controller, required bool readOnly}) {
return QuillEditor(
controller: controller,
scrollController: ScrollController(),
scrollable: true,
focusNode: FocusNode(),
autoFocus: true,
readOnly: readOnly,
expands: false,
padding: EdgeInsets.zero);
}
@override
_QuillEditorState createState() => _QuillEditorState();
}
@ -295,10 +298,10 @@ class _QuillEditorState extends State<QuillEditor>
class _QuillEditorSelectionGestureDetectorBuilder
extends EditorTextSelectionGestureDetectorBuilder {
final _QuillEditorState _state;
_QuillEditorSelectionGestureDetectorBuilder(this._state) : super(_state);
final _QuillEditorState _state;
@override
void onForcePressStart(ForcePressDetails details) {
super.onForcePressStart(details);
@ -495,6 +498,24 @@ typedef TextSelectionChangedHandler = void Function(
class RenderEditor extends RenderEditableContainerBox
implements RenderAbstractEditor {
RenderEditor(
List<RenderEditableBox>? children,
TextDirection textDirection,
EdgeInsetsGeometry padding,
this.document,
this.selection,
this._hasFocus,
this.onSelectionChanged,
this._startHandleLayerLink,
this._endHandleLayerLink,
EdgeInsets floatingCursorAddedMargin,
) : super(
children,
document.root,
textDirection,
padding,
);
Document document;
TextSelection selection;
bool _hasFocus = false;
@ -510,24 +531,6 @@ class RenderEditor extends RenderEditableContainerBox
ValueListenable<bool> get selectionEndInViewport => _selectionEndInViewport;
final ValueNotifier<bool> _selectionEndInViewport = ValueNotifier<bool>(true);
RenderEditor(
List<RenderEditableBox>? children,
TextDirection textDirection,
EdgeInsetsGeometry padding,
this.document,
this.selection,
this._hasFocus,
this.onSelectionChanged,
this._startHandleLayerLink,
this._endHandleLayerLink,
EdgeInsets floatingCursorAddedMargin)
: super(
children,
document.root,
textDirection,
padding,
);
void setDocument(Document doc) {
if (document == doc) {
return;
@ -866,17 +869,20 @@ class RenderEditableContainerBox extends RenderBox
EditableContainerParentData>,
RenderBoxContainerDefaultsMixin<RenderEditableBox,
EditableContainerParentData> {
RenderEditableContainerBox(
List<RenderEditableBox>? children,
this._container,
this.textDirection,
this._padding,
) : assert(_padding.isNonNegative) {
addAll(children);
}
container_node.Container _container;
TextDirection textDirection;
EdgeInsetsGeometry _padding;
EdgeInsets? _resolvedPadding;
RenderEditableContainerBox(List<RenderEditableBox>? children, this._container,
this.textDirection, this._padding)
: assert(_padding.isNonNegative) {
addAll(children);
}
container_node.Container getContainer() {
return _container;
}

@ -9,9 +9,12 @@ typedef InputShortcutCallback = void Function(InputShortcut? shortcut);
typedef OnDeleteCallback = void Function(bool forward);
class KeyboardListener {
KeyboardListener(this.onCursorMove, this.onShortcut, this.onDelete);
final CursorMoveCallback onCursorMove;
final InputShortcutCallback onShortcut;
final OnDeleteCallback onDelete;
static final Set<LogicalKeyboardKey> _moveKeys = <LogicalKeyboardKey>{
LogicalKeyboardKey.arrowRight,
LogicalKeyboardKey.arrowLeft,
@ -59,8 +62,6 @@ class KeyboardListener {
LogicalKeyboardKey.keyA: InputShortcut.SELECT_ALL,
};
KeyboardListener(this.onCursorMove, this.onShortcut, this.onDelete);
bool handleRawKeyEvent(RawKeyEvent event) {
if (kIsWeb) {
// On web platform, we should ignore the key because it's processed already.

@ -4,12 +4,12 @@ import 'package:flutter/widgets.dart';
import 'box.dart';
class BaselineProxy extends SingleChildRenderObjectWidget {
final TextStyle? textStyle;
final EdgeInsets? padding;
const BaselineProxy({Key? key, Widget? child, this.textStyle, this.padding})
: super(key: key, child: child);
final TextStyle? textStyle;
final EdgeInsets? padding;
@override
RenderBaselineProxy createRenderObject(BuildContext context) {
return RenderBaselineProxy(
@ -122,6 +122,18 @@ class RenderEmbedProxy extends RenderProxyBox implements RenderContentProxyBox {
}
class RichTextProxy extends SingleChildRenderObjectWidget {
const RichTextProxy(
RichText child,
this.textStyle,
this.textAlign,
this.textDirection,
this.textScaleFactor,
this.locale,
this.strutStyle,
this.textWidthBasis,
this.textHeightBehavior,
) : super(child: child);
final TextStyle textStyle;
final TextAlign textAlign;
final TextDirection textDirection;
@ -145,18 +157,6 @@ class RichTextProxy extends SingleChildRenderObjectWidget {
textHeightBehavior);
}
const RichTextProxy(
RichText child,
this.textStyle,
this.textAlign,
this.textDirection,
this.textScaleFactor,
this.locale,
this.strutStyle,
this.textWidthBasis,
this.textHeightBehavior)
: super(child: child);
@override
void updateRenderObject(
BuildContext context, covariant RenderParagraphProxy renderObject) {

@ -28,6 +28,39 @@ import 'text_line.dart';
import 'text_selection.dart';
class RawEditor extends StatefulWidget {
const RawEditor(
Key key,
this.controller,
this.focusNode,
this.scrollController,
this.scrollable,
this.padding,
this.readOnly,
this.placeholder,
this.onLaunchUrl,
this.toolbarOptions,
this.showSelectionHandles,
bool? showCursor,
this.cursorStyle,
this.textCapitalization,
this.maxHeight,
this.minHeight,
this.customStyles,
this.expands,
this.autoFocus,
this.selectionColor,
this.selectionCtrls,
this.keyboardAppearance,
this.enableInteractiveSelection,
this.scrollPhysics,
this.embedBuilder,
) : assert(maxHeight == null || maxHeight > 0, 'maxHeight cannot be null'),
assert(minHeight == null || minHeight >= 0, 'minHeight cannot be null'),
assert(maxHeight == null || minHeight == null || maxHeight >= minHeight,
'maxHeight cannot be null'),
showCursor = showCursor ?? true,
super(key: key);
final QuillController controller;
final FocusNode focusNode;
final ScrollController scrollController;
@ -53,39 +86,6 @@ class RawEditor extends StatefulWidget {
final ScrollPhysics? scrollPhysics;
final EmbedBuilder embedBuilder;
const RawEditor(
Key key,
this.controller,
this.focusNode,
this.scrollController,
this.scrollable,
this.padding,
this.readOnly,
this.placeholder,
this.onLaunchUrl,
this.toolbarOptions,
this.showSelectionHandles,
bool? showCursor,
this.cursorStyle,
this.textCapitalization,
this.maxHeight,
this.minHeight,
this.customStyles,
this.expands,
this.autoFocus,
this.selectionColor,
this.selectionCtrls,
this.keyboardAppearance,
this.enableInteractiveSelection,
this.scrollPhysics,
this.embedBuilder)
: assert(maxHeight == null || maxHeight > 0, 'maxHeight cannot be null'),
assert(minHeight == null || minHeight >= 0, 'minHeight cannot be null'),
assert(maxHeight == null || minHeight == null || maxHeight >= minHeight,
'maxHeight cannot be null'),
showCursor = showCursor ?? true,
super(key: key);
@override
State<StatefulWidget> createState() {
return RawEditorState();

@ -1,10 +1,6 @@
import 'package:flutter/material.dart';
class ResponsiveWidget extends StatelessWidget {
final Widget largeScreen;
final Widget? mediumScreen;
final Widget? smallScreen;
const ResponsiveWidget({
required this.largeScreen,
this.mediumScreen,
@ -12,6 +8,10 @@ class ResponsiveWidget extends StatelessWidget {
Key? key,
}) : super(key: key);
final Widget largeScreen;
final Widget? mediumScreen;
final Widget? smallScreen;
static bool isSmallScreen(BuildContext context) {
return MediaQuery.of(context).size.width < 800;
}

@ -47,6 +47,21 @@ const List<String> romanNumbers = [
];
class EditableTextBlock extends StatelessWidget {
const EditableTextBlock(
this.block,
this.textDirection,
this.verticalSpacing,
this.textSelection,
this.color,
this.styles,
this.enableInteractiveSelection,
this.hasFocus,
this.contentPadding,
this.embedBuilder,
this.cursorCont,
this.indentLevelCounts,
);
final Block block;
final TextDirection textDirection;
final Tuple2 verticalSpacing;
@ -60,20 +75,6 @@ class EditableTextBlock extends StatelessWidget {
final CursorCont cursorCont;
final Map<int, int> indentLevelCounts;
const EditableTextBlock(
this.block,
this.textDirection,
this.verticalSpacing,
this.textSelection,
this.color,
this.styles,
this.enableInteractiveSelection,
this.hasFocus,
this.contentPadding,
this.embedBuilder,
this.cursorCont,
this.indentLevelCounts);
@override
Widget build(BuildContext context) {
assert(debugCheckHasMediaQuery(context));
@ -509,16 +510,21 @@ class RenderEditableTextBlock extends RenderEditableContainerBox
}
class _EditableBlock extends MultiChildRenderObjectWidget {
_EditableBlock(
this.block,
this.textDirection,
this.padding,
this.decoration,
this.contentPadding,
List<Widget> children,
) : super(children: children);
final Block block;
final TextDirection textDirection;
final Tuple2<double, double> padding;
final Decoration decoration;
final EdgeInsets? contentPadding;
_EditableBlock(this.block, this.textDirection, this.padding, this.decoration,
this.contentPadding, List<Widget> children)
: super(children: children);
EdgeInsets get _padding =>
EdgeInsets.only(top: padding.item1, bottom: padding.item2);
@ -548,15 +554,6 @@ class _EditableBlock extends MultiChildRenderObjectWidget {
}
class _NumberPoint extends StatelessWidget {
final int index;
final Map<int?, int> indentLevelCounts;
final int count;
final TextStyle style;
final double width;
final Map<String, Attribute> attrs;
final bool withDot;
final double padding;
const _NumberPoint({
required this.index,
required this.indentLevelCounts,
@ -569,6 +566,15 @@ class _NumberPoint extends StatelessWidget {
Key? key,
}) : super(key: key);
final int index;
final Map<int?, int> indentLevelCounts;
final int count;
final TextStyle style;
final double width;
final Map<String, Attribute> attrs;
final bool withDot;
final double padding;
@override
Widget build(BuildContext context) {
var s = index.toString();
@ -652,15 +658,15 @@ class _NumberPoint extends StatelessWidget {
}
class _BulletPoint extends StatelessWidget {
final TextStyle style;
final double width;
const _BulletPoint({
required this.style,
required this.width,
Key? key,
}) : super(key: key);
final TextStyle style;
final double width;
@override
Widget build(BuildContext context) {
return Container(
@ -673,12 +679,13 @@ class _BulletPoint extends StatelessWidget {
}
class _Checkbox extends StatefulWidget {
const _Checkbox({Key? key, this.style, this.width, this.isChecked})
: super(key: key);
final TextStyle? style;
final double? width;
final bool? isChecked;
const _Checkbox({Key? key, this.style, this.width, this.isChecked})
: super(key: key);
@override
__CheckboxState createState() => __CheckboxState();
}

@ -20,11 +20,6 @@ import 'proxy.dart';
import 'text_selection.dart';
class TextLine extends StatelessWidget {
final Line line;
final TextDirection? textDirection;
final EmbedBuilder embedBuilder;
final DefaultStyles styles;
const TextLine({
required this.line,
required this.embedBuilder,
@ -33,6 +28,11 @@ class TextLine extends StatelessWidget {
Key? key,
}) : super(key: key);
final Line line;
final TextDirection? textDirection;
final EmbedBuilder embedBuilder;
final DefaultStyles styles;
@override
Widget build(BuildContext context) {
assert(debugCheckHasMediaQuery(context));
@ -194,6 +194,21 @@ class TextLine extends StatelessWidget {
}
class EditableTextLine extends RenderObjectWidget {
const EditableTextLine(
this.line,
this.leading,
this.body,
this.indentWidth,
this.verticalSpacing,
this.textDirection,
this.textSelection,
this.color,
this.enableInteractiveSelection,
this.hasFocus,
this.devicePixelRatio,
this.cursorCont,
);
final Line line;
final Widget? leading;
final Widget body;
@ -207,20 +222,6 @@ class EditableTextLine extends RenderObjectWidget {
final double devicePixelRatio;
final CursorCont cursorCont;
const EditableTextLine(
this.line,
this.leading,
this.body,
this.indentWidth,
this.verticalSpacing,
this.textDirection,
this.textSelection,
this.color,
this.enableInteractiveSelection,
this.hasFocus,
this.devicePixelRatio,
this.cursorCont);
@override
RenderObjectElement createElement() {
return _TextLineElement(this);
@ -266,6 +267,18 @@ class EditableTextLine extends RenderObjectWidget {
enum TextLineSlot { LEADING, BODY }
class RenderEditableTextLine extends RenderEditableBox {
RenderEditableTextLine(
this.line,
this.textDirection,
this.textSelection,
this.enableInteractiveSelection,
this.hasFocus,
this.devicePixelRatio,
this.padding,
this.color,
this.cursorCont,
);
RenderBox? _leading;
RenderContentProxyBox? _body;
Line line;
@ -283,17 +296,6 @@ class RenderEditableTextLine extends RenderEditableBox {
Rect? _caretPrototype;
final Map<TextLineSlot, RenderBox> children = <TextLineSlot, RenderBox>{};
RenderEditableTextLine(
this.line,
this.textDirection,
this.textSelection,
this.enableInteractiveSelection,
this.hasFocus,
this.devicePixelRatio,
this.padding,
this.color,
this.cursorCont);
Iterable<RenderBox> get _children sync* {
if (_leading != null) {
yield _leading!;

@ -24,6 +24,27 @@ TextSelection localSelection(Node node, TextSelection selection, fromParent) {
enum _TextSelectionHandlePosition { START, END }
class EditorTextSelectionOverlay {
EditorTextSelectionOverlay(
this.value,
this.handlesVisible,
this.context,
this.debugRequiredFor,
this.toolbarLayerLink,
this.startHandleLayerLink,
this.endHandleLayerLink,
this.renderObject,
this.selectionCtrls,
this.selectionDelegate,
this.dragStartBehavior,
this.onSelectionHandleTapped,
this.clipboardStatus,
) {
final overlay = Overlay.of(context, rootOverlay: true)!;
_toolbarController = AnimationController(
duration: const Duration(milliseconds: 150), vsync: overlay);
}
TextEditingValue value;
bool handlesVisible = false;
final BuildContext context;
@ -41,26 +62,6 @@ class EditorTextSelectionOverlay {
List<OverlayEntry>? _handles;
OverlayEntry? toolbar;
EditorTextSelectionOverlay(
this.value,
this.handlesVisible,
this.context,
this.debugRequiredFor,
this.toolbarLayerLink,
this.startHandleLayerLink,
this.endHandleLayerLink,
this.renderObject,
this.selectionCtrls,
this.selectionDelegate,
this.dragStartBehavior,
this.onSelectionHandleTapped,
this.clipboardStatus) {
final overlay = Overlay.of(context, rootOverlay: true)!;
_toolbarController = AnimationController(
duration: const Duration(milliseconds: 150), vsync: overlay);
}
TextSelection get _selection => value.selection;
Animation<double> get _toolbarOpacity => _toolbarController.view;

@ -21,15 +21,15 @@ typedef OnImagePickCallback = Future<String> Function(File file);
typedef ImagePickImpl = Future<String> Function(ImageSource source);
class InsertEmbedButton extends StatelessWidget {
final QuillController controller;
final IconData icon;
const InsertEmbedButton({
required this.controller,
required this.icon,
Key? key,
}) : super(key: key);
final QuillController controller;
final IconData icon;
@override
Widget build(BuildContext context) {
return QuillIconButton(
@ -52,15 +52,15 @@ class InsertEmbedButton extends StatelessWidget {
}
class LinkStyleButton extends StatefulWidget {
final QuillController controller;
final IconData? icon;
const LinkStyleButton({
required this.controller,
this.icon,
Key? key,
}) : super(key: key);
final QuillController controller;
final IconData? icon;
@override
_LinkStyleButtonState createState() => _LinkStyleButtonState();
}
@ -174,14 +174,6 @@ typedef ToggleStyleButtonBuilder = Widget Function(
);
class ToggleStyleButton extends StatefulWidget {
final Attribute attribute;
final IconData icon;
final QuillController controller;
final ToggleStyleButtonBuilder childBuilder;
const ToggleStyleButton({
required this.attribute,
required this.icon,
@ -190,6 +182,14 @@ class ToggleStyleButton extends StatefulWidget {
Key? key,
}) : super(key: key);
final Attribute attribute;
final IconData icon;
final QuillController controller;
final ToggleStyleButtonBuilder childBuilder;
@override
_ToggleStyleButtonState createState() => _ToggleStyleButtonState();
}
@ -258,14 +258,6 @@ class _ToggleStyleButtonState extends State<ToggleStyleButton> {
}
class ToggleCheckListButton extends StatefulWidget {
final IconData icon;
final QuillController controller;
final ToggleStyleButtonBuilder childBuilder;
final Attribute attribute;
const ToggleCheckListButton({
required this.icon,
required this.controller,
@ -274,6 +266,14 @@ class ToggleCheckListButton extends StatefulWidget {
Key? key,
}) : super(key: key);
final IconData icon;
final QuillController controller;
final ToggleStyleButtonBuilder childBuilder;
final Attribute attribute;
@override
_ToggleCheckListButtonState createState() => _ToggleCheckListButtonState();
}
@ -369,11 +369,11 @@ Widget defaultToggleStyleButtonBuilder(
}
class SelectHeaderStyleButton extends StatefulWidget {
final QuillController controller;
const SelectHeaderStyleButton({required this.controller, Key? key})
: super(key: key);
final QuillController controller;
@override
_SelectHeaderStyleButtonState createState() =>
_SelectHeaderStyleButtonState();
@ -490,6 +490,15 @@ Widget _selectHeadingStyleButtonBuilder(BuildContext context, Attribute? value,
}
class ImageButton extends StatefulWidget {
const ImageButton({
required this.icon,
required this.controller,
required this.imageSource,
this.onImagePickCallback,
this.imagePickImpl,
Key? key,
}) : super(key: key);
final IconData icon;
final QuillController controller;
@ -500,15 +509,6 @@ class ImageButton extends StatefulWidget {
final ImageSource imageSource;
const ImageButton({
required this.icon,
required this.controller,
required this.imageSource,
this.onImagePickCallback,
this.imagePickImpl,
Key? key,
}) : super(key: key);
@override
_ImageButtonState createState() => _ImageButtonState();
}
@ -602,10 +602,6 @@ class _ImageButtonState extends State<ImageButton> {
/// When pressed, this button displays overlay toolbar with
/// buttons for each color.
class ColorButton extends StatefulWidget {
final IconData icon;
final bool background;
final QuillController controller;
const ColorButton({
required this.icon,
required this.controller,
@ -613,6 +609,10 @@ class ColorButton extends StatefulWidget {
Key? key,
}) : super(key: key);
final IconData icon;
final bool background;
final QuillController controller;
@override
_ColorButtonState createState() => _ColorButtonState();
}
@ -740,10 +740,6 @@ class _ColorButtonState extends State<ColorButton> {
}
class HistoryButton extends StatefulWidget {
final IconData icon;
final bool undo;
final QuillController controller;
const HistoryButton({
required this.icon,
required this.controller,
@ -751,6 +747,10 @@ class HistoryButton extends StatefulWidget {
Key? key,
}) : super(key: key);
final IconData icon;
final bool undo;
final QuillController controller;
@override
_HistoryButtonState createState() => _HistoryButtonState();
}
@ -812,10 +812,6 @@ class _HistoryButtonState extends State<HistoryButton> {
}
class IndentButton extends StatefulWidget {
final IconData icon;
final QuillController controller;
final bool isIncrease;
const IndentButton({
required this.icon,
required this.controller,
@ -823,6 +819,10 @@ class IndentButton extends StatefulWidget {
Key? key,
}) : super(key: key);
final IconData icon;
final QuillController controller;
final bool isIncrease;
@override
_IndentButtonState createState() => _IndentButtonState();
}
@ -867,16 +867,16 @@ class _IndentButtonState extends State<IndentButton> {
}
class ClearFormatButton extends StatefulWidget {
final IconData icon;
final QuillController controller;
const ClearFormatButton({
required this.icon,
required this.controller,
Key? key,
}) : super(key: key);
final IconData icon;
final QuillController controller;
@override
_ClearFormatButtonState createState() => _ClearFormatButtonState();
}
@ -903,8 +903,6 @@ class _ClearFormatButtonState extends State<ClearFormatButton> {
}
class QuillToolbar extends StatefulWidget implements PreferredSizeWidget {
final List<Widget> children;
const QuillToolbar({required this.children, Key? key}) : super(key: key);
factory QuillToolbar.basic({
@ -1117,6 +1115,8 @@ class QuillToolbar extends StatefulWidget implements PreferredSizeWidget {
]);
}
final List<Widget> children;
@override
_QuillToolbarState createState() => _QuillToolbarState();
@ -1148,13 +1148,6 @@ class _QuillToolbarState extends State<QuillToolbar> {
}
class QuillIconButton extends StatelessWidget {
final VoidCallback? onPressed;
final Widget? icon;
final double size;
final Color? fillColor;
final double hoverElevation;
final double highlightElevation;
const QuillIconButton({
required this.onPressed,
this.icon,
@ -1165,6 +1158,13 @@ class QuillIconButton extends StatelessWidget {
Key? key,
}) : super(key: key);
final VoidCallback? onPressed;
final Widget? icon;
final double size;
final Color? fillColor;
final double hoverElevation;
final double highlightElevation;
@override
Widget build(BuildContext context) {
return ConstrainedBox(
@ -1184,15 +1184,6 @@ class QuillIconButton extends StatelessWidget {
}
class QuillDropdownButton<T> extends StatefulWidget {
final double height;
final Color? fillColor;
final double hoverElevation;
final double highlightElevation;
final Widget child;
final T initialValue;
final List<PopupMenuEntry<T>> items;
final ValueChanged<T> onSelected;
const QuillDropdownButton({
required this.child,
required this.initialValue,
@ -1205,6 +1196,15 @@ class QuillDropdownButton<T> extends StatefulWidget {
Key? key,
}) : super(key: key);
final double height;
final Color? fillColor;
final double hoverElevation;
final double highlightElevation;
final Widget child;
final T initialValue;
final List<PopupMenuEntry<T>> items;
final ValueChanged<T> onSelected;
@override
_QuillDropdownButtonState<T> createState() => _QuillDropdownButtonState<T>();
}

Loading…
Cancel
Save