Skip to content

Commit 73ad789

Browse files
authored
Merge pull request #1696 from abichinger/feat/md-blockquote
feat: greater to blockquote
2 parents 4fb2afe + b2bc59c commit 73ad789

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/whitespace_handler.dart

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ const _bulletedListSymbols = ['*', '-'];
2020
const _checkboxListSymbols = ['[x]', '-[x]'];
2121
const _unCheckboxListSymbols = ['[]', '-[]'];
2222

23+
const _quoteSymbols = ['>'];
24+
2325
final _numberRegex = RegExp(r'^(\d+)\.');
2426

2527
ShortcutEventHandler whiteSpaceHandler = (editorState, event) {
@@ -49,6 +51,8 @@ ShortcutEventHandler whiteSpaceHandler = (editorState, event) {
4951
return _toBulletedList(editorState, textNode);
5052
} else if (_countOfSign(text, selection) != 0) {
5153
return _toHeadingStyle(editorState, textNode, selection);
54+
} else if (_quoteSymbols.contains(text)) {
55+
return _toQuoteStyle(editorState, textNode);
5256
} else if (numberMatch != null) {
5357
final matchText = numberMatch.group(0);
5458
final numText = numberMatch.group(1);
@@ -196,3 +200,22 @@ int _countOfSign(String text, Selection selection) {
196200
}
197201
return 0;
198202
}
203+
204+
KeyEventResult _toQuoteStyle(EditorState editorState, TextNode textNode) {
205+
if (textNode.subtype == BuiltInAttributeKey.quote) {
206+
return KeyEventResult.ignored;
207+
}
208+
final transaction = editorState.transaction
209+
..deleteText(textNode, 0, 1)
210+
..updateNode(textNode, {
211+
BuiltInAttributeKey.subtype: BuiltInAttributeKey.quote,
212+
})
213+
..afterSelection = Selection.collapsed(
214+
Position(
215+
path: textNode.path,
216+
offset: 0,
217+
),
218+
);
219+
editorState.apply(transaction);
220+
return KeyEventResult.handled;
221+
}

frontend/app_flowy/packages/appflowy_editor/test/service/internal_key_event_handlers/white_space_handler_test.dart

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ void main() async {
184184
Selection.single(path: [0], startOffset: 0),
185185
);
186186

187+
await editor.insertText(textNode, '>', 0);
188+
await editor.pressLogicKey(LogicalKeyboardKey.space);
189+
expect(textNode.subtype, BuiltInAttributeKey.quote);
190+
187191
await editor.insertText(textNode, '*', 0);
188192
await editor.pressLogicKey(LogicalKeyboardKey.space);
189193
expect(textNode.subtype, BuiltInAttributeKey.bulletedList);
@@ -227,5 +231,65 @@ void main() async {
227231
expect(textNode.subtype, null);
228232
expect(textNode.toPlainText(), text);
229233
});
234+
235+
group('convert geater to blockquote', () {
236+
testWidgets('> AppFlowy to blockquote AppFlowy', (tester) async {
237+
const text = 'AppFlowy';
238+
final editor = tester.editor..insertTextNode('');
239+
await editor.startTesting();
240+
await editor.updateSelection(
241+
Selection.single(path: [0], startOffset: 0),
242+
);
243+
244+
final textNode = editor.nodeAtPath([0]) as TextNode;
245+
await editor.insertText(textNode, '>', 0);
246+
await editor.pressLogicKey(LogicalKeyboardKey.space);
247+
expect(textNode.subtype, BuiltInAttributeKey.quote);
248+
for (var i = 0; i < text.length; i++) {
249+
await editor.insertText(textNode, text[i], i);
250+
}
251+
expect(textNode.toPlainText(), 'AppFlowy');
252+
});
253+
254+
testWidgets('AppFlowy > nothing changes', (tester) async {
255+
const text = 'AppFlowy >';
256+
final editor = tester.editor..insertTextNode('');
257+
await editor.startTesting();
258+
await editor.updateSelection(
259+
Selection.single(path: [0], startOffset: 0),
260+
);
261+
262+
final textNode = editor.nodeAtPath([0]) as TextNode;
263+
for (var i = 0; i < text.length; i++) {
264+
await editor.insertText(textNode, text[i], i);
265+
}
266+
await editor.pressLogicKey(LogicalKeyboardKey.space);
267+
final isQuote = textNode.subtype == BuiltInAttributeKey.quote;
268+
expect(isQuote, false);
269+
expect(textNode.toPlainText(), text);
270+
});
271+
272+
testWidgets('> in front of text to blockquote', (tester) async {
273+
const text = 'AppFlowy';
274+
final editor = tester.editor..insertTextNode('');
275+
await editor.startTesting();
276+
await editor.updateSelection(
277+
Selection.single(path: [0], startOffset: 0),
278+
);
279+
final textNode = editor.nodeAtPath([0]) as TextNode;
280+
for (var i = 0; i < text.length; i++) {
281+
await editor.insertText(textNode, text[i], i);
282+
}
283+
await editor.updateSelection(
284+
Selection.single(path: [0], startOffset: 0),
285+
);
286+
await editor.insertText(textNode, '>', 0);
287+
await editor.pressLogicKey(LogicalKeyboardKey.space);
288+
289+
final isQuote = textNode.subtype == BuiltInAttributeKey.quote;
290+
expect(isQuote, true);
291+
expect(textNode.toPlainText(), text);
292+
});
293+
});
230294
});
231295
}

0 commit comments

Comments
 (0)