Bug fix for link button text selection

pull/602/head
X Code 3 years ago
parent 23a2a9c97d
commit 059ac6f5a4
  1. 28
      lib/src/widgets/link.dart
  2. 29
      lib/src/widgets/text_line.dart
  3. 16
      lib/src/widgets/toolbar/link_style_button.dart

@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import '../models/documents/attribute.dart';
import '../models/documents/nodes/node.dart';
import '../translations/toolbar.i18n.dart';
@ -42,6 +43,33 @@ Future<LinkMenuAction> defaultLinkActionPickerDelegate(
}
}
TextRange getLinkRange(Node node) {
var start = node.documentOffset;
var length = node.length;
var prev = node.previous;
final linkAttr = node.style.attributes[Attribute.link.key]!;
while (prev != null) {
if (prev.style.attributes[Attribute.link.key] == linkAttr) {
start = prev.documentOffset;
length += prev.length;
prev = prev.previous;
} else {
break;
}
}
var next = node.next;
while (next != null) {
if (next.style.attributes[Attribute.link.key] == linkAttr) {
length += next.length;
next = next.next;
} else {
break;
}
}
return TextRange(start: start, end: start + length);
}
Future<LinkMenuAction> _showCupertinoLinkMenu(
BuildContext context, String link) async {
final result = await showCupertinoModalPopup<LinkMenuAction>(

@ -423,7 +423,7 @@ class _TextLineState extends State<TextLine> {
Clipboard.setData(ClipboardData(text: link));
break;
case LinkMenuAction.remove:
final range = _getLinkRange(node);
final range = getLinkRange(node);
widget.controller
.formatText(range.start, range.end - range.start, Attribute.link);
break;
@ -432,33 +432,6 @@ class _TextLineState extends State<TextLine> {
}
}
TextRange _getLinkRange(Node node) {
var start = node.documentOffset;
var length = node.length;
var prev = node.previous;
final linkAttr = node.style.attributes[Attribute.link.key]!;
while (prev != null) {
if (prev.style.attributes[Attribute.link.key] == linkAttr) {
start = prev.documentOffset;
length += prev.length;
prev = prev.previous;
} else {
break;
}
}
var next = node.next;
while (next != null) {
if (next.style.attributes[Attribute.link.key] == linkAttr) {
length += next.length;
next = next.next;
} else {
break;
}
}
return TextRange(start: start, end: start + length);
}
TextStyle _merge(TextStyle a, TextStyle b) {
final decorations = <TextDecoration?>[];
if (a.decoration != null) {

@ -7,6 +7,7 @@ import '../../models/themes/quill_dialog_theme.dart';
import '../../models/themes/quill_icon_theme.dart';
import '../../translations/toolbar.i18n.dart';
import '../controller.dart';
import '../link.dart';
import '../toolbar.dart';
class LinkStyleButton extends StatefulWidget {
@ -134,10 +135,19 @@ class _LinkStyleButtonState extends State<LinkStyleButton> {
final String text = (value as Tuple2).item1;
final String link = value.item2;
final index = widget.controller.selection.baseOffset;
final length = widget.controller.selection.extentOffset - index;
var index = widget.controller.selection.baseOffset;
var length = widget.controller.selection.extentOffset - index;
if (_getLinkAttributeValue() != null) {
// text should be the link's corresponding text, not selection
final leaf = widget.controller.document.querySegmentLeafNode(index).item2;
if (leaf != null) {
final range = getLinkRange(leaf);
index = range.start;
length = range.end - range.start;
}
}
widget.controller.replaceText(index, length, text, null);
widget.controller.formatSelection(LinkAttribute(link));
widget.controller.formatText(index, text.length, LinkAttribute(link));
}
}

Loading…
Cancel
Save