- Refactor getPlainText (better handling of blank lines and lines with multiple markups) (#700)

pull/705/head
Michael Allen 3 years ago committed by GitHub
parent e51367b733
commit 61551d0a48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 89
      lib/src/models/documents/nodes/line.dart
  2. 29
      lib/src/widgets/raw_editor.dart

@ -460,66 +460,53 @@ class Line extends Container<Leaf?> {
/// Returns plain text within the specified text range. /// Returns plain text within the specified text range.
String getPlainText(int offset, int len) { String getPlainText(int offset, int len) {
final res = _getPlainText(offset, len); final plainText = StringBuffer();
if (res.length == 1) { _getPlainText(offset, len, plainText);
final data = queryChild(offset, true); return plainText.toString();
final text = res.single.item2; }
return text == Embed.kObjectReplacementCharacter
? ''
: text.substring(data.offset, data.offset + len);
}
final total = <String>[];
// Adjust first node
final firstNodeLen = res[1].item1;
var text = res[0].item2;
if (text != Embed.kObjectReplacementCharacter) {
total.add(text.substring(text.length - firstNodeLen));
}
var middleNodesLen = 0;
for (var i = 1; i < res.length - 1; i++) {
if (res[i].item2 != Embed.kObjectReplacementCharacter) {
middleNodesLen += res[i].item1;
total.add(res[i].item2);
}
}
// Adjust last node int _getNodeText(Leaf node, StringBuffer buffer, int offset, int remaining) {
final lastNodeLen = len - middleNodesLen - res[res.length - 1].item1; final text = node.toPlainText();
text = res[res.length - 1].item2; if (text == Embed.kObjectReplacementCharacter) {
if (text != Embed.kObjectReplacementCharacter) { return remaining - node.length;
total.add(text.substring(0, lastNodeLen));
} }
return total.join();
}
List<Tuple2<int, String>> _getPlainText(int offset, int len, {int beg = 0}) { final end = math.min(offset + remaining, text.length);
final local = math.min(length - offset, len); buffer.write(text.substring(offset, end));
final result = <Tuple2<int, String>>[]; return remaining - (end - offset);
}
int _getPlainText(int offset, int len, StringBuffer plainText) {
var _len = len;
final data = queryChild(offset, true); final data = queryChild(offset, true);
var node = data.node as Leaf?; var node = data.node as Leaf?;
if (node != null) {
var pos = node.length - data.offset; while (_len > 0) {
result.add(Tuple2(beg, node.toPlainText())); if (node == null) {
while (!node!.isLast && pos < local) { // blank line
node = node.next as Leaf; plainText.write('\n');
result.add(Tuple2(pos + beg, node.toPlainText())); _len -= 1;
pos += node.length;
} }
} else {
_len = _getNodeText(node, plainText, offset, _len);
final remaining = len - local; while (!node!.isLast && _len > 0) {
if (remaining > 0) { node = node.next as Leaf;
final lastElem = result[result.length - 1]; _len = _getNodeText(node, plainText, 0, _len);
result }
..removeLast()
..add(Tuple2(lastElem.item1, '${lastElem.item2}\n')); if (_len > 0) {
final rest = nextLine!._getPlainText(0, remaining, beg: local); // end of this line
result.addAll(rest); plainText.write('\n');
_len -= 1;
}
}
if (_len > 0) {
_len = nextLine!._getPlainText(0, _len, plainText);
}
} }
return result; return _len;
} }
} }

@ -904,19 +904,20 @@ class RawEditorState extends EditorState
if (cause == SelectionChangedCause.toolbar) { if (cause == SelectionChangedCause.toolbar) {
bringIntoView(textEditingValue.selection.extent); bringIntoView(textEditingValue.selection.extent);
// on iOS, Safari does not hide the selection after copy
// however, most other iOS apps do as well as other platforms
// so we'll hide toolbar & selection after copy
hideToolbar(false); hideToolbar(false);
if (!Platform.isIOS) { // Collapse the selection and hide the toolbar and handles.
// Collapse the selection and hide the toolbar and handles. userUpdateTextEditingValue(
userUpdateTextEditingValue( TextEditingValue(
TextEditingValue( text: textEditingValue.text,
text: textEditingValue.text, selection:
selection: TextSelection.collapsed(offset: textEditingValue.selection.end),
TextSelection.collapsed(offset: textEditingValue.selection.end), ),
), SelectionChangedCause.toolbar,
SelectionChangedCause.toolbar, );
);
}
} }
} }
@ -983,7 +984,11 @@ class RawEditorState extends EditorState
ReplaceTextIntent(textEditingValue, data.text!, selection, cause)); ReplaceTextIntent(textEditingValue, data.text!, selection, cause));
if (cause == SelectionChangedCause.toolbar) { if (cause == SelectionChangedCause.toolbar) {
bringIntoView(textEditingValue.selection.extent); try {
// ignore exception when paste window is at end of document
bringIntoView(textEditingValue.selection.extent);
}
catch(_){};
hideToolbar(); hideToolbar();
} }
} }

Loading…
Cancel
Save