collectStyle method

Style collectStyle(
  1. int index,
  2. int len
)

Only attributes applied to all characters within this range are included in the result. Special case of no-selection at start of empty line: gets inline style(s) from preceding non-empty line.

Implementation

Style collectStyle(int index, int len) {
  var res = queryChild(index);
  if (res.node == null) {
    return const Style();
  }
  if (len > 0) {
    return (res.node as Line).collectStyle(res.offset, len);
  }
  //
  if (res.offset == 0) {
    final current = (res.node as Line).collectStyle(0, 0);
    //
    while ((res.node as Line).length == 1 && index > 0) {
      res = queryChild(--index);
    }
    // Get inline attributes from previous line (link does not cross line breaks)
    final prev = (res.node as Line).collectStyle(res.offset, 0);
    final attributes = <String, Attribute>{};
    for (final attr in prev.attributes.values) {
      if (attr.scope == AttributeScope.inline &&
          attr.key != Attribute.link.key) {
        attributes[attr.key] = attr;
      }
    }
    // Combine with block attributes from current line (exclude headers which apply only to the active line)
    for (final attr in current.attributes.values) {
      if (attr.scope == AttributeScope.block &&
          attr.key != Attribute.header.key) {
        attributes[attr.key] = attr;
      }
    }
    return Style.attr(attributes);
  }
  //
  final style = (res.node as Line).collectStyle(res.offset - 1, 0);
  final linkAttribute = style.attributes[Attribute.link.key];
  if (linkAttribute != null) {
    if ((res.node!.length - 1 == res.offset) ||
        (linkAttribute.value !=
            (res.node as Line)
                .collectStyle(res.offset, len)
                .attributes[Attribute.link.key]
                ?.value)) {
      return style.removeAll({linkAttribute});
    }
  }
  return style;
}