diff --git a/analysis_options.yaml b/analysis_options.yaml index 099921dd..306d335b 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -7,5 +7,9 @@ analyzer: unsafe_html: ignore linter: rules: + - always_put_required_named_parameters_first - avoid_print + - avoid_redundant_argument_values + - prefer_const_constructors + - prefer_const_constructors_in_immutables - unnecessary_parenthesis diff --git a/example/lib/pages/home_page.dart b/example/lib/pages/home_page.dart index 2e044fd7..9e91cde4 100644 --- a/example/lib/pages/home_page.dart +++ b/example/lib/pages/home_page.dart @@ -110,7 +110,6 @@ class _HomePageState extends State { autoFocus: false, readOnly: false, placeholder: 'Add content', - enableInteractiveSelection: true, expands: false, padding: EdgeInsets.zero, customStyles: DefaultStyles( diff --git a/example/lib/pages/read_only_page.dart b/example/lib/pages/read_only_page.dart index 8f03d45c..6e2ec0e0 100644 --- a/example/lib/pages/read_only_page.dart +++ b/example/lib/pages/read_only_page.dart @@ -42,7 +42,6 @@ class _ReadOnlyPageState extends State { focusNode: _focusNode, autoFocus: true, readOnly: !_edit, - enableInteractiveSelection: true, expands: false, padding: EdgeInsets.zero, ), diff --git a/lib/models/documents/document.dart b/lib/models/documents/document.dart index ee49034e..0ff76faf 100644 --- a/lib/models/documents/document.dart +++ b/lib/models/documents/document.dart @@ -183,7 +183,7 @@ class Document { bool nextOpIsImage = i + 1 < ops.length && ops[i + 1].isInsert && ops[i + 1].data is! String; if (nextOpIsImage && !(op.data as String).endsWith('\n')) { - res.push(Operation.insert('\n', null)); + res.push(Operation.insert('\n')); } // Currently embed is equivalent to image and hence `is! String` bool opInsertImage = op.isInsert && op.data is! String; @@ -193,7 +193,7 @@ class Document { (ops[i + 1].data as String).startsWith('\n'); if (opInsertImage && (i + 1 == ops.length - 1 || !nextOpIsLineBreak)) { // automatically append '\n' for image - res.push(Operation.insert('\n', null)); + res.push(Operation.insert('\n')); } } @@ -213,7 +213,7 @@ class Document { _history.clear(); } - String toPlainText() => _root.children.map((e) => e.toPlainText()).join(''); + String toPlainText() => _root.children.map((e) => e.toPlainText()).join(); void _loadDocument(Delta doc) { assert((doc.last.data as String).endsWith('\n')); diff --git a/lib/models/documents/history.dart b/lib/models/documents/history.dart index 32e780c9..6d89b389 100644 --- a/lib/models/documents/history.dart +++ b/lib/models/documents/history.dart @@ -86,7 +86,7 @@ class History { Tuple2 _change(Document doc, List source, List dest) { if (source.isEmpty) { - return Tuple2(false, 0); + return const Tuple2(false, 0); } Delta delta = source.removeLast(); // look for insert or delete diff --git a/lib/models/quill_delta.dart b/lib/models/quill_delta.dart index 7fb215b8..ddccb710 100644 --- a/lib/models/quill_delta.dart +++ b/lib/models/quill_delta.dart @@ -294,7 +294,7 @@ class Delta { if (other is! Delta) return false; Delta typedOther = other; final comparator = - ListEquality(const DefaultEquality()); + const ListEquality(DefaultEquality()); return comparator.equals(_operations, typedOther._operations); } @@ -520,7 +520,7 @@ class Delta { if (op.isInsert) { inverted.delete(op.length!); } else if (op.isRetain && op.isPlain) { - inverted.retain(op.length!, null); + inverted.retain(op.length!); baseIndex += op.length!; } else if (op.isDelete || (op.isRetain && op.isNotPlain)) { final length = op.length!; diff --git a/lib/models/rules/insert.dart b/lib/models/rules/insert.dart index 62585ec3..5ea7f215 100644 --- a/lib/models/rules/insert.dart +++ b/lib/models/rules/insert.dart @@ -378,5 +378,5 @@ Tuple2 _getNextNewLine(DeltaIterator iterator) { return Tuple2(op, skipped); } } - return Tuple2(null, null); + return const Tuple2(null, null); } diff --git a/lib/models/rules/rule.dart b/lib/models/rules/rule.dart index df8e0b4a..70a5aa74 100644 --- a/lib/models/rules/rule.dart +++ b/lib/models/rules/rule.dart @@ -29,21 +29,21 @@ abstract class Rule { class Rules { final List _rules; static final Rules _instance = Rules([ - FormatLinkAtCaretPositionRule(), - ResolveLineFormatRule(), - ResolveInlineFormatRule(), - InsertEmbedsRule(), - ForceNewlineForInsertsAroundEmbedRule(), - AutoExitBlockRule(), - PreserveBlockStyleOnInsertRule(), - PreserveLineStyleOnSplitRule(), - ResetLineFormatOnNewLineRule(), - AutoFormatLinksRule(), - PreserveInlineStylesRule(), - CatchAllInsertRule(), - EnsureEmbedLineRule(), - PreserveLineStyleOnMergeRule(), - CatchAllDeleteRule(), + const FormatLinkAtCaretPositionRule(), + const ResolveLineFormatRule(), + const ResolveInlineFormatRule(), + const InsertEmbedsRule(), + const ForceNewlineForInsertsAroundEmbedRule(), + const AutoExitBlockRule(), + const PreserveBlockStyleOnInsertRule(), + const PreserveLineStyleOnSplitRule(), + const ResetLineFormatOnNewLineRule(), + const AutoFormatLinksRule(), + const PreserveInlineStylesRule(), + const CatchAllInsertRule(), + const EnsureEmbedLineRule(), + const PreserveLineStyleOnMergeRule(), + const CatchAllDeleteRule(), ]); Rules(this._rules); diff --git a/lib/widgets/controller.dart b/lib/widgets/controller.dart index 29206059..da876bf1 100644 --- a/lib/widgets/controller.dart +++ b/lib/widgets/controller.dart @@ -18,7 +18,9 @@ class QuillController extends ChangeNotifier { factory QuillController.basic() { return QuillController( - document: Document(), selection: TextSelection.collapsed(offset: 0)); + document: Document(), + selection: const TextSelection.collapsed(offset: 0), + ); } // item1: Document state before [change]. @@ -31,7 +33,6 @@ class QuillController extends ChangeNotifier { TextEditingValue get plainTextEditingValue => TextEditingValue( text: document.toPlainText(), selection: selection, - composing: TextRange.empty, ); Style getSelectionStyle() { @@ -73,7 +74,8 @@ class QuillController extends ChangeNotifier { bool get hasRedo => document.hasRedo; - void replaceText(int index, int len, Object? data, TextSelection? textSelection) { + void replaceText( + int index, int len, Object? data, TextSelection? textSelection) { assert(data is String || data is Embeddable); Delta? delta; diff --git a/lib/widgets/cursor.dart b/lib/widgets/cursor.dart index 8fa45437..4195d947 100644 --- a/lib/widgets/cursor.dart +++ b/lib/widgets/cursor.dart @@ -109,7 +109,8 @@ class CursorCont extends ChangeNotifier { void _cursorWaitForStart(Timer timer) { _cursorTimer?.cancel(); - _cursorTimer = Timer.periodic(Duration(milliseconds: 500), _cursorTick); + _cursorTimer = + Timer.periodic(const Duration(milliseconds: 500), _cursorTick); } void startCursorTimer() { @@ -117,10 +118,11 @@ class CursorCont extends ChangeNotifier { _blinkOpacityCont.value = 1.0; if (style.opacityAnimates) { - _cursorTimer = - Timer.periodic(Duration(milliseconds: 150), _cursorWaitForStart); + _cursorTimer = Timer.periodic( + const Duration(milliseconds: 150), _cursorWaitForStart); } else { - _cursorTimer = Timer.periodic(Duration(milliseconds: 500), _cursorTick); + _cursorTimer = + Timer.periodic(const Duration(milliseconds: 500), _cursorTick); } } diff --git a/lib/widgets/default_styles.dart b/lib/widgets/default_styles.dart index bbe8db10..5583307d 100644 --- a/lib/widgets/default_styles.dart +++ b/lib/widgets/default_styles.dart @@ -5,10 +5,10 @@ import 'package:tuple/tuple.dart'; class QuillStyles extends InheritedWidget { final DefaultStyles data; - QuillStyles({ - Key? key, + const QuillStyles({ required this.data, required Widget child, + Key? key, }) : super(key: key, child: child); @override @@ -86,7 +86,7 @@ class DefaultStyles { fontSize: 16.0, height: 1.3, ); - Tuple2 baseSpacing = Tuple2(6.0, 0); + Tuple2 baseSpacing = const Tuple2(6.0, 0); String fontFamily; switch (themeData.platform) { case TargetPlatform.iOS: @@ -111,8 +111,8 @@ class DefaultStyles { height: 1.15, fontWeight: FontWeight.w300, ), - Tuple2(16.0, 0.0), - Tuple2(0.0, 0.0), + const Tuple2(16.0, 0.0), + const Tuple2(0.0, 0.0), null), h2: DefaultTextBlockStyle( defaultTextStyle.style.copyWith( @@ -121,8 +121,8 @@ class DefaultStyles { height: 1.15, fontWeight: FontWeight.normal, ), - Tuple2(8.0, 0.0), - Tuple2(0.0, 0.0), + const Tuple2(8.0, 0.0), + const Tuple2(0.0, 0.0), null), h3: DefaultTextBlockStyle( defaultTextStyle.style.copyWith( @@ -131,15 +131,15 @@ class DefaultStyles { height: 1.25, fontWeight: FontWeight.w500, ), - Tuple2(8.0, 0.0), - Tuple2(0.0, 0.0), + const Tuple2(8.0, 0.0), + const Tuple2(0.0, 0.0), null), paragraph: DefaultTextBlockStyle( - baseStyle, Tuple2(0.0, 0.0), Tuple2(0.0, 0.0), null), - bold: TextStyle(fontWeight: FontWeight.bold), - italic: TextStyle(fontStyle: FontStyle.italic), - underline: TextStyle(decoration: TextDecoration.underline), - strikeThrough: TextStyle(decoration: TextDecoration.lineThrough), + baseStyle, const Tuple2(0.0, 0.0), const Tuple2(0.0, 0.0), null), + bold: const TextStyle(fontWeight: FontWeight.bold), + italic: const TextStyle(fontStyle: FontStyle.italic), + underline: const TextStyle(decoration: TextDecoration.underline), + strikeThrough: const TextStyle(decoration: TextDecoration.lineThrough), link: TextStyle( color: themeData.accentColor, decoration: TextDecoration.underline, @@ -150,15 +150,15 @@ class DefaultStyles { height: 1.5, color: Colors.grey.withOpacity(0.6), ), - Tuple2(0.0, 0.0), - Tuple2(0.0, 0.0), + const Tuple2(0.0, 0.0), + const Tuple2(0.0, 0.0), null), lists: DefaultTextBlockStyle( - baseStyle, baseSpacing, Tuple2(0.0, 6.0), null), + baseStyle, baseSpacing, const Tuple2(0.0, 6.0), null), quote: DefaultTextBlockStyle( TextStyle(color: baseStyle.color!.withOpacity(0.6)), baseSpacing, - Tuple2(6.0, 2.0), + const Tuple2(6.0, 2.0), BoxDecoration( border: Border( left: BorderSide(width: 4, color: Colors.grey.shade300), @@ -172,18 +172,18 @@ class DefaultStyles { height: 1.15, ), baseSpacing, - Tuple2(0.0, 0.0), + const Tuple2(0.0, 0.0), BoxDecoration( color: Colors.grey.shade50, borderRadius: BorderRadius.circular(2), )), indent: DefaultTextBlockStyle( - baseStyle, baseSpacing, Tuple2(0.0, 6.0), null), + baseStyle, baseSpacing, const Tuple2(0.0, 6.0), null), align: DefaultTextBlockStyle( - baseStyle, Tuple2(0.0, 0.0), Tuple2(0.0, 0.0), null), - sizeSmall: TextStyle(fontSize: 10.0), - sizeLarge: TextStyle(fontSize: 18.0), - sizeHuge: TextStyle(fontSize: 22.0)); + baseStyle, const Tuple2(0.0, 0.0), const Tuple2(0.0, 0.0), null), + sizeSmall: const TextStyle(fontSize: 10.0), + sizeLarge: const TextStyle(fontSize: 18.0), + sizeHuge: const TextStyle(fontSize: 22.0)); } DefaultStyles merge(DefaultStyles other) { diff --git a/lib/widgets/editor.dart b/lib/widgets/editor.dart index 6256aa6e..5bab5fb4 100644 --- a/lib/widgets/editor.dart +++ b/lib/widgets/editor.dart @@ -169,21 +169,21 @@ class QuillEditor extends StatefulWidget { final ValueChanged? onLaunchUrl; final EmbedBuilder embedBuilder; - QuillEditor( + const QuillEditor( {required this.controller, required this.focusNode, required this.scrollController, required this.scrollable, required this.padding, required this.autoFocus, - this.showCursor, required this.readOnly, + required this.expands, + this.showCursor, this.placeholder, this.enableInteractiveSelection = true, this.minHeight, this.maxHeight, this.customStyles, - required this.expands, this.textCapitalization = TextCapitalization.sentences, this.keyboardAppearance = Brightness.light, this.scrollPhysics, @@ -200,7 +200,6 @@ class QuillEditor extends StatefulWidget { focusNode: FocusNode(), autoFocus: true, readOnly: readOnly, - enableInteractiveSelection: true, expands: false, padding: EdgeInsets.zero); } @@ -726,8 +725,7 @@ class RenderEditor extends RenderEditableContainerBox ); if (position.offset - word.start <= 1) { _handleSelectionChange( - TextSelection.collapsed( - offset: word.start, affinity: TextAffinity.downstream), + TextSelection.collapsed(offset: word.start), cause, ); } else { @@ -866,6 +864,11 @@ class RenderEditor extends RenderEditableContainerBox ); } + /// Returns the y-offset of the editor at which [selection] is visible. + /// + /// The offset is the distance from the top of the editor and is the minimum + /// from the current scroll position until [selection] becomes visible. + /// Returns null if [selection] is already visible. double? getOffsetToRevealCursor( double viewportHeight, double scrollOffset, double offsetInViewport) { List endpoints = getEndpointsForSelection(selection); diff --git a/lib/widgets/proxy.dart b/lib/widgets/proxy.dart index f3e38c4e..8717d12a 100644 --- a/lib/widgets/proxy.dart +++ b/lib/widgets/proxy.dart @@ -7,7 +7,7 @@ class BaselineProxy extends SingleChildRenderObjectWidget { final TextStyle? textStyle; final EdgeInsets? padding; - BaselineProxy({Key? key, Widget? child, this.textStyle, this.padding}) + const BaselineProxy({Key? key, Widget? child, this.textStyle, this.padding}) : super(key: key, child: child); @override @@ -73,7 +73,7 @@ class RenderBaselineProxy extends RenderProxyBox { } class EmbedProxy extends SingleChildRenderObjectWidget { - EmbedProxy(Widget child) : super(child: child); + const EmbedProxy(Widget child) : super(child: child); @override RenderEmbedProxy createRenderObject(BuildContext context) => @@ -113,7 +113,7 @@ class RenderEmbedProxy extends RenderProxyBox implements RenderContentProxyBox { @override TextRange getWordBoundary(TextPosition position) => - TextRange(start: 0, end: 1); + const TextRange(start: 0, end: 1); @override double getPreferredLineHeight() { @@ -145,7 +145,7 @@ class RichTextProxy extends SingleChildRenderObjectWidget { textHeightBehavior); } - RichTextProxy( + const RichTextProxy( RichText child, this.textStyle, this.textAlign, diff --git a/lib/widgets/raw_editor.dart b/lib/widgets/raw_editor.dart index b4e6756b..e0774208 100644 --- a/lib/widgets/raw_editor.dart +++ b/lib/widgets/raw_editor.dart @@ -55,7 +55,7 @@ class RawEditor extends StatefulWidget { final ScrollPhysics? scrollPhysics; final EmbedBuilder embedBuilder; - RawEditor( + const RawEditor( Key key, this.controller, this.focusNode, @@ -382,8 +382,6 @@ class RawEditorState extends EditorState TextInputConfiguration( inputType: TextInputType.multiline, readOnly: widget.readOnly, - obscureText: false, - autocorrect: true, inputAction: TextInputAction.newline, keyboardAppearance: widget.keyboardAppearance, textCapitalization: widget.textCapitalization, @@ -554,7 +552,7 @@ class RawEditorState extends EditorState } BoxConstraints constraints = widget.expands - ? BoxConstraints.expand() + ? const BoxConstraints.expand() : BoxConstraints( minHeight: widget.minHeight ?? 0.0, maxHeight: widget.maxHeight ?? double.infinity); @@ -602,7 +600,7 @@ class RawEditorState extends EditorState widget.enableInteractiveSelection, _hasFocus, attrs.containsKey(Attribute.codeBlock.key) - ? EdgeInsets.all(16.0) + ? const EdgeInsets.all(16.0) : null, widget.embedBuilder, _cursorCont, @@ -702,6 +700,7 @@ class RawEditorState extends EditorState _keyboardVisible = true; } else { _keyboardVisibilityController = KeyboardVisibilityController(); + _keyboardVisible = _keyboardVisibilityController!.isVisible; _keyboardVisibilitySubscription = _keyboardVisibilityController?.onChange.listen((bool visible) { _keyboardVisible = visible; @@ -817,7 +816,8 @@ class RawEditorState extends EditorState String plainText = textEditingValue.text; if (shortcut == InputShortcut.COPY) { if (!selection.isCollapsed) { - await Clipboard.setData(ClipboardData(text: selection.textInside(plainText))); + await Clipboard.setData( + ClipboardData(text: selection.textInside(plainText))); } return; } @@ -985,7 +985,7 @@ class RawEditorState extends EditorState final viewport = RenderAbstractViewport.of(getRenderEditor())!; final editorOffset = getRenderEditor()! - .localToGlobal(Offset(0.0, 0.0), ancestor: viewport); + .localToGlobal(const Offset(0.0, 0.0), ancestor: viewport); final offsetInViewport = _scrollController!.offset + editorOffset.dy; final offset = getRenderEditor()!.getOffsetToRevealCursor( @@ -997,7 +997,7 @@ class RawEditorState extends EditorState if (offset != null) { _scrollController!.animateTo( offset, - duration: Duration(milliseconds: 100), + duration: const Duration(milliseconds: 100), curve: Curves.fastOutSlowIn, ); } @@ -1151,16 +1151,17 @@ class _Editor extends MultiChildRenderObjectWidget { @override RenderEditor createRenderObject(BuildContext context) { return RenderEditor( - null, - textDirection, - padding, - document, - selection, - hasFocus, - onSelectionChanged, - startHandleLayerLink, - endHandleLayerLink, - EdgeInsets.fromLTRB(4, 4, 4, 5)); + null, + textDirection, + padding, + document, + selection, + hasFocus, + onSelectionChanged, + startHandleLayerLink, + endHandleLayerLink, + const EdgeInsets.fromLTRB(4, 4, 4, 5), + ); } @override diff --git a/lib/widgets/responsive_widget.dart b/lib/widgets/responsive_widget.dart index 806883ec..dbfec8d5 100644 --- a/lib/widgets/responsive_widget.dart +++ b/lib/widgets/responsive_widget.dart @@ -5,12 +5,12 @@ class ResponsiveWidget extends StatelessWidget { final Widget? mediumScreen; final Widget? smallScreen; - const ResponsiveWidget( - {Key? key, - required this.largeScreen, - this.mediumScreen, - this.smallScreen}) - : super(key: key); + const ResponsiveWidget({ + required this.largeScreen, + this.mediumScreen, + this.smallScreen, + Key? key, + }) : super(key: key); static bool isSmallScreen(BuildContext context) { return MediaQuery.of(context).size.width < 800; diff --git a/lib/widgets/text_block.dart b/lib/widgets/text_block.dart index 603ee461..7ea5b278 100644 --- a/lib/widgets/text_block.dart +++ b/lib/widgets/text_block.dart @@ -61,7 +61,7 @@ class EditableTextBlock extends StatelessWidget { final CursorCont cursorCont; final Map indentLevelCounts; - EditableTextBlock( + const EditableTextBlock( this.block, this.textDirection, this.verticalSpacing, @@ -84,7 +84,7 @@ class EditableTextBlock extends StatelessWidget { block, textDirection, verticalSpacing as Tuple2, - _getDecorationForBlock(block, defaultStyles) ?? BoxDecoration(), + _getDecorationForBlock(block, defaultStyles) ?? const BoxDecoration(), contentPadding, _buildChildren(context, indentLevelCounts)); } @@ -253,11 +253,11 @@ class EditableTextBlock extends StatelessWidget { class RenderEditableTextBlock extends RenderEditableContainerBox implements RenderEditableBox { RenderEditableTextBlock({ - List? children, required Block block, required TextDirection textDirection, required EdgeInsetsGeometry padding, required Decoration decoration, + List? children, ImageConfiguration configuration = ImageConfiguration.empty, EdgeInsets contentPadding = EdgeInsets.zero, }) : _decoration = decoration, @@ -402,7 +402,8 @@ class RenderEditableTextBlock extends RenderEditableContainerBox } Offset caretOffset = child.getOffsetForCaret(childLocalPosition); - Offset testOffset = sibling.getOffsetForCaret(TextPosition(offset: 0)); + Offset testOffset = + sibling.getOffsetForCaret(const TextPosition(offset: 0)); Offset finalOffset = Offset(caretOffset.dx, testOffset.dy); return TextPosition( offset: sibling.getContainer().getOffset() + @@ -558,7 +559,6 @@ class _NumberPoint extends StatelessWidget { final double padding; const _NumberPoint({ - Key? key, required this.index, required this.indentLevelCounts, required this.count, @@ -567,6 +567,7 @@ class _NumberPoint extends StatelessWidget { required this.attrs, this.withDot = true, this.padding = 0.0, + Key? key, }) : super(key: key); @override @@ -623,7 +624,7 @@ class _NumberPoint extends StatelessWidget { n = (n / 26).floor(); } - return result.toString().split('').reversed.join(''); + return result.toString().split('').reversed.join(); } String _intToRoman(int input) { @@ -656,9 +657,9 @@ class _BulletPoint extends StatelessWidget { final double width; const _BulletPoint({ - Key? key, required this.style, required this.width, + Key? key, }) : super(key: key); @override @@ -666,7 +667,7 @@ class _BulletPoint extends StatelessWidget { return Container( alignment: AlignmentDirectional.topEnd, width: width, - padding: EdgeInsetsDirectional.only(end: 13.0), + padding: const EdgeInsetsDirectional.only(end: 13.0), child: Text('•', style: style), ); } @@ -707,7 +708,7 @@ class __CheckboxState extends State<_Checkbox> { return Container( alignment: AlignmentDirectional.topEnd, width: widget.width, - padding: EdgeInsetsDirectional.only(end: 13.0), + padding: const EdgeInsetsDirectional.only(end: 13.0), child: Checkbox( value: widget.isChecked, onChanged: _onCheckboxClicked, diff --git a/lib/widgets/text_line.dart b/lib/widgets/text_line.dart index 1b081ea7..0a9ef94e 100644 --- a/lib/widgets/text_line.dart +++ b/lib/widgets/text_line.dart @@ -27,13 +27,13 @@ class TextLine extends StatelessWidget { final EmbedBuilder embedBuilder; final DefaultStyles styles; - const TextLine( - {Key? key, - required this.line, - this.textDirection, - required this.embedBuilder, - required this.styles}) - : super(key: key); + const TextLine({ + required this.line, + required this.embedBuilder, + required this.styles, + this.textDirection, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -87,7 +87,7 @@ class TextLine extends StatelessWidget { .map((node) => _getTextSpanFromNode(defaultStyles, node)) .toList(growable: false); - TextStyle textStyle = TextStyle(); + TextStyle textStyle = const TextStyle(); if (line.style.containsKey(Attribute.placeholder.key)) { textStyle = defaultStyles.placeHolder!.style; @@ -121,7 +121,7 @@ class TextLine extends StatelessWidget { TextSpan _getTextSpanFromNode(DefaultStyles defaultStyles, Node node) { leaf.Text textNode = node as leaf.Text; Style style = textNode.style; - TextStyle res = TextStyle(); + TextStyle res = const TextStyle(); Map m = { Attribute.bold.key: defaultStyles.bold, @@ -206,7 +206,7 @@ class EditableTextLine extends RenderObjectWidget { final double devicePixelRatio; final CursorCont cursorCont; - EditableTextLine( + const EditableTextLine( this.line, this.leading, this.body, @@ -534,7 +534,8 @@ class RenderEditableTextLine extends RenderEditableBox { double get cursorWidth => cursorCont.style.width; double get cursorHeight => - cursorCont.style.height ?? preferredLineHeight(TextPosition(offset: 0)); + cursorCont.style.height ?? + preferredLineHeight(const TextPosition(offset: 0)); void _computeCaretPrototype() { switch (defaultTargetPlatform) { @@ -839,7 +840,8 @@ class _TextLineElement extends RenderObjectElement { } @override - void moveRenderObjectChild(RenderObject child, dynamic oldSlot, dynamic newSlot) { + void moveRenderObjectChild( + RenderObject child, dynamic oldSlot, dynamic newSlot) { throw UnimplementedError(); } diff --git a/lib/widgets/text_selection.dart b/lib/widgets/text_selection.dart index b03dd2bb..8aa29d25 100644 --- a/lib/widgets/text_selection.dart +++ b/lib/widgets/text_selection.dart @@ -58,7 +58,7 @@ class EditorTextSelectionOverlay { OverlayState overlay = Overlay.of(context, rootOverlay: true)!; _toolbarController = AnimationController( - duration: Duration(milliseconds: 150), vsync: overlay); + duration: const Duration(milliseconds: 150), vsync: overlay); } TextSelection get _selection => value.selection; @@ -143,13 +143,14 @@ class EditorTextSelectionOverlay { TextPosition textPosition; switch (position) { case _TextSelectionHandlePosition.START: - textPosition = - newSelection != null ? newSelection.base : TextPosition(offset: 0); + textPosition = newSelection != null + ? newSelection.base + : const TextPosition(offset: 0); break; case _TextSelectionHandlePosition.END: textPosition = newSelection != null ? newSelection.extent - : TextPosition(offset: 0); + : const TextPosition(offset: 0); break; default: throw 'Invalid position'; @@ -198,7 +199,7 @@ class EditorTextSelectionOverlay { endpoints, selectionDelegate, clipboardStatus, - Offset(0, 0)), + const Offset(0, 0)), ), ); } @@ -245,7 +246,6 @@ class EditorTextSelectionOverlay { class _TextSelectionHandleOverlay extends StatefulWidget { const _TextSelectionHandleOverlay({ - Key? key, required this.selection, required this.position, required this.startHandleLayerLink, @@ -255,6 +255,7 @@ class _TextSelectionHandleOverlay extends StatefulWidget { required this.onSelectionHandleTapped, required this.selectionControls, this.dragStartBehavior = DragStartBehavior.start, + Key? key, }) : super(key: key); final TextSelection selection; @@ -292,8 +293,8 @@ class _TextSelectionHandleOverlayState void initState() { super.initState(); - _controller = - AnimationController(duration: Duration(milliseconds: 150), vsync: this); + _controller = AnimationController( + duration: const Duration(milliseconds: 150), vsync: this); _handleVisibilityChanged(); widget._visibility!.addListener(_handleVisibilityChanged); @@ -468,7 +469,7 @@ class _TextSelectionHandleOverlayState class EditorTextSelectionGestureDetector extends StatefulWidget { const EditorTextSelectionGestureDetector({ - Key? key, + required this.child, this.onTapDown, this.onForcePressStart, this.onForcePressEnd, @@ -482,7 +483,7 @@ class EditorTextSelectionGestureDetector extends StatefulWidget { this.onDragSelectionUpdate, this.onDragSelectionEnd, this.behavior, - required this.child, + Key? key, }) : super(key: key); final GestureTapDownCallback? onTapDown; @@ -579,7 +580,7 @@ class _EditorTextSelectionGestureDetectorState void _handleDragUpdate(DragUpdateDetails details) { _lastDragUpdateDetails = details; _dragUpdateThrottleTimer ??= - Timer(Duration(milliseconds: 50), _handleDragUpdateThrottled); + Timer(const Duration(milliseconds: 50), _handleDragUpdateThrottled); } void _handleDragUpdateThrottled() { diff --git a/lib/widgets/toolbar.dart b/lib/widgets/toolbar.dart index cb23a19e..d3440cfa 100644 --- a/lib/widgets/toolbar.dart +++ b/lib/widgets/toolbar.dart @@ -25,9 +25,9 @@ class InsertEmbedButton extends StatelessWidget { final IconData icon; const InsertEmbedButton({ - Key? key, required this.controller, required this.icon, + Key? key, }) : super(key: key); @override @@ -56,9 +56,9 @@ class LinkStyleButton extends StatefulWidget { final IconData? icon; const LinkStyleButton({ - Key? key, required this.controller, this.icon, + Key? key, }) : super(key: key); @override @@ -114,7 +114,7 @@ class _LinkStyleButtonState extends State { showDialog( context: context, builder: (ctx) { - return _LinkDialog(); + return const _LinkDialog(); }, ).then(_linkSubmitted); } @@ -141,14 +141,14 @@ class _LinkDialogState extends State<_LinkDialog> { Widget build(BuildContext context) { return AlertDialog( content: TextField( - decoration: InputDecoration(labelText: 'Paste a link'), + decoration: const InputDecoration(labelText: 'Paste a link'), autofocus: true, onChanged: _linkChanged, ), actions: [ TextButton( onPressed: _link.isNotEmpty ? _applyLink : null, - child: Text('Apply'), + child: const Text('Apply'), ), ], ); @@ -182,12 +182,12 @@ class ToggleStyleButton extends StatefulWidget { final ToggleStyleButtonBuilder childBuilder; - ToggleStyleButton({ - Key? key, + const ToggleStyleButton({ required this.attribute, required this.icon, required this.controller, this.childBuilder = defaultToggleStyleButtonBuilder, + Key? key, }) : super(key: key); @override @@ -266,12 +266,12 @@ class ToggleCheckListButton extends StatefulWidget { final Attribute attribute; - ToggleCheckListButton({ - Key? key, + const ToggleCheckListButton({ required this.icon, required this.controller, - this.childBuilder = defaultToggleStyleButtonBuilder, required this.attribute, + this.childBuilder = defaultToggleStyleButtonBuilder, + Key? key, }) : super(key: key); @override @@ -371,7 +371,7 @@ Widget defaultToggleStyleButtonBuilder( class SelectHeaderStyleButton extends StatefulWidget { final QuillController controller; - const SelectHeaderStyleButton({Key? key, required this.controller}) + const SelectHeaderStyleButton({required this.controller, Key? key}) : super(key: key); @override @@ -430,7 +430,7 @@ class _SelectHeaderStyleButtonState extends State { Widget _selectHeadingStyleButtonBuilder(BuildContext context, Attribute? value, ValueChanged onSelected) { - final style = TextStyle(fontSize: 13); + final style = const TextStyle(fontSize: 13); final Map _valueToText = { Attribute.header: 'Normal text', @@ -478,7 +478,7 @@ Widget _selectHeadingStyleButtonBuilder(BuildContext context, Attribute? value, : (value.key == 'h2') ? Attribute.h2 : Attribute.h3]!, - style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600), + style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600), ), ); } @@ -494,14 +494,14 @@ class ImageButton extends StatefulWidget { final ImageSource imageSource; - ImageButton( - {Key? key, - required this.icon, - required this.controller, - required this.imageSource, - this.onImagePickCallback, - this.imagePickImpl}) - : super(key: key); + const ImageButton({ + required this.icon, + required this.controller, + required this.imageSource, + this.onImagePickCallback, + this.imagePickImpl, + Key? key, + }) : super(key: key); @override _ImageButtonState createState() => _ImageButtonState(); @@ -525,7 +525,6 @@ class _ImageButtonState extends State { Future _pickImageWeb() async { _paths = (await FilePicker.platform.pickFiles( type: _pickingType, - allowMultiple: false, allowedExtensions: (_extension?.isNotEmpty ?? false) ? _extension?.replaceAll(' ', '').split(',') : null, @@ -601,12 +600,12 @@ class ColorButton extends StatefulWidget { final bool background; final QuillController controller; - ColorButton( - {Key? key, - required this.icon, - required this.controller, - required this.background}) - : super(key: key); + const ColorButton({ + required this.icon, + required this.controller, + required this.background, + Key? key, + }) : super(key: key); @override _ColorButtonState createState() => _ColorButtonState(); @@ -726,7 +725,7 @@ class _ColorButtonState extends State { backgroundColor: Theme.of(context).canvasColor, content: SingleChildScrollView( child: MaterialPicker( - pickerColor: Color(0x00000000), + pickerColor: const Color(0x00000000), onColorChanged: _changeColor, ), )), @@ -739,12 +738,12 @@ class HistoryButton extends StatefulWidget { final bool undo; final QuillController controller; - HistoryButton( - {Key? key, - required this.icon, - required this.controller, - required this.undo}) - : super(key: key); + const HistoryButton({ + required this.icon, + required this.controller, + required this.undo, + Key? key, + }) : super(key: key); @override _HistoryButtonState createState() => _HistoryButtonState(); @@ -811,12 +810,12 @@ class IndentButton extends StatefulWidget { final QuillController controller; final bool isIncrease; - IndentButton( - {Key? key, - required this.icon, - required this.controller, - required this.isIncrease}) - : super(key: key); + const IndentButton({ + required this.icon, + required this.controller, + required this.isIncrease, + Key? key, + }) : super(key: key); @override _IndentButtonState createState() => _IndentButtonState(); @@ -866,8 +865,11 @@ class ClearFormatButton extends StatefulWidget { final QuillController controller; - ClearFormatButton({Key? key, required this.icon, required this.controller}) - : super(key: key); + const ClearFormatButton({ + required this.icon, + required this.controller, + Key? key, + }) : super(key: key); @override _ClearFormatButtonState createState() => _ClearFormatButtonState(); @@ -897,30 +899,31 @@ class _ClearFormatButtonState extends State { class QuillToolbar extends StatefulWidget implements PreferredSizeWidget { final List children; - const QuillToolbar({Key? key, required this.children}) : super(key: key); - - factory QuillToolbar.basic( - {Key? key, - required QuillController controller, - double toolbarIconSize = 18.0, - bool showBoldButton = true, - bool showItalicButton = true, - bool showUnderLineButton = true, - bool showStrikeThrough = true, - bool showColorButton = true, - bool showBackgroundColorButton = true, - bool showClearFormat = true, - bool showHeaderStyle = true, - bool showListNumbers = true, - bool showListBullets = true, - bool showListCheck = true, - bool showCodeBlock = true, - bool showQuote = true, - bool showIndent = true, - bool showLink = true, - bool showHistory = true, - bool showHorizontalRule = false, - OnImagePickCallback? onImagePickCallback}) { + const QuillToolbar({required this.children, Key? key}) : super(key: key); + + factory QuillToolbar.basic({ + required QuillController controller, + double toolbarIconSize = 18.0, + bool showBoldButton = true, + bool showItalicButton = true, + bool showUnderLineButton = true, + bool showStrikeThrough = true, + bool showColorButton = true, + bool showBackgroundColorButton = true, + bool showClearFormat = true, + bool showHeaderStyle = true, + bool showListNumbers = true, + bool showListBullets = true, + bool showListCheck = true, + bool showCodeBlock = true, + bool showQuote = true, + bool showIndent = true, + bool showLink = true, + bool showHistory = true, + bool showHorizontalRule = false, + OnImagePickCallback? onImagePickCallback, + Key? key, + }) { iconSize = toolbarIconSize; return QuillToolbar(key: key, children: [ Visibility( @@ -939,7 +942,7 @@ class QuillToolbar extends StatefulWidget implements PreferredSizeWidget { undo: false, ), ), - SizedBox(width: 0.6), + const SizedBox(width: 0.6), Visibility( visible: showBoldButton, child: ToggleStyleButton( @@ -948,7 +951,7 @@ class QuillToolbar extends StatefulWidget implements PreferredSizeWidget { controller: controller, ), ), - SizedBox(width: 0.6), + const SizedBox(width: 0.6), Visibility( visible: showItalicButton, child: ToggleStyleButton( @@ -957,7 +960,7 @@ class QuillToolbar extends StatefulWidget implements PreferredSizeWidget { controller: controller, ), ), - SizedBox(width: 0.6), + const SizedBox(width: 0.6), Visibility( visible: showUnderLineButton, child: ToggleStyleButton( @@ -966,7 +969,7 @@ class QuillToolbar extends StatefulWidget implements PreferredSizeWidget { controller: controller, ), ), - SizedBox(width: 0.6), + const SizedBox(width: 0.6), Visibility( visible: showStrikeThrough, child: ToggleStyleButton( @@ -975,7 +978,7 @@ class QuillToolbar extends StatefulWidget implements PreferredSizeWidget { controller: controller, ), ), - SizedBox(width: 0.6), + const SizedBox(width: 0.6), Visibility( visible: showColorButton, child: ColorButton( @@ -984,7 +987,7 @@ class QuillToolbar extends StatefulWidget implements PreferredSizeWidget { background: false, ), ), - SizedBox(width: 0.6), + const SizedBox(width: 0.6), Visibility( visible: showBackgroundColorButton, child: ColorButton( @@ -993,7 +996,7 @@ class QuillToolbar extends StatefulWidget implements PreferredSizeWidget { background: true, ), ), - SizedBox(width: 0.6), + const SizedBox(width: 0.6), Visibility( visible: showClearFormat, child: ClearFormatButton( @@ -1001,7 +1004,7 @@ class QuillToolbar extends StatefulWidget implements PreferredSizeWidget { controller: controller, ), ), - SizedBox(width: 0.6), + const SizedBox(width: 0.6), Visibility( visible: onImagePickCallback != null, child: ImageButton( @@ -1011,7 +1014,7 @@ class QuillToolbar extends StatefulWidget implements PreferredSizeWidget { onImagePickCallback: onImagePickCallback, ), ), - SizedBox(width: 0.6), + const SizedBox(width: 0.6), Visibility( visible: onImagePickCallback != null, child: ImageButton( @@ -1119,7 +1122,7 @@ class _QuillToolbarState extends State { @override Widget build(BuildContext context) { return Container( - padding: EdgeInsets.symmetric(horizontal: 8), + padding: const EdgeInsets.symmetric(horizontal: 8), constraints: BoxConstraints.tightFor(height: widget.preferredSize.height), color: Theme.of(context).canvasColor, child: CustomScrollView( @@ -1147,13 +1150,13 @@ class QuillIconButton extends StatelessWidget { final double highlightElevation; const QuillIconButton({ - Key? key, required this.onPressed, this.icon, this.size = 40, this.fillColor, this.hoverElevation = 1, this.highlightElevation = 1, + Key? key, }) : super(key: key); @override @@ -1163,7 +1166,6 @@ class QuillIconButton extends StatelessWidget { child: RawMaterialButton( visualDensity: VisualDensity.compact, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2)), - padding: EdgeInsets.zero, fillColor: fillColor, elevation: 0, hoverElevation: hoverElevation, @@ -1186,15 +1188,15 @@ class QuillDropdownButton extends StatefulWidget { final ValueChanged onSelected; const QuillDropdownButton({ - Key? key, - this.height = 40, - this.fillColor, - this.hoverElevation = 1, - this.highlightElevation = 1, required this.child, required this.initialValue, required this.items, required this.onSelected, + this.height = 40, + this.fillColor, + this.hoverElevation = 1, + this.highlightElevation = 1, + Key? key, }) : super(key: key); @override @@ -1209,7 +1211,6 @@ class _QuillDropdownButtonState extends State> { child: RawMaterialButton( visualDensity: VisualDensity.compact, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2)), - padding: EdgeInsets.zero, fillColor: widget.fillColor, elevation: 0, hoverElevation: widget.hoverElevation, @@ -1250,19 +1251,20 @@ class _QuillDropdownButtonState extends State> { // if (widget.onCanceled != null) widget.onCanceled(); return null; } + widget.onSelected(newValue); }); } Widget _buildContent(BuildContext context) { return ConstrainedBox( - constraints: BoxConstraints.tightFor(width: 110), + constraints: const BoxConstraints.tightFor(width: 110), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), child: Row( children: [ widget.child, Expanded(child: Container()), - Icon(Icons.arrow_drop_down, size: 15) + const Icon(Icons.arrow_drop_down, size: 15) ], ), ),