visitElementAfter method

  1. @override
void visitElementAfter(
  1. Element element
)

Called when an Element has been reached, after its children have been visited.

Will not be called if visitElementBefore returns false.

Implementation

@override
void visitElementAfter(md.Element element) {
  final String tag = element.tag;

  if (_isBlockTag(tag)) {
    _addAnonymousBlockIfNeeded();

    final _BlockElement current = _blocks.removeLast();
    Widget child;

    if (current.children.isNotEmpty) {
      child = Column(
        crossAxisAlignment: fitContent
            ? CrossAxisAlignment.start
            : CrossAxisAlignment.stretch,
        children: current.children,
      );
    } else {
      child = const SizedBox();
    }

    if (_isListTag(tag)) {
      assert(_listIndents.isNotEmpty);
      _listIndents.removeLast();
    } else if (tag == 'li') {
      if (_listIndents.isNotEmpty) {
        if (element.children!.isEmpty) {
          element.children!.add(md.Text(''));
        }
        Widget bullet;
        final dynamic el = element.children![0];
        if (el is md.Element && el.attributes['type'] == 'checkbox') {
          final bool val = el.attributes['checked'] != 'false';
          bullet = _buildCheckbox(val);
        } else {
          bullet = _buildBullet(_listIndents.last);
        }
        child = Row(
          textBaseline: listItemCrossAxisAlignment ==
                  MarkdownListItemCrossAxisAlignment.start
              ? null
              : TextBaseline.alphabetic,
          crossAxisAlignment: listItemCrossAxisAlignment ==
                  MarkdownListItemCrossAxisAlignment.start
              ? CrossAxisAlignment.start
              : CrossAxisAlignment.baseline,
          children: <Widget>[
            SizedBox(
              width: styleSheet.listIndent! +
                  styleSheet.listBulletPadding!.left +
                  styleSheet.listBulletPadding!.right,
              child: bullet,
            ),
            Expanded(child: child)
          ],
        );
      }
    } else if (tag == 'table') {
      child = Table(
        defaultColumnWidth: styleSheet.tableColumnWidth!,
        defaultVerticalAlignment: TableCellVerticalAlignment.middle,
        border: styleSheet.tableBorder,
        children: _tables.removeLast().rows,
      );
    } else if (tag == 'blockquote') {
      _isInBlockquote = false;
      child = DecoratedBox(
        decoration: styleSheet.blockquoteDecoration!,
        child: Padding(
          padding: styleSheet.blockquotePadding!,
          child: child,
        ),
      );
    } else if (tag == 'pre') {
      child = DecoratedBox(
        decoration: styleSheet.codeblockDecoration!,
        child: child,
      );
    } else if (tag == 'hr') {
      child = Container(decoration: styleSheet.horizontalRuleDecoration);
    }

    _addBlockChild(child);
  } else {
    final _InlineElement current = _inlines.removeLast();
    final _InlineElement parent = _inlines.last;

    if (builders.containsKey(tag)) {
      final Widget? child =
          builders[tag]!.visitElementAfter(element, styleSheet.styles[tag]);
      if (child != null) {
        current.children[0] = child;
      }
    } else if (tag == 'img') {
      // create an image widget for this image
      current.children.add(BuildImage(
        element.attributes['src']!,
        element.attributes['title'],
        element.attributes['alt'],
        imageBuilder,
        imageDirectory,
        _linkHandlers,
      ));
    } else if (tag == 'br') {
      current.children.add(_buildRichText(const TextSpan(text: '\n')));
    } else if (tag == 'th' || tag == 'td') {
      TextAlign? align;
      final String? style = element.attributes['style'];
      if (style == null) {
        align = tag == 'th' ? styleSheet.tableHeadAlign : TextAlign.left;
      } else {
        final RegExp regExp = RegExp(r'text-align: (left|center|right)');
        final Match match = regExp.matchAsPrefix(style)!;
        switch (match[1]) {
          case 'left':
            align = TextAlign.left;
            break;
          case 'center':
            align = TextAlign.center;
            break;
          case 'right':
            align = TextAlign.right;
            break;
        }
      }
      final Widget child = _buildTableCell(
        _mergeInlineChildren(current.children, align),
        textAlign: align,
      );
      _tables.single.rows.last.children!.add(child);
    } else if (tag == 'a') {
      _linkHandlers.removeLast();
    }

    if (current.children.isNotEmpty) {
      parent.children.addAll(current.children);
    }
  }
  if (_currentBlockTag == tag) {
    _currentBlockTag = null;
  }
  _lastTag = tag;
}