Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Fixed an issue where bullet points became visually detached from the text body when toggling text direction formatting (RTL) by locking the list leading block to the editor's base text direction.
- Fixed typed text being inserted at the previous caret position on Android after moving the caret with a tap/mouse by keeping the platform IME's editing state in sync with the selection even when the keyboard is hidden.
- Fixed a `Null check operator used on a null value` crash in `_TextLineState._tapNodeLink`/`_longPressLink` when a cached link gesture recognizer fires after the document mutates: the captured node can be detached or have lost its `link` attribute by the time the tap is swept by the gesture arena (`_linkRecognizers` is not cleared when the line content changes), so the link attribute is now read defensively instead of force-unwrapped.

### Removed

Expand Down
14 changes: 12 additions & 2 deletions lib/src/editor/widgets/text/text_line.dart
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,12 @@ class _TextLineState extends State<TextLine> {
}

void _tapNodeLink(Node node) {
final link = node.style.attributes[Attribute.link.key]!.value;
// The recognizer's onTap closure captures a specific node, but the cached
// recognizer outlives document mutations (_linkRecognizers is not cleared
// when the line content changes). By the time a queued tap is swept by the
// gesture arena, the captured node may be detached or have lost its link
// attribute, so read it defensively instead of force-unwrapping.
final link = node.style.attributes[Attribute.link.key]?.value;

_tapLink(link);
}
Expand All @@ -723,7 +728,12 @@ class _TextLineState extends State<TextLine> {
}

Future<void> _longPressLink(Node node) async {
final link = node.style.attributes[Attribute.link.key]!.value!;
// See _tapNodeLink: the captured node may no longer carry a link attribute
// by the time the gesture fires, so guard instead of force-unwrapping.
final link = node.style.attributes[Attribute.link.key]?.value;
if (link == null) {
return;
}
final action = await widget.linkActionPicker(node);
switch (action) {
case LinkMenuAction.launch:
Expand Down
Loading