convert method

Delta convert(
  1. String htmlText, {
  2. bool transformTableAsEmbed = false,
})

Converts an HTML string into Delta operations.

Converts the HTML string htmlText into Delta operations using QuillJS-compatible attributes. Custom blocks can be applied based on registered customBlocks.

Parameters:

  • htmlText: The HTML string to convert into Delta operations.
  • transformTableAsEmbed: Determine if the table will be inserted as an embed or a simple paragraph.

Returns: A Delta object representing the formatted content from HTML.

Example:

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

Implementation

Delta convert(
  String htmlText, {
  bool transformTableAsEmbed = false,
}) {
  final parsedText = htmlText
      .split('\n')
      .map(
        (e) => e.trim(),
      )
      .join()
      .removeAllNewLines;
  final Delta delta = Delta();
  final dom.Document $document = dparser.parse(replaceNormalNewLinesToBr
      ? parsedText.transformNewLinesToBrTag
      : parsedText);
  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];
    //first just verify if the customBlocks aren't empty and then store on them to
    //validate if one of them make match with the current Node
    if (customBlocks != null &&
        customBlocks!.isNotEmpty &&
        node is dom.Element) {
      for (CustomHtmlPart 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 is dom.Element ? nextNode.isBlock : false;
    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
  if (delta.isNotEmpty) {
    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;
}