DeltaX.fromHtml

pull/1609/head
agu 1 year ago
parent b03cb72888
commit 821e02d8c9
  1. 2
      example/lib/presentation/quill/quill_screen.dart
  2. 58
      lib/src/models/documents/document.dart
  3. 2
      lib/src/widgets/raw_editor/raw_editor_state.dart

@ -76,7 +76,7 @@ class _QuillScreenState extends State<QuillScreen> {
onPressed: () { onPressed: () {
final html = _controller.document.toDelta().toHtml(); final html = _controller.document.toDelta().toHtml();
_controller.document = _controller.document =
Document.fromDelta(Document.fromHtml(html)); Document.fromDelta(DeltaX.fromHtml(html));
}, },
icon: const Icon(Icons.html), icon: const Icon(Icons.html),
), ),

@ -4,7 +4,6 @@ import 'package:html2md/html2md.dart' as html2md;
import 'package:markdown/markdown.dart' as md; import 'package:markdown/markdown.dart' as md;
import '../../../markdown_quill.dart'; import '../../../markdown_quill.dart';
import '../../../quill_delta.dart'; import '../../../quill_delta.dart';
import '../../widgets/quill/embeds.dart'; import '../../widgets/quill/embeds.dart';
import '../rules/rule.dart'; import '../rules/rule.dart';
@ -58,8 +57,7 @@ class Document {
_rules.setCustomRules(customRules); _rules.setCustomRules(customRules);
} }
final StreamController<DocChange> documentChangeObserver = final StreamController<DocChange> documentChangeObserver = StreamController.broadcast();
StreamController.broadcast();
final History history = History(); final History history = History();
@ -84,8 +82,7 @@ class Document {
return Delta(); return Delta();
} }
final delta = _rules.apply(RuleType.insert, this, index, final delta = _rules.apply(RuleType.insert, this, index, data: data, len: replaceLength);
data: data, len: replaceLength);
compose(delta, ChangeSource.local); compose(delta, ChangeSource.local);
return delta; return delta;
} }
@ -148,8 +145,7 @@ class Document {
var delta = Delta(); var delta = Delta();
final formatDelta = _rules.apply(RuleType.format, this, index, final formatDelta = _rules.apply(RuleType.format, this, index, len: len, attribute: attribute);
len: len, attribute: attribute);
if (formatDelta.isNotEmpty) { if (formatDelta.isNotEmpty) {
compose(formatDelta, ChangeSource.local); compose(formatDelta, ChangeSource.local);
delta = delta.compose(formatDelta); delta = delta.compose(formatDelta);
@ -189,8 +185,7 @@ class Document {
/// Returns all styles and Embed for each node within selection /// Returns all styles and Embed for each node within selection
List<OffsetValue> collectAllIndividualStyleAndEmbed(int index, int len) { List<OffsetValue> collectAllIndividualStyleAndEmbed(int index, int len) {
final res = queryChild(index); final res = queryChild(index);
return (res.node as Line) return (res.node as Line).collectAllIndividualStylesAndEmbed(res.offset, len);
.collectAllIndividualStylesAndEmbed(res.offset, len);
} }
/// Returns all styles for any character within the specified text range. /// Returns all styles for any character within the specified text range.
@ -299,8 +294,7 @@ class Document {
delta = _transform(delta); delta = _transform(delta);
final originalDelta = toDelta(); final originalDelta = toDelta();
for (final op in delta.toList()) { for (final op in delta.toList()) {
final style = final style = op.attributes != null ? Style.fromJson(op.attributes) : null;
op.attributes != null ? Style.fromJson(op.attributes) : null;
if (op.isInsert) { if (op.isInsert) {
// Must normalize data before inserting into the document, makes sure // Must normalize data before inserting into the document, makes sure
@ -366,8 +360,7 @@ class Document {
res.push(Operation.insert('\n')); res.push(Operation.insert('\n'));
} }
// embed could be image or video // embed could be image or video
final opInsertEmbed = final opInsertEmbed = op.isInsert && op.data is Map && (op.data as Map).containsKey(type);
op.isInsert && op.data is Map && (op.data as Map).containsKey(type);
final nextOpIsLineBreak = i + 1 < ops.length && final nextOpIsLineBreak = i + 1 < ops.length &&
ops[i + 1].isInsert && ops[i + 1].isInsert &&
ops[i + 1].data is String && ops[i + 1].data is String &&
@ -399,9 +392,7 @@ class Document {
Iterable<EmbedBuilder>? embedBuilders, Iterable<EmbedBuilder>? embedBuilders,
EmbedBuilder? unknownEmbedBuilder, EmbedBuilder? unknownEmbedBuilder,
]) => ]) =>
_root.children _root.children.map((e) => e.toPlainText(embedBuilders, unknownEmbedBuilder)).join();
.map((e) => e.toPlainText(embedBuilders, unknownEmbedBuilder))
.join();
void _loadDocument(Delta doc) { void _loadDocument(Delta doc) {
if (doc.isEmpty) { if (doc.isEmpty) {
@ -414,20 +405,16 @@ class Document {
var offset = 0; var offset = 0;
for (final op in doc.toList()) { for (final op in doc.toList()) {
if (!op.isInsert) { if (!op.isInsert) {
throw ArgumentError.value(doc, throw ArgumentError.value(
'Document can only contain insert operations but ${op.key} found.'); doc, 'Document can only contain insert operations but ${op.key} found.');
} }
final style = final style = op.attributes != null ? Style.fromJson(op.attributes) : null;
op.attributes != null ? Style.fromJson(op.attributes) : null;
final data = _normalize(op.data); final data = _normalize(op.data);
_root.insert(offset, data, style); _root.insert(offset, data, style);
offset += op.length!; offset += op.length!;
} }
final node = _root.last; final node = _root.last;
if (node is Line && if (node is Line && node.parent is! Block && node.style.isEmpty && _root.childCount > 1) {
node.parent is! Block &&
node.style.isEmpty &&
_root.childCount > 1) {
_root.remove(node); _root.remove(node);
} }
} }
@ -443,11 +430,11 @@ class Document {
} }
final delta = node.toDelta(); final delta = node.toDelta();
return delta.length == 1 && return delta.length == 1 && delta.first.data == '\n' && delta.first.key == 'insert';
delta.first.data == '\n' && }
delta.first.key == 'insert';
} }
class DeltaX {
/// Convert the HTML Raw string to [Delta] /// Convert the HTML Raw string to [Delta]
/// ///
/// It will run using the following steps: /// It will run using the following steps:
@ -458,28 +445,13 @@ class Document {
/// ///
/// for more [info](https://github.com/singerdmx/flutter-quill/issues/1100) /// for more [info](https://github.com/singerdmx/flutter-quill/issues/1100)
static Delta fromHtml(String html) { static Delta fromHtml(String html) {
final markdown = html2md final markdown = html2md.convert(html).replaceAll('unsafe:', '');
.convert(
html,
)
.replaceAll('unsafe:', '');
final mdDocument = md.Document(encodeHtml: false); final mdDocument = md.Document(encodeHtml: false);
final mdToDelta = MarkdownToDelta(markdownDocument: mdDocument); final mdToDelta = MarkdownToDelta(markdownDocument: mdDocument);
return mdToDelta.convert(markdown); return mdToDelta.convert(markdown);
// final deltaJsonString = markdownToDelta(markdown);
// final deltaJson = jsonDecode(deltaJsonString);
// if (deltaJson is! List) {
// throw ArgumentError(
// 'The delta json string should be of type list when jsonDecode() it',
// );
// }
// return Delta.fromJson(
// deltaJson,
// );
} }
} }

@ -213,7 +213,7 @@ class QuillRawEditorState extends EditorState
if (html == null) { if (html == null) {
return; return;
} }
final deltaFromCliboard = Document.fromHtml(html); final deltaFromCliboard = DeltaX.fromHtml(html);
final delta = deltaFromCliboard.compose(controller.document.toDelta()); final delta = deltaFromCliboard.compose(controller.document.toDelta());
controller controller

Loading…
Cancel
Save