mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-26 08:36:50 +08:00
Checklist: Implement serialization back into Note
This commit is contained in:
@ -1,29 +1,55 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:markdown/markdown.dart' as md;
|
import 'package:markdown/markdown.dart' as md;
|
||||||
|
|
||||||
import 'package:gitjournal/core/note.dart';
|
import 'package:gitjournal/core/note.dart';
|
||||||
|
|
||||||
class ChecklistItem {
|
class ChecklistItem {
|
||||||
bool checked;
|
|
||||||
String text;
|
|
||||||
md.Element element;
|
md.Element element;
|
||||||
|
|
||||||
ChecklistItem({
|
bool get checked {
|
||||||
@required this.checked,
|
return element.attributes['checked'] != "false";
|
||||||
@required this.text,
|
}
|
||||||
@required this.element,
|
|
||||||
});
|
set checked(bool val) {
|
||||||
|
element.attributes['checked'] = val.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
String get text {
|
||||||
|
return element.attributes['text'];
|
||||||
|
}
|
||||||
|
|
||||||
|
set text(String val) {
|
||||||
|
element.attributes['text'] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChecklistItem.fromMarkdownElement(this.element);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'ChecklistItem: $checked $text';
|
String toString() => 'ChecklistItem: $checked $text';
|
||||||
}
|
}
|
||||||
|
|
||||||
class Checklist {
|
class Checklist {
|
||||||
Note note;
|
Note _note;
|
||||||
List<ChecklistItem> items;
|
List<ChecklistItem> items;
|
||||||
|
List<md.Node> nodes;
|
||||||
|
|
||||||
Checklist(this.note) {
|
Checklist(this._note) {
|
||||||
items = ChecklistBuilder().parse(note.body);
|
var doc = md.Document(
|
||||||
|
encodeHtml: false,
|
||||||
|
inlineSyntaxes: [TaskListSyntax()],
|
||||||
|
extensionSet: md.ExtensionSet.gitHubFlavored,
|
||||||
|
);
|
||||||
|
|
||||||
|
nodes = doc.parseInline(_note.body);
|
||||||
|
items = ChecklistBuilder().build(nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
Note get note {
|
||||||
|
if (nodes.isEmpty) return _note;
|
||||||
|
|
||||||
|
var renderer = CustomRenderer();
|
||||||
|
_note.body = renderer.render(nodes);
|
||||||
|
|
||||||
|
return _note;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,19 +88,12 @@ class ChecklistBuilder implements md.NodeVisitor {
|
|||||||
void visitText(md.Text text) {}
|
void visitText(md.Text text) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void visitElementAfter(md.Element element) {
|
void visitElementAfter(md.Element el) {
|
||||||
final String tag = element.tag;
|
final String tag = el.tag;
|
||||||
|
|
||||||
if (tag == 'input') {
|
if (tag == 'input') {
|
||||||
var el = element;
|
|
||||||
if (el is md.Element && el.attributes['type'] == 'checkbox') {
|
if (el is md.Element && el.attributes['type'] == 'checkbox') {
|
||||||
bool val = el.attributes['checked'] != 'false';
|
list.add(ChecklistItem.fromMarkdownElement(el));
|
||||||
var item = ChecklistItem(
|
|
||||||
checked: val,
|
|
||||||
text: el.attributes['text'],
|
|
||||||
element: el,
|
|
||||||
);
|
|
||||||
list.add(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,15 +106,49 @@ class ChecklistBuilder implements md.NodeVisitor {
|
|||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<ChecklistItem> parse(String text) {
|
class CustomRenderer implements md.NodeVisitor {
|
||||||
var doc = md.Document(
|
StringBuffer buffer;
|
||||||
encodeHtml: false,
|
|
||||||
inlineSyntaxes: [TaskListSyntax()],
|
|
||||||
extensionSet: md.ExtensionSet.gitHubFlavored,
|
|
||||||
);
|
|
||||||
|
|
||||||
var nodes = doc.parseInline(text);
|
@override
|
||||||
return build(nodes);
|
bool visitElementBefore(md.Element element) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitText(md.Text text) {
|
||||||
|
buffer.write(text.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitElementAfter(md.Element element) {
|
||||||
|
final String tag = element.tag;
|
||||||
|
|
||||||
|
if (tag == 'input') {
|
||||||
|
var el = element;
|
||||||
|
if (el is md.Element && el.attributes['type'] == 'checkbox') {
|
||||||
|
bool val = el.attributes['checked'] != 'false';
|
||||||
|
if (val) {
|
||||||
|
if (el.attributes['xUpperCase'] != 'false') {
|
||||||
|
buffer.write('[x] ');
|
||||||
|
} else {
|
||||||
|
buffer.write('[X] ');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buffer.write('[ ] ');
|
||||||
|
}
|
||||||
|
buffer.write(el.attributes['text']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String render(List<md.Node> nodes) {
|
||||||
|
buffer = StringBuffer();
|
||||||
|
|
||||||
|
for (final node in nodes) {
|
||||||
|
node.accept(this);
|
||||||
|
}
|
||||||
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ How are you doing?
|
|||||||
|
|
||||||
[ ] item 1
|
[ ] item 1
|
||||||
[x] item 2
|
[x] item 2
|
||||||
[X] item 3
|
[x] item 3
|
||||||
[ ] item 4
|
[ ] item 4
|
||||||
|
|
||||||
Booga Wooga
|
Booga Wooga
|
||||||
@ -55,6 +55,36 @@ Booga Wooga
|
|||||||
expect(checklist.items[1].text, "item 2");
|
expect(checklist.items[1].text, "item 2");
|
||||||
expect(checklist.items[2].text, "item 3");
|
expect(checklist.items[2].text, "item 3");
|
||||||
expect(checklist.items[3].text, "item 4");
|
expect(checklist.items[3].text, "item 4");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Serialization
|
||||||
|
//
|
||||||
|
|
||||||
|
checklist.items[0].checked = true;
|
||||||
|
checklist.items[1].checked = false;
|
||||||
|
checklist.items[1].text = "Foo";
|
||||||
|
|
||||||
|
await checklist.note.save();
|
||||||
|
|
||||||
|
var expectedContent = """---
|
||||||
|
title: Foo
|
||||||
|
modified: 2017-02-15T22:41:19+01:00
|
||||||
|
---
|
||||||
|
|
||||||
|
# Title 1
|
||||||
|
|
||||||
|
How are you doing?
|
||||||
|
|
||||||
|
[x] item 1
|
||||||
|
[ ] Foo
|
||||||
|
[X] item 3
|
||||||
|
[ ] item 4
|
||||||
|
|
||||||
|
Booga Wooga
|
||||||
|
""";
|
||||||
|
|
||||||
|
var actualContent = File(notePath).readAsStringSync();
|
||||||
|
expect(actualContent, equals(expectedContent));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user