Apply default null-safety migrations

pull/87/head
Miller Adulu 4 years ago
parent 599595e349
commit e9c5a2238e
  1. 80
      lib/models/documents/attribute.dart
  2. 20
      lib/models/documents/document.dart
  3. 4
      lib/models/documents/history.dart
  4. 16
      lib/models/documents/nodes/block.dart
  5. 44
      lib/models/documents/nodes/container.dart
  6. 46
      lib/models/documents/nodes/leaf.dart
  7. 68
      lib/models/documents/nodes/line.dart
  8. 20
      lib/models/documents/nodes/node.dart
  9. 6
      lib/models/documents/style.dart
  10. 110
      lib/models/quill_delta.dart
  11. 42
      lib/models/rules/delete.dart
  12. 52
      lib/models/rules/format.dart
  13. 119
      lib/models/rules/insert.dart
  14. 12
      lib/models/rules/rule.dart
  15. 4
      lib/utils/color.dart
  16. 14
      lib/utils/diff_delta.dart
  17. 8
      lib/widgets/box.dart
  18. 18
      lib/widgets/controller.dart
  19. 48
      lib/widgets/cursor.dart
  20. 56
      lib/widgets/default_styles.dart
  21. 44
      lib/widgets/delegate.dart
  22. 208
      lib/widgets/editor.dart
  23. 2
      lib/widgets/image.dart
  24. 2
      lib/widgets/keyboard_listener.dart
  25. 75
      lib/widgets/proxy.dart
  26. 242
      lib/widgets/raw_editor.dart
  27. 8
      lib/widgets/responsive_widget.dart
  28. 154
      lib/widgets/text_block.dart
  29. 244
      lib/widgets/text_line.dart
  30. 201
      lib/widgets/text_selection.dart
  31. 198
      lib/widgets/toolbar.dart
  32. 2
      pubspec.yaml

@ -102,46 +102,46 @@ class Attribute<T> {
Attribute.blockQuote.key,
};
static Attribute<int> get h1 => HeaderAttribute(level: 1);
static Attribute<int?> get h1 => HeaderAttribute(level: 1);
static Attribute<int> get h2 => HeaderAttribute(level: 2);
static Attribute<int?> get h2 => HeaderAttribute(level: 2);
static Attribute<int> get h3 => HeaderAttribute(level: 3);
static Attribute<int?> get h3 => HeaderAttribute(level: 3);
// "attributes":{"align":"left"}
static Attribute<String> get leftAlignment => AlignAttribute('left');
static Attribute<String?> get leftAlignment => AlignAttribute('left');
// "attributes":{"align":"center"}
static Attribute<String> get centerAlignment => AlignAttribute('center');
static Attribute<String?> get centerAlignment => AlignAttribute('center');
// "attributes":{"align":"right"}
static Attribute<String> get rightAlignment => AlignAttribute('right');
static Attribute<String?> get rightAlignment => AlignAttribute('right');
// "attributes":{"align":"justify"}
static Attribute<String> get justifyAlignment => AlignAttribute('justify');
static Attribute<String?> get justifyAlignment => AlignAttribute('justify');
// "attributes":{"list":"bullet"}
static Attribute<String> get ul => ListAttribute('bullet');
static Attribute<String?> get ul => ListAttribute('bullet');
// "attributes":{"list":"ordered"}
static Attribute<String> get ol => ListAttribute('ordered');
static Attribute<String?> get ol => ListAttribute('ordered');
// "attributes":{"list":"checked"}
static Attribute<String> get checked => ListAttribute('checked');
static Attribute<String?> get checked => ListAttribute('checked');
// "attributes":{"list":"unchecked"}
static Attribute<String> get unchecked => ListAttribute('unchecked');
static Attribute<String?> get unchecked => ListAttribute('unchecked');
// "attributes":{"indent":1"}
static Attribute<int> get indentL1 => IndentAttribute(level: 1);
static Attribute<int?> get indentL1 => IndentAttribute(level: 1);
// "attributes":{"indent":2"}
static Attribute<int> get indentL2 => IndentAttribute(level: 2);
static Attribute<int?> get indentL2 => IndentAttribute(level: 2);
// "attributes":{"indent":3"}
static Attribute<int> get indentL3 => IndentAttribute(level: 3);
static Attribute<int?> get indentL3 => IndentAttribute(level: 3);
static Attribute<int> getIndentLevel(int level) {
static Attribute<int?> getIndentLevel(int? level) {
if (level == 1) {
return indentL1;
}
@ -161,7 +161,7 @@ class Attribute<T> {
if (!_registry.containsKey(key)) {
throw ArgumentError.value(key, 'key "$key" not found.');
}
Attribute origin = _registry[key];
Attribute origin = _registry[key]!;
Attribute attribute = clone(origin, value);
return attribute;
}
@ -205,24 +205,24 @@ class StrikeThroughAttribute extends Attribute<bool> {
StrikeThroughAttribute() : super('strike', AttributeScope.INLINE, true);
}
class FontAttribute extends Attribute<String> {
FontAttribute(String val) : super('font', AttributeScope.INLINE, val);
class FontAttribute extends Attribute<String?> {
FontAttribute(String? val) : super('font', AttributeScope.INLINE, val);
}
class SizeAttribute extends Attribute<String> {
SizeAttribute(String val) : super('size', AttributeScope.INLINE, val);
class SizeAttribute extends Attribute<String?> {
SizeAttribute(String? val) : super('size', AttributeScope.INLINE, val);
}
class LinkAttribute extends Attribute<String> {
LinkAttribute(String val) : super('link', AttributeScope.INLINE, val);
class LinkAttribute extends Attribute<String?> {
LinkAttribute(String? val) : super('link', AttributeScope.INLINE, val);
}
class ColorAttribute extends Attribute<String> {
ColorAttribute(String val) : super('color', AttributeScope.INLINE, val);
class ColorAttribute extends Attribute<String?> {
ColorAttribute(String? val) : super('color', AttributeScope.INLINE, val);
}
class BackgroundAttribute extends Attribute<String> {
BackgroundAttribute(String val)
class BackgroundAttribute extends Attribute<String?> {
BackgroundAttribute(String? val)
: super('background', AttributeScope.INLINE, val);
}
@ -231,20 +231,20 @@ class PlaceholderAttribute extends Attribute<bool> {
PlaceholderAttribute() : super('placeholder', AttributeScope.INLINE, true);
}
class HeaderAttribute extends Attribute<int> {
HeaderAttribute({int level}) : super('header', AttributeScope.BLOCK, level);
class HeaderAttribute extends Attribute<int?> {
HeaderAttribute({int? level}) : super('header', AttributeScope.BLOCK, level);
}
class IndentAttribute extends Attribute<int> {
IndentAttribute({int level}) : super('indent', AttributeScope.BLOCK, level);
class IndentAttribute extends Attribute<int?> {
IndentAttribute({int? level}) : super('indent', AttributeScope.BLOCK, level);
}
class AlignAttribute extends Attribute<String> {
AlignAttribute(String val) : super('align', AttributeScope.BLOCK, val);
class AlignAttribute extends Attribute<String?> {
AlignAttribute(String? val) : super('align', AttributeScope.BLOCK, val);
}
class ListAttribute extends Attribute<String> {
ListAttribute(String val) : super('list', AttributeScope.BLOCK, val);
class ListAttribute extends Attribute<String?> {
ListAttribute(String? val) : super('list', AttributeScope.BLOCK, val);
}
class CodeBlockAttribute extends Attribute<bool> {
@ -255,14 +255,14 @@ class BlockQuoteAttribute extends Attribute<bool> {
BlockQuoteAttribute() : super('blockquote', AttributeScope.BLOCK, true);
}
class WidthAttribute extends Attribute<String> {
WidthAttribute(String val) : super('width', AttributeScope.IGNORE, val);
class WidthAttribute extends Attribute<String?> {
WidthAttribute(String? val) : super('width', AttributeScope.IGNORE, val);
}
class HeightAttribute extends Attribute<String> {
HeightAttribute(String val) : super('height', AttributeScope.IGNORE, val);
class HeightAttribute extends Attribute<String?> {
HeightAttribute(String? val) : super('height', AttributeScope.IGNORE, val);
}
class StyleAttribute extends Attribute<String> {
StyleAttribute(String val) : super('style', AttributeScope.IGNORE, val);
class StyleAttribute extends Attribute<String?> {
StyleAttribute(String? val) : super('style', AttributeScope.IGNORE, val);
}

@ -43,11 +43,11 @@ class Document {
_loadDocument(_delta);
}
Delta insert(int index, Object data) {
Delta insert(int index, Object? data) {
assert(index >= 0);
assert(data is String || data is Embeddable);
if (data is Embeddable) {
data = (data as Embeddable).toJson();
data = data.toJson();
} else if ((data as String).isEmpty) {
return Delta();
}
@ -66,7 +66,7 @@ class Document {
return delta;
}
Delta replace(int index, int len, Object data) {
Delta replace(int index, int len, Object? data) {
assert(index >= 0);
assert(data is String || data is Embeddable);
@ -88,7 +88,7 @@ class Document {
return delta;
}
Delta format(int index, int len, Attribute attribute) {
Delta format(int index, int len, Attribute? attribute) {
assert(index >= 0 && len >= 0 && attribute != null);
Delta delta = Delta();
@ -113,7 +113,7 @@ class Document {
if (res.node is Line) {
return res;
}
Block block = res.node;
Block block = res.node as Block;
return block.queryChild(res.offset, true);
}
@ -126,7 +126,7 @@ class Document {
delta = _transform(delta);
Delta originalDelta = toDelta();
for (Operation op in delta.toList()) {
Style style =
Style? style =
op.attributes != null ? Style.fromJson(op.attributes) : null;
if (op.isInsert) {
@ -138,7 +138,7 @@ class Document {
}
if (!op.isDelete) {
offset += op.length;
offset += op.length!;
}
}
try {
@ -197,7 +197,7 @@ class Document {
}
}
Object _normalize(Object data) {
Object _normalize(Object? data) {
if (data is String) {
return data;
}
@ -205,7 +205,7 @@ class Document {
if (data is Embeddable) {
return data;
}
return Embeddable.fromJson(data);
return Embeddable.fromJson(data as Map<String, dynamic>);
}
close() {
@ -227,7 +227,7 @@ class Document {
op.attributes != null ? Style.fromJson(op.attributes) : null;
final data = _normalize(op.data);
_root.insert(offset, data, style);
offset += op.length;
offset += op.length!;
}
final node = _root.last;
if (node is Line &&

@ -90,13 +90,13 @@ class History {
}
Delta delta = source.removeLast();
// look for insert or delete
int len = 0;
int? len = 0;
List<Operation> ops = delta.toList();
for (var i = 0; i < ops.length; i++) {
if (ops[i].key == Operation.insertKey) {
len = ops[i].length;
} else if (ops[i].key == Operation.deleteKey) {
len = ops[i].length * -1;
len = ops[i].length! * -1;
}
}
Delta base = Delta.from(doc.toDelta());

@ -4,7 +4,7 @@ import 'container.dart';
import 'line.dart';
import 'node.dart';
class Block extends Container<Line> {
class Block extends Container<Line?> {
@override
Line get defaultChild => Line();
@ -18,7 +18,7 @@ class Block extends Container<Line> {
@override
adjust() {
if (isEmpty) {
Node sibling = previous;
Node? sibling = previous;
unlink();
if (sibling != null) {
sibling.adjust();
@ -27,18 +27,18 @@ class Block extends Container<Line> {
}
Block block = this;
Node prev = block.previous;
Node? prev = block.previous;
// merging it with previous block if style is the same
if (!block.isFirst &&
block.previous is Block &&
prev.style == block.style) {
block.moveChildToNewParent(prev);
prev!.style == block.style) {
block.moveChildToNewParent(prev as Container<Node?>?);
block.unlink();
block = prev;
block = prev as Block;
}
Node next = block.next;
Node? next = block.next;
// merging it with next block if style is the same
if (!block.isLast && block.next is Block && next.style == block.style) {
if (!block.isLast && block.next is Block && next!.style == block.style) {
(next as Block).moveChildToNewParent(block);
next.unlink();
}

@ -4,7 +4,7 @@ import '../style.dart';
import 'node.dart';
/* Container of multiple nodes */
abstract class Container<T extends Node> extends Node {
abstract class Container<T extends Node?> extends Node {
final LinkedList<Node> _children = LinkedList<Node>();
LinkedList<Node> get children => _children;
@ -26,32 +26,32 @@ abstract class Container<T extends Node> extends Node {
/// abstract methods end
add(T node) {
assert(node.parent == null);
node.parent = this;
_children.add(node);
assert(node?.parent == null);
node?.parent = this;
_children.add(node!);
}
addFirst(T node) {
assert(node.parent == null);
node.parent = this;
_children.addFirst(node);
assert(node?.parent == null);
node?.parent = this;
_children.addFirst(node!);
}
void remove(T node) {
assert(node.parent == this);
node.parent = null;
_children.remove(node);
assert(node?.parent == this);
node?.parent = null;
_children.remove(node!);
}
void moveChildToNewParent(Container newParent) {
void moveChildToNewParent(Container? newParent) {
if (isEmpty) {
return;
}
T last = newParent.isEmpty ? null : newParent.last;
T? last = newParent!.isEmpty ? null : newParent.last as T?;
while (isNotEmpty) {
T child = first;
child.unlink();
T child = first as T;
child?.unlink();
newParent.add(child);
}
@ -80,12 +80,12 @@ abstract class Container<T extends Node> extends Node {
int get length => _children.fold(0, (cur, node) => cur + node.length);
@override
insert(int index, Object data, Style style) {
insert(int index, Object data, Style? style) {
assert(index == 0 || (index > 0 && index < length));
if (isNotEmpty) {
ChildQuery child = queryChild(index, false);
child.node.insert(child.offset, data, style);
child.node!.insert(child.offset, data, style);
return;
}
@ -93,21 +93,21 @@ abstract class Container<T extends Node> extends Node {
assert(index == 0);
T node = defaultChild;
add(node);
node.insert(index, data, style);
node?.insert(index, data, style);
}
@override
retain(int index, int length, Style attributes) {
retain(int index, int? length, Style? attributes) {
assert(isNotEmpty);
ChildQuery child = queryChild(index, false);
child.node.retain(child.offset, length, attributes);
child.node!.retain(child.offset, length, attributes);
}
@override
delete(int index, int length) {
delete(int index, int? length) {
assert(isNotEmpty);
ChildQuery child = queryChild(index, false);
child.node.delete(child.offset, length);
child.node!.delete(child.offset, length);
}
@override
@ -116,7 +116,7 @@ abstract class Container<T extends Node> extends Node {
/// Query of a child in a Container
class ChildQuery {
final Node node; // null if not found
final Node? node; // null if not found
final int offset;

@ -13,13 +13,9 @@ abstract class Leaf extends Node {
Object get value => _value;
Leaf.val(Object val)
: assert(val != null),
_value = val;
factory Leaf([Object data]) {
assert(data != null);
Leaf.val(Object val) : _value = val;
factory Leaf(Object data) {
if (data is Embeddable) {
return Embed(data);
}
@ -37,7 +33,7 @@ abstract class Leaf extends Node {
}
@override
Line get parent => super.parent as Line;
Line? get parent => super.parent as Line?;
@override
int get length {
@ -55,11 +51,11 @@ abstract class Leaf extends Node {
}
@override
insert(int index, Object data, Style style) {
insert(int index, Object data, Style? style) {
assert(data != null && index >= 0 && index <= length);
Leaf node = Leaf(data);
if (index < length) {
splitAt(index).insertBefore(node);
splitAt(index)!.insertBefore(node);
} else {
insertAfter(node);
}
@ -67,36 +63,36 @@ abstract class Leaf extends Node {
}
@override
retain(int index, int len, Style style) {
retain(int index, int? len, Style? style) {
if (style == null) {
return;
}
int local = math.min(this.length - index, len);
int local = math.min(this.length - index, len!);
int remain = len - local;
Leaf node = _isolate(index, local);
if (remain > 0) {
assert(node.next != null);
node.next.retain(0, remain, style);
node.next!.retain(0, remain, style);
}
node.format(style);
}
@override
delete(int index, int len) {
delete(int index, int? len) {
assert(index < this.length);
int local = math.min(this.length - index, len);
int local = math.min(this.length - index, len!);
Leaf target = _isolate(index, local);
Leaf prev = target.previous;
Leaf next = target.next;
Leaf? prev = target.previous as Leaf?;
Leaf? next = target.next as Leaf?;
target.unlink();
int remain = len - local;
if (remain > 0) {
assert(next != null);
next.delete(0, remain);
next!.delete(0, remain);
}
if (prev != null) {
@ -112,7 +108,7 @@ abstract class Leaf extends Node {
Text node = this as Text;
// merging it with previous node if style is the same
Node prev = node.previous;
Node? prev = node.previous;
if (!node.isFirst && prev is Text && prev.style == node.style) {
prev._value = prev.value + node.value;
node.unlink();
@ -120,27 +116,27 @@ abstract class Leaf extends Node {
}
// merging it with next node if style is the same
Node next = node.next;
Node? next = node.next;
if (!node.isLast && next is Text && next.style == node.style) {
node._value = node.value + next.value;
next.unlink();
}
}
Leaf cutAt(int index) {
Leaf? cutAt(int index) {
assert(index >= 0 && index <= length);
Leaf cut = splitAt(index);
Leaf? cut = splitAt(index);
cut?.unlink();
return cut;
}
Leaf splitAt(int index) {
Leaf? splitAt(int index) {
assert(index >= 0 && index <= length);
if (index == 0) {
return this;
}
if (index == length) {
return isLast ? null : next as Leaf;
return isLast ? null : next as Leaf?;
}
assert(this is Text);
@ -152,7 +148,7 @@ abstract class Leaf extends Node {
return split;
}
format(Style style) {
format(Style? style) {
if (style != null && style.isNotEmpty) {
applyStyle(style);
}
@ -163,7 +159,7 @@ abstract class Leaf extends Node {
Leaf _isolate(int index, int length) {
assert(
index >= 0 && index < this.length && (index + length <= this.length));
Leaf target = splitAt(index);
Leaf target = splitAt(index)!;
target.splitAt(length);
return target;
}

@ -10,7 +10,7 @@ import 'container.dart';
import 'embed.dart';
import 'leaf.dart';
class Line extends Container<Leaf> {
class Line extends Container<Leaf?> {
@override
Leaf get defaultChild => Text();
@ -25,28 +25,28 @@ class Line extends Container<Leaf> {
return children.single is Embed;
}
Line get nextLine {
Line? get nextLine {
if (!isLast) {
return next is Block ? (next as Block).first : next;
return next is Block ? (next as Block).first as Line? : next as Line?;
}
if (parent is! Block) {
return null;
}
if (parent.isLast) {
if (parent!.isLast) {
return null;
}
return parent.next is Block ? (parent.next as Block).first : parent.next;
return parent!.next is Block ? (parent!.next as Block).first as Line? : parent!.next as Line?;
}
@override
Delta toDelta() {
final delta = children
.map((child) => child.toDelta())
.fold(Delta(), (a, b) => a.concat(b));
.fold(Delta(), (dynamic a, b) => a.concat(b));
var attributes = style;
if (parent is Block) {
Block block = parent;
Block block = parent as Block;
attributes = attributes.mergeAll(block.style);
}
delta.insert('\n', attributes.toJson());
@ -64,7 +64,7 @@ class Line extends Container<Leaf> {
}
@override
insert(int index, Object data, Style style) {
insert(int index, Object data, Style? style) {
if (data is Embeddable) {
_insert(index, data, style);
return;
@ -99,13 +99,13 @@ class Line extends Container<Leaf> {
}
@override
retain(int index, int len, Style style) {
retain(int index, int? len, Style? style) {
if (style == null) {
return;
}
int thisLen = this.length;
int local = math.min(thisLen - index, len);
int local = math.min(thisLen - index, len!);
if (index + local == thisLen && local == 1) {
assert(style.values.every((attr) => attr.scope == AttributeScope.BLOCK));
@ -119,13 +119,13 @@ class Line extends Container<Leaf> {
int remain = len - local;
if (remain > 0) {
assert(nextLine != null);
nextLine.retain(0, remain, style);
nextLine!.retain(0, remain, style);
}
}
@override
delete(int index, int len) {
int local = math.min(this.length - index, len);
delete(int index, int? len) {
int local = math.min(this.length - index, len!);
bool deleted = index + local == this.length;
if (deleted) {
clearStyle();
@ -139,35 +139,35 @@ class Line extends Container<Leaf> {
int remain = len - local;
if (remain > 0) {
assert(nextLine != null);
nextLine.delete(0, remain);
nextLine!.delete(0, remain);
}
if (deleted && isNotEmpty) {
assert(nextLine != null);
nextLine.moveChildToNewParent(this);
nextLine!.moveChildToNewParent(this);
moveChildToNewParent(nextLine);
}
if (deleted) {
Node p = parent;
Node p = parent!;
unlink();
p.adjust();
}
}
void _format(Style newStyle) {
void _format(Style? newStyle) {
if (newStyle == null || newStyle.isEmpty) {
return;
}
applyStyle(newStyle);
Attribute blockStyle = newStyle.getBlockExceptHeader();
Attribute? blockStyle = newStyle.getBlockExceptHeader();
if (blockStyle == null) {
return;
}
if (parent is Block) {
Attribute parentStyle = (parent as Block).style.getBlockExceptHeader();
Attribute? parentStyle = (parent as Block).style.getBlockExceptHeader();
if (blockStyle.value == null) {
_unwrap();
} else if (blockStyle != parentStyle) {
@ -196,7 +196,7 @@ class Line extends Container<Leaf> {
if (parent is! Block) {
throw ArgumentError('Invalid parent');
}
Block block = parent;
Block block = parent as Block;
assert(block.children.contains(this));
@ -207,10 +207,10 @@ class Line extends Container<Leaf> {
unlink();
block.insertAfter(this);
} else {
Block before = block.clone();
Block before = block.clone() as Block;
block.insertBefore(before);
Line child = block.first;
Line child = block.first as Line;
while (child != this) {
child.unlink();
before.add(child);
@ -232,19 +232,19 @@ class Line extends Container<Leaf> {
}
ChildQuery query = queryChild(index, false);
while (!query.node.isLast) {
Leaf next = last;
while (!query.node!.isLast) {
Leaf next = last as Leaf;
next.unlink();
line.addFirst(next);
}
Leaf child = query.node;
Leaf cut = child.splitAt(query.offset);
Leaf child = query.node as Leaf;
Leaf? cut = child.splitAt(query.offset);
cut?.unlink();
line.addFirst(cut);
return line;
}
_insert(int index, Object data, Style style) {
_insert(int index, Object data, Style? style) {
assert(index == 0 || (index > 0 && index < length));
if (data is String) {
@ -256,7 +256,7 @@ class Line extends Container<Leaf> {
if (isNotEmpty) {
ChildQuery result = queryChild(index, true);
result.node.insert(result.offset, data, style);
result.node!.insert(result.offset, data, style);
return;
}
@ -291,26 +291,26 @@ class Line extends Container<Leaf> {
}
ChildQuery data = queryChild(offset, true);
Leaf node = data.node;
Leaf? node = data.node as Leaf?;
if (node != null) {
res = res.mergeAll(node.style);
int pos = node.length - data.offset;
while (!node.isLast && pos < local) {
node = node.next as Leaf;
_handle(node.style);
while (!node!.isLast && pos < local) {
node = node.next as Leaf?;
_handle(node!.style);
pos += node.length;
}
}
res = res.mergeAll(style);
if (parent is Block) {
Block block = parent;
Block block = parent as Block;
res = res.mergeAll(block.style);
}
int remain = len - local;
if (remain > 0) {
_handle(nextLine.collectStyle(0, remain));
_handle(nextLine!.collectStyle(0, remain));
}
return res;

@ -9,7 +9,7 @@ import 'line.dart';
/* node in a document tree */
abstract class Node extends LinkedListEntry<Node> {
Container parent;
Container? parent;
Style _style = Style();
Style get style => _style;
@ -29,9 +29,9 @@ abstract class Node extends LinkedListEntry<Node> {
_style = Style();
}
bool get isFirst => list.first == this;
bool get isFirst => list!.first == this;
bool get isLast => list.last == this;
bool get isLast => list!.last == this;
int get length;
@ -50,14 +50,14 @@ abstract class Node extends LinkedListEntry<Node> {
Node cur = this;
do {
cur = cur.previous;
cur = cur.previous!;
offset += cur.length;
} while (!cur.isFirst);
return offset;
}
int getDocumentOffset() {
final parentOffset = (parent is! Root) ? parent.getDocumentOffset() : 0;
final parentOffset = (parent is! Root) ? parent!.getDocumentOffset() : 0;
return parentOffset + getOffset();
}
@ -99,20 +99,20 @@ abstract class Node extends LinkedListEntry<Node> {
Delta toDelta();
insert(int index, Object data, Style style);
insert(int index, Object data, Style? style);
retain(int index, int len, Style style);
retain(int index, int? len, Style? style);
delete(int index, int len);
delete(int index, int? len);
/// abstract methods end
}
/* Root node of document tree */
class Root extends Container<Container<Node>> {
class Root extends Container<Container<Node?>> {
@override
Container<Node> get defaultChild => Line();
Container<Node?> get defaultChild => Line();
@override
Delta toDelta() => children

@ -10,7 +10,7 @@ class Style {
Style() : _attributes = <String, Attribute>{};
static Style fromJson(Map<String, dynamic> attributes) {
static Style fromJson(Map<String, dynamic>? attributes) {
if (attributes == null) {
return Style();
}
@ -22,7 +22,7 @@ class Style {
return Style.attr(result);
}
Map<String, dynamic> toJson() => _attributes.isEmpty
Map<String, dynamic>? toJson() => _attributes.isEmpty
? null
: _attributes.map<String, dynamic>((String _, Attribute attribute) =>
MapEntry<String, dynamic>(attribute.key, attribute.value));
@ -46,7 +46,7 @@ class Style {
bool containsKey(String key) => _attributes.containsKey(key);
Attribute getBlockExceptHeader() {
Attribute? getBlockExceptHeader() {
for (Attribute val in values) {
if (val.isBlockExceptHeader) {
return val;

@ -15,10 +15,10 @@ const _valueEquality = DeepCollectionEquality();
/// Decoder function to convert raw `data` object into a user-defined data type.
///
/// Useful with embedded content.
typedef DataDecoder = Object Function(Object data);
typedef DataDecoder = Object? Function(Object data);
/// Default data decoder which simply passes through the original value.
Object _passThroughDataDecoder(Object data) => data;
Object? _passThroughDataDecoder(Object? data) => data;
/// Operation performed on a rich-text document.
class Operation {
@ -40,17 +40,17 @@ class Operation {
final String key;
/// Length of this operation.
final int length;
final int? length;
/// Payload of "insert" operation, for other types is set to empty string.
final Object data;
final Object? data;
/// Rich-text attributes set by this operation, can be `null`.
Map<String, dynamic> get attributes =>
_attributes == null ? null : Map<String, dynamic>.from(_attributes);
final Map<String, dynamic> _attributes;
Map<String, dynamic>? get attributes =>
_attributes == null ? null : Map<String, dynamic>.from(_attributes!);
final Map<String, dynamic>? _attributes;
Operation._(this.key, this.length, this.data, Map attributes)
Operation._(this.key, this.length, this.data, Map? attributes)
: assert(key != null && length != null && data != null),
assert(_validKeys.contains(key), 'Invalid operation key "$key".'),
assert(() {
@ -64,7 +64,7 @@ class Operation {
///
/// If `dataDecoder` parameter is not null then it is used to additionally
/// decode the operation's data object. Only applied to insert operations.
static Operation fromJson(Map data, {DataDecoder dataDecoder}) {
static Operation fromJson(Map data, {DataDecoder? dataDecoder}) {
dataDecoder ??= _passThroughDataDecoder;
final map = Map<String, dynamic>.from(data);
if (map.containsKey(Operation.insertKey)) {
@ -73,10 +73,10 @@ class Operation {
return Operation._(
Operation.insertKey, dataLength, data, map[Operation.attributesKey]);
} else if (map.containsKey(Operation.deleteKey)) {
final int length = map[Operation.deleteKey];
final int? length = map[Operation.deleteKey];
return Operation._(Operation.deleteKey, length, '', null);
} else if (map.containsKey(Operation.retainKey)) {
final int length = map[Operation.retainKey];
final int? length = map[Operation.retainKey];
return Operation._(
Operation.retainKey, length, '', map[Operation.attributesKey]);
}
@ -95,13 +95,13 @@ class Operation {
Operation._(Operation.deleteKey, length, '', null);
/// Creates operation which inserts [text] with optional [attributes].
factory Operation.insert(dynamic data, [Map<String, dynamic> 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]) =>
factory Operation.retain(int? length, [Map<String, dynamic>? attributes]) =>
Operation._(Operation.retainKey, length, '', attributes);
/// Returns value of this operation.
@ -119,7 +119,7 @@ class Operation {
bool get isRetain => key == Operation.retainKey;
/// Returns `true` if this operation has no attributes, e.g. is plain text.
bool get isPlain => (_attributes == null || _attributes.isEmpty);
bool get isPlain => (_attributes == null || _attributes!.isEmpty);
/// Returns `true` if this operation sets at least one attribute.
bool get isNotPlain => !isPlain;
@ -130,7 +130,7 @@ class Operation {
bool get isEmpty => length == 0;
/// Returns `true` is this operation is not empty.
bool get isNotEmpty => length > 0;
bool get isNotEmpty => length! > 0;
@override
bool operator ==(other) {
@ -144,7 +144,7 @@ class Operation {
}
/// Returns `true` if this operation has attribute specified by [name].
bool hasAttribute(String name) => isNotPlain && _attributes.containsKey(name);
bool hasAttribute(String name) => isNotPlain && _attributes!.containsKey(name);
/// Returns `true` if [other] operation has the same attributes as this one.
bool hasSameAttributes(Operation other) {
@ -153,9 +153,9 @@ class Operation {
@override
int get hashCode {
if (_attributes != null && _attributes.isNotEmpty) {
if (_attributes != null && _attributes!.isNotEmpty) {
final attrsHash =
hashObjects(_attributes.entries.map((e) => hash2(e.key, e.value)));
hashObjects(_attributes!.entries.map((e) => hash2(e.key, e.value)));
return hash3(key, value, attrsHash);
}
return hash2(key, value);
@ -181,8 +181,8 @@ class Operation {
/// it is a "change delta".
class Delta {
/// Transforms two attribute sets.
static Map<String, dynamic> transformAttributes(
Map<String, dynamic> a, Map<String, dynamic> b, bool priority) {
static Map<String, dynamic>? transformAttributes(
Map<String, dynamic>? a, Map<String, dynamic>? b, bool priority) {
if (a == null) return b;
if (b == null) return null;
@ -197,8 +197,8 @@ class Delta {
}
/// Composes two attribute sets.
static Map<String, dynamic> composeAttributes(
Map<String, dynamic> a, Map<String, dynamic> b,
static Map<String, dynamic>? composeAttributes(
Map<String, dynamic>? a, Map<String, dynamic>? b,
{bool keepNull = false}) {
a ??= const {};
b ??= const {};
@ -217,12 +217,12 @@ class Delta {
///get anti-attr result base on base
static Map<String, dynamic> invertAttributes(
Map<String, dynamic> attr, Map<String, dynamic> base) {
Map<String, dynamic>? attr, Map<String, dynamic>? base) {
attr ??= const {};
base ??= const {};
var baseInverted = base.keys.fold({}, (memo, key) {
if (base[key] != attr[key] && attr.containsKey(key)) {
var baseInverted = base.keys.fold({}, (dynamic memo, key) {
if (base![key] != attr![key] && attr.containsKey(key)) {
memo[key] = base[key];
}
return memo;
@ -230,7 +230,7 @@ class Delta {
var inverted =
Map<String, dynamic>.from(attr.keys.fold(baseInverted, (memo, key) {
if (base[key] != attr[key] && !base.containsKey(key)) {
if (base![key] != attr![key] && !base.containsKey(key)) {
memo[key] = null;
}
return memo;
@ -257,7 +257,7 @@ class Delta {
///
/// If `dataDecoder` parameter is not null then it is used to additionally
/// decode the operation's data object. Only applied to insert operations.
static Delta fromJson(List data, {DataDecoder dataDecoder}) {
static Delta fromJson(List data, {DataDecoder? dataDecoder}) {
return Delta._(data
.map((op) => Operation.fromJson(op, dataDecoder: dataDecoder))
.toList());
@ -304,14 +304,14 @@ class Delta {
int get hashCode => hashObjects(_operations);
/// Retain [count] of characters from current position.
void retain(int count, [Map<String, dynamic> attributes]) {
void retain(int count, [Map<String, dynamic>? attributes]) {
assert(count >= 0);
if (count == 0) return; // no-op
push(Operation.retain(count, attributes));
}
/// Insert [data] at current position.
void insert(dynamic data, [Map<String, dynamic> attributes]) {
void insert(dynamic data, [Map<String, dynamic>? attributes]) {
assert(data != null);
if (data is String && data.isEmpty) return; // no-op
push(Operation.insert(data, attributes));
@ -329,7 +329,7 @@ class Delta {
assert(operation != null && last.key == operation.key);
assert(operation.data is String && last.data is String);
final length = operation.length + last.length;
final length = operation.length! + last.length!;
final lastText = last.data as String;
final opText = operation.data as String;
final resultText = lastText + opText;
@ -396,12 +396,12 @@ class Delta {
/// Returns new operation or `null` if operations from [thisIter] and
/// [otherIter] nullify each other. For instance, for the pair `insert('abc')`
/// and `delete(3)` composition result would be empty string.
Operation _composeOperation(DeltaIterator thisIter, DeltaIterator otherIter) {
Operation? _composeOperation(DeltaIterator thisIter, DeltaIterator otherIter) {
if (otherIter.isNextInsert) return otherIter.next();
if (thisIter.isNextDelete) return thisIter.next();
final length = math.min(thisIter.peekLength(), otherIter.peekLength());
final thisOp = thisIter.next(length);
final thisOp = thisIter.next(length as int);
final otherOp = otherIter.next(length);
assert(thisOp.length == otherOp.length);
@ -448,7 +448,7 @@ class Delta {
/// [thisIter].
///
/// Returns `null` if both operations nullify each other.
Operation _transformOperation(
Operation? _transformOperation(
DeltaIterator thisIter, DeltaIterator otherIter, bool priority) {
if (thisIter.isNextInsert && (priority || !otherIter.isNextInsert)) {
return Operation.retain(thisIter.next().length);
@ -457,7 +457,7 @@ class Delta {
}
final length = math.min(thisIter.peekLength(), otherIter.peekLength());
final thisOp = thisIter.next(length);
final thisOp = thisIter.next(length as int);
final otherOp = otherIter.next(length);
assert(thisOp.length == otherOp.length);
@ -520,12 +520,12 @@ class Delta {
var baseIndex = 0;
for (final op in _operations) {
if (op.isInsert) {
inverted.delete(op.length);
inverted.delete(op.length!);
} else if (op.isRetain && op.isPlain) {
inverted.retain(op.length, null);
baseIndex += op.length;
inverted.retain(op.length!, null);
baseIndex += op.length!;
} else if (op.isDelete || (op.isRetain && op.isNotPlain)) {
final length = op.length;
final length = op.length!;
final sliceDelta = base.slice(baseIndex, baseIndex + length);
sliceDelta.toList().forEach((baseOp) {
if (op.isDelete) {
@ -533,7 +533,7 @@ class Delta {
} else if (op.isRetain && op.isNotPlain) {
var invertAttr = invertAttributes(op.attributes, baseOp.attributes);
inverted.retain(
baseOp.length, invertAttr.isEmpty ? null : invertAttr);
baseOp.length!, invertAttr.isEmpty ? null : invertAttr);
}
});
baseIndex += length;
@ -547,7 +547,7 @@ class Delta {
/// Returns slice of this delta from [start] index (inclusive) to [end]
/// (exclusive).
Delta slice(int start, [int end]) {
Delta slice(int start, [int? end]) {
final delta = Delta();
var index = 0;
var opIterator = DeltaIterator(this);
@ -559,10 +559,10 @@ class Delta {
if (index < start) {
op = opIterator.next(start - index);
} else {
op = opIterator.next(actualEnd - index);
op = opIterator.next(actualEnd - index as int);
delta.push(op);
}
index += op.length;
index += op.length!;
}
return delta;
}
@ -585,12 +585,12 @@ class Delta {
while (iter.hasNext && offset <= index) {
final op = iter.next();
if (op.isDelete) {
index -= math.min(op.length, index - offset);
index -= math.min(op.length!, index - offset);
continue;
} else if (op.isInsert && (offset < index || force)) {
index += op.length;
index += op.length!;
}
offset += op.length;
offset += op.length!;
}
return index;
}
@ -614,7 +614,7 @@ class DeltaIterator {
bool get isNextRetain => nextOperationKey == Operation.retainKey;
String get nextOperationKey {
String? get nextOperationKey {
if (_index < delta.length) {
return delta.elementAt(_index).key;
} else {
@ -630,7 +630,7 @@ class DeltaIterator {
num peekLength() {
if (_index < delta.length) {
final operation = delta._operations[_index];
return operation.length - _offset;
return operation.length! - _offset;
}
return double.infinity;
}
@ -651,8 +651,8 @@ class DeltaIterator {
final opKey = op.key;
final opAttributes = op.attributes;
final _currentOffset = _offset;
final actualLength = math.min(op.length - _currentOffset, length);
if (actualLength == op.length - _currentOffset) {
final actualLength = math.min(op.length! - _currentOffset, length);
if (actualLength == op.length! - _currentOffset) {
_index++;
_offset = 0;
} else {
@ -660,12 +660,12 @@ class DeltaIterator {
}
final opData = op.isInsert && op.data is String
? (op.data as String)
.substring(_currentOffset, _currentOffset + actualLength)
.substring(_currentOffset as int, _currentOffset + (actualLength as int))
: op.data;
final opIsNotEmpty =
opData is String ? opData.isNotEmpty : true; // embeds are never empty
final opLength = opData is String ? opData.length : 1;
final int opActualLength = opIsNotEmpty ? opLength : actualLength;
final int opActualLength = opIsNotEmpty ? opLength : actualLength as int;
return Operation._(opKey, opActualLength, opData, opAttributes);
}
return Operation.retain(length);
@ -674,14 +674,14 @@ class DeltaIterator {
/// Skips [length] characters in source delta.
///
/// Returns last skipped operation, or `null` if there was nothing to skip.
Operation skip(int length) {
Operation? skip(int length) {
var skipped = 0;
Operation op;
Operation? op;
while (skipped < length && hasNext) {
final opLength = peekLength();
final skip = math.min(length - skipped, opLength);
op = next(skip);
skipped += op.length;
op = next(skip as int);
skipped += op.length!;
}
return op;
}

@ -9,7 +9,7 @@ abstract class DeleteRule extends Rule {
RuleType get type => RuleType.DELETE;
@override
validateArgs(int len, Object data, Attribute attribute) {
validateArgs(int? len, Object? data, Attribute? attribute) {
assert(len != null);
assert(data == null);
assert(attribute == null);
@ -21,10 +21,10 @@ class CatchAllDeleteRule extends DeleteRule {
@override
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute}) {
{int? len, Object? data, Attribute? attribute}) {
return Delta()
..retain(index)
..delete(len);
..delete(len!);
}
}
@ -32,8 +32,8 @@ class PreserveLineStyleOnMergeRule extends DeleteRule {
const PreserveLineStyleOnMergeRule();
@override
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute}) {
Delta? applyRule(Delta document, int index,
{int? len, Object? data, Attribute? attribute}) {
DeltaIterator itr = DeltaIterator(document);
itr.skip(index);
Operation op = itr.next(1);
@ -42,30 +42,30 @@ class PreserveLineStyleOnMergeRule extends DeleteRule {
}
bool isNotPlain = op.isNotPlain;
Map<String, dynamic> attrs = op.attributes;
Map<String, dynamic>? attrs = op.attributes;
itr.skip(len - 1);
itr.skip(len! - 1);
Delta delta = Delta()
..retain(index)
..delete(len);
while (itr.hasNext) {
op = itr.next();
String text = op.data is String ? op.data as String : '';
String text = op.data is String ? (op.data as String?)! : '';
int lineBreak = text.indexOf('\n');
if (lineBreak == -1) {
delta..retain(op.length);
delta..retain(op.length!);
continue;
}
Map<String, dynamic> attributes = op.attributes == null
Map<String, dynamic>? attributes = op.attributes == null
? null
: op.attributes.map<String, dynamic>((String key, dynamic value) =>
: op.attributes!.map<String, dynamic>((String key, dynamic value) =>
MapEntry<String, dynamic>(key, null));
if (isNotPlain) {
attributes ??= <String, dynamic>{};
attributes.addAll(attrs);
attributes.addAll(attrs!);
}
delta..retain(lineBreak)..retain(1, attributes);
break;
@ -78,17 +78,18 @@ class EnsureEmbedLineRule extends DeleteRule {
const EnsureEmbedLineRule();
@override
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute}) {
Delta? applyRule(Delta document, int index,
{int? len, Object? data, Attribute? attribute}) {
DeltaIterator itr = DeltaIterator(document);
Operation op = itr.skip(index);
int indexDelta = 0, lengthDelta = 0, remain = len;
Operation? op = itr.skip(index);
int? indexDelta = 0, lengthDelta = 0, remain = len;
bool embedFound = op != null && op.data is! String;
bool hasLineBreakBefore =
!embedFound && (op == null || (op?.data as String).endsWith('\n'));
!embedFound && (op == null || (op.data as String).endsWith('\n'));
if (embedFound) {
Operation candidate = itr.next(1);
if (remain != null) {
remain--;
if (candidate.data == '\n') {
indexDelta++;
@ -101,10 +102,11 @@ class EnsureEmbedLineRule extends DeleteRule {
}
}
}
}
op = itr.skip(remain);
op = itr.skip(remain!);
if (op != null &&
(op?.data is String ? op.data as String : '').endsWith('\n')) {
(op.data is String ? op.data as String? : '')!.endsWith('\n')) {
Operation candidate = itr.next(1);
if (candidate.data is! String && !hasLineBreakBefore) {
embedFound = true;
@ -118,6 +120,6 @@ class EnsureEmbedLineRule extends DeleteRule {
return Delta()
..retain(index + indexDelta)
..delete(len + lengthDelta);
..delete(len! + lengthDelta);
}
}

@ -9,7 +9,7 @@ abstract class FormatRule extends Rule {
RuleType get type => RuleType.FORMAT;
@override
validateArgs(int len, Object data, Attribute attribute) {
validateArgs(int? len, Object? data, Attribute? attribute) {
assert(len != null);
assert(data == null);
assert(attribute != null);
@ -20,9 +20,9 @@ class ResolveLineFormatRule extends FormatRule {
const ResolveLineFormatRule();
@override
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute}) {
if (attribute.scope != AttributeScope.BLOCK) {
Delta? applyRule(Delta document, int index,
{int? len, Object? data, Attribute? attribute}) {
if (attribute!.scope != AttributeScope.BLOCK) {
return null;
}
@ -30,13 +30,13 @@ class ResolveLineFormatRule extends FormatRule {
DeltaIterator itr = DeltaIterator(document);
itr.skip(index);
Operation op;
for (int cur = 0; cur < len && itr.hasNext; cur += op.length) {
for (int cur = 0; cur < len! && itr.hasNext; cur += op.length!) {
op = itr.next(len - cur);
if (op.data is! String || !(op.data as String).contains('\n')) {
delta.retain(op.length);
delta.retain(op.length!);
continue;
}
String text = op.data;
String text = op.data as String;
Delta tmp = Delta();
int offset = 0;
@ -52,10 +52,10 @@ class ResolveLineFormatRule extends FormatRule {
while (itr.hasNext) {
op = itr.next();
String text = op.data is String ? op.data as String : '';
String text = op.data is String ? (op.data as String?)! : '';
int lineBreak = text.indexOf('\n');
if (lineBreak < 0) {
delta..retain(op.length);
delta..retain(op.length!);
continue;
}
delta..retain(lineBreak)..retain(1, attribute.toJson());
@ -69,28 +69,28 @@ class FormatLinkAtCaretPositionRule extends FormatRule {
const FormatLinkAtCaretPositionRule();
@override
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute}) {
if (attribute.key != Attribute.link.key || len > 0) {
Delta? applyRule(Delta document, int index,
{int? len, Object? data, Attribute? attribute}) {
if (attribute!.key != Attribute.link.key || len! > 0) {
return null;
}
Delta delta = Delta();
DeltaIterator itr = DeltaIterator(document);
Operation before = itr.skip(index), after = itr.next();
int beg = index, retain = 0;
Operation? before = itr.skip(index), after = itr.next();
int? beg = index, retain = 0;
if (before != null && before.hasAttribute(attribute.key)) {
beg -= before.length;
beg -= before.length!;
retain = before.length;
}
if (after != null && after.hasAttribute(attribute.key)) {
retain += after.length;
if (after.hasAttribute(attribute.key)) {
if (retain != null) retain += after.length!;
}
if (retain == 0) {
return null;
}
delta..retain(beg)..retain(retain, attribute.toJson());
delta..retain(beg)..retain(retain!, attribute.toJson());
return delta;
}
}
@ -99,9 +99,9 @@ class ResolveInlineFormatRule extends FormatRule {
const ResolveInlineFormatRule();
@override
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute}) {
if (attribute.scope != AttributeScope.INLINE) {
Delta? applyRule(Delta document, int index,
{int? len, Object? data, Attribute? attribute}) {
if (attribute!.scope != AttributeScope.INLINE) {
return null;
}
@ -110,12 +110,12 @@ class ResolveInlineFormatRule extends FormatRule {
itr.skip(index);
Operation op;
for (int cur = 0; cur < len && itr.hasNext; cur += op.length) {
for (int cur = 0; cur < len! && itr.hasNext; cur += op.length!) {
op = itr.next(len - cur);
String text = op.data is String ? op.data as String : '';
String text = op.data is String ? (op.data as String?)! : '';
int lineBreak = text.indexOf('\n');
if (lineBreak < 0) {
delta.retain(op.length, attribute.toJson());
delta.retain(op.length!, attribute.toJson());
continue;
}
int pos = 0;
@ -124,8 +124,8 @@ class ResolveInlineFormatRule extends FormatRule {
pos = lineBreak + 1;
lineBreak = text.indexOf('\n', pos);
}
if (pos < op.length) {
delta.retain(op.length - pos, attribute.toJson());
if (pos < op.length!) {
delta.retain(op.length! - pos, attribute.toJson());
}
}

@ -11,7 +11,7 @@ abstract class InsertRule extends Rule {
RuleType get type => RuleType.INSERT;
@override
validateArgs(int len, Object data, Attribute attribute) {
validateArgs(int? len, Object? data, Attribute? attribute) {
assert(len == null);
assert(data != null);
assert(attribute == null);
@ -22,23 +22,21 @@ class PreserveLineStyleOnSplitRule extends InsertRule {
const PreserveLineStyleOnSplitRule();
@override
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute}) {
if (data is! String || (data as String) != '\n') {
Delta? applyRule(Delta document, int index,
{int? len, Object? data, Attribute? attribute}) {
if (data is! String || data != '\n') {
return null;
}
DeltaIterator itr = DeltaIterator(document);
Operation before = itr.skip(index);
Operation? before = itr.skip(index);
if (before == null ||
before.data is! String ||
(before.data as String).endsWith('\n')) {
return null;
}
Operation after = itr.next();
if (after == null ||
after.data is! String ||
(after.data as String).startsWith('\n')) {
if (after.data is! String || (after.data as String).startsWith('\n')) {
return null;
}
@ -50,8 +48,8 @@ class PreserveLineStyleOnSplitRule extends InsertRule {
delta..insert('\n');
return delta;
}
Tuple2<Operation, int> nextNewLine = _getNextNewLine(itr);
Map<String, dynamic> attributes = nextNewLine?.item1?.attributes;
Tuple2<Operation?, int?> nextNewLine = _getNextNewLine(itr);
Map<String, dynamic>? attributes = nextNewLine.item1?.attributes;
return delta..insert('\n', attributes);
}
@ -61,33 +59,33 @@ class PreserveBlockStyleOnInsertRule extends InsertRule {
const PreserveBlockStyleOnInsertRule();
@override
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute}) {
if (data is! String || !(data as String).contains('\n')) {
Delta? applyRule(Delta document, int index,
{int? len, Object? data, Attribute? attribute}) {
if (data is! String || !data.contains('\n')) {
return null;
}
DeltaIterator itr = DeltaIterator(document);
itr.skip(index);
Tuple2<Operation, int> nextNewLine = _getNextNewLine(itr);
Tuple2<Operation?, int?> nextNewLine = _getNextNewLine(itr);
Style lineStyle =
Style.fromJson(nextNewLine.item1?.attributes ?? <String, dynamic>{});
Attribute attribute = lineStyle.getBlockExceptHeader();
Attribute? attribute = lineStyle.getBlockExceptHeader();
if (attribute == null) {
return null;
}
var blockStyle = <String, dynamic>{attribute.key: attribute.value};
Map<String, dynamic> resetStyle;
Map<String, dynamic>? resetStyle;
if (lineStyle.containsKey(Attribute.header.key)) {
resetStyle = Attribute.header.toJson();
}
List<String> lines = (data as String).split('\n');
List<String> lines = data.split('\n');
Delta delta = Delta()..retain(index);
for (int i = 0; i < lines.length; i++) {
String line = lines[i];
@ -102,9 +100,9 @@ class PreserveBlockStyleOnInsertRule extends InsertRule {
}
if (resetStyle != null) {
delta.retain(nextNewLine.item2);
delta.retain(nextNewLine.item2!);
delta
..retain((nextNewLine.item1.data as String).indexOf('\n'))
..retain((nextNewLine.item1!.data as String).indexOf('\n'))
..retain(1, resetStyle);
}
@ -115,26 +113,26 @@ class PreserveBlockStyleOnInsertRule extends InsertRule {
class AutoExitBlockRule extends InsertRule {
const AutoExitBlockRule();
bool _isEmptyLine(Operation before, Operation after) {
bool _isEmptyLine(Operation? before, Operation? after) {
if (before == null) {
return true;
}
return before.data is String &&
(before.data as String).endsWith('\n') &&
after.data is String &&
after!.data is String &&
(after.data as String).startsWith('\n');
}
@override
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute}) {
if (data is! String || (data as String) != '\n') {
Delta? applyRule(Delta document, int index,
{int? len, Object? data, Attribute? attribute}) {
if (data is! String || data != '\n') {
return null;
}
DeltaIterator itr = DeltaIterator(document);
Operation prev = itr.skip(index), cur = itr.next();
Attribute blockStyle =
Operation? prev = itr.skip(index), cur = itr.next();
Attribute? blockStyle =
Style.fromJson(cur.attributes).getBlockExceptHeader();
if (cur.isPlain || blockStyle == null) {
return null;
@ -147,10 +145,10 @@ class AutoExitBlockRule extends InsertRule {
return null;
}
Tuple2<Operation, int> nextNewLine = _getNextNewLine(itr);
Tuple2<Operation?, int?> nextNewLine = _getNextNewLine(itr);
if (nextNewLine.item1 != null &&
nextNewLine.item1.attributes != null &&
Style.fromJson(nextNewLine.item1.attributes).getBlockExceptHeader() ==
nextNewLine.item1!.attributes != null &&
Style.fromJson(nextNewLine.item1!.attributes).getBlockExceptHeader() ==
blockStyle) {
return null;
}
@ -168,9 +166,9 @@ class ResetLineFormatOnNewLineRule extends InsertRule {
const ResetLineFormatOnNewLineRule();
@override
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute}) {
if (data is! String || (data as String) != '\n') {
Delta? applyRule(Delta document, int index,
{int? len, Object? data, Attribute? attribute}) {
if (data is! String || data != '\n') {
return null;
}
@ -181,9 +179,9 @@ class ResetLineFormatOnNewLineRule extends InsertRule {
return null;
}
Map<String, dynamic> resetStyle;
Map<String, dynamic>? resetStyle;
if (cur.attributes != null &&
cur.attributes.containsKey(Attribute.header.key)) {
cur.attributes!.containsKey(Attribute.header.key)) {
resetStyle = Attribute.header.toJson();
}
return Delta()
@ -198,33 +196,33 @@ class InsertEmbedsRule extends InsertRule {
const InsertEmbedsRule();
@override
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute}) {
Delta? applyRule(Delta document, int index,
{int? len, Object? data, Attribute? attribute}) {
if (data is String) {
return null;
}
Delta delta = Delta()..retain(index);
DeltaIterator itr = DeltaIterator(document);
Operation prev = itr.skip(index), cur = itr.next();
Operation? prev = itr.skip(index), cur = itr.next();
String textBefore = prev?.data is String ? prev.data as String : '';
String textAfter = cur.data is String ? cur.data as String : '';
String? textBefore = prev?.data is String ? prev!.data as String? : '';
String textAfter = cur.data is String ? (cur.data as String?)! : '';
final isNewlineBefore = prev == null || textBefore.endsWith('\n');
final isNewlineBefore = prev == null || textBefore!.endsWith('\n');
final isNewlineAfter = textAfter.startsWith('\n');
if (isNewlineBefore && isNewlineAfter) {
return delta..insert(data);
}
Map<String, dynamic> lineStyle;
Map<String, dynamic>? lineStyle;
if (textAfter.contains('\n')) {
lineStyle = cur.attributes;
} else {
while (itr.hasNext) {
Operation op = itr.next();
if ((op.data is String ? op.data as String : '').indexOf('\n') >= 0) {
if ((op.data is String ? op.data as String? : '')!.indexOf('\n') >= 0) {
lineStyle = op.attributes;
break;
}
@ -246,13 +244,13 @@ class ForceNewlineForInsertsAroundEmbedRule extends InsertRule {
const ForceNewlineForInsertsAroundEmbedRule();
@override
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute}) {
Delta? applyRule(Delta document, int index,
{int? len, Object? data, Attribute? attribute}) {
if (data is! String) {
return null;
}
String text = data as String;
String text = data;
DeltaIterator itr = DeltaIterator(document);
final prev = itr.skip(index);
final cur = itr.next();
@ -277,14 +275,14 @@ class AutoFormatLinksRule extends InsertRule {
const AutoFormatLinksRule();
@override
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute}) {
if (data is! String || (data as String) != ' ') {
Delta? applyRule(Delta document, int index,
{int? len, Object? data, Attribute? attribute}) {
if (data is! String || data != ' ') {
return null;
}
DeltaIterator itr = DeltaIterator(document);
Operation prev = itr.skip(index);
Operation? prev = itr.skip(index);
if (prev == null || prev.data is! String) {
return null;
}
@ -305,7 +303,7 @@ class AutoFormatLinksRule extends InsertRule {
return Delta()
..retain(index - cand.length)
..retain(cand.length, attributes)
..insert(data as String, prev.attributes);
..insert(data, prev.attributes);
} on FormatException {
return null;
}
@ -316,22 +314,22 @@ class PreserveInlineStylesRule extends InsertRule {
const PreserveInlineStylesRule();
@override
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute}) {
if (data is! String || (data as String).contains('\n')) {
Delta? applyRule(Delta document, int index,
{int? len, Object? data, Attribute? attribute}) {
if (data is! String || data.contains('\n')) {
return null;
}
DeltaIterator itr = DeltaIterator(document);
Operation prev = itr.skip(index);
Operation? prev = itr.skip(index);
if (prev == null ||
prev.data is! String ||
(prev.data as String).contains('\n')) {
return null;
}
Map<String, dynamic> attributes = prev.attributes;
String text = data as String;
Map<String, dynamic>? attributes = prev.attributes;
String text = data;
if (attributes == null || !attributes.containsKey(Attribute.link.key)) {
return Delta()
..retain(index)
@ -365,18 +363,19 @@ class CatchAllInsertRule extends InsertRule {
@override
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute}) {
{int? len, Object? data, Attribute? attribute}) {
return Delta()
..retain(index)
..insert(data);
}
}
Tuple2<Operation, int> _getNextNewLine(DeltaIterator iterator) {
Tuple2<Operation?, int?> _getNextNewLine(DeltaIterator iterator) {
Operation op;
for (int skipped = 0; iterator.hasNext; skipped += op.length) {
for (int skipped = 0; iterator.hasNext; skipped += op.length!) {
op = iterator.next();
int lineBreak = (op.data is String ? op.data as String : '').indexOf('\n');
int lineBreak =
(op.data is String ? op.data as String? : '')!.indexOf('\n');
if (lineBreak >= 0) {
return Tuple2(op, skipped);
}

@ -11,8 +11,8 @@ enum RuleType { INSERT, DELETE, FORMAT }
abstract class Rule {
const Rule();
Delta apply(Delta document, int index,
{int len, Object data, Attribute attribute}) {
Delta? apply(Delta document, int index,
{int? len, Object? data, Attribute? attribute}) {
assert(document != null);
assert(index != null);
validateArgs(len, data, attribute);
@ -20,10 +20,10 @@ abstract class Rule {
len: len, data: data, attribute: attribute);
}
validateArgs(int len, Object data, Attribute attribute);
validateArgs(int? len, Object? data, Attribute? attribute);
Delta applyRule(Delta document, int index,
{int len, Object data, Attribute attribute});
Delta? applyRule(Delta document, int index,
{int? len, Object? data, Attribute? attribute});
RuleType get type;
}
@ -53,7 +53,7 @@ class Rules {
static Rules getInstance() => _instance;
Delta apply(RuleType ruleType, Document document, int index,
{int len, Object data, Attribute attribute}) {
{int? len, Object? data, Attribute? attribute}) {
final delta = document.toDelta();
for (var rule in _rules) {
if (rule.type != ruleType) {

@ -2,7 +2,7 @@ import 'dart:ui';
import 'package:flutter/material.dart';
Color stringToColor(String s) {
Color stringToColor(String? s) {
switch (s) {
case 'transparent':
return Colors.transparent;
@ -106,7 +106,7 @@ Color stringToColor(String s) {
return Colors.brown;
}
if (s.startsWith('rgba')) {
if (s!.startsWith('rgba')) {
s = s.substring(5); // trim left 'rgba('
s = s.substring(0, s.length - 1); // trim right ')'
final arr = s.split(',').map((e) => e.trim()).toList();

@ -76,7 +76,7 @@ int getPositionDelta(Delta user, Delta actual) {
int diff = 0;
while (userItr.hasNext || actualItr.hasNext) {
final length = math.min(userItr.peekLength(), actualItr.peekLength());
Operation userOperation = userItr.next(length);
Operation userOperation = userItr.next(length as int);
Operation actualOperation = actualItr.next(length);
if (userOperation.length != actualOperation.length) {
throw ('userOp ' +
@ -88,18 +88,18 @@ int getPositionDelta(Delta user, Delta actual) {
if (userOperation.key == actualOperation.key) {
continue;
} else if (userOperation.isInsert && actualOperation.isRetain) {
diff -= userOperation.length;
diff -= userOperation.length!;
} else if (userOperation.isDelete && actualOperation.isRetain) {
diff += userOperation.length;
diff += userOperation.length!;
} else if (userOperation.isRetain && actualOperation.isInsert) {
String operationTxt = '';
String? operationTxt = '';
if (actualOperation.data is String) {
operationTxt = actualOperation.data as String;
operationTxt = actualOperation.data as String?;
}
if (operationTxt.startsWith('\n')) {
if (operationTxt!.startsWith('\n')) {
continue;
}
diff += actualOperation.length;
diff += actualOperation.length!;
}
}
return diff;

@ -4,11 +4,11 @@ import 'package:flutter_quill/models/documents/nodes/container.dart';
abstract class RenderContentProxyBox implements RenderBox {
double getPreferredLineHeight();
Offset getOffsetForCaret(TextPosition position, Rect caretPrototype);
Offset getOffsetForCaret(TextPosition position, Rect? caretPrototype);
TextPosition getPositionForOffset(Offset offset);
double getFullHeightForCaret(TextPosition position);
double? getFullHeightForCaret(TextPosition position);
TextRange getWordBoundary(TextPosition position);
@ -24,9 +24,9 @@ abstract class RenderEditableBox extends RenderBox {
TextPosition getPositionForOffset(Offset offset);
TextPosition getPositionAbove(TextPosition position);
TextPosition? getPositionAbove(TextPosition position);
TextPosition getPositionBelow(TextPosition position);
TextPosition? getPositionBelow(TextPosition position);
TextRange getWordBoundary(TextPosition position);

@ -14,7 +14,7 @@ class QuillController extends ChangeNotifier {
TextSelection selection;
Style toggledStyle = Style();
QuillController({@required this.document, @required this.selection})
QuillController({required this.document, required this.selection})
: assert(document != null),
assert(selection != null);
@ -49,14 +49,14 @@ class QuillController extends ChangeNotifier {
}
}
void _handleHistoryChange(int len) {
void _handleHistoryChange(int? len) {
if (len != 0) {
// if (this.selection.extentOffset >= document.length) {
// // cursor exceeds the length of document, position it in the end
// updateSelection(
// TextSelection.collapsed(offset: document.length), ChangeSource.LOCAL);
updateSelection(
TextSelection.collapsed(offset: this.selection.baseOffset + len),
TextSelection.collapsed(offset: this.selection.baseOffset + len!),
ChangeSource.LOCAL);
} else {
// no need to move cursor
@ -75,11 +75,11 @@ class QuillController extends ChangeNotifier {
get hasRedo => document.hasRedo;
replaceText(int index, int len, Object data, TextSelection textSelection) {
replaceText(int index, int len, Object? data, TextSelection? textSelection) {
assert(data is String || data is Embeddable);
Delta delta;
if (len > 0 || data is! String || (data as String).isNotEmpty) {
Delta? delta;
if (len > 0 || data is! String || data.isNotEmpty) {
try {
delta = document.replace(index, len, data);
} catch (e) {
@ -137,8 +137,8 @@ class QuillController extends ChangeNotifier {
notifyListeners();
}
formatText(int index, int len, Attribute attribute) {
if (len == 0 && attribute.isInline && attribute.key != Attribute.link.key) {
formatText(int index, int len, Attribute? attribute) {
if (len == 0 && attribute!.isInline && attribute.key != Attribute.link.key) {
toggledStyle = toggledStyle.put(attribute);
}
@ -152,7 +152,7 @@ class QuillController extends ChangeNotifier {
notifyListeners();
}
formatSelection(Attribute attribute) {
formatSelection(Attribute? attribute) {
formatText(selection.start, selection.end - selection.start, attribute);
}

@ -11,25 +11,22 @@ class CursorStyle {
final Color color;
final Color backgroundColor;
final double width;
final double height;
final Radius radius;
final Offset offset;
final double? height;
final Radius? radius;
final Offset? offset;
final bool opacityAnimates;
final bool paintAboveText;
const CursorStyle({
@required this.color,
@required this.backgroundColor,
required this.color,
required this.backgroundColor,
this.width = 1.0,
this.height,
this.radius,
this.offset,
this.opacityAnimates = false,
this.paintAboveText = false,
}) : assert(color != null),
assert(backgroundColor != null),
assert(opacityAnimates != null),
assert(paintAboveText != null);
});
@override
bool operator ==(Object other) =>
@ -61,19 +58,17 @@ class CursorCont extends ChangeNotifier {
final ValueNotifier<bool> show;
final ValueNotifier<bool> _blink;
final ValueNotifier<Color> color;
AnimationController _blinkOpacityCont;
Timer _cursorTimer;
late AnimationController _blinkOpacityCont;
Timer? _cursorTimer;
bool _targetCursorVisibility = false;
CursorStyle _style;
CursorCont({
@required ValueNotifier<bool> show,
@required CursorStyle style,
@required TickerProvider tickerProvider,
}) : assert(show != null),
assert(style != null),
assert(tickerProvider != null),
show = show ?? ValueNotifier<bool>(false),
required ValueNotifier<bool> show,
required CursorStyle style,
required TickerProvider tickerProvider,
}) :
show = show,
_style = style,
_blink = ValueNotifier(false),
color = ValueNotifier(style.color) {
@ -89,7 +84,6 @@ class CursorCont extends ChangeNotifier {
CursorStyle get style => _style;
set style(CursorStyle value) {
assert(value != null);
if (_style == value) return;
_style = value;
notifyListeners();
@ -161,9 +155,9 @@ class CursorCont extends ChangeNotifier {
}
class CursorPainter {
final RenderContentProxyBox editable;
final RenderContentProxyBox? editable;
final CursorStyle style;
final Rect prototype;
final Rect? prototype;
final Color color;
final double devicePixelRatio;
@ -174,17 +168,17 @@ class CursorPainter {
assert(prototype != null);
Offset caretOffset =
editable.getOffsetForCaret(position, prototype) + offset;
Rect caretRect = prototype.shift(caretOffset);
editable!.getOffsetForCaret(position, prototype) + offset;
Rect caretRect = prototype!.shift(caretOffset);
if (style.offset != null) {
caretRect = caretRect.shift(style.offset);
caretRect = caretRect.shift(style.offset!);
}
if (caretRect.left < 0.0) {
caretRect = caretRect.shift(Offset(-caretRect.left, 0.0));
}
double caretHeight = editable.getFullHeightForCaret(position);
double? caretHeight = editable!.getFullHeightForCaret(position);
if (caretHeight != null) {
switch (defaultTargetPlatform) {
case TargetPlatform.android:
@ -212,7 +206,7 @@ class CursorPainter {
}
}
Offset caretPosition = editable.localToGlobal(caretRect.topLeft);
Offset caretPosition = editable!.localToGlobal(caretRect.topLeft);
double pixelMultiple = 1.0 / devicePixelRatio;
caretRect = caretRect.shift(Offset(
caretPosition.dx.isFinite
@ -230,7 +224,7 @@ class CursorPainter {
return;
}
RRect caretRRect = RRect.fromRectAndRadius(caretRect, style.radius);
RRect caretRRect = RRect.fromRectAndRadius(caretRect, style.radius!);
canvas.drawRRect(caretRRect, paint);
}
}

@ -6,9 +6,9 @@ class QuillStyles extends InheritedWidget {
final DefaultStyles data;
QuillStyles({
Key key,
@required this.data,
@required Widget child,
Key? key,
required this.data,
required Widget child,
}) : assert(data != null),
assert(child != null),
super(key: key, child: child);
@ -18,13 +18,13 @@ class QuillStyles extends InheritedWidget {
return data != oldWidget.data;
}
static DefaultStyles getStyles(BuildContext context, bool nullOk) {
static DefaultStyles? getStyles(BuildContext context, bool nullOk) {
var widget = context.dependOnInheritedWidgetOfExactType<QuillStyles>();
if (widget == null && nullOk) {
return null;
}
assert(widget != null);
return widget.data;
return widget!.data;
}
}
@ -35,31 +35,31 @@ class DefaultTextBlockStyle {
final Tuple2<double, double> lineSpacing;
final BoxDecoration decoration;
final BoxDecoration? decoration;
DefaultTextBlockStyle(
this.style, this.verticalSpacing, this.lineSpacing, this.decoration);
}
class DefaultStyles {
final DefaultTextBlockStyle h1;
final DefaultTextBlockStyle h2;
final DefaultTextBlockStyle h3;
final DefaultTextBlockStyle paragraph;
final TextStyle bold;
final TextStyle italic;
final TextStyle underline;
final TextStyle strikeThrough;
final TextStyle sizeSmall; // 'small'
final TextStyle sizeLarge; // 'large'
final TextStyle sizeHuge; // 'huge'
final TextStyle link;
final DefaultTextBlockStyle placeHolder;
final DefaultTextBlockStyle lists;
final DefaultTextBlockStyle quote;
final DefaultTextBlockStyle code;
final DefaultTextBlockStyle indent;
final DefaultTextBlockStyle align;
final DefaultTextBlockStyle? h1;
final DefaultTextBlockStyle? h2;
final DefaultTextBlockStyle? h3;
final DefaultTextBlockStyle? paragraph;
final TextStyle? bold;
final TextStyle? italic;
final TextStyle? underline;
final TextStyle? strikeThrough;
final TextStyle? sizeSmall; // 'small'
final TextStyle? sizeLarge; // 'large'
final TextStyle? sizeHuge; // 'huge'
final TextStyle? link;
final DefaultTextBlockStyle? placeHolder;
final DefaultTextBlockStyle? lists;
final DefaultTextBlockStyle? quote;
final DefaultTextBlockStyle? code;
final DefaultTextBlockStyle? indent;
final DefaultTextBlockStyle? align;
DefaultStyles(
{this.h1,
@ -109,7 +109,7 @@ class DefaultStyles {
h1: DefaultTextBlockStyle(
defaultTextStyle.style.copyWith(
fontSize: 34.0,
color: defaultTextStyle.style.color.withOpacity(0.70),
color: defaultTextStyle.style.color!.withOpacity(0.70),
height: 1.15,
fontWeight: FontWeight.w300,
),
@ -119,7 +119,7 @@ class DefaultStyles {
h2: DefaultTextBlockStyle(
defaultTextStyle.style.copyWith(
fontSize: 24.0,
color: defaultTextStyle.style.color.withOpacity(0.70),
color: defaultTextStyle.style.color!.withOpacity(0.70),
height: 1.15,
fontWeight: FontWeight.normal,
),
@ -129,7 +129,7 @@ class DefaultStyles {
h3: DefaultTextBlockStyle(
defaultTextStyle.style.copyWith(
fontSize: 20.0,
color: defaultTextStyle.style.color.withOpacity(0.70),
color: defaultTextStyle.style.color!.withOpacity(0.70),
height: 1.25,
fontWeight: FontWeight.w500,
),
@ -158,7 +158,7 @@ class DefaultStyles {
lists: DefaultTextBlockStyle(
baseStyle, baseSpacing, Tuple2(0.0, 6.0), null),
quote: DefaultTextBlockStyle(
TextStyle(color: baseStyle.color.withOpacity(0.6)),
TextStyle(color: baseStyle.color!.withOpacity(0.6)),
baseSpacing,
Tuple2(6.0, 2.0),
BoxDecoration(

@ -14,7 +14,7 @@ abstract class EditorTextSelectionGestureDetectorBuilderDelegate {
bool getForcePressEnabled();
bool getSelectionEnabled();
bool? getSelectionEnabled();
}
class EditorTextSelectionGestureDetectorBuilder {
@ -24,18 +24,18 @@ class EditorTextSelectionGestureDetectorBuilder {
EditorTextSelectionGestureDetectorBuilder(this.delegate)
: assert(delegate != null);
EditorState getEditor() {
EditorState? getEditor() {
return delegate.getEditableTextKey().currentState;
}
RenderEditor getRenderEditor() {
return this.getEditor().getRenderEditor();
RenderEditor? getRenderEditor() {
return this.getEditor()!.getRenderEditor();
}
onTapDown(TapDownDetails details) {
getRenderEditor().handleTapDown(details);
getRenderEditor()!.handleTapDown(details);
PointerDeviceKind kind = details.kind;
PointerDeviceKind? kind = details.kind;
shouldShowSelectionToolbar = kind == null ||
kind == PointerDeviceKind.touch ||
kind == PointerDeviceKind.stylus;
@ -44,8 +44,8 @@ class EditorTextSelectionGestureDetectorBuilder {
onForcePressStart(ForcePressDetails details) {
assert(delegate.getForcePressEnabled());
shouldShowSelectionToolbar = true;
if (delegate.getSelectionEnabled()) {
getRenderEditor().selectWordsInRange(
if (delegate.getSelectionEnabled()!) {
getRenderEditor()!.selectWordsInRange(
details.globalPosition,
null,
SelectionChangedCause.forcePress,
@ -55,27 +55,27 @@ class EditorTextSelectionGestureDetectorBuilder {
onForcePressEnd(ForcePressDetails details) {
assert(delegate.getForcePressEnabled());
getRenderEditor().selectWordsInRange(
getRenderEditor()!.selectWordsInRange(
details.globalPosition,
null,
SelectionChangedCause.forcePress,
);
if (shouldShowSelectionToolbar) {
getEditor().showToolbar();
getEditor()!.showToolbar();
}
}
onSingleTapUp(TapUpDetails details) {
if (delegate.getSelectionEnabled()) {
getRenderEditor().selectWordEdge(SelectionChangedCause.tap);
if (delegate.getSelectionEnabled()!) {
getRenderEditor()!.selectWordEdge(SelectionChangedCause.tap);
}
}
onSingleTapCancel() {}
onSingleLongTapStart(LongPressStartDetails details) {
if (delegate.getSelectionEnabled()) {
getRenderEditor().selectPositionAt(
if (delegate.getSelectionEnabled()!) {
getRenderEditor()!.selectPositionAt(
details.globalPosition,
null,
SelectionChangedCause.longPress,
@ -84,8 +84,8 @@ class EditorTextSelectionGestureDetectorBuilder {
}
onSingleLongTapMoveUpdate(LongPressMoveUpdateDetails details) {
if (delegate.getSelectionEnabled()) {
getRenderEditor().selectPositionAt(
if (delegate.getSelectionEnabled()!) {
getRenderEditor()!.selectPositionAt(
details.globalPosition,
null,
SelectionChangedCause.longPress,
@ -95,21 +95,21 @@ class EditorTextSelectionGestureDetectorBuilder {
onSingleLongTapEnd(LongPressEndDetails details) {
if (shouldShowSelectionToolbar) {
getEditor().showToolbar();
getEditor()!.showToolbar();
}
}
onDoubleTapDown(TapDownDetails details) {
if (delegate.getSelectionEnabled()) {
getRenderEditor().selectWord(SelectionChangedCause.tap);
if (delegate.getSelectionEnabled()!) {
getRenderEditor()!.selectWord(SelectionChangedCause.tap);
if (shouldShowSelectionToolbar) {
getEditor().showToolbar();
getEditor()!.showToolbar();
}
}
}
onDragSelectionStart(DragStartDetails details) {
getRenderEditor().selectPositionAt(
getRenderEditor()!.selectPositionAt(
details.globalPosition,
null,
SelectionChangedCause.drag,
@ -118,7 +118,7 @@ class EditorTextSelectionGestureDetectorBuilder {
onDragSelectionUpdate(
DragStartDetails startDetails, DragUpdateDetails updateDetails) {
getRenderEditor().selectPositionAt(
getRenderEditor()!.selectPositionAt(
startDetails.globalPosition,
updateDetails.globalPosition,
SelectionChangedCause.drag,

@ -53,9 +53,9 @@ abstract class EditorState extends State<RawEditor> {
void setTextEditingValue(TextEditingValue value);
RenderEditor getRenderEditor();
RenderEditor? getRenderEditor();
EditorTextSelectionOverlay getSelectionOverlay();
EditorTextSelectionOverlay? getSelectionOverlay();
bool showToolbar();
@ -146,35 +146,35 @@ class QuillEditor extends StatefulWidget {
final bool scrollable;
final EdgeInsetsGeometry padding;
final bool autoFocus;
final bool showCursor;
final bool? showCursor;
final bool readOnly;
final String placeholder;
final bool enableInteractiveSelection;
final double minHeight;
final double maxHeight;
final DefaultStyles customStyles;
final String? placeholder;
final bool? enableInteractiveSelection;
final double? minHeight;
final double? maxHeight;
final DefaultStyles? customStyles;
final bool expands;
final TextCapitalization textCapitalization;
final Brightness keyboardAppearance;
final ScrollPhysics scrollPhysics;
final ValueChanged<String> onLaunchUrl;
final ScrollPhysics? scrollPhysics;
final ValueChanged<String>? onLaunchUrl;
final EmbedBuilder embedBuilder;
QuillEditor(
{@required this.controller,
@required this.focusNode,
@required this.scrollController,
@required this.scrollable,
@required this.padding,
@required this.autoFocus,
{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.readOnly,
this.placeholder,
this.enableInteractiveSelection,
this.minHeight,
this.maxHeight,
this.customStyles,
@required this.expands,
required this.expands,
this.textCapitalization = TextCapitalization.sentences,
this.keyboardAppearance = Brightness.light,
this.scrollPhysics,
@ -190,7 +190,7 @@ class QuillEditor extends StatefulWidget {
assert(embedBuilder != null);
factory QuillEditor.basic(
{@required QuillController controller, bool readOnly}) {
{required QuillController controller, required bool readOnly}) {
return QuillEditor(
controller: controller,
scrollController: ScrollController(),
@ -210,7 +210,7 @@ class QuillEditor extends StatefulWidget {
class _QuillEditorState extends State<QuillEditor>
implements EditorTextSelectionGestureDetectorBuilderDelegate {
final GlobalKey<EditorState> _editorKey = GlobalKey<EditorState>();
EditorTextSelectionGestureDetectorBuilder _selectionGestureDetectorBuilder;
late EditorTextSelectionGestureDetectorBuilder _selectionGestureDetectorBuilder;
@override
void initState() {
@ -227,10 +227,10 @@ class _QuillEditorState extends State<QuillEditor>
TextSelectionControls textSelectionControls;
bool paintCursorAboveText;
bool cursorOpacityAnimates;
Offset cursorOffset;
Color cursorColor;
Offset? cursorOffset;
Color? cursorColor;
Color selectionColor;
Radius cursorRadius;
Radius? cursorRadius;
switch (theme.platform) {
case TargetPlatform.android:
@ -301,7 +301,7 @@ class _QuillEditorState extends State<QuillEditor>
selectionColor,
textSelectionControls,
widget.keyboardAppearance,
widget.enableInteractiveSelection,
widget.enableInteractiveSelection!,
widget.scrollPhysics,
widget.embedBuilder),
);
@ -318,12 +318,12 @@ class _QuillEditorState extends State<QuillEditor>
}
@override
bool getSelectionEnabled() {
bool? getSelectionEnabled() {
return widget.enableInteractiveSelection;
}
_requestKeyboard() {
_editorKey.currentState.requestKeyboard();
_editorKey.currentState!.requestKeyboard();
}
}
@ -336,8 +336,8 @@ class _QuillEditorSelectionGestureDetectorBuilder
@override
onForcePressStart(ForcePressDetails details) {
super.onForcePressStart(details);
if (delegate.getSelectionEnabled() && shouldShowSelectionToolbar) {
getEditor().showToolbar();
if (delegate.getSelectionEnabled()! && shouldShowSelectionToolbar) {
getEditor()!.showToolbar();
}
}
@ -346,13 +346,13 @@ class _QuillEditorSelectionGestureDetectorBuilder
@override
void onSingleLongTapMoveUpdate(LongPressMoveUpdateDetails details) {
if (!delegate.getSelectionEnabled()) {
if (!delegate.getSelectionEnabled()!) {
return;
}
switch (Theme.of(_state.context).platform) {
case TargetPlatform.iOS:
case TargetPlatform.macOS:
getRenderEditor().selectPositionAt(
getRenderEditor()!.selectPositionAt(
details.globalPosition,
null,
SelectionChangedCause.longPress,
@ -362,7 +362,7 @@ class _QuillEditorSelectionGestureDetectorBuilder
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
getRenderEditor().selectWordsInRange(
getRenderEditor()!.selectWordsInRange(
details.globalPosition - details.offsetFromOrigin,
details.globalPosition,
SelectionChangedCause.longPress,
@ -378,9 +378,9 @@ class _QuillEditorSelectionGestureDetectorBuilder
return false;
}
TextPosition pos =
getRenderEditor().getPositionForOffset(details.globalPosition);
getRenderEditor()!.getPositionForOffset(details.globalPosition);
containerNode.ChildQuery result =
getEditor().widget.controller.document.queryChild(pos.offset);
getEditor()!.widget.controller.document.queryChild(pos.offset);
if (result.node == null) {
return false;
}
@ -391,7 +391,7 @@ class _QuillEditorSelectionGestureDetectorBuilder
if (line.length == 1) {
// tapping when no text yet on this line
_flipListCheckbox(pos, line, segmentResult);
getEditor().widget.controller.updateSelection(
getEditor()!.widget.controller.updateSelection(
TextSelection.collapsed(offset: pos.offset), ChangeSource.LOCAL);
return true;
}
@ -399,33 +399,33 @@ class _QuillEditorSelectionGestureDetectorBuilder
}
leaf.Leaf segment = segmentResult.node as leaf.Leaf;
if (segment.style.containsKey(Attribute.link.key)) {
var launchUrl = getEditor().widget.onLaunchUrl;
var launchUrl = getEditor()!.widget.onLaunchUrl;
if (launchUrl == null) {
launchUrl = _launchUrl;
}
String link = segment.style.attributes[Attribute.link.key].value;
if (getEditor().widget.readOnly && link != null) {
String? link = segment.style.attributes[Attribute.link.key]!.value;
if (getEditor()!.widget.readOnly && link != null) {
link = link.trim();
if (!linkPrefixes
.any((linkPrefix) => link.toLowerCase().startsWith(linkPrefix))) {
.any((linkPrefix) => link!.toLowerCase().startsWith(linkPrefix))) {
link = 'https://$link';
}
launchUrl(link);
}
return false;
}
if (getEditor().widget.readOnly && segment.value is BlockEmbed) {
if (getEditor()!.widget.readOnly && segment.value is BlockEmbed) {
BlockEmbed blockEmbed = segment.value as BlockEmbed;
if (blockEmbed.type == 'image') {
final String imageUrl = blockEmbed.data;
Navigator.push(
getEditor().context,
getEditor()!.context,
MaterialPageRoute(
builder: (context) => ImageTapWrapper(
imageProvider: imageUrl.startsWith('http')
? NetworkImage(imageUrl)
: isBase64(imageUrl)
? Image.memory(base64.decode(imageUrl))
? Image.memory(base64.decode(imageUrl)) as ImageProvider<Object>?
: FileImage(io.File(imageUrl)),
),
),
@ -441,25 +441,25 @@ class _QuillEditorSelectionGestureDetectorBuilder
bool _flipListCheckbox(
TextPosition pos, Line line, containerNode.ChildQuery segmentResult) {
if (getEditor().widget.readOnly ||
if (getEditor()!.widget.readOnly ||
!line.style.containsKey(Attribute.list.key) ||
segmentResult.offset != 0) {
return false;
}
// segmentResult.offset == 0 means tap at the beginning of the TextLine
String listVal = line.style.attributes[Attribute.list.key].value;
String? listVal = line.style.attributes[Attribute.list.key]!.value;
if (listVal == Attribute.unchecked.value) {
getEditor()
getEditor()!
.widget
.controller
.formatText(pos.offset, 0, Attribute.checked);
} else if (listVal == Attribute.checked.value) {
getEditor()
getEditor()!
.widget
.controller
.formatText(pos.offset, 0, Attribute.unchecked);
}
getEditor().widget.controller.updateSelection(
getEditor()!.widget.controller.updateSelection(
TextSelection.collapsed(offset: pos.offset), ChangeSource.LOCAL);
return true;
}
@ -470,11 +470,11 @@ class _QuillEditorSelectionGestureDetectorBuilder
@override
onSingleTapUp(TapUpDetails details) {
getEditor().hideToolbar();
getEditor()!.hideToolbar();
bool positionSelected = _onTapping(details);
if (delegate.getSelectionEnabled() && !positionSelected) {
if (delegate.getSelectionEnabled()! && !positionSelected) {
switch (Theme.of(_state.context).platform) {
case TargetPlatform.iOS:
case TargetPlatform.macOS:
@ -482,11 +482,11 @@ class _QuillEditorSelectionGestureDetectorBuilder
case PointerDeviceKind.mouse:
case PointerDeviceKind.stylus:
case PointerDeviceKind.invertedStylus:
getRenderEditor().selectPosition(SelectionChangedCause.tap);
getRenderEditor()!.selectPosition(SelectionChangedCause.tap);
break;
case PointerDeviceKind.touch:
case PointerDeviceKind.unknown:
getRenderEditor().selectWordEdge(SelectionChangedCause.tap);
getRenderEditor()!.selectWordEdge(SelectionChangedCause.tap);
break;
}
break;
@ -494,7 +494,7 @@ class _QuillEditorSelectionGestureDetectorBuilder
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
getRenderEditor().selectPosition(SelectionChangedCause.tap);
getRenderEditor()!.selectPosition(SelectionChangedCause.tap);
break;
}
}
@ -503,11 +503,11 @@ class _QuillEditorSelectionGestureDetectorBuilder
@override
void onSingleLongTapStart(LongPressStartDetails details) {
if (delegate.getSelectionEnabled()) {
if (delegate.getSelectionEnabled()!) {
switch (Theme.of(_state.context).platform) {
case TargetPlatform.iOS:
case TargetPlatform.macOS:
getRenderEditor().selectPositionAt(
getRenderEditor()!.selectPositionAt(
details.globalPosition,
null,
SelectionChangedCause.longPress,
@ -517,7 +517,7 @@ class _QuillEditorSelectionGestureDetectorBuilder
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
getRenderEditor().selectWord(SelectionChangedCause.longPress);
getRenderEditor()!.selectWord(SelectionChangedCause.longPress);
Feedback.forLongPress(_state.context);
break;
default:
@ -548,7 +548,7 @@ class RenderEditor extends RenderEditableContainerBox
final ValueNotifier<bool> _selectionEndInViewport = ValueNotifier<bool>(true);
RenderEditor(
List<RenderEditableBox> children,
List<RenderEditableBox>? children,
TextDirection textDirection,
EdgeInsetsGeometry padding,
this.document,
@ -622,7 +622,7 @@ class RenderEditor extends RenderEditableContainerBox
offset:
textSelection.extentOffset - child.getContainer().getOffset());
Offset localOffset = child.getOffsetForCaret(localPosition);
BoxParentData parentData = child.parentData;
BoxParentData parentData = child.parentData as BoxParentData;
return <TextSelectionPoint>[
TextSelectionPoint(
Offset(0.0, child.preferredLineHeight(localPosition)) +
@ -632,7 +632,7 @@ class RenderEditor extends RenderEditableContainerBox
];
}
Node baseNode = _container.queryChild(textSelection.start, false).node;
Node? baseNode = _container.queryChild(textSelection.start, false).node;
var baseChild = firstChild;
while (baseChild != null) {
@ -643,7 +643,7 @@ class RenderEditor extends RenderEditableContainerBox
}
assert(baseChild != null);
BoxParentData baseParentData = baseChild.parentData;
BoxParentData baseParentData = baseChild!.parentData as BoxParentData;
TextSelection baseSelection =
localSelection(baseChild.getContainer(), textSelection, true);
TextSelectionPoint basePoint =
@ -651,8 +651,8 @@ class RenderEditor extends RenderEditableContainerBox
basePoint = TextSelectionPoint(
basePoint.point + baseParentData.offset, basePoint.direction);
Node extentNode = _container.queryChild(textSelection.end, false).node;
var extentChild = baseChild;
Node? extentNode = _container.queryChild(textSelection.end, false).node;
RenderEditableBox? extentChild = baseChild;
while (extentChild != null) {
if (extentChild.getContainer() == extentNode) {
break;
@ -661,7 +661,7 @@ class RenderEditor extends RenderEditableContainerBox
}
assert(extentChild != null);
BoxParentData extentParentData = extentChild.parentData;
BoxParentData extentParentData = extentChild!.parentData as BoxParentData;
TextSelection extentSelection =
localSelection(extentChild.getContainer(), textSelection, true);
TextSelectionPoint extentPoint =
@ -672,7 +672,7 @@ class RenderEditor extends RenderEditableContainerBox
return <TextSelectionPoint>[basePoint, extentPoint];
}
Offset _lastTapDownPosition;
Offset? _lastTapDownPosition;
@override
handleTapDown(TapDownDetails details) {
@ -682,7 +682,7 @@ class RenderEditor extends RenderEditableContainerBox
@override
selectWordsInRange(
Offset from,
Offset to,
Offset? to,
SelectionChangedCause cause,
) {
assert(cause != null);
@ -729,7 +729,7 @@ class RenderEditor extends RenderEditableContainerBox
if (onSelectionChanged == null) {
return;
}
TextPosition position = getPositionForOffset(_lastTapDownPosition);
TextPosition position = getPositionForOffset(_lastTapDownPosition!);
RenderEditableBox child = childAtPosition(position);
int nodeOffset = child.getContainer().getOffset();
TextPosition localPosition = TextPosition(
@ -759,7 +759,7 @@ class RenderEditor extends RenderEditableContainerBox
@override
selectPositionAt(
Offset from,
Offset to,
Offset? to,
SelectionChangedCause cause,
) {
assert(cause != null);
@ -768,7 +768,7 @@ class RenderEditor extends RenderEditableContainerBox
return;
}
TextPosition fromPosition = getPositionForOffset(from);
TextPosition toPosition = to == null ? null : getPositionForOffset(to);
TextPosition? toPosition = to == null ? null : getPositionForOffset(to);
int baseOffset = fromPosition.offset;
int extentOffset = fromPosition.offset;
@ -787,12 +787,12 @@ class RenderEditor extends RenderEditableContainerBox
@override
selectWord(SelectionChangedCause cause) {
selectWordsInRange(_lastTapDownPosition, null, cause);
selectWordsInRange(_lastTapDownPosition!, null, cause);
}
@override
selectPosition(SelectionChangedCause cause) {
selectPositionAt(_lastTapDownPosition, null, cause);
selectPositionAt(_lastTapDownPosition!, null, cause);
}
@override
@ -837,7 +837,7 @@ class RenderEditor extends RenderEditableContainerBox
}
@override
bool hitTestChildren(BoxHitTestResult result, {Offset position}) {
bool hitTestChildren(BoxHitTestResult result, {required Offset position}) {
return defaultHitTestChildren(result, position: position);
}
@ -877,9 +877,9 @@ class RenderEditor extends RenderEditableContainerBox
@override
TextPosition getPositionForOffset(Offset offset) {
Offset local = globalToLocal(offset);
RenderEditableBox child = childAtOffset(local);
RenderEditableBox child = childAtOffset(local)!;
BoxParentData parentData = child.parentData;
BoxParentData parentData = child.parentData as BoxParentData;
Offset localOffset = local - parentData.offset;
TextPosition localPosition = child.getPositionForOffset(localOffset);
return TextPosition(
@ -888,7 +888,7 @@ class RenderEditor extends RenderEditableContainerBox
);
}
double getOffsetToRevealCursor(
double? getOffsetToRevealCursor(
double viewportHeight, double scrollOffset, double offsetInViewport) {
List<TextSelectionPoint> endpoints = getEndpointsForSelection(selection);
TextSelectionPoint endpoint = endpoints.first;
@ -902,7 +902,7 @@ class RenderEditor extends RenderEditableContainerBox
kMargin +
offsetInViewport;
final caretBottom = endpoint.point.dy + kMargin + offsetInViewport;
double dy;
double? dy;
if (caretTop < scrollOffset) {
dy = caretTop;
} else if (caretBottom > scrollOffset + viewportHeight) {
@ -927,9 +927,9 @@ class RenderEditableContainerBox extends RenderBox
containerNode.Container _container;
TextDirection textDirection;
EdgeInsetsGeometry _padding;
EdgeInsets _resolvedPadding;
EdgeInsets? _resolvedPadding;
RenderEditableContainerBox(List<RenderEditableBox> children, this._container,
RenderEditableContainerBox(List<RenderEditableBox>? children, this._container,
this.textDirection, this._padding)
: assert(_container != null),
assert(textDirection != null),
@ -963,22 +963,22 @@ class RenderEditableContainerBox extends RenderBox
_markNeedsPaddingResolution();
}
EdgeInsets get resolvedPadding => _resolvedPadding;
EdgeInsets? get resolvedPadding => _resolvedPadding;
_resolvePadding() {
if (_resolvedPadding != null) {
return;
}
_resolvedPadding = _padding.resolve(textDirection);
_resolvedPadding = _resolvedPadding.copyWith(left: _resolvedPadding.left);
_resolvedPadding = _resolvedPadding!.copyWith(left: _resolvedPadding!.left);
assert(_resolvedPadding.isNonNegative);
assert(_resolvedPadding!.isNonNegative);
}
RenderEditableBox childAtPosition(TextPosition position) {
assert(firstChild != null);
Node targetNode = _container.queryChild(position.offset, false).node;
Node? targetNode = _container.queryChild(position.offset, false).node;
var targetChild = firstChild;
while (targetChild != null) {
@ -998,19 +998,19 @@ class RenderEditableContainerBox extends RenderBox
markNeedsLayout();
}
RenderEditableBox childAtOffset(Offset offset) {
RenderEditableBox? childAtOffset(Offset offset) {
assert(firstChild != null);
_resolvePadding();
if (offset.dy <= _resolvedPadding.top) {
if (offset.dy <= _resolvedPadding!.top) {
return firstChild;
}
if (offset.dy >= size.height - _resolvedPadding.bottom) {
if (offset.dy >= size.height - _resolvedPadding!.bottom) {
return lastChild;
}
var child = firstChild;
double dx = -offset.dx, dy = _resolvedPadding.top;
double dx = -offset.dx, dy = _resolvedPadding!.top;
while (child != null) {
if (child.size.contains(offset.translate(dx, -dy))) {
return child;
@ -1037,20 +1037,20 @@ class RenderEditableContainerBox extends RenderBox
_resolvePadding();
assert(_resolvedPadding != null);
double mainAxisExtent = _resolvedPadding.top;
double mainAxisExtent = _resolvedPadding!.top;
var child = firstChild;
BoxConstraints innerConstraints =
BoxConstraints.tightFor(width: constraints.maxWidth)
.deflate(_resolvedPadding);
.deflate(_resolvedPadding!);
while (child != null) {
child.layout(innerConstraints, parentUsesSize: true);
final EditableContainerParentData childParentData = child.parentData;
childParentData.offset = Offset(_resolvedPadding.left, mainAxisExtent);
final EditableContainerParentData childParentData = child.parentData as EditableContainerParentData;
childParentData.offset = Offset(_resolvedPadding!.left, mainAxisExtent);
mainAxisExtent += child.size.height;
assert(child.parentData == childParentData);
child = childParentData.nextSibling;
}
mainAxisExtent += _resolvedPadding.bottom;
mainAxisExtent += _resolvedPadding!.bottom;
size = constraints.constrain(Size(constraints.maxWidth, mainAxisExtent));
assert(size.isFinite);
@ -1061,7 +1061,7 @@ class RenderEditableContainerBox extends RenderBox
var child = firstChild;
while (child != null) {
extent = math.max(extent, childSize(child));
EditableContainerParentData childParentData = child.parentData;
EditableContainerParentData childParentData = child.parentData as EditableContainerParentData;
child = childParentData.nextSibling;
}
return extent;
@ -1072,7 +1072,7 @@ class RenderEditableContainerBox extends RenderBox
var child = firstChild;
while (child != null) {
extent += childSize(child);
EditableContainerParentData childParentData = child.parentData;
EditableContainerParentData childParentData = child.parentData as EditableContainerParentData;
child = childParentData.nextSibling;
}
return extent;
@ -1083,10 +1083,10 @@ class RenderEditableContainerBox extends RenderBox
_resolvePadding();
return _getIntrinsicCrossAxis((RenderBox child) {
double childHeight = math.max(
0.0, height - _resolvedPadding.top + _resolvedPadding.bottom);
0.0, height - _resolvedPadding!.top + _resolvedPadding!.bottom);
return child.getMinIntrinsicWidth(childHeight) +
_resolvedPadding.left +
_resolvedPadding.right;
_resolvedPadding!.left +
_resolvedPadding!.right;
});
}
@ -1095,10 +1095,10 @@ class RenderEditableContainerBox extends RenderBox
_resolvePadding();
return _getIntrinsicCrossAxis((RenderBox child) {
double childHeight = math.max(
0.0, height - _resolvedPadding.top + _resolvedPadding.bottom);
0.0, height - _resolvedPadding!.top + _resolvedPadding!.bottom);
return child.getMaxIntrinsicWidth(childHeight) +
_resolvedPadding.left +
_resolvedPadding.right;
_resolvedPadding!.left +
_resolvedPadding!.right;
});
}
@ -1107,10 +1107,10 @@ class RenderEditableContainerBox extends RenderBox
_resolvePadding();
return _getIntrinsicMainAxis((RenderBox child) {
double childWidth =
math.max(0.0, width - _resolvedPadding.left + _resolvedPadding.right);
math.max(0.0, width - _resolvedPadding!.left + _resolvedPadding!.right);
return child.getMinIntrinsicHeight(childWidth) +
_resolvedPadding.top +
_resolvedPadding.bottom;
_resolvedPadding!.top +
_resolvedPadding!.bottom;
});
}
@ -1119,17 +1119,17 @@ class RenderEditableContainerBox extends RenderBox
_resolvePadding();
return _getIntrinsicMainAxis((RenderBox child) {
final childWidth =
math.max(0.0, width - _resolvedPadding.left + _resolvedPadding.right);
math.max(0.0, width - _resolvedPadding!.left + _resolvedPadding!.right);
return child.getMaxIntrinsicHeight(childWidth) +
_resolvedPadding.top +
_resolvedPadding.bottom;
_resolvedPadding!.top +
_resolvedPadding!.bottom;
});
}
@override
double computeDistanceToActualBaseline(TextBaseline baseline) {
_resolvePadding();
return defaultComputeDistanceToFirstActualBaseline(baseline) +
_resolvedPadding.top;
return defaultComputeDistanceToFirstActualBaseline(baseline)! +
_resolvedPadding!.top;
}
}

@ -8,7 +8,7 @@ class ImageTapWrapper extends StatelessWidget {
this.imageProvider,
});
final ImageProvider imageProvider;
final ImageProvider? imageProvider;
@override
Widget build(BuildContext context) {

@ -4,7 +4,7 @@ enum InputShortcut { CUT, COPY, PASTE, SELECT_ALL }
typedef CursorMoveCallback = void Function(
LogicalKeyboardKey key, bool wordModifier, bool lineModifier, bool shift);
typedef InputShortcutCallback = void Function(InputShortcut shortcut);
typedef InputShortcutCallback = void Function(InputShortcut? shortcut);
typedef OnDeleteCallback = void Function(bool forward);
class KeyboardListener {

@ -4,17 +4,17 @@ import 'package:flutter/widgets.dart';
import 'box.dart';
class BaselineProxy extends SingleChildRenderObjectWidget {
final TextStyle textStyle;
final EdgeInsets padding;
final TextStyle? textStyle;
final EdgeInsets? padding;
BaselineProxy({Key key, Widget child, this.textStyle, this.padding})
BaselineProxy({Key? key, Widget? child, this.textStyle, this.padding})
: super(key: key, child: child);
@override
RenderBaselineProxy createRenderObject(BuildContext context) {
return RenderBaselineProxy(
null,
textStyle,
textStyle!,
padding,
);
}
@ -23,16 +23,16 @@ class BaselineProxy extends SingleChildRenderObjectWidget {
void updateRenderObject(
BuildContext context, covariant RenderBaselineProxy renderObject) {
renderObject
..textStyle = textStyle
..padding = padding;
..textStyle = textStyle!
..padding = padding!;
}
}
class RenderBaselineProxy extends RenderProxyBox {
RenderBaselineProxy(
RenderParagraph child,
RenderParagraph? child,
TextStyle textStyle,
EdgeInsets padding,
EdgeInsets? padding,
) : _prototypePainter = TextPainter(
text: TextSpan(text: ' ', style: textStyle),
textDirection: TextDirection.ltr,
@ -43,18 +43,16 @@ class RenderBaselineProxy extends RenderProxyBox {
final TextPainter _prototypePainter;
set textStyle(TextStyle value) {
assert(value != null);
if (_prototypePainter.text.style == value) {
if (_prototypePainter.text!.style == value) {
return;
}
_prototypePainter.text = TextSpan(text: ' ', style: value);
markNeedsLayout();
}
EdgeInsets _padding;
EdgeInsets? _padding;
set padding(EdgeInsets value) {
assert(value != null);
if (_padding == value) {
return;
}
@ -64,9 +62,8 @@ class RenderBaselineProxy extends RenderProxyBox {
@override
double computeDistanceToActualBaseline(TextBaseline baseline) =>
_prototypePainter.computeDistanceToActualBaseline(baseline) +
_padding?.top ??
0.0;
_prototypePainter.computeDistanceToActualBaseline(baseline);
// SEE What happens + _padding?.top;
@override
performLayout() {
@ -84,7 +81,7 @@ class EmbedProxy extends SingleChildRenderObjectWidget {
}
class RenderEmbedProxy extends RenderProxyBox implements RenderContentProxyBox {
RenderEmbedProxy(RenderBox child) : super(child);
RenderEmbedProxy(RenderBox? child) : super(child);
@override
List<TextBox> getBoxesForSelection(TextSelection selection) {
@ -105,10 +102,8 @@ class RenderEmbedProxy extends RenderProxyBox implements RenderContentProxyBox {
double getFullHeightForCaret(TextPosition position) => size.height;
@override
Offset getOffsetForCaret(TextPosition position, Rect caretPrototype) {
assert(position.offset != null &&
position.offset <= 1 &&
position.offset >= 0);
Offset getOffsetForCaret(TextPosition position, Rect? caretPrototype) {
assert(position.offset <= 1 && position.offset >= 0);
return position.offset == 0 ? Offset.zero : Offset(size.width, 0.0);
}
@ -134,7 +129,7 @@ class RichTextProxy extends SingleChildRenderObjectWidget {
final Locale locale;
final StrutStyle strutStyle;
final TextWidthBasis textWidthBasis;
final TextHeightBehavior textHeightBehavior;
final TextHeightBehavior? textHeightBehavior;
@override
RenderParagraphProxy createRenderObject(BuildContext context) {
@ -160,13 +155,7 @@ class RichTextProxy extends SingleChildRenderObjectWidget {
this.strutStyle,
this.textWidthBasis,
this.textHeightBehavior)
: assert(child != null),
assert(textStyle != null),
assert(textAlign != null),
assert(textDirection != null),
assert(locale != null),
assert(strutStyle != null),
super(child: child);
: super(child: child);
@override
void updateRenderObject(
@ -185,7 +174,7 @@ class RichTextProxy extends SingleChildRenderObjectWidget {
class RenderParagraphProxy extends RenderProxyBox
implements RenderContentProxyBox {
RenderParagraphProxy(
RenderParagraph child,
RenderParagraph? child,
TextStyle textStyle,
TextAlign textAlign,
TextDirection textDirection,
@ -193,7 +182,7 @@ class RenderParagraphProxy extends RenderProxyBox
StrutStyle strutStyle,
Locale locale,
TextWidthBasis textWidthBasis,
TextHeightBehavior textHeightBehavior,
TextHeightBehavior? textHeightBehavior,
) : _prototypePainter = TextPainter(
text: TextSpan(text: ' ', style: textStyle),
textAlign: textAlign,
@ -208,8 +197,7 @@ class RenderParagraphProxy extends RenderProxyBox
final TextPainter _prototypePainter;
set textStyle(TextStyle value) {
assert(value != null);
if (_prototypePainter.text.style == value) {
if (_prototypePainter.text!.style == value) {
return;
}
_prototypePainter.text = TextSpan(text: ' ', style: value);
@ -217,7 +205,6 @@ class RenderParagraphProxy extends RenderProxyBox
}
set textAlign(TextAlign value) {
assert(value != null);
if (_prototypePainter.textAlign == value) {
return;
}
@ -226,7 +213,6 @@ class RenderParagraphProxy extends RenderProxyBox
}
set textDirection(TextDirection value) {
assert(value != null);
if (_prototypePainter.textDirection == value) {
return;
}
@ -235,7 +221,6 @@ class RenderParagraphProxy extends RenderProxyBox
}
set textScaleFactor(double value) {
assert(value != null);
if (_prototypePainter.textScaleFactor == value) {
return;
}
@ -244,7 +229,6 @@ class RenderParagraphProxy extends RenderProxyBox
}
set strutStyle(StrutStyle value) {
assert(value != null);
if (_prototypePainter.strutStyle == value) {
return;
}
@ -261,7 +245,6 @@ class RenderParagraphProxy extends RenderProxyBox
}
set textWidthBasis(TextWidthBasis value) {
assert(value != null);
if (_prototypePainter.textWidthBasis == value) {
return;
}
@ -269,7 +252,7 @@ class RenderParagraphProxy extends RenderProxyBox
markNeedsLayout();
}
set textHeightBehavior(TextHeightBehavior value) {
set textHeightBehavior(TextHeightBehavior? value) {
if (_prototypePainter.textHeightBehavior == value) {
return;
}
@ -278,7 +261,7 @@ class RenderParagraphProxy extends RenderProxyBox
}
@override
RenderParagraph get child => super.child;
RenderParagraph? get child => super.child as RenderParagraph?;
@override
double getPreferredLineHeight() {
@ -286,24 +269,24 @@ class RenderParagraphProxy extends RenderProxyBox
}
@override
Offset getOffsetForCaret(TextPosition position, Rect caretPrototype) =>
child.getOffsetForCaret(position, caretPrototype);
Offset getOffsetForCaret(TextPosition position, Rect? caretPrototype) =>
child!.getOffsetForCaret(position, caretPrototype!);
@override
TextPosition getPositionForOffset(Offset offset) =>
child.getPositionForOffset(offset);
child!.getPositionForOffset(offset);
@override
double getFullHeightForCaret(TextPosition position) =>
child.getFullHeightForCaret(position);
double? getFullHeightForCaret(TextPosition position) =>
child!.getFullHeightForCaret(position);
@override
TextRange getWordBoundary(TextPosition position) =>
child.getWordBoundary(position);
child!.getWordBoundary(position);
@override
List<TextBox> getBoxesForSelection(TextSelection selection) =>
child.getBoxesForSelection(selection);
child!.getBoxesForSelection(selection);
@override
performLayout() {

@ -36,23 +36,23 @@ class RawEditor extends StatefulWidget {
final bool scrollable;
final EdgeInsetsGeometry padding;
final bool readOnly;
final String placeholder;
final ValueChanged<String> onLaunchUrl;
final String? placeholder;
final ValueChanged<String>? onLaunchUrl;
final ToolbarOptions toolbarOptions;
final bool showSelectionHandles;
final bool showCursor;
final CursorStyle cursorStyle;
final TextCapitalization textCapitalization;
final double maxHeight;
final double minHeight;
final DefaultStyles customStyles;
final double? maxHeight;
final double? minHeight;
final DefaultStyles? customStyles;
final bool expands;
final bool autoFocus;
final Color selectionColor;
final TextSelectionControls selectionCtrls;
final Brightness keyboardAppearance;
final bool enableInteractiveSelection;
final ScrollPhysics scrollPhysics;
final ScrollPhysics? scrollPhysics;
final EmbedBuilder embedBuilder;
RawEditor(
@ -67,7 +67,7 @@ class RawEditor extends StatefulWidget {
this.onLaunchUrl,
this.toolbarOptions,
this.showSelectionHandles,
bool showCursor,
bool? showCursor,
this.cursorStyle,
this.textCapitalization,
this.maxHeight,
@ -81,26 +81,11 @@ class RawEditor extends StatefulWidget {
this.enableInteractiveSelection,
this.scrollPhysics,
this.embedBuilder)
: assert(controller != null, 'controller cannot be null'),
assert(focusNode != null, 'focusNode cannot be null'),
assert(scrollable || scrollController != null,
'scrollController cannot be null'),
assert(selectionColor != null, 'selectionColor cannot be null'),
assert(enableInteractiveSelection != null,
'enableInteractiveSelection cannot be null'),
assert(showSelectionHandles != null,
'showSelectionHandles cannot be null'),
assert(readOnly != null, 'readOnly cannot be null'),
assert(maxHeight == null || maxHeight > 0, 'maxHeight cannot be null'),
: 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'),
assert(autoFocus != null, 'autoFocus cannot be null'),
assert(toolbarOptions != null, 'toolbarOptions cannot be null'),
showCursor = showCursor ?? !readOnly,
assert(embedBuilder != null, 'embedBuilder cannot be null'),
assert(expands != null, 'expands cannot be null'),
assert(padding != null),
super(key: key);
@override
@ -117,20 +102,20 @@ class RawEditorState extends EditorState
implements TextSelectionDelegate, TextInputClient {
final GlobalKey _editorKey = GlobalKey();
final List<TextEditingValue> _sentRemoteValues = [];
TextInputConnection _textInputConnection;
TextEditingValue _lastKnownRemoteTextEditingValue;
TextInputConnection? _textInputConnection;
TextEditingValue? _lastKnownRemoteTextEditingValue;
int _cursorResetLocation = -1;
bool _wasSelectingVerticallyWithKeyboard = false;
EditorTextSelectionOverlay _selectionOverlay;
FocusAttachment _focusAttachment;
CursorCont _cursorCont;
ScrollController _scrollController;
KeyboardVisibilityController _keyboardVisibilityController;
StreamSubscription<bool> _keyboardVisibilitySubscription;
KeyboardListener _keyboardListener;
EditorTextSelectionOverlay? _selectionOverlay;
FocusAttachment? _focusAttachment;
late CursorCont _cursorCont;
ScrollController? _scrollController;
late KeyboardVisibilityController _keyboardVisibilityController;
late StreamSubscription<bool> _keyboardVisibilitySubscription;
late KeyboardListener _keyboardListener;
bool _didAutoFocus = false;
bool _keyboardVisible = false;
DefaultStyles _styles;
DefaultStyles? _styles;
final ClipboardStatusNotifier _clipboardStatus = ClipboardStatusNotifier();
final LayerLink _toolbarLayerLink = LayerLink();
final LayerLink _startHandleLayerLink = LayerLink();
@ -140,7 +125,6 @@ class RawEditorState extends EditorState
TextDirection get _textDirection {
TextDirection result = Directionality.of(context);
assert(result != null);
return result;
}
@ -154,7 +138,6 @@ class RawEditorState extends EditorState
return;
}
TextSelection selection = widget.controller.selection;
assert(selection != null);
TextSelection newSelection = widget.controller.selection;
@ -210,19 +193,20 @@ class RawEditorState extends EditorState
TextPosition originPosition = TextPosition(
offset: upKey ? selection.baseOffset : selection.extentOffset);
RenderEditableBox child = getRenderEditor().childAtPosition(originPosition);
RenderEditableBox child =
getRenderEditor()!.childAtPosition(originPosition);
TextPosition localPosition = TextPosition(
offset:
originPosition.offset - child.getContainer().getDocumentOffset());
TextPosition position = upKey
TextPosition? position = upKey
? child.getPositionAbove(localPosition)
: child.getPositionBelow(localPosition);
if (position == null) {
var sibling = upKey
? getRenderEditor().childBefore(child)
: getRenderEditor().childAfter(child);
? getRenderEditor()!.childBefore(child)
: getRenderEditor()!.childAfter(child);
if (sibling == null) {
position = TextPosition(offset: upKey ? 0 : plainText.length - 1);
} else {
@ -273,20 +257,20 @@ class RawEditorState extends EditorState
bool shift) {
if (wordModifier) {
if (leftKey) {
TextSelection textSelection = getRenderEditor().selectWordAtPosition(
TextSelection textSelection = getRenderEditor()!.selectWordAtPosition(
TextPosition(
offset: _previousCharacter(
newSelection.extentOffset, plainText, false)));
return newSelection.copyWith(extentOffset: textSelection.baseOffset);
}
TextSelection textSelection = getRenderEditor().selectWordAtPosition(
TextSelection textSelection = getRenderEditor()!.selectWordAtPosition(
TextPosition(
offset:
_nextCharacter(newSelection.extentOffset, plainText, false)));
return newSelection.copyWith(extentOffset: textSelection.extentOffset);
} else if (lineModifier) {
if (leftKey) {
TextSelection textSelection = getRenderEditor().selectLineAtPosition(
TextSelection textSelection = getRenderEditor()!.selectLineAtPosition(
TextPosition(
offset: _previousCharacter(
newSelection.extentOffset, plainText, false)));
@ -294,7 +278,7 @@ class RawEditorState extends EditorState
}
int startPoint = newSelection.extentOffset;
if (startPoint < plainText.length) {
TextSelection textSelection = getRenderEditor()
TextSelection textSelection = getRenderEditor()!
.selectLineAtPosition(TextPosition(offset: startPoint));
return newSelection.copyWith(extentOffset: textSelection.extentOffset);
}
@ -352,7 +336,7 @@ class RawEditorState extends EditorState
}
int count = 0;
int lastNonWhitespace;
int? lastNonWhitespace;
for (String currentString in string.characters) {
if (!includeWhitespace &&
!WHITE_SPACE.contains(
@ -368,7 +352,7 @@ class RawEditorState extends EditorState
}
bool get hasConnection =>
_textInputConnection != null && _textInputConnection.attached;
_textInputConnection != null && _textInputConnection!.attached;
openConnectionIfNeeded() {
if (widget.readOnly) {
@ -390,17 +374,17 @@ class RawEditorState extends EditorState
),
);
_textInputConnection.setEditingState(_lastKnownRemoteTextEditingValue);
_textInputConnection!.setEditingState(_lastKnownRemoteTextEditingValue!);
// _sentRemoteValues.add(_lastKnownRemoteTextEditingValue);
}
_textInputConnection.show();
_textInputConnection!.show();
}
closeConnectionIfNeeded() {
if (!hasConnection) {
return;
}
_textInputConnection.close();
_textInputConnection!.close();
_textInputConnection = null;
_lastKnownRemoteTextEditingValue = null;
_sentRemoteValues.clear();
@ -412,7 +396,7 @@ class RawEditorState extends EditorState
}
TextEditingValue actualValue = textEditingValue.copyWith(
composing: _lastKnownRemoteTextEditingValue.composing,
composing: _lastKnownRemoteTextEditingValue!.composing,
);
if (actualValue == _lastKnownRemoteTextEditingValue) {
@ -420,20 +404,20 @@ class RawEditorState extends EditorState
}
bool shouldRemember =
textEditingValue.text != _lastKnownRemoteTextEditingValue.text;
textEditingValue.text != _lastKnownRemoteTextEditingValue!.text;
_lastKnownRemoteTextEditingValue = actualValue;
_textInputConnection.setEditingState(actualValue);
_textInputConnection!.setEditingState(actualValue);
if (shouldRemember) {
_sentRemoteValues.add(actualValue);
}
}
@override
TextEditingValue get currentTextEditingValue =>
TextEditingValue? get currentTextEditingValue =>
_lastKnownRemoteTextEditingValue;
@override
AutofillScope get currentAutofillScope => null;
AutofillScope? get currentAutofillScope => null;
@override
void updateEditingValue(TextEditingValue value) {
@ -450,13 +434,14 @@ class RawEditorState extends EditorState
return;
}
if (_lastKnownRemoteTextEditingValue.text == value.text &&
_lastKnownRemoteTextEditingValue.selection == value.selection) {
if (_lastKnownRemoteTextEditingValue!.text == value.text &&
_lastKnownRemoteTextEditingValue!.selection == value.selection) {
_lastKnownRemoteTextEditingValue = value;
return;
}
TextEditingValue effectiveLastKnownValue = _lastKnownRemoteTextEditingValue;
TextEditingValue effectiveLastKnownValue =
_lastKnownRemoteTextEditingValue!;
_lastKnownRemoteTextEditingValue = value;
String oldText = effectiveLastKnownValue.text;
String text = value.text;
@ -500,7 +485,7 @@ class RawEditorState extends EditorState
if (!hasConnection) {
return;
}
_textInputConnection.connectionClosedReceived();
_textInputConnection!.connectionClosedReceived();
_textInputConnection = null;
_lastKnownRemoteTextEditingValue = null;
_sentRemoteValues.clear();
@ -509,7 +494,7 @@ class RawEditorState extends EditorState
@override
Widget build(BuildContext context) {
assert(debugCheckHasMediaQuery(context));
_focusAttachment.reparent();
_focusAttachment!.reparent();
super.build(context);
Document _doc = widget.controller.document;
@ -540,9 +525,9 @@ class RawEditorState extends EditorState
if (widget.scrollable) {
EdgeInsets baselinePadding =
EdgeInsets.only(top: _styles.paragraph.verticalSpacing.item1);
EdgeInsets.only(top: _styles!.paragraph!.verticalSpacing.item1);
child = BaselineProxy(
textStyle: _styles.paragraph.style,
textStyle: _styles!.paragraph!.style,
padding: baselinePadding,
child: SingleChildScrollView(
controller: _scrollController,
@ -559,7 +544,7 @@ class RawEditorState extends EditorState
maxHeight: widget.maxHeight ?? double.infinity);
return QuillStyles(
data: _styles,
data: _styles!,
child: MouseRegion(
cursor: SystemMouseCursors.text,
child: Container(
@ -620,7 +605,7 @@ class RawEditorState extends EditorState
line: node,
textDirection: _textDirection,
embedBuilder: widget.embedBuilder,
styles: _styles,
styles: _styles!,
);
EditableTextLine editableTextLine = EditableTextLine(
node,
@ -639,57 +624,52 @@ class RawEditorState extends EditorState
}
Tuple2<double, double> _getVerticalSpacingForLine(
Line line, DefaultStyles defaultStyles) {
Line line, DefaultStyles? defaultStyles) {
Map<String, Attribute> attrs = line.style.attributes;
if (attrs.containsKey(Attribute.header.key)) {
int level = attrs[Attribute.header.key].value;
int? level = attrs[Attribute.header.key]!.value;
switch (level) {
case 1:
return defaultStyles.h1.verticalSpacing;
return defaultStyles!.h1!.verticalSpacing;
case 2:
return defaultStyles.h2.verticalSpacing;
return defaultStyles!.h2!.verticalSpacing;
case 3:
return defaultStyles.h3.verticalSpacing;
return defaultStyles!.h3!.verticalSpacing;
default:
throw ('Invalid level $level');
}
}
return defaultStyles.paragraph.verticalSpacing;
return defaultStyles!.paragraph!.verticalSpacing;
}
Tuple2<double, double> _getVerticalSpacingForBlock(
Block node, DefaultStyles defaultStyles) {
Block node, DefaultStyles? defaultStyles) {
Map<String, Attribute> attrs = node.style.attributes;
if (attrs.containsKey(Attribute.blockQuote.key)) {
return defaultStyles.quote.verticalSpacing;
return defaultStyles!.quote!.verticalSpacing;
} else if (attrs.containsKey(Attribute.codeBlock.key)) {
return defaultStyles.code.verticalSpacing;
return defaultStyles!.code!.verticalSpacing;
} else if (attrs.containsKey(Attribute.indent.key)) {
return defaultStyles.indent.verticalSpacing;
return defaultStyles!.indent!.verticalSpacing;
}
return defaultStyles.lists.verticalSpacing;
return defaultStyles!.lists!.verticalSpacing;
}
@override
void initState() {
super.initState();
_clipboardStatus?.addListener(_onChangedClipboardStatus);
_clipboardStatus.addListener(_onChangedClipboardStatus);
widget.controller.addListener(_didChangeTextEditingValue);
_scrollController = widget.scrollController ?? ScrollController();
_scrollController.addListener(_updateSelectionOverlayForScroll);
_scrollController = widget.scrollController;
_scrollController!.addListener(_updateSelectionOverlayForScroll);
_cursorCont = CursorCont(
show: ValueNotifier<bool>(widget.showCursor ?? false),
style: widget.cursorStyle ??
CursorStyle(
color: Colors.blueAccent,
backgroundColor: Colors.grey,
width: 2.0,
),
show: ValueNotifier<bool>(widget.showCursor),
style: widget.cursorStyle,
tickerProvider: this,
);
@ -716,14 +696,14 @@ class RawEditorState extends EditorState
@override
didChangeDependencies() {
super.didChangeDependencies();
DefaultStyles parentStyles = QuillStyles.getStyles(context, true);
DefaultStyles? parentStyles = QuillStyles.getStyles(context, true);
DefaultStyles defaultStyles = DefaultStyles.getInstance(context);
_styles = (parentStyles != null)
? defaultStyles.merge(parentStyles)
: defaultStyles;
if (widget.customStyles != null) {
_styles = _styles.merge(widget.customStyles);
_styles = _styles!.merge(widget.customStyles!);
}
if (!_didAutoFocus && widget.autoFocus) {
@ -745,11 +725,10 @@ class RawEditorState extends EditorState
updateRemoteValueIfNeeded();
}
if (widget.scrollController != null &&
widget.scrollController != _scrollController) {
_scrollController.removeListener(_updateSelectionOverlayForScroll);
if (widget.scrollController != _scrollController) {
_scrollController!.removeListener(_updateSelectionOverlayForScroll);
_scrollController = widget.scrollController;
_scrollController.addListener(_updateSelectionOverlayForScroll);
_scrollController!.addListener(_updateSelectionOverlayForScroll);
}
if (widget.focusNode != oldWidget.focusNode) {
@ -783,7 +762,6 @@ class RawEditorState extends EditorState
handleDelete(bool forward) {
TextSelection selection = widget.controller.selection;
String plainText = textEditingValue.text;
assert(selection != null);
int cursorPosition = selection.start;
String textBefore = selection.textBefore(plainText);
String textAfter = selection.textAfter(plainText);
@ -811,9 +789,8 @@ class RawEditorState extends EditorState
);
}
Future<void> handleShortcut(InputShortcut shortcut) async {
void handleShortcut(InputShortcut? shortcut) async {
TextSelection selection = widget.controller.selection;
assert(selection != null);
String plainText = textEditingValue.text;
if (shortcut == InputShortcut.COPY) {
if (!selection.isCollapsed) {
@ -842,13 +819,13 @@ class RawEditorState extends EditorState
return;
}
if (shortcut == InputShortcut.PASTE && !widget.readOnly) {
ClipboardData data = await Clipboard.getData(Clipboard.kTextPlain);
ClipboardData? data = await Clipboard.getData(Clipboard.kTextPlain);
if (data != null) {
widget.controller.replaceText(
selection.start,
selection.end - selection.start,
data.text,
TextSelection.collapsed(offset: selection.start + data.text.length),
TextSelection.collapsed(offset: selection.start + data.text!.length),
);
}
return;
@ -874,10 +851,10 @@ class RawEditorState extends EditorState
_selectionOverlay = null;
widget.controller.removeListener(_didChangeTextEditingValue);
widget.focusNode.removeListener(_handleFocusChanged);
_focusAttachment.detach();
_focusAttachment!.detach();
_cursorCont.dispose();
_clipboardStatus?.removeListener(_onChangedClipboardStatus);
_clipboardStatus?.dispose();
_clipboardStatus.removeListener(_onChangedClipboardStatus);
_clipboardStatus.dispose();
super.dispose();
}
@ -909,7 +886,7 @@ class RawEditorState extends EditorState
_cursorCont.startCursorTimer();
}
SchedulerBinding.instance.addPostFrameCallback(
SchedulerBinding.instance!.addPostFrameCallback(
(Duration _) => _updateOrDisposeSelectionOverlayIfNeeded());
if (!mounted) return;
setState(() {
@ -921,9 +898,9 @@ class RawEditorState extends EditorState
_updateOrDisposeSelectionOverlayIfNeeded() {
if (_selectionOverlay != null) {
if (_hasFocus) {
_selectionOverlay.update(textEditingValue);
_selectionOverlay!.update(textEditingValue);
} else {
_selectionOverlay.dispose();
_selectionOverlay!.dispose();
_selectionOverlay = null;
}
} else if (_hasFocus) {
@ -945,8 +922,8 @@ class RawEditorState extends EditorState
DragStartBehavior.start,
null,
_clipboardStatus);
_selectionOverlay.handlesVisible = _shouldShowSelectionHandles();
_selectionOverlay.showHandles();
_selectionOverlay!.handlesVisible = _shouldShowSelectionHandles();
_selectionOverlay!.showHandles();
}
}
}
@ -957,10 +934,10 @@ class RawEditorState extends EditorState
_hasFocus, widget.controller.selection);
_updateOrDisposeSelectionOverlayIfNeeded();
if (_hasFocus) {
WidgetsBinding.instance.addObserver(this);
WidgetsBinding.instance!.addObserver(this);
_showCaretOnScreen();
} else {
WidgetsBinding.instance.removeObserver(this);
WidgetsBinding.instance!.removeObserver(this);
}
updateKeepAlive();
}
@ -981,23 +958,22 @@ class RawEditorState extends EditorState
}
_showCaretOnScreenScheduled = true;
SchedulerBinding.instance.addPostFrameCallback((Duration _) {
SchedulerBinding.instance!.addPostFrameCallback((Duration _) {
_showCaretOnScreenScheduled = false;
final viewport = RenderAbstractViewport.of(getRenderEditor());
assert(viewport != null);
final editorOffset =
getRenderEditor().localToGlobal(Offset(0.0, 0.0), ancestor: viewport);
final offsetInViewport = _scrollController.offset + editorOffset.dy;
final viewport = RenderAbstractViewport.of(getRenderEditor())!;
final editorOffset = getRenderEditor()!
.localToGlobal(Offset(0.0, 0.0), ancestor: viewport);
final offsetInViewport = _scrollController!.offset + editorOffset.dy;
final offset = getRenderEditor().getOffsetToRevealCursor(
_scrollController.position.viewportDimension,
_scrollController.offset,
final offset = getRenderEditor()!.getOffsetToRevealCursor(
_scrollController!.position.viewportDimension,
_scrollController!.offset,
offsetInViewport,
);
if (offset != null) {
_scrollController.animateTo(
_scrollController!.animateTo(
offset,
duration: Duration(milliseconds: 100),
curve: Curves.fastOutSlowIn,
@ -1007,12 +983,12 @@ class RawEditorState extends EditorState
}
@override
RenderEditor getRenderEditor() {
return _editorKey.currentContext.findRenderObject();
RenderEditor? getRenderEditor() {
return _editorKey.currentContext!.findRenderObject() as RenderEditor?;
}
@override
EditorTextSelectionOverlay getSelectionOverlay() {
EditorTextSelectionOverlay? getSelectionOverlay() {
return _selectionOverlay;
}
@ -1068,7 +1044,7 @@ class RawEditorState extends EditorState
);
} else {
final TextEditingValue value = textEditingValue;
final ClipboardData data = await Clipboard.getData(Clipboard.kTextPlain);
final ClipboardData? data = await Clipboard.getData(Clipboard.kTextPlain);
if (data != null) {
final length =
textEditingValue.selection.end - textEditingValue.selection.start;
@ -1081,24 +1057,26 @@ class RawEditorState extends EditorState
// move cursor to the end of pasted text selection
widget.controller.updateSelection(
TextSelection.collapsed(
offset: value.selection.start + data.text.length),
offset: value.selection.start + data.text!.length),
ChangeSource.LOCAL);
}
}
}
Future<bool> __isItCut(TextEditingValue value) async {
final ClipboardData data = await Clipboard.getData(Clipboard.kTextPlain);
return textEditingValue.text.length - value.text.length == data.text.length;
final ClipboardData data = await (Clipboard.getData(Clipboard.kTextPlain)
as FutureOr<ClipboardData>);
return textEditingValue.text.length - value.text.length ==
data.text!.length;
}
@override
bool showToolbar() {
if (_selectionOverlay == null || _selectionOverlay.toolbar != null) {
if (_selectionOverlay == null || _selectionOverlay!.toolbar != null) {
return false;
}
_selectionOverlay.showToolbar();
_selectionOverlay!.showToolbar();
return true;
}
@ -1116,15 +1094,15 @@ class RawEditorState extends EditorState
class _Editor extends MultiChildRenderObjectWidget {
_Editor({
@required Key key,
@required List<Widget> children,
@required this.document,
@required this.textDirection,
@required this.hasFocus,
@required this.selection,
@required this.startHandleLayerLink,
@required this.endHandleLayerLink,
@required this.onSelectionChanged,
required Key key,
required List<Widget> children,
required this.document,
required this.textDirection,
required this.hasFocus,
required this.selection,
required this.startHandleLayerLink,
required this.endHandleLayerLink,
required this.onSelectionChanged,
this.padding = EdgeInsets.zero,
}) : super(key: key, children: children);

@ -2,12 +2,12 @@ import 'package:flutter/material.dart';
class ResponsiveWidget extends StatelessWidget {
final Widget largeScreen;
final Widget mediumScreen;
final Widget smallScreen;
final Widget? mediumScreen;
final Widget? smallScreen;
const ResponsiveWidget(
{Key key,
@required this.largeScreen,
{Key? key,
required this.largeScreen,
this.mediumScreen,
this.smallScreen})
: super(key: key);

@ -53,10 +53,10 @@ class EditableTextBlock extends StatelessWidget {
final Tuple2 verticalSpacing;
final TextSelection textSelection;
final Color color;
final DefaultStyles styles;
final DefaultStyles? styles;
final bool enableInteractiveSelection;
final bool hasFocus;
final EdgeInsets contentPadding;
final EdgeInsets? contentPadding;
final EmbedBuilder embedBuilder;
final CursorCont cursorCont;
final Map<int, int> indentLevelCounts;
@ -82,35 +82,35 @@ class EditableTextBlock extends StatelessWidget {
Widget build(BuildContext context) {
assert(debugCheckHasMediaQuery(context));
DefaultStyles defaultStyles = QuillStyles.getStyles(context, false);
DefaultStyles? defaultStyles = QuillStyles.getStyles(context, false);
return _EditableBlock(
block,
textDirection,
verticalSpacing,
verticalSpacing as Tuple2<double, double>,
_getDecorationForBlock(block, defaultStyles) ?? BoxDecoration(),
contentPadding,
_buildChildren(context, this.indentLevelCounts));
}
BoxDecoration _getDecorationForBlock(
Block node, DefaultStyles defaultStyles) {
BoxDecoration? _getDecorationForBlock(
Block node, DefaultStyles? defaultStyles) {
Map<String, Attribute> attrs = block.style.attributes;
if (attrs.containsKey(Attribute.blockQuote.key)) {
return defaultStyles.quote.decoration;
return defaultStyles!.quote!.decoration;
}
if (attrs.containsKey(Attribute.codeBlock.key)) {
return defaultStyles.code.decoration;
return defaultStyles!.code!.decoration;
}
return null;
}
List<Widget> _buildChildren(
BuildContext context, Map<int, int> indentLevelCounts) {
DefaultStyles defaultStyles = QuillStyles.getStyles(context, false);
DefaultStyles? defaultStyles = QuillStyles.getStyles(context, false);
int count = block.children.length;
var children = <Widget>[];
int index = 0;
for (Line line in block.children) {
for (Line line in block.children as Iterable<Line>) {
index++;
EditableTextLine editableTextLine = EditableTextLine(
line,
@ -119,7 +119,7 @@ class EditableTextBlock extends StatelessWidget {
line: line,
textDirection: textDirection,
embedBuilder: embedBuilder,
styles: styles,
styles: styles!,
),
_getIndentWidth(),
_getSpacingForLine(line, index, count, defaultStyles),
@ -135,16 +135,16 @@ class EditableTextBlock extends StatelessWidget {
return children.toList(growable: false);
}
Widget _buildLeading(BuildContext context, Line line, int index,
Widget? _buildLeading(BuildContext context, Line line, int index,
Map<int, int> indentLevelCounts, int count) {
DefaultStyles defaultStyles = QuillStyles.getStyles(context, false);
DefaultStyles? defaultStyles = QuillStyles.getStyles(context, false);
Map<String, Attribute> attrs = line.style.attributes;
if (attrs[Attribute.list.key] == Attribute.ol) {
return _NumberPoint(
index: index,
indentLevelCounts: indentLevelCounts,
count: count,
style: defaultStyles.paragraph.style,
style: defaultStyles!.paragraph!.style,
attrs: attrs,
width: 32.0,
padding: 8.0,
@ -154,19 +154,19 @@ class EditableTextBlock extends StatelessWidget {
if (attrs[Attribute.list.key] == Attribute.ul) {
return _BulletPoint(
style:
defaultStyles.paragraph.style.copyWith(fontWeight: FontWeight.bold),
defaultStyles!.paragraph!.style.copyWith(fontWeight: FontWeight.bold),
width: 32,
);
}
if (attrs[Attribute.list.key] == Attribute.checked) {
return _Checkbox(
style: defaultStyles.paragraph.style, width: 32, isChecked: true);
style: defaultStyles!.paragraph!.style, width: 32, isChecked: true);
}
if (attrs[Attribute.list.key] == Attribute.unchecked) {
return _Checkbox(
style: defaultStyles.paragraph.style, width: 32, isChecked: false);
style: defaultStyles!.paragraph!.style, width: 32, isChecked: false);
}
if (attrs.containsKey(Attribute.codeBlock.key)) {
@ -174,8 +174,8 @@ class EditableTextBlock extends StatelessWidget {
index: index,
indentLevelCounts: indentLevelCounts,
count: count,
style: defaultStyles.code.style
.copyWith(color: defaultStyles.code.style.color.withOpacity(0.4)),
style: defaultStyles!.code!.style
.copyWith(color: defaultStyles.code!.style.color!.withOpacity(0.4)),
width: 32.0,
attrs: attrs,
padding: 16.0,
@ -188,7 +188,7 @@ class EditableTextBlock extends StatelessWidget {
double _getIndentWidth() {
Map<String, Attribute> attrs = block.style.attributes;
Attribute indent = attrs[Attribute.indent.key];
Attribute? indent = attrs[Attribute.indent.key];
double extraIndent = 0.0;
if (indent != null && indent.value != null) {
extraIndent = 16.0 * indent.value;
@ -202,40 +202,40 @@ class EditableTextBlock extends StatelessWidget {
}
Tuple2 _getSpacingForLine(
Line node, int index, int count, DefaultStyles defaultStyles) {
Line node, int index, int count, DefaultStyles? defaultStyles) {
double top = 0.0, bottom = 0.0;
Map<String, Attribute> attrs = block.style.attributes;
if (attrs.containsKey(Attribute.header.key)) {
int level = attrs[Attribute.header.key].value;
int? level = attrs[Attribute.header.key]!.value;
switch (level) {
case 1:
top = defaultStyles.h1.verticalSpacing.item1;
bottom = defaultStyles.h1.verticalSpacing.item2;
top = defaultStyles!.h1!.verticalSpacing.item1;
bottom = defaultStyles.h1!.verticalSpacing.item2;
break;
case 2:
top = defaultStyles.h2.verticalSpacing.item1;
bottom = defaultStyles.h2.verticalSpacing.item2;
top = defaultStyles!.h2!.verticalSpacing.item1;
bottom = defaultStyles.h2!.verticalSpacing.item2;
break;
case 3:
top = defaultStyles.h3.verticalSpacing.item1;
bottom = defaultStyles.h3.verticalSpacing.item2;
top = defaultStyles!.h3!.verticalSpacing.item1;
bottom = defaultStyles.h3!.verticalSpacing.item2;
break;
default:
throw ('Invalid level $level');
}
} else {
Tuple2 lineSpacing;
late Tuple2 lineSpacing;
if (attrs.containsKey(Attribute.blockQuote.key)) {
lineSpacing = defaultStyles.quote.lineSpacing;
lineSpacing = defaultStyles!.quote!.lineSpacing;
} else if (attrs.containsKey(Attribute.indent.key)) {
lineSpacing = defaultStyles.indent.lineSpacing;
lineSpacing = defaultStyles!.indent!.lineSpacing;
} else if (attrs.containsKey(Attribute.list.key)) {
lineSpacing = defaultStyles.lists.lineSpacing;
lineSpacing = defaultStyles!.lists!.lineSpacing;
} else if (attrs.containsKey(Attribute.codeBlock.key)) {
lineSpacing = defaultStyles.code.lineSpacing;
lineSpacing = defaultStyles!.code!.lineSpacing;
} else if (attrs.containsKey(Attribute.align.key)) {
lineSpacing = defaultStyles.align.lineSpacing;
lineSpacing = defaultStyles!.align!.lineSpacing;
}
top = lineSpacing.item1;
bottom = lineSpacing.item2;
@ -256,11 +256,11 @@ class EditableTextBlock extends StatelessWidget {
class RenderEditableTextBlock extends RenderEditableContainerBox
implements RenderEditableBox {
RenderEditableTextBlock({
List<RenderEditableBox> children,
@required Block block,
@required TextDirection textDirection,
@required EdgeInsetsGeometry padding,
@required Decoration decoration,
List<RenderEditableBox>? children,
required Block block,
required TextDirection textDirection,
required EdgeInsetsGeometry padding,
required Decoration decoration,
ImageConfiguration configuration = ImageConfiguration.empty,
EdgeInsets contentPadding = EdgeInsets.zero,
}) : assert(block != null),
@ -295,7 +295,7 @@ class RenderEditableTextBlock extends RenderEditableContainerBox
_savedPadding = value;
}
BoxPainter _painter;
BoxPainter? _painter;
Decoration get decoration => _decoration;
Decoration _decoration;
@ -344,8 +344,8 @@ class RenderEditableTextBlock extends RenderEditableContainerBox
@override
TextPosition getPositionForOffset(Offset offset) {
RenderEditableBox child = childAtOffset(offset);
BoxParentData parentData = child.parentData;
RenderEditableBox child = childAtOffset(offset)!;
BoxParentData parentData = child.parentData as BoxParentData;
TextPosition localPosition =
child.getPositionForOffset(offset - parentData.offset);
return TextPosition(
@ -367,19 +367,19 @@ class RenderEditableTextBlock extends RenderEditableContainerBox
}
@override
TextPosition getPositionAbove(TextPosition position) {
TextPosition? getPositionAbove(TextPosition position) {
assert(position.offset < getContainer().length);
RenderEditableBox child = childAtPosition(position);
TextPosition childLocalPosition = TextPosition(
offset: position.offset - child.getContainer().getOffset());
TextPosition result = child.getPositionAbove(childLocalPosition);
TextPosition? result = child.getPositionAbove(childLocalPosition);
if (result != null) {
return TextPosition(
offset: result.offset + child.getContainer().getOffset());
}
RenderEditableBox sibling = childBefore(child);
RenderEditableBox? sibling = childBefore(child);
if (sibling == null) {
return null;
}
@ -395,19 +395,19 @@ class RenderEditableTextBlock extends RenderEditableContainerBox
}
@override
TextPosition getPositionBelow(TextPosition position) {
TextPosition? getPositionBelow(TextPosition position) {
assert(position.offset < getContainer().length);
RenderEditableBox child = childAtPosition(position);
TextPosition childLocalPosition = TextPosition(
offset: position.offset - child.getContainer().getOffset());
TextPosition result = child.getPositionBelow(childLocalPosition);
TextPosition? result = child.getPositionBelow(childLocalPosition);
if (result != null) {
return TextPosition(
offset: result.offset + child.getContainer().getOffset());
}
RenderEditableBox sibling = childAfter(child);
RenderEditableBox? sibling = childAfter(child);
if (sibling == null) {
return null;
}
@ -436,7 +436,7 @@ class RenderEditableTextBlock extends RenderEditableContainerBox
null);
}
Node baseNode = getContainer().queryChild(selection.start, false).node;
Node? baseNode = getContainer().queryChild(selection.start, false).node;
var baseChild = firstChild;
while (baseChild != null) {
if (baseChild.getContainer() == baseNode) {
@ -446,7 +446,7 @@ class RenderEditableTextBlock extends RenderEditableContainerBox
}
assert(baseChild != null);
TextSelectionPoint basePoint = baseChild.getBaseEndpointForSelection(
TextSelectionPoint basePoint = baseChild!.getBaseEndpointForSelection(
localSelection(baseChild.getContainer(), selection, true));
return TextSelectionPoint(
basePoint.point + (baseChild.parentData as BoxParentData).offset,
@ -462,7 +462,7 @@ class RenderEditableTextBlock extends RenderEditableContainerBox
null);
}
Node extentNode = getContainer().queryChild(selection.end, false).node;
Node? extentNode = getContainer().queryChild(selection.end, false).node;
var extentChild = firstChild;
while (extentChild != null) {
@ -473,7 +473,7 @@ class RenderEditableTextBlock extends RenderEditableContainerBox
}
assert(extentChild != null);
TextSelectionPoint extentPoint = extentChild.getExtentEndpointForSelection(
TextSelectionPoint extentPoint = extentChild!.getExtentEndpointForSelection(
localSelection(extentChild.getContainer(), selection, true));
return TextSelectionPoint(
extentPoint.point + (extentChild.parentData as BoxParentData).offset,
@ -499,7 +499,7 @@ class RenderEditableTextBlock extends RenderEditableContainerBox
assert(size.height != null);
_painter ??= _decoration.createBoxPainter(markNeedsPaint);
EdgeInsets decorationPadding = resolvedPadding - _contentPadding;
EdgeInsets decorationPadding = resolvedPadding! - _contentPadding;
ImageConfiguration filledConfiguration =
configuration.copyWith(size: decorationPadding.deflateSize(size));
@ -507,7 +507,7 @@ class RenderEditableTextBlock extends RenderEditableContainerBox
final decorationOffset =
offset.translate(decorationPadding.left, decorationPadding.top);
_painter.paint(context.canvas, decorationOffset, filledConfiguration);
_painter!.paint(context.canvas, decorationOffset, filledConfiguration);
if (debugSaveCount != context.canvas.getSaveCount()) {
throw ('${_decoration.runtimeType} painter had mismatching save and restore calls.');
}
@ -517,7 +517,7 @@ class RenderEditableTextBlock extends RenderEditableContainerBox
}
@override
bool hitTestChildren(BoxHitTestResult result, {Offset position}) {
bool hitTestChildren(BoxHitTestResult result, {required Offset position}) {
return defaultHitTestChildren(result, position: position);
}
}
@ -527,7 +527,7 @@ class _EditableBlock extends MultiChildRenderObjectWidget {
final TextDirection textDirection;
final Tuple2<double, double> padding;
final Decoration decoration;
final EdgeInsets contentPadding;
final EdgeInsets? contentPadding;
_EditableBlock(this.block, this.textDirection, this.padding, this.decoration,
this.contentPadding, List<Widget> children)
@ -567,7 +567,7 @@ class _EditableBlock extends MultiChildRenderObjectWidget {
class _NumberPoint extends StatelessWidget {
final int index;
final Map<int, int> indentLevelCounts;
final Map<int?, int> indentLevelCounts;
final int count;
final TextStyle style;
final double width;
@ -576,13 +576,13 @@ class _NumberPoint extends StatelessWidget {
final double padding;
const _NumberPoint({
Key key,
@required this.index,
@required this.indentLevelCounts,
@required this.count,
@required this.style,
@required this.width,
@required this.attrs,
Key? key,
required this.index,
required this.indentLevelCounts,
required this.count,
required this.style,
required this.width,
required this.attrs,
this.withDot = true,
this.padding = 0.0,
}) : super(key: key);
@ -590,7 +590,7 @@ class _NumberPoint extends StatelessWidget {
@override
Widget build(BuildContext context) {
String s = this.index.toString();
int level = 0;
int? level = 0;
if (!this.attrs.containsKey(Attribute.indent.key) &&
!this.indentLevelCounts.containsKey(1)) {
this.indentLevelCounts.clear();
@ -602,13 +602,13 @@ class _NumberPoint extends StatelessWidget {
);
}
if (this.attrs.containsKey(Attribute.indent.key)) {
level = this.attrs[Attribute.indent.key].value;
level = this.attrs[Attribute.indent.key]!.value;
} else {
// first level but is back from previous indent level
// supposed to be "2."
this.indentLevelCounts[0] = 1;
}
if (this.indentLevelCounts.containsKey(level + 1)) {
if (this.indentLevelCounts.containsKey(level! + 1)) {
// last visited level is done, going up
this.indentLevelCounts.remove(level + 1);
}
@ -674,9 +674,9 @@ class _BulletPoint extends StatelessWidget {
final double width;
const _BulletPoint({
Key key,
@required this.style,
@required this.width,
Key? key,
required this.style,
required this.width,
}) : super(key: key);
@override
@ -691,23 +691,23 @@ class _BulletPoint extends StatelessWidget {
}
class _Checkbox extends StatefulWidget {
final TextStyle style;
final double width;
final bool isChecked;
final TextStyle? style;
final double? width;
final bool? isChecked;
const _Checkbox({Key key, this.style, this.width, this.isChecked})
const _Checkbox({Key? key, this.style, this.width, this.isChecked})
: super(key: key);
@override
__CheckboxState createState() => __CheckboxState();
}
class __CheckboxState extends State<_Checkbox> {
bool isChecked;
bool? isChecked;
void _onCheckboxClicked(bool newValue) => setState(() {
void _onCheckboxClicked(bool? newValue) => setState(() {
isChecked = newValue;
if (isChecked) {
if (isChecked!) {
// check list
} else {
// uncheck list

@ -23,16 +23,17 @@ import 'delegate.dart';
class TextLine extends StatelessWidget {
final Line line;
final TextDirection textDirection;
final TextDirection? textDirection;
final EmbedBuilder embedBuilder;
final DefaultStyles styles;
const TextLine(
{Key key, this.line, this.textDirection, this.embedBuilder, this.styles})
: assert(line != null),
assert(embedBuilder != null),
assert(styles != null),
super(key: key);
{Key? key,
required this.line,
this.textDirection,
required this.embedBuilder,
required this.styles})
: super(key: key);
@override
Widget build(BuildContext context) {
@ -45,7 +46,7 @@ class TextLine extends StatelessWidget {
TextSpan textSpan = _buildTextSpan(context);
StrutStyle strutStyle =
StrutStyle.fromTextStyle(textSpan.style, forceStrutHeight: true);
StrutStyle.fromTextStyle(textSpan.style!, forceStrutHeight: true);
final textAlign = _getTextAlign();
RichText child = RichText(
text: TextSpan(children: [textSpan]),
@ -56,9 +57,9 @@ class TextLine extends StatelessWidget {
);
return RichTextProxy(
child,
textSpan.style,
textSpan.style!,
textAlign,
textDirection,
textDirection!,
1.0,
Localizations.localeOf(context),
strutStyle,
@ -89,27 +90,27 @@ class TextLine extends StatelessWidget {
TextStyle textStyle = TextStyle();
if (line.style.containsKey(Attribute.placeholder.key)) {
textStyle = defaultStyles.placeHolder.style;
textStyle = defaultStyles.placeHolder!.style;
return TextSpan(children: children, style: textStyle);
}
Attribute header = line.style.attributes[Attribute.header.key];
Attribute? header = line.style.attributes[Attribute.header.key];
Map<Attribute, TextStyle> m = {
Attribute.h1: defaultStyles.h1.style,
Attribute.h2: defaultStyles.h2.style,
Attribute.h3: defaultStyles.h3.style,
Attribute.h1: defaultStyles.h1!.style,
Attribute.h2: defaultStyles.h2!.style,
Attribute.h3: defaultStyles.h3!.style,
};
textStyle = textStyle.merge(m[header] ?? defaultStyles.paragraph.style);
textStyle = textStyle.merge(m[header!] ?? defaultStyles.paragraph!.style);
Attribute block = line.style.getBlockExceptHeader();
TextStyle toMerge;
Attribute? block = line.style.getBlockExceptHeader();
TextStyle? toMerge;
if (block == Attribute.blockQuote) {
toMerge = defaultStyles.quote.style;
toMerge = defaultStyles.quote!.style;
} else if (block == Attribute.codeBlock) {
toMerge = defaultStyles.code.style;
toMerge = defaultStyles.code!.style;
} else if (block != null) {
toMerge = defaultStyles.lists.style;
toMerge = defaultStyles.lists!.style;
}
textStyle = textStyle.merge(toMerge);
@ -122,7 +123,7 @@ class TextLine extends StatelessWidget {
Style style = textNode.style;
TextStyle res = TextStyle();
Map<String, TextStyle> m = {
Map<String, TextStyle?> m = {
Attribute.bold.key: defaultStyles.bold,
Attribute.italic.key: defaultStyles.italic,
Attribute.link.key: defaultStyles.link,
@ -131,16 +132,16 @@ class TextLine extends StatelessWidget {
};
m.forEach((k, s) {
if (style.values.any((v) => v.key == k)) {
res = _merge(res, s);
res = _merge(res, s!);
}
});
Attribute font = textNode.style.attributes[Attribute.font.key];
Attribute? font = textNode.style.attributes[Attribute.font.key];
if (font != null && font.value != null) {
res = res.merge(TextStyle(fontFamily: font.value));
}
Attribute size = textNode.style.attributes[Attribute.size.key];
Attribute? size = textNode.style.attributes[Attribute.size.key];
if (size != null && size.value != null) {
switch (size.value) {
case 'small':
@ -153,7 +154,7 @@ class TextLine extends StatelessWidget {
res = res.merge(defaultStyles.sizeHuge);
break;
default:
double fontSize = double.tryParse(size.value);
double? fontSize = double.tryParse(size.value);
if (fontSize != null) {
res = res.merge(TextStyle(fontSize: fontSize));
} else {
@ -162,13 +163,13 @@ class TextLine extends StatelessWidget {
}
}
Attribute color = textNode.style.attributes[Attribute.color.key];
Attribute? color = textNode.style.attributes[Attribute.color.key];
if (color != null && color.value != null) {
final textColor = stringToColor(color.value);
res = res.merge(new TextStyle(color: textColor));
}
Attribute background = textNode.style.attributes[Attribute.background.key];
Attribute? background = textNode.style.attributes[Attribute.background.key];
if (background != null && background.value != null) {
final backgroundColor = stringToColor(background.value);
res = res.merge(new TextStyle(backgroundColor: backgroundColor));
@ -178,20 +179,22 @@ class TextLine extends StatelessWidget {
}
TextStyle _merge(TextStyle a, TextStyle b) {
final decorations = <TextDecoration>[];
final decorations = <TextDecoration?>[];
if (a.decoration != null) {
decorations.add(a.decoration);
}
if (b.decoration != null) {
decorations.add(b.decoration);
}
return a.merge(b).apply(decoration: TextDecoration.combine(decorations));
return a.merge(b).apply(
decoration:
TextDecoration.combine(decorations as List<TextDecoration>));
}
}
class EditableTextLine extends RenderObjectWidget {
final Line line;
final Widget leading;
final Widget? leading;
final Widget body;
final double indentWidth;
final Tuple2 verticalSpacing;
@ -215,14 +218,7 @@ class EditableTextLine extends RenderObjectWidget {
this.enableInteractiveSelection,
this.hasFocus,
this.devicePixelRatio,
this.cursorCont)
: assert(line != null),
assert(indentWidth != null),
assert(textSelection != null),
assert(color != null),
assert(enableInteractiveSelection != null),
assert(hasFocus != null),
assert(cursorCont != null);
this.cursorCont);
@override
RenderObjectElement createElement() {
@ -268,8 +264,8 @@ class EditableTextLine extends RenderObjectWidget {
enum TextLineSlot { LEADING, BODY }
class RenderEditableTextLine extends RenderEditableBox {
RenderBox _leading;
RenderContentProxyBox _body;
RenderBox? _leading;
RenderContentProxyBox? _body;
Line line;
TextDirection textDirection;
TextSelection textSelection;
@ -279,10 +275,10 @@ class RenderEditableTextLine extends RenderEditableBox {
double devicePixelRatio;
EdgeInsetsGeometry padding;
CursorCont cursorCont;
EdgeInsets _resolvedPadding;
bool _containsCursor;
List<TextBox> _selectedRects;
Rect _caretPrototype;
EdgeInsets? _resolvedPadding;
bool? _containsCursor;
List<TextBox>? _selectedRects;
Rect? _caretPrototype;
final Map<TextLineSlot, RenderBox> children = <TextLineSlot, RenderBox>{};
RenderEditableTextLine(
@ -294,26 +290,18 @@ class RenderEditableTextLine extends RenderEditableBox {
this.devicePixelRatio,
this.padding,
this.color,
this.cursorCont)
: assert(line != null),
assert(padding != null),
assert(padding.isNonNegative),
assert(devicePixelRatio != null),
assert(hasFocus != null),
assert(color != null),
assert(cursorCont != null);
this.cursorCont);
Iterable<RenderBox> get _children sync* {
if (_leading != null) {
yield _leading;
yield _leading!;
}
if (_body != null) {
yield _body;
yield _body!;
}
}
setCursorCont(CursorCont c) {
assert(c != null);
if (cursorCont == c) {
return;
}
@ -383,7 +371,6 @@ class RenderEditableTextLine extends RenderEditableBox {
}
setLine(Line l) {
assert(l != null);
if (line == l) {
return;
}
@ -393,7 +380,6 @@ class RenderEditableTextLine extends RenderEditableBox {
}
setPadding(EdgeInsetsGeometry p) {
assert(p != null);
assert(p.isNonNegative);
if (padding == p) {
return;
@ -403,12 +389,12 @@ class RenderEditableTextLine extends RenderEditableBox {
markNeedsLayout();
}
setLeading(RenderBox l) {
setLeading(RenderBox? l) {
_leading = _updateChild(_leading, l, TextLineSlot.LEADING);
}
setBody(RenderContentProxyBox b) {
_body = _updateChild(_body, b, TextLineSlot.BODY);
setBody(RenderContentProxyBox? b) {
_body = _updateChild(_body, b, TextLineSlot.BODY) as RenderContentProxyBox?;
}
bool containsTextSelection() {
@ -421,7 +407,8 @@ class RenderEditableTextLine extends RenderEditableBox {
line.containsOffset(textSelection.baseOffset);
}
RenderBox _updateChild(RenderBox old, RenderBox newChild, TextLineSlot slot) {
RenderBox? _updateChild(
RenderBox? old, RenderBox? newChild, TextLineSlot slot) {
if (old != null) {
dropChild(old);
children.remove(slot);
@ -434,10 +421,10 @@ class RenderEditableTextLine extends RenderEditableBox {
}
List<TextBox> _getBoxes(TextSelection textSelection) {
BoxParentData parentData = _body.parentData as BoxParentData;
return _body.getBoxesForSelection(textSelection).map((box) {
BoxParentData? parentData = _body!.parentData as BoxParentData?;
return _body!.getBoxesForSelection(textSelection).map((box) {
return TextBox.fromLTRBD(
box.left + parentData.offset.dx,
box.left + parentData!.offset.dx,
box.top + parentData.offset.dy,
box.right + parentData.offset.dx,
box.bottom + parentData.offset.dy,
@ -451,7 +438,7 @@ class RenderEditableTextLine extends RenderEditableBox {
return;
}
_resolvedPadding = padding.resolve(textDirection);
assert(_resolvedPadding.isNonNegative);
assert(_resolvedPadding!.isNonNegative);
}
@override
@ -498,26 +485,26 @@ class RenderEditableTextLine extends RenderEditableBox {
@override
Offset getOffsetForCaret(TextPosition position) {
return _body.getOffsetForCaret(position, _caretPrototype) +
(_body.parentData as BoxParentData).offset;
return _body!.getOffsetForCaret(position, _caretPrototype) +
(_body!.parentData as BoxParentData).offset;
}
@override
TextPosition getPositionAbove(TextPosition position) {
TextPosition? getPositionAbove(TextPosition position) {
return _getPosition(position, -0.5);
}
@override
TextPosition getPositionBelow(TextPosition position) {
TextPosition? getPositionBelow(TextPosition position) {
return _getPosition(position, 1.5);
}
TextPosition _getPosition(TextPosition textPosition, double dyScale) {
TextPosition? _getPosition(TextPosition textPosition, double dyScale) {
assert(textPosition.offset < line.length);
Offset offset = getOffsetForCaret(textPosition)
.translate(0, dyScale * preferredLineHeight(textPosition));
if (_body.size
.contains(offset - (_body.parentData as BoxParentData).offset)) {
if (_body!.size
.contains(offset - (_body!.parentData as BoxParentData).offset)) {
return getPositionForOffset(offset);
}
return null;
@ -525,18 +512,18 @@ class RenderEditableTextLine extends RenderEditableBox {
@override
TextPosition getPositionForOffset(Offset offset) {
return _body.getPositionForOffset(
offset - (_body.parentData as BoxParentData).offset);
return _body!.getPositionForOffset(
offset - (_body!.parentData as BoxParentData).offset);
}
@override
TextRange getWordBoundary(TextPosition position) {
return _body.getWordBoundary(position);
return _body!.getWordBoundary(position);
}
@override
double preferredLineHeight(TextPosition position) {
return _body.getPreferredLineHeight();
return _body!.getPreferredLineHeight();
}
@override
@ -550,7 +537,6 @@ class RenderEditableTextLine extends RenderEditableBox {
cursorCont.style.height ?? preferredLineHeight(TextPosition(offset: 0));
_computeCaretPrototype() {
assert(defaultTargetPlatform != null);
switch (defaultTargetPlatform) {
case TargetPlatform.iOS:
case TargetPlatform.macOS:
@ -606,7 +592,7 @@ class RenderEditableTextLine extends RenderEditableBox {
@override
List<DiagnosticsNode> debugDescribeChildren() {
var value = <DiagnosticsNode>[];
void add(RenderBox child, String name) {
void add(RenderBox? child, String name) {
if (child != null) {
value.add(child.toDiagnosticsNode(name: name));
}
@ -623,38 +609,40 @@ class RenderEditableTextLine extends RenderEditableBox {
@override
double computeMinIntrinsicWidth(double height) {
_resolvePadding();
double horizontalPadding = _resolvedPadding.left + _resolvedPadding.right;
double verticalPadding = _resolvedPadding.top + _resolvedPadding.bottom;
double horizontalPadding = _resolvedPadding!.left + _resolvedPadding!.right;
double verticalPadding = _resolvedPadding!.top + _resolvedPadding!.bottom;
int leadingWidth = _leading == null
? 0
: _leading.getMinIntrinsicWidth(height - verticalPadding);
: _leading!.getMinIntrinsicWidth(height - verticalPadding) as int;
int bodyWidth = _body == null
? 0
: _body.getMinIntrinsicWidth(math.max(0.0, height - verticalPadding));
: _body!.getMinIntrinsicWidth(math.max(0.0, height - verticalPadding))
as int;
return horizontalPadding + leadingWidth + bodyWidth;
}
@override
double computeMaxIntrinsicWidth(double height) {
_resolvePadding();
double horizontalPadding = _resolvedPadding.left + _resolvedPadding.right;
double verticalPadding = _resolvedPadding.top + _resolvedPadding.bottom;
double horizontalPadding = _resolvedPadding!.left + _resolvedPadding!.right;
double verticalPadding = _resolvedPadding!.top + _resolvedPadding!.bottom;
int leadingWidth = _leading == null
? 0
: _leading.getMaxIntrinsicWidth(height - verticalPadding);
: _leading!.getMaxIntrinsicWidth(height - verticalPadding) as int;
int bodyWidth = _body == null
? 0
: _body.getMaxIntrinsicWidth(math.max(0.0, height - verticalPadding));
: _body!.getMaxIntrinsicWidth(math.max(0.0, height - verticalPadding))
as int;
return horizontalPadding + leadingWidth + bodyWidth;
}
@override
double computeMinIntrinsicHeight(double width) {
_resolvePadding();
double horizontalPadding = _resolvedPadding.left + _resolvedPadding.right;
double verticalPadding = _resolvedPadding.top + _resolvedPadding.bottom;
double horizontalPadding = _resolvedPadding!.left + _resolvedPadding!.right;
double verticalPadding = _resolvedPadding!.top + _resolvedPadding!.bottom;
if (_body != null) {
return _body
return _body!
.getMinIntrinsicHeight(math.max(0.0, width - horizontalPadding)) +
verticalPadding;
}
@ -664,10 +652,10 @@ class RenderEditableTextLine extends RenderEditableBox {
@override
double computeMaxIntrinsicHeight(double width) {
_resolvePadding();
double horizontalPadding = _resolvedPadding.left + _resolvedPadding.right;
double verticalPadding = _resolvedPadding.top + _resolvedPadding.bottom;
double horizontalPadding = _resolvedPadding!.left + _resolvedPadding!.right;
double verticalPadding = _resolvedPadding!.top + _resolvedPadding!.bottom;
if (_body != null) {
return _body
return _body!
.getMaxIntrinsicHeight(math.max(0.0, width - horizontalPadding)) +
verticalPadding;
}
@ -677,7 +665,8 @@ class RenderEditableTextLine extends RenderEditableBox {
@override
double computeDistanceToActualBaseline(TextBaseline baseline) {
_resolvePadding();
return _body.getDistanceToActualBaseline(baseline) + _resolvedPadding.top;
return _body!.getDistanceToActualBaseline(baseline)! +
_resolvedPadding!.top;
}
@override
@ -690,34 +679,35 @@ class RenderEditableTextLine extends RenderEditableBox {
if (_body == null && _leading == null) {
size = constraints.constrain(Size(
_resolvedPadding.left + _resolvedPadding.right,
_resolvedPadding.top + _resolvedPadding.bottom,
_resolvedPadding!.left + _resolvedPadding!.right,
_resolvedPadding!.top + _resolvedPadding!.bottom,
));
return;
}
final innerConstraints = constraints.deflate(_resolvedPadding);
final innerConstraints = constraints.deflate(_resolvedPadding!);
final indentWidth = textDirection == TextDirection.ltr
? _resolvedPadding.left
: _resolvedPadding.right;
? _resolvedPadding!.left
: _resolvedPadding!.right;
_body.layout(innerConstraints, parentUsesSize: true);
final bodyParentData = _body.parentData as BoxParentData;
bodyParentData.offset = Offset(_resolvedPadding.left, _resolvedPadding.top);
_body!.layout(innerConstraints, parentUsesSize: true);
final bodyParentData = _body!.parentData as BoxParentData;
bodyParentData.offset =
Offset(_resolvedPadding!.left, _resolvedPadding!.top);
if (_leading != null) {
final leadingConstraints = innerConstraints.copyWith(
minWidth: indentWidth,
maxWidth: indentWidth,
maxHeight: _body.size.height);
_leading.layout(leadingConstraints, parentUsesSize: true);
final parentData = _leading.parentData as BoxParentData;
parentData.offset = Offset(0.0, _resolvedPadding.top);
maxHeight: _body!.size.height);
_leading!.layout(leadingConstraints, parentUsesSize: true);
final parentData = _leading!.parentData as BoxParentData;
parentData.offset = Offset(0.0, _resolvedPadding!.top);
}
size = constraints.constrain(Size(
_resolvedPadding.left + _body.size.width + _resolvedPadding.right,
_resolvedPadding.top + _body.size.height + _resolvedPadding.bottom,
_resolvedPadding!.left + _body!.size.width + _resolvedPadding!.right,
_resolvedPadding!.top + _body!.size.height + _resolvedPadding!.bottom,
));
_computeCaretPrototype();
@ -734,19 +724,19 @@ class RenderEditableTextLine extends RenderEditableBox {
@override
paint(PaintingContext context, Offset offset) {
if (_leading != null) {
final parentData = _leading.parentData as BoxParentData;
final parentData = _leading!.parentData as BoxParentData;
final effectiveOffset = offset + parentData.offset;
context.paintChild(_leading, effectiveOffset);
context.paintChild(_leading!, effectiveOffset);
}
if (_body != null) {
final parentData = _body.parentData as BoxParentData;
final parentData = _body!.parentData as BoxParentData;
final effectiveOffset = offset + parentData.offset;
if ((enableInteractiveSelection ?? true) &&
if ((enableInteractiveSelection) &&
line.getDocumentOffset() <= textSelection.end &&
textSelection.start <= line.getDocumentOffset() + line.length - 1) {
final local = localSelection(line, textSelection, false);
_selectedRects ??= _body.getBoxesForSelection(
_selectedRects ??= _body!.getBoxesForSelection(
local,
);
_paintSelection(context, effectiveOffset);
@ -759,7 +749,7 @@ class RenderEditableTextLine extends RenderEditableBox {
_paintCursor(context, effectiveOffset);
}
context.paintChild(_body, effectiveOffset);
context.paintChild(_body!, effectiveOffset);
if (hasFocus &&
cursorCont.show.value &&
@ -773,7 +763,7 @@ class RenderEditableTextLine extends RenderEditableBox {
_paintSelection(PaintingContext context, Offset effectiveOffset) {
assert(_selectedRects != null);
final paint = Paint()..color = color;
for (final box in _selectedRects) {
for (final box in _selectedRects!) {
context.canvas.drawRect(box.toRect().shift(effectiveOffset), paint);
}
}
@ -814,7 +804,7 @@ class _TextLineElement extends RenderObjectElement {
}
@override
mount(Element parent, dynamic newSlot) {
mount(Element? parent, dynamic newSlot) {
super.mount(parent, newSlot);
_mountChild(widget.leading, TextLineSlot.LEADING);
_mountChild(widget.body, TextLineSlot.BODY);
@ -829,16 +819,16 @@ class _TextLineElement extends RenderObjectElement {
}
@override
insertRenderObjectChild(RenderObject child, TextLineSlot slot) {
insertRenderObjectChild(RenderObject child, TextLineSlot? slot) {
assert(child is RenderBox);
_updateRenderObject(child, slot);
assert(renderObject.children.keys.contains(slot));
}
@override
removeRenderObjectChild(RenderObject child, TextLineSlot slot) {
removeRenderObjectChild(RenderObject child, TextLineSlot? slot) {
assert(child is RenderBox);
assert(renderObject.children[slot] == child);
assert(renderObject.children[slot!] == child);
_updateRenderObject(null, slot);
assert(!renderObject.children.keys.contains(slot));
}
@ -848,9 +838,9 @@ class _TextLineElement extends RenderObjectElement {
throw UnimplementedError();
}
_mountChild(Widget widget, TextLineSlot slot) {
Element oldChild = _slotToChildren[slot];
Element newChild = updateChild(oldChild, widget, slot);
_mountChild(Widget? widget, TextLineSlot slot) {
Element? oldChild = _slotToChildren[slot];
Element? newChild = updateChild(oldChild, widget, slot);
if (oldChild != null) {
_slotToChildren.remove(slot);
}
@ -859,22 +849,22 @@ class _TextLineElement extends RenderObjectElement {
}
}
_updateRenderObject(RenderObject child, TextLineSlot slot) {
_updateRenderObject(RenderObject? child, TextLineSlot? slot) {
switch (slot) {
case TextLineSlot.LEADING:
renderObject.setLeading(child as RenderBox);
renderObject.setLeading(child as RenderBox?);
break;
case TextLineSlot.BODY:
renderObject.setBody(child as RenderBox);
renderObject.setBody((child as RenderBox?) as RenderContentProxyBox?);
break;
default:
throw UnimplementedError();
}
}
_updateChild(Widget widget, TextLineSlot slot) {
Element oldChild = _slotToChildren[slot];
Element newChild = updateChild(oldChild, widget, slot);
_updateChild(Widget? widget, TextLineSlot slot) {
Element? oldChild = _slotToChildren[slot];
Element? newChild = updateChild(oldChild, widget, slot);
if (oldChild != null) {
_slotToChildren.remove(slot);
}

@ -31,15 +31,15 @@ class EditorTextSelectionOverlay {
final LayerLink toolbarLayerLink;
final LayerLink startHandleLayerLink;
final LayerLink endHandleLayerLink;
final RenderEditor renderObject;
final RenderEditor? renderObject;
final TextSelectionControls selectionCtrls;
final TextSelectionDelegate selectionDelegate;
final DragStartBehavior dragStartBehavior;
final VoidCallback onSelectionHandleTapped;
final VoidCallback? onSelectionHandleTapped;
final ClipboardStatusNotifier clipboardStatus;
AnimationController _toolbarController;
List<OverlayEntry> _handles;
OverlayEntry toolbar;
late AnimationController _toolbarController;
List<OverlayEntry>? _handles;
OverlayEntry? toolbar;
EditorTextSelectionOverlay(
this.value,
@ -58,7 +58,7 @@ class EditorTextSelectionOverlay {
: assert(value != null),
assert(context != null),
assert(handlesVisible != null) {
OverlayState overlay = Overlay.of(context, rootOverlay: true);
OverlayState overlay = Overlay.of(context, rootOverlay: true)!;
assert(
overlay != null,
);
@ -76,9 +76,9 @@ class EditorTextSelectionOverlay {
return;
}
handlesVisible = visible;
if (SchedulerBinding.instance.schedulerPhase ==
if (SchedulerBinding.instance!.schedulerPhase ==
SchedulerPhase.persistentCallbacks) {
SchedulerBinding.instance.addPostFrameCallback(markNeedsBuild);
SchedulerBinding.instance!.addPostFrameCallback(markNeedsBuild);
} else {
markNeedsBuild();
}
@ -88,23 +88,23 @@ class EditorTextSelectionOverlay {
if (_handles == null) {
return;
}
_handles[0].remove();
_handles[1].remove();
_handles![0].remove();
_handles![1].remove();
_handles = null;
}
hideToolbar() {
assert(toolbar != null);
_toolbarController.stop();
toolbar.remove();
toolbar!.remove();
toolbar = null;
}
showToolbar() {
assert(toolbar == null);
toolbar = OverlayEntry(builder: _buildToolbar);
Overlay.of(context, rootOverlay: true, debugRequiredFor: debugRequiredFor)
.insert(toolbar);
Overlay.of(context, rootOverlay: true, debugRequiredFor: debugRequiredFor)!
.insert(toolbar!);
_toolbarController.forward(from: 0.0);
}
@ -118,7 +118,7 @@ class EditorTextSelectionOverlay {
return Visibility(
visible: handlesVisible,
child: _TextSelectionHandleOverlay(
onSelectionHandleChanged: (TextSelection newSelection) {
onSelectionHandleChanged: (TextSelection? newSelection) {
_handleSelectionHandleChanged(newSelection, position);
},
onSelectionHandleTapped: onSelectionHandleTapped,
@ -137,23 +137,26 @@ class EditorTextSelectionOverlay {
return;
}
value = newValue;
if (SchedulerBinding.instance.schedulerPhase ==
if (SchedulerBinding.instance!.schedulerPhase ==
SchedulerPhase.persistentCallbacks) {
SchedulerBinding.instance.addPostFrameCallback(markNeedsBuild);
SchedulerBinding.instance!.addPostFrameCallback(markNeedsBuild);
} else {
markNeedsBuild();
}
}
_handleSelectionHandleChanged(
TextSelection newSelection, _TextSelectionHandlePosition position) {
TextSelection? newSelection, _TextSelectionHandlePosition position) {
TextPosition textPosition;
switch (position) {
case _TextSelectionHandlePosition.START:
textPosition = newSelection.base;
textPosition =
newSelection != null ? newSelection.base : TextPosition(offset: 0);
break;
case _TextSelectionHandlePosition.END:
textPosition = newSelection.extent;
textPosition = newSelection != null
? newSelection.extent
: TextPosition(offset: 0);
break;
default:
throw ('Invalid position');
@ -169,16 +172,16 @@ class EditorTextSelectionOverlay {
}
List<TextSelectionPoint> endpoints =
renderObject.getEndpointsForSelection(_selection);
renderObject!.getEndpointsForSelection(_selection);
Rect editingRegion = Rect.fromPoints(
renderObject.localToGlobal(Offset.zero),
renderObject.localToGlobal(renderObject.size.bottomRight(Offset.zero)),
renderObject!.localToGlobal(Offset.zero),
renderObject!.localToGlobal(renderObject!.size.bottomRight(Offset.zero)),
);
double baseLineHeight = renderObject.preferredLineHeight(_selection.base);
double baseLineHeight = renderObject!.preferredLineHeight(_selection.base);
double extentLineHeight =
renderObject.preferredLineHeight(_selection.extent);
renderObject!.preferredLineHeight(_selection.extent);
double smallestLineHeight = math.min(baseLineHeight, extentLineHeight);
bool isMultiline = endpoints.last.point.dy - endpoints.first.point.dy >
smallestLineHeight / 2;
@ -211,18 +214,18 @@ class EditorTextSelectionOverlay {
);
}
markNeedsBuild([Duration duration]) {
markNeedsBuild([Duration? duration]) {
if (_handles != null) {
_handles[0].markNeedsBuild();
_handles[1].markNeedsBuild();
_handles![0].markNeedsBuild();
_handles![1].markNeedsBuild();
}
toolbar?.markNeedsBuild();
}
hide() {
if (_handles != null) {
_handles[0].remove();
_handles[1].remove();
_handles![0].remove();
_handles![1].remove();
_handles = null;
}
if (toolbar != null) {
@ -246,22 +249,22 @@ class EditorTextSelectionOverlay {
_buildHandle(context, _TextSelectionHandlePosition.END)),
];
Overlay.of(context, rootOverlay: true, debugRequiredFor: debugRequiredFor)
.insertAll(_handles);
Overlay.of(context, rootOverlay: true, debugRequiredFor: debugRequiredFor)!
.insertAll(_handles!);
}
}
class _TextSelectionHandleOverlay extends StatefulWidget {
const _TextSelectionHandleOverlay({
Key key,
@required this.selection,
@required this.position,
@required this.startHandleLayerLink,
@required this.endHandleLayerLink,
@required this.renderObject,
@required this.onSelectionHandleChanged,
@required this.onSelectionHandleTapped,
@required this.selectionControls,
Key? key,
required this.selection,
required this.position,
required this.startHandleLayerLink,
required this.endHandleLayerLink,
required this.renderObject,
required this.onSelectionHandleChanged,
required this.onSelectionHandleTapped,
required this.selectionControls,
this.dragStartBehavior = DragStartBehavior.start,
}) : super(key: key);
@ -269,9 +272,9 @@ class _TextSelectionHandleOverlay extends StatefulWidget {
final _TextSelectionHandlePosition position;
final LayerLink startHandleLayerLink;
final LayerLink endHandleLayerLink;
final RenderEditor renderObject;
final ValueChanged<TextSelection> onSelectionHandleChanged;
final VoidCallback onSelectionHandleTapped;
final RenderEditor? renderObject;
final ValueChanged<TextSelection?> onSelectionHandleChanged;
final VoidCallback? onSelectionHandleTapped;
final TextSelectionControls selectionControls;
final DragStartBehavior dragStartBehavior;
@ -279,12 +282,12 @@ class _TextSelectionHandleOverlay extends StatefulWidget {
_TextSelectionHandleOverlayState createState() =>
_TextSelectionHandleOverlayState();
ValueListenable<bool> get _visibility {
ValueListenable<bool>? get _visibility {
switch (position) {
case _TextSelectionHandlePosition.START:
return renderObject.selectionStartInViewport;
return renderObject!.selectionStartInViewport;
case _TextSelectionHandlePosition.END:
return renderObject.selectionEndInViewport;
return renderObject!.selectionEndInViewport;
}
return null;
}
@ -293,7 +296,7 @@ class _TextSelectionHandleOverlay extends StatefulWidget {
class _TextSelectionHandleOverlayState
extends State<_TextSelectionHandleOverlay>
with SingleTickerProviderStateMixin {
AnimationController _controller;
late AnimationController _controller;
Animation<double> get _opacity => _controller.view;
@ -305,11 +308,11 @@ class _TextSelectionHandleOverlayState
AnimationController(duration: Duration(milliseconds: 150), vsync: this);
_handleVisibilityChanged();
widget._visibility.addListener(_handleVisibilityChanged);
widget._visibility!.addListener(_handleVisibilityChanged);
}
_handleVisibilityChanged() {
if (widget._visibility.value) {
if (widget._visibility!.value) {
_controller.forward();
} else {
_controller.reverse();
@ -319,14 +322,14 @@ class _TextSelectionHandleOverlayState
@override
didUpdateWidget(_TextSelectionHandleOverlay oldWidget) {
super.didUpdateWidget(oldWidget);
oldWidget._visibility.removeListener(_handleVisibilityChanged);
oldWidget._visibility!.removeListener(_handleVisibilityChanged);
_handleVisibilityChanged();
widget._visibility.addListener(_handleVisibilityChanged);
widget._visibility!.addListener(_handleVisibilityChanged);
}
@override
void dispose() {
widget._visibility.removeListener(_handleVisibilityChanged);
widget._visibility!.removeListener(_handleVisibilityChanged);
_controller.dispose();
super.dispose();
}
@ -335,7 +338,7 @@ class _TextSelectionHandleOverlayState
_handleDragUpdate(DragUpdateDetails details) {
TextPosition position =
widget.renderObject.getPositionForOffset(details.globalPosition);
widget.renderObject!.getPositionForOffset(details.globalPosition);
if (widget.selection.isCollapsed) {
widget.onSelectionHandleChanged(TextSelection.fromPosition(position));
return;
@ -343,7 +346,7 @@ class _TextSelectionHandleOverlayState
bool isNormalized =
widget.selection.extentOffset >= widget.selection.baseOffset;
TextSelection newSelection;
TextSelection? newSelection;
switch (widget.position) {
case _TextSelectionHandlePosition.START:
newSelection = TextSelection(
@ -368,19 +371,19 @@ class _TextSelectionHandleOverlayState
_handleTap() {
if (widget.onSelectionHandleTapped != null)
widget.onSelectionHandleTapped();
widget.onSelectionHandleTapped!();
}
@override
Widget build(BuildContext context) {
LayerLink layerLink;
TextSelectionHandleType type;
late LayerLink layerLink;
TextSelectionHandleType? type;
switch (widget.position) {
case _TextSelectionHandlePosition.START:
layerLink = widget.startHandleLayerLink;
type = _chooseType(
widget.renderObject.textDirection,
widget.renderObject!.textDirection,
TextSelectionHandleType.left,
TextSelectionHandleType.right,
);
@ -389,7 +392,7 @@ class _TextSelectionHandleOverlayState
assert(!widget.selection.isCollapsed);
layerLink = widget.endHandleLayerLink;
type = _chooseType(
widget.renderObject.textDirection,
widget.renderObject!.textDirection,
TextSelectionHandleType.right,
TextSelectionHandleType.left,
);
@ -400,9 +403,9 @@ class _TextSelectionHandleOverlayState
widget.position == _TextSelectionHandlePosition.START
? widget.selection.base
: widget.selection.extent;
double lineHeight = widget.renderObject.preferredLineHeight(textPosition);
double lineHeight = widget.renderObject!.preferredLineHeight(textPosition);
Offset handleAnchor =
widget.selectionControls.getHandleAnchor(type, lineHeight);
widget.selectionControls.getHandleAnchor(type!, lineHeight);
Size handleSize = widget.selectionControls.getHandleSize(lineHeight);
Rect handleRect = Rect.fromLTWH(
@ -458,7 +461,7 @@ class _TextSelectionHandleOverlayState
);
}
TextSelectionHandleType _chooseType(
TextSelectionHandleType? _chooseType(
TextDirection textDirection,
TextSelectionHandleType ltrType,
TextSelectionHandleType rtlType,
@ -478,7 +481,7 @@ class _TextSelectionHandleOverlayState
class EditorTextSelectionGestureDetector extends StatefulWidget {
const EditorTextSelectionGestureDetector({
Key key,
Key? key,
this.onTapDown,
this.onForcePressStart,
this.onForcePressEnd,
@ -492,35 +495,35 @@ class EditorTextSelectionGestureDetector extends StatefulWidget {
this.onDragSelectionUpdate,
this.onDragSelectionEnd,
this.behavior,
@required this.child,
required this.child,
}) : assert(child != null),
super(key: key);
final GestureTapDownCallback onTapDown;
final GestureTapDownCallback? onTapDown;
final GestureForcePressStartCallback onForcePressStart;
final GestureForcePressStartCallback? onForcePressStart;
final GestureForcePressEndCallback onForcePressEnd;
final GestureForcePressEndCallback? onForcePressEnd;
final GestureTapUpCallback onSingleTapUp;
final GestureTapUpCallback? onSingleTapUp;
final GestureTapCancelCallback onSingleTapCancel;
final GestureTapCancelCallback? onSingleTapCancel;
final GestureLongPressStartCallback onSingleLongTapStart;
final GestureLongPressStartCallback? onSingleLongTapStart;
final GestureLongPressMoveUpdateCallback onSingleLongTapMoveUpdate;
final GestureLongPressMoveUpdateCallback? onSingleLongTapMoveUpdate;
final GestureLongPressEndCallback onSingleLongTapEnd;
final GestureLongPressEndCallback? onSingleLongTapEnd;
final GestureTapDownCallback onDoubleTapDown;
final GestureTapDownCallback? onDoubleTapDown;
final GestureDragStartCallback onDragSelectionStart;
final GestureDragStartCallback? onDragSelectionStart;
final DragSelectionUpdateCallback onDragSelectionUpdate;
final DragSelectionUpdateCallback? onDragSelectionUpdate;
final GestureDragEndCallback onDragSelectionEnd;
final GestureDragEndCallback? onDragSelectionEnd;
final HitTestBehavior behavior;
final HitTestBehavior? behavior;
final Widget child;
@ -531,8 +534,8 @@ class EditorTextSelectionGestureDetector extends StatefulWidget {
class _EditorTextSelectionGestureDetectorState
extends State<EditorTextSelectionGestureDetector> {
Timer _doubleTapTimer;
Offset _lastTapOffset;
Timer? _doubleTapTimer;
Offset? _lastTapOffset;
bool _isDoubleTap = false;
@override
@ -544,15 +547,15 @@ class _EditorTextSelectionGestureDetectorState
_handleTapDown(TapDownDetails details) {
if (widget.onTapDown != null) {
widget.onTapDown(details);
widget.onTapDown!(details);
}
if (_doubleTapTimer != null &&
_isWithinDoubleTapTolerance(details.globalPosition)) {
if (widget.onDoubleTapDown != null) {
widget.onDoubleTapDown(details);
widget.onDoubleTapDown!(details);
}
_doubleTapTimer.cancel();
_doubleTapTimer!.cancel();
_doubleTapTimeout();
_isDoubleTap = true;
}
@ -561,7 +564,7 @@ class _EditorTextSelectionGestureDetectorState
_handleTapUp(TapUpDetails details) {
if (!_isDoubleTap) {
if (widget.onSingleTapUp != null) {
widget.onSingleTapUp(details);
widget.onSingleTapUp!(details);
}
_lastTapOffset = details.globalPosition;
_doubleTapTimer = Timer(kDoubleTapTimeout, _doubleTapTimeout);
@ -571,19 +574,19 @@ class _EditorTextSelectionGestureDetectorState
_handleTapCancel() {
if (widget.onSingleTapCancel != null) {
widget.onSingleTapCancel();
widget.onSingleTapCancel!();
}
}
DragStartDetails _lastDragStartDetails;
DragUpdateDetails _lastDragUpdateDetails;
Timer _dragUpdateThrottleTimer;
DragStartDetails? _lastDragStartDetails;
DragUpdateDetails? _lastDragUpdateDetails;
Timer? _dragUpdateThrottleTimer;
_handleDragStart(DragStartDetails details) {
assert(_lastDragStartDetails == null);
_lastDragStartDetails = details;
if (widget.onDragSelectionStart != null) {
widget.onDragSelectionStart(details);
widget.onDragSelectionStart!(details);
}
}
@ -597,8 +600,8 @@ class _EditorTextSelectionGestureDetectorState
assert(_lastDragStartDetails != null);
assert(_lastDragUpdateDetails != null);
if (widget.onDragSelectionUpdate != null) {
widget.onDragSelectionUpdate(
_lastDragStartDetails, _lastDragUpdateDetails);
widget.onDragSelectionUpdate!(
_lastDragStartDetails!, _lastDragUpdateDetails!);
}
_dragUpdateThrottleTimer = null;
_lastDragUpdateDetails = null;
@ -607,11 +610,11 @@ class _EditorTextSelectionGestureDetectorState
_handleDragEnd(DragEndDetails details) {
assert(_lastDragStartDetails != null);
if (_dragUpdateThrottleTimer != null) {
_dragUpdateThrottleTimer.cancel();
_dragUpdateThrottleTimer!.cancel();
_handleDragUpdateThrottled();
}
if (widget.onDragSelectionEnd != null) {
widget.onDragSelectionEnd(details);
widget.onDragSelectionEnd!(details);
}
_dragUpdateThrottleTimer = null;
_lastDragStartDetails = null;
@ -622,31 +625,31 @@ class _EditorTextSelectionGestureDetectorState
_doubleTapTimer?.cancel();
_doubleTapTimer = null;
if (widget.onForcePressStart != null) {
widget.onForcePressStart(details);
widget.onForcePressStart!(details);
}
}
_forcePressEnded(ForcePressDetails details) {
if (widget.onForcePressEnd != null) {
widget.onForcePressEnd(details);
widget.onForcePressEnd!(details);
}
}
_handleLongPressStart(LongPressStartDetails details) {
if (!_isDoubleTap && widget.onSingleLongTapStart != null) {
widget.onSingleLongTapStart(details);
widget.onSingleLongTapStart!(details);
}
}
_handleLongPressMoveUpdate(LongPressMoveUpdateDetails details) {
if (!_isDoubleTap && widget.onSingleLongTapMoveUpdate != null) {
widget.onSingleLongTapMoveUpdate(details);
widget.onSingleLongTapMoveUpdate!(details);
}
}
_handleLongPressEnd(LongPressEndDetails details) {
if (!_isDoubleTap && widget.onSingleLongTapEnd != null) {
widget.onSingleLongTapEnd(details);
widget.onSingleLongTapEnd!(details);
}
_isDoubleTap = false;
}
@ -662,7 +665,7 @@ class _EditorTextSelectionGestureDetectorState
return false;
}
return (secondTapOffset - _lastTapOffset).distance <= kDoubleTapSlop;
return (secondTapOffset - _lastTapOffset!).distance <= kDoubleTapSlop;
}
@override
@ -738,7 +741,7 @@ class _EditorTextSelectionGestureDetectorState
class _TransparentTapGestureRecognizer extends TapGestureRecognizer {
_TransparentTapGestureRecognizer({
Object debugOwner,
Object? debugOwner,
}) : super(debugOwner: debugOwner);
@override

@ -23,9 +23,9 @@ class InsertEmbedButton extends StatelessWidget {
final IconData icon;
const InsertEmbedButton({
Key key,
@required this.controller,
@required this.icon,
Key? key,
required this.controller,
required this.icon,
}) : super(key: key);
@override
@ -51,11 +51,11 @@ class InsertEmbedButton extends StatelessWidget {
class LinkStyleButton extends StatefulWidget {
final QuillController controller;
final IconData icon;
final IconData? icon;
const LinkStyleButton({
Key key,
@required this.controller,
Key? key,
required this.controller,
this.icon,
}) : super(key: key);
@ -117,7 +117,7 @@ class _LinkStyleButtonState extends State<LinkStyleButton> {
).then(_linkSubmitted);
}
void _linkSubmitted(String value) {
void _linkSubmitted(String? value) {
if (value == null || value.isEmpty) {
return;
}
@ -126,7 +126,7 @@ class _LinkStyleButtonState extends State<LinkStyleButton> {
}
class _LinkDialog extends StatefulWidget {
const _LinkDialog({Key key}) : super(key: key);
const _LinkDialog({Key? key}) : super(key: key);
@override
_LinkDialogState createState() => _LinkDialogState();
@ -167,8 +167,8 @@ typedef ToggleStyleButtonBuilder = Widget Function(
BuildContext context,
Attribute attribute,
IconData icon,
bool isToggled,
VoidCallback onPressed,
bool? isToggled,
VoidCallback? onPressed,
);
class ToggleStyleButton extends StatefulWidget {
@ -181,10 +181,10 @@ class ToggleStyleButton extends StatefulWidget {
final ToggleStyleButtonBuilder childBuilder;
ToggleStyleButton({
Key key,
@required this.attribute,
@required this.icon,
@required this.controller,
Key? key,
required this.attribute,
required this.icon,
required this.controller,
this.childBuilder = defaultToggleStyleButtonBuilder,
}) : assert(attribute.value != null),
assert(icon != null),
@ -197,7 +197,7 @@ class ToggleStyleButton extends StatefulWidget {
}
class _ToggleStyleButtonState extends State<ToggleStyleButton> {
bool _isToggled;
bool? _isToggled;
Style get _selectionStyle => widget.controller.getSelectionStyle();
@ -217,7 +217,7 @@ class _ToggleStyleButtonState extends State<ToggleStyleButton> {
bool _getIsToggled(Map<String, Attribute> attrs) {
if (widget.attribute.key == Attribute.list.key) {
Attribute attribute = attrs[widget.attribute.key];
Attribute? attribute = attrs[widget.attribute.key];
if (attribute == null) {
return false;
}
@ -253,7 +253,7 @@ class _ToggleStyleButtonState extends State<ToggleStyleButton> {
}
_toggleAttribute() {
widget.controller.formatSelection(_isToggled
widget.controller.formatSelection(_isToggled!
? Attribute.clone(widget.attribute, null)
: widget.attribute);
}
@ -269,11 +269,11 @@ class ToggleCheckListButton extends StatefulWidget {
final Attribute attribute;
ToggleCheckListButton({
Key key,
@required this.icon,
@required this.controller,
Key? key,
required this.icon,
required this.controller,
this.childBuilder = defaultToggleStyleButtonBuilder,
@required this.attribute,
required this.attribute,
}) : assert(icon != null),
assert(controller != null),
assert(childBuilder != null),
@ -284,7 +284,7 @@ class ToggleCheckListButton extends StatefulWidget {
}
class _ToggleCheckListButtonState extends State<ToggleCheckListButton> {
bool _isToggled;
bool? _isToggled;
Style get _selectionStyle => widget.controller.getSelectionStyle();
@ -304,7 +304,7 @@ class _ToggleCheckListButtonState extends State<ToggleCheckListButton> {
bool _getIsToggled(Map<String, Attribute> attrs) {
if (widget.attribute.key == Attribute.list.key) {
Attribute attribute = attrs[widget.attribute.key];
Attribute? attribute = attrs[widget.attribute.key];
if (attribute == null) {
return false;
}
@ -341,7 +341,7 @@ class _ToggleCheckListButtonState extends State<ToggleCheckListButton> {
}
_toggleAttribute() {
widget.controller.formatSelection(_isToggled
widget.controller.formatSelection(_isToggled!
? Attribute.clone(Attribute.unchecked, null)
: Attribute.unchecked);
}
@ -351,17 +351,17 @@ Widget defaultToggleStyleButtonBuilder(
BuildContext context,
Attribute attribute,
IconData icon,
bool isToggled,
VoidCallback onPressed,
bool? isToggled,
VoidCallback? onPressed,
) {
final theme = Theme.of(context);
final isEnabled = onPressed != null;
final iconColor = isEnabled
? isToggled
? isToggled != null
? theme.primaryIconTheme.color
: theme.iconTheme.color
: theme.disabledColor;
final fillColor = isToggled ? theme.toggleableActiveColor : theme.canvasColor;
final fillColor = isToggled != null ? theme.toggleableActiveColor : theme.canvasColor;
return QuillIconButton(
highlightElevation: 0,
hoverElevation: 0,
@ -375,7 +375,7 @@ Widget defaultToggleStyleButtonBuilder(
class SelectHeaderStyleButton extends StatefulWidget {
final QuillController controller;
const SelectHeaderStyleButton({Key key, @required this.controller})
const SelectHeaderStyleButton({Key? key, required this.controller})
: super(key: key);
@override
@ -384,7 +384,7 @@ class SelectHeaderStyleButton extends StatefulWidget {
}
class _SelectHeaderStyleButtonState extends State<SelectHeaderStyleButton> {
Attribute _value;
Attribute? _value;
Style get _selectionStyle => widget.controller.getSelectionStyle();
@ -433,7 +433,7 @@ class _SelectHeaderStyleButtonState extends State<SelectHeaderStyleButton> {
}
Widget _selectHeadingStyleButtonBuilder(
BuildContext context, Attribute value, ValueChanged<Attribute> onSelected) {
BuildContext context, Attribute? value, ValueChanged<Attribute?> onSelected) {
final style = TextStyle(fontSize: 13);
final Map<Attribute, String> _valueToText = {
@ -443,42 +443,42 @@ Widget _selectHeadingStyleButtonBuilder(
Attribute.h3: 'Heading 3',
};
return QuillDropdownButton<Attribute>(
return QuillDropdownButton<Attribute?>(
highlightElevation: 0,
hoverElevation: 0,
height: iconSize * 1.77,
fillColor: Theme.of(context).canvasColor,
child: Text(
!kIsWeb
? _valueToText[value]
: _valueToText[value.key == "header"
? _valueToText[value!]!
: _valueToText[value!.key == "header"
? Attribute.header
: (value.key == "h1")
? Attribute.h1
: (value.key == "h2")
? Attribute.h2
: Attribute.h3],
: Attribute.h3]!,
style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600),
),
initialValue: value,
items: [
PopupMenuItem(
child: Text(_valueToText[Attribute.header], style: style),
child: Text(_valueToText[Attribute.header]!, style: style),
value: Attribute.header,
height: iconSize * 1.77,
),
PopupMenuItem(
child: Text(_valueToText[Attribute.h1], style: style),
child: Text(_valueToText[Attribute.h1]!, style: style),
value: Attribute.h1,
height: iconSize * 1.77,
),
PopupMenuItem(
child: Text(_valueToText[Attribute.h2], style: style),
child: Text(_valueToText[Attribute.h2]!, style: style),
value: Attribute.h2,
height: iconSize * 1.77,
),
PopupMenuItem(
child: Text(_valueToText[Attribute.h3], style: style),
child: Text(_valueToText[Attribute.h3]!, style: style),
value: Attribute.h3,
height: iconSize * 1.77,
),
@ -492,15 +492,15 @@ class ImageButton extends StatefulWidget {
final QuillController controller;
final OnImagePickCallback onImagePickCallback;
final OnImagePickCallback? onImagePickCallback;
final ImageSource imageSource;
ImageButton(
{Key key,
@required this.icon,
@required this.controller,
@required this.imageSource,
{Key? key,
required this.icon,
required this.controller,
required this.imageSource,
this.onImagePickCallback})
: assert(icon != null),
assert(controller != null),
@ -511,13 +511,13 @@ class ImageButton extends StatefulWidget {
}
class _ImageButtonState extends State<ImageButton> {
List<PlatformFile> _paths;
String _extension;
List<PlatformFile>? _paths;
String? _extension;
final _picker = ImagePicker();
FileType _pickingType = FileType.any;
Future<String> _pickImage(ImageSource source) async {
final PickedFile pickedFile = await _picker.getImage(source: source);
Future<String?> _pickImage(ImageSource source) async {
final PickedFile? pickedFile = await _picker.getImage(source: source);
if (pickedFile == null) return null;
final File file = File(pickedFile.path);
@ -525,7 +525,7 @@ class _ImageButtonState extends State<ImageButton> {
if (file == null || widget.onImagePickCallback == null) return null;
// We simply return the absolute path to selected file.
try {
String url = await widget.onImagePickCallback(file);
String url = await widget.onImagePickCallback!(file);
print('Image uploaded and its url is $url');
return url;
} catch (error) {
@ -534,13 +534,13 @@ class _ImageButtonState extends State<ImageButton> {
return null;
}
Future<String> _pickImageWeb() async {
Future<String?> _pickImageWeb() async {
try {
_paths = (await FilePicker.platform.pickFiles(
type: _pickingType,
allowMultiple: false,
allowedExtensions: (_extension?.isNotEmpty ?? false)
? _extension?.replaceAll(' ', '')?.split(',')
? _extension?.replaceAll(' ', '').split(',')
: null,
))
?.files;
@ -550,14 +550,14 @@ class _ImageButtonState extends State<ImageButton> {
print(ex);
}
var _fileName =
_paths != null ? _paths.map((e) => e.name).toString() : '...';
_paths != null ? _paths!.map((e) => e.name).toString() : '...';
if (_paths != null) {
File file = File(_fileName);
if (file == null || widget.onImagePickCallback == null) return null;
// We simply return the absolute path to selected file.
try {
String url = await widget.onImagePickCallback(file);
String url = await widget.onImagePickCallback!(file);
print('Image uploaded and its url is $url');
return url;
} catch (error) {
@ -607,10 +607,10 @@ class ColorButton extends StatefulWidget {
final QuillController controller;
ColorButton(
{Key key,
@required this.icon,
@required this.controller,
@required this.background})
{Key? key,
required this.icon,
required this.controller,
required this.background})
: assert(icon != null),
assert(controller != null),
assert(background != null),
@ -621,10 +621,10 @@ class ColorButton extends StatefulWidget {
}
class _ColorButtonState extends State<ColorButton> {
bool _isToggledColor;
bool _isToggledBackground;
bool _isWhite;
bool _isWhitebackground;
late bool _isToggledColor;
late bool _isToggledBackground;
late bool _isWhite;
late bool _isWhitebackground;
Style get _selectionStyle => widget.controller.getSelectionStyle();
@ -635,9 +635,9 @@ class _ColorButtonState extends State<ColorButton> {
_isToggledBackground = _getIsToggledBackground(
widget.controller.getSelectionStyle().attributes);
_isWhite = _isToggledColor &&
_selectionStyle.attributes["color"].value == '#ffffff';
_selectionStyle.attributes["color"]!.value == '#ffffff';
_isWhitebackground = _isToggledBackground &&
_selectionStyle.attributes["background"].value == '#ffffff';
_selectionStyle.attributes["background"]!.value == '#ffffff';
});
}
@ -647,9 +647,9 @@ class _ColorButtonState extends State<ColorButton> {
_isToggledColor = _getIsToggledColor(_selectionStyle.attributes);
_isToggledBackground = _getIsToggledBackground(_selectionStyle.attributes);
_isWhite = _isToggledColor &&
_selectionStyle.attributes["color"].value == '#ffffff';
_selectionStyle.attributes["color"]!.value == '#ffffff';
_isWhitebackground = _isToggledBackground &&
_selectionStyle.attributes["background"].value == '#ffffff';
_selectionStyle.attributes["background"]!.value == '#ffffff';
widget.controller.addListener(_didChangeEditingValue);
}
@ -671,9 +671,9 @@ class _ColorButtonState extends State<ColorButton> {
_isToggledBackground =
_getIsToggledBackground(_selectionStyle.attributes);
_isWhite = _isToggledColor &&
_selectionStyle.attributes["color"].value == '#ffffff';
_selectionStyle.attributes["color"]!.value == '#ffffff';
_isWhitebackground = _isToggledBackground &&
_selectionStyle.attributes["background"].value == '#ffffff';
_selectionStyle.attributes["background"]!.value == '#ffffff';
}
}
@ -686,13 +686,13 @@ class _ColorButtonState extends State<ColorButton> {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
Color iconColor = _isToggledColor && !widget.background && !_isWhite
? stringToColor(_selectionStyle.attributes["color"].value)
Color? iconColor = _isToggledColor && !widget.background && !_isWhite
? stringToColor(_selectionStyle.attributes["color"]!.value)
: theme.iconTheme.color;
Color iconColorBackground =
Color? iconColorBackground =
_isToggledBackground && widget.background && !_isWhitebackground
? stringToColor(_selectionStyle.attributes["background"].value)
? stringToColor(_selectionStyle.attributes["background"]!.value)
: theme.iconTheme.color;
Color fillColor = _isToggledColor && !widget.background && _isWhite
@ -748,10 +748,10 @@ class HistoryButton extends StatefulWidget {
final QuillController controller;
HistoryButton(
{Key key,
@required this.icon,
@required this.controller,
@required this.undo})
{Key? key,
required this.icon,
required this.controller,
required this.undo})
: assert(icon != null),
assert(controller != null),
assert(undo != null),
@ -762,8 +762,8 @@ class HistoryButton extends StatefulWidget {
}
class _HistoryButtonState extends State<HistoryButton> {
Color _iconColor;
ThemeData theme;
Color? _iconColor;
late ThemeData theme;
@override
Widget build(BuildContext context) {
@ -823,10 +823,10 @@ class IndentButton extends StatefulWidget {
final bool isIncrease;
IndentButton(
{Key key,
@required this.icon,
@required this.controller,
@required this.isIncrease})
{Key? key,
required this.icon,
required this.controller,
required this.isIncrease})
: assert(icon != null),
assert(controller != null),
assert(isIncrease != null),
@ -880,7 +880,7 @@ class ClearFormatButton extends StatefulWidget {
final QuillController controller;
ClearFormatButton({Key key, @required this.icon, @required this.controller})
ClearFormatButton({Key? key, required this.icon, required this.controller})
: assert(icon != null),
assert(controller != null),
super(key: key);
@ -913,11 +913,11 @@ class _ClearFormatButtonState extends State<ClearFormatButton> {
class QuillToolbar extends StatefulWidget implements PreferredSizeWidget {
final List<Widget> children;
const QuillToolbar({Key key, @required this.children}) : super(key: key);
const QuillToolbar({Key? key, required this.children}) : super(key: key);
factory QuillToolbar.basic(
{Key key,
@required QuillController controller,
{Key? key,
required QuillController controller,
double toolbarIconSize = 18.0,
bool showBoldButton = true,
bool showItalicButton = true,
@ -936,7 +936,7 @@ class QuillToolbar extends StatefulWidget implements PreferredSizeWidget {
bool showLink = true,
bool showHistory = true,
bool showHorizontalRule = false,
OnImagePickCallback onImagePickCallback}) {
OnImagePickCallback? onImagePickCallback}) {
iconSize = toolbarIconSize;
return QuillToolbar(key: key, children: [
Visibility(
@ -1155,16 +1155,16 @@ class _QuillToolbarState extends State<QuillToolbar> {
}
class QuillIconButton extends StatelessWidget {
final VoidCallback onPressed;
final Widget icon;
final VoidCallback? onPressed;
final Widget? icon;
final double size;
final Color fillColor;
final Color? fillColor;
final double hoverElevation;
final double highlightElevation;
const QuillIconButton({
Key key,
@required this.onPressed,
Key? key,
required this.onPressed,
this.icon,
this.size = 40,
this.fillColor,
@ -1193,7 +1193,7 @@ class QuillIconButton extends StatelessWidget {
class QuillDropdownButton<T> extends StatefulWidget {
final double height;
final Color fillColor;
final Color? fillColor;
final double hoverElevation;
final double highlightElevation;
final Widget child;
@ -1202,15 +1202,15 @@ class QuillDropdownButton<T> extends StatefulWidget {
final ValueChanged<T> onSelected;
const QuillDropdownButton({
Key key,
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,
required this.child,
required this.initialValue,
required this.items,
required this.onSelected,
}) : super(key: key);
@override
@ -1239,7 +1239,7 @@ class _QuillDropdownButtonState<T> extends State<QuillDropdownButton<T>> {
void _showMenu() {
final popupMenuTheme = PopupMenuTheme.of(context);
final button = context.findRenderObject() as RenderBox;
final overlay = Overlay.of(context).context.findRenderObject() as RenderBox;
final overlay = Overlay.of(context)!.context.findRenderObject() as RenderBox;
final position = RelativeRect.fromRect(
Rect.fromPoints(
button.localToGlobal(Offset.zero, ancestor: overlay),
@ -1259,7 +1259,7 @@ class _QuillDropdownButtonState<T> extends State<QuillDropdownButton<T>> {
// widget.shape ?? popupMenuTheme.shape,
color: popupMenuTheme.color, // widget.color ?? popupMenuTheme.color,
// captureInheritedThemes: widget.captureInheritedThemes,
).then((T newValue) {
).then((T? newValue) {
if (!mounted) return null;
if (newValue == null) {
// if (widget.onCanceled != null) widget.onCanceled();

@ -6,7 +6,7 @@ homepage: https://bulletjournal.us/home/index.html
repository: https://github.com/singerdmx/flutter-quill.git
environment:
sdk: ">=2.7.0 <3.0.0"
sdk: '>=2.12.0 <3.0.0'
flutter: ">=1.17.0"
dependencies:

Loading…
Cancel
Save