convertDocument method

Delta convertDocument(
  1. Document $document, {
  2. bool transformTableAsEmbed = false,
})

Converts a full DOM document into Delta operations.

Processes the entire DOM document $document and converts its nodes into Delta operations. Custom blocks can be applied based on registered customBlocks.

Parameters:

  • $document: The DOM document to convert into Delta operations.

Returns: A Delta object representing the formatted content from the DOM document.

Example:

final document = dparser.parse('<p>Hello <strong>world</strong></p>');
final delta = converter.convertDocument(document);
print(delta.toJson()); // Output: [{"insert":"Hello "},{"insert":"world","attributes":{"bold":true}},{"insert":"\n"}]

Implementation

Delta convertDocument(
  dom.Document $document, {
  bool transformTableAsEmbed = false,
}) {
  final Delta delta = Delta();
  final dom.Element? $body = $document.body;
  final dom.Element? $html = $document.documentElement;

  // Determine nodes to process: <body>, <html>, or document nodes if neither is present
  final List<dom.Node> nodesToProcess =
      $body?.nodes ?? $html?.nodes ?? $document.nodes;

  for (int i = 0; i < nodesToProcess.length; i++) {
    dom.Node node = nodesToProcess[i];
    if (customBlocks != null &&
        customBlocks!.isNotEmpty &&
        node is dom.Element) {
      for (var customBlock in customBlocks!) {
        if (customBlock.matches(node)) {
          final operations = customBlock.convert(node);
          operations.forEach((Operation op) {
            delta.insert(op.data, op.attributes);
          });
          continue;
        }
      }
    }
    final dom.Node? nextNode = nodesToProcess.elementAtOrNull(i + 1);
    bool nextIsBlock = nextNode == null
        ? false
        : nextNode is! dom.Element
            ? false
            : nextNode.isBlock;
    if (isBlockValidator != null) {
      nextIsBlock = isBlockValidator?.call(nextNode is dom.Element
              ? nextNode.localName ?? 'no-localname'
              : 'text-node') ??
          false;
    }
    final List<Operation> operations = nodeToOperation(
      node,
      htmlToOp,
      nextIsBlock,
      transformTableAsEmbed,
    );
    if (operations.isNotEmpty) {
      for (final op in operations) {
        delta.insert(op.data, op.attributes);
      }
    }
    final bool? shouldInsertNewLine = shouldInsertANewLine?.call(
        node is dom.Element ? node.localName ?? 'no-localname' : 'text-node');
    if (shouldInsertNewLine != null && shouldInsertNewLine) {
      delta.insert('\n');
    }
  }
  //ensure insert a new line at the final to avoid any conflict with assertions
  final Operation lastOpdata = delta.last;
  final bool lastDataIsNotNewLine = lastOpdata.data.toString() != '\n';
  final bool hasAttributes = lastOpdata.attributes != null;
  if (lastDataIsNotNewLine && hasAttributes ||
      lastDataIsNotNewLine ||
      !lastDataIsNotNewLine && hasAttributes) {
    delta.insert('\n');
  }
  return delta;
}