diff --git a/lib/parser/default_html_to_ops.dart b/lib/parser/default_html_to_ops.dart
index d1a2b5a..4757f0c 100644
--- a/lib/parser/default_html_to_ops.dart
+++ b/lib/parser/default_html_to_ops.dart
@@ -2,9 +2,9 @@ import 'package:dart_quill_delta/dart_quill_delta.dart';
import 'package:flutter_quill_delta_from_html/parser/extensions/node_ext.dart';
import 'package:flutter_quill_delta_from_html/parser/html_to_operation.dart';
import 'package:flutter_quill_delta_from_html/parser/html_utils.dart';
+import 'package:flutter_quill_delta_from_html/parser/node_processor.dart';
import 'package:flutter_quill_delta_from_html/parser/typedef/typedefs.dart';
import 'package:html/dom.dart' as dom;
-import 'package:flutter_quill_delta_from_html/parser/node_processor.dart';
/// Default implementation of `HtmlOperations` for converting common HTML to Delta operations.
///
@@ -59,10 +59,19 @@ class DefaultHtmlToOperations extends HtmlOperations {
}
inlineAttributes.addAll(styleAttributes);
}
+
+ // Check if paragraph is inside a list item
+ final isInsideListItem = element.parent?.localName == 'li';
+
final nodes = element.nodes;
//this store into all nodes into a paragraph, and
//ensure getting all attributes or tags into a paragraph
for (final node in nodes) {
+ // Skip
tags if inside a list item
+ if (isInsideListItem && node is dom.Element && node.isBreakLine) {
+ continue;
+ }
+
processNode(
node,
inlineAttributes,
@@ -75,6 +84,12 @@ class DefaultHtmlToOperations extends HtmlOperations {
if (blockAttributes.isNotEmpty) {
blockAttributes.removeWhere((key, value) => value == null);
delta.insert('\n', blockAttributes);
+ } else {
+ // Insert newline if parent is not a list, OR if parent is a list but current element is not the last child of
+ final parent = element.parent;
+ if (parent?.isList == false) {
+ delta.insert('\n');
+ }
}
return delta.toList();
@@ -239,6 +254,10 @@ class DefaultHtmlToOperations extends HtmlOperations {
final List items =
element.children.where((child) => child.localName == 'li').toList();
+ final startAttr = element.attributes["start"];
+ if (startAttr != null) {
+ attributes["start"] = startAttr;
+ }
if (tagName == 'ul') {
attributes['list'] = 'bullet';
} else if (tagName == 'ol') {
diff --git a/lib/parser/html_to_delta.dart b/lib/parser/html_to_delta.dart
index b5734e5..18cc6d5 100644
--- a/lib/parser/html_to_delta.dart
+++ b/lib/parser/html_to_delta.dart
@@ -170,7 +170,8 @@ class HtmlToDelta {
//ensure insert a new line at the final to avoid any conflict with assertions
if (delta.isNotEmpty) {
final Operation lastOpdata = delta.last;
- final bool lastDataIsNotNewLine = lastOpdata.data.toString() != '\n';
+ final bool lastDataIsNotNewLine = lastOpdata.data.toString() != '\n' &&
+ !lastOpdata.data.toString().endsWith('\n');
final bool hasAttributes = lastOpdata.attributes != null;
if (lastDataIsNotNewLine && hasAttributes ||
lastDataIsNotNewLine ||
diff --git a/lib/parser/node_processor.dart b/lib/parser/node_processor.dart
index 5862fe6..5d8f688 100644
--- a/lib/parser/node_processor.dart
+++ b/lib/parser/node_processor.dart
@@ -1,5 +1,6 @@
import 'package:dart_quill_delta/dart_quill_delta.dart';
import 'package:flutter_quill_delta_from_html/flutter_quill_delta_from_html.dart';
+import 'package:flutter_quill_delta_from_html/parser/default_html_to_ops.dart';
import 'package:html/dom.dart' as dom;
/// Processes a DOM [node], converting it into Quill Delta operations.
@@ -21,15 +22,14 @@ import 'package:html/dom.dart' as dom;
/// processNode(htmlNode, {}, delta);
/// print(delta.toJson()); // Output: [{"insert": "Hello, "}, {"insert": "World", "attributes": {"italic": true, "bold": true}}, {"insert": "!"}]
/// ```
-void processNode(
- dom.Node node,
- Map attributes,
- Delta delta, {
- bool addSpanAttrs = false,
- List? customBlocks,
- List? removeTheseAttributesFromSpan,
- CSSVarible? onDetectLineheightCssVariable,
-}) {
+void processNode(dom.Node node,
+ Map attributes,
+ Delta delta, {
+ bool addSpanAttrs = false,
+ List? customBlocks,
+ List? removeTheseAttributesFromSpan,
+ CSSVarible? onDetectLineheightCssVariable,
+ }) {
if (node is dom.Text) {
delta.insert(node.text, attributes.isEmpty ? null : attributes);
} else if (node is dom.Element) {
@@ -42,20 +42,33 @@ void processNode(
if (node.isStrike) newAttributes['strike'] = true;
if (node.isSubscript) newAttributes['script'] = 'sub';
if (node.isSuperscript) newAttributes['script'] = 'super';
+ bool handledByCustomBlock = false;
// Use custom block definitions if provided
if (customBlocks != null && customBlocks.isNotEmpty) {
for (var customBlock in customBlocks) {
if (customBlock.matches(node)) {
final operations =
- customBlock.convert(node, currentAttributes: newAttributes);
+ customBlock.convert(node, currentAttributes: newAttributes);
operations.forEach((Operation op) {
delta.insert(op.data, op.attributes);
});
+ handledByCustomBlock = true;
continue;
}
}
- } else {
+ }
+
+ if (!handledByCustomBlock) {
+ final htmlOperations =DefaultHtmlToOperations(onDetectLineheightCssVariable);
+ if(node.isCodeBlock){
+
+ final operations=htmlOperations.codeblockToOp(node);
+ operations.forEach((Operation op) {
+ delta.insert(op.data, op.attributes);
+ });
+ return;
+ }
// Handle tags
if (node.isSpan) {
final spanAttributes = parseStyleAttribute(
@@ -77,6 +90,7 @@ void processNode(
}
}
+
// Handle
tags
if (node.isImg) {
final String src = node.attributes['src'] ?? '';
@@ -89,11 +103,11 @@ void processNode(
styles.isEmpty
? null
: {
- 'style': attributes.entries
- .map((entry) => '${entry.key}:${entry.value}')
- .toList()
- .join(';'),
- },
+ 'style': attributes.entries
+ .map((entry) => '${entry.key}:${entry.value}')
+ .toList()
+ .join(';'),
+ },
);
}
}