buildTextSpan method

  1. @override
TextSpan buildTextSpan({
  1. required BuildContext context,
  2. TextStyle? style,
  3. required bool withComposing,
})
override

Builds TextSpan from current editing value.

Implementation

@override
TextSpan buildTextSpan(
    {required BuildContext context,
    TextStyle? style,
    required bool withComposing}) {
  List<TextSpan> children = [];
  final matches = <String>{};
  List<Map<String, List<int>>> matchIndex = [];

  // Validating with REGEX
  RegExp? allRegex;
  allRegex = patternMatchMap != null
      ? RegExp(patternMatchMap?.keys.map((e) => e.pattern).join('|') ?? "",
          caseSensitive: regExpCaseSensitive,
          dotAll: regExpDotAll,
          multiLine: regExpMultiLine,
          unicode: regExpUnicode)
      : null;
  // Validating with Strings
  RegExp? stringRegex;
  stringRegex = stringMatchMap != null
      ? RegExp(r'\b' + stringMatchMap!.keys.join('|').toString() + r'+\$',
          caseSensitive: regExpCaseSensitive,
          dotAll: regExpDotAll,
          multiLine: regExpMultiLine,
          unicode: regExpUnicode)
      : null;
  ////
  text.splitMapJoin(
    stringMatchMap == null ? allRegex! : stringRegex!,
    onNonMatch: (String span) {
      if (stringMatchMap != null &&
          children.isNotEmpty &&
          stringMatchMap!.keys.contains("${children.last.text}$span")) {
        final String? ks =
            stringMatchMap!["${children.last.text}$span"] != null
                ? stringMatchMap?.entries.lastWhere((element) {
                    return element.key
                        .allMatches("${children.last.text}$span")
                        .isNotEmpty;
                  }).key
                : '';

        children.add(TextSpan(text: span, style: stringMatchMap![ks!]));
        return span.toString();
      } else {
        children.add(TextSpan(text: span, style: style));
        return span.toString();
      }
    },
    onMatch: (Match m) {
      matches.add(m[0]!);
      final RegExp? k = patternMatchMap?.entries.firstWhere((element) {
        return element.key.allMatches(m[0]!).isNotEmpty;
      }).key;

      final String? ks = stringMatchMap?[m[0]] != null
          ? stringMatchMap?.entries.firstWhere((element) {
              return element.key.allMatches(m[0]!).isNotEmpty;
            }).key
          : '';
      if (deleteOnBack!) {
        if ((isBack(text, _lastValue) && m.end == selection.baseOffset)) {
          WidgetsBinding.instance.addPostFrameCallback((_) {
            children.removeWhere((element) => element.text! == text);
            text = text.replaceRange(m.start, m.end, "");
            selection = selection.copyWith(
              baseOffset: m.end - (m.end - m.start),
              extentOffset: m.end - (m.end - m.start),
            );
          });
        } else {
          children.add(
            TextSpan(
              text: m[0],
              style: stringMatchMap == null
                  ? patternMatchMap![k]
                  : stringMatchMap![ks],
            ),
          );
        }
      } else {
        children.add(
          TextSpan(
            text: m[0],
            style: stringMatchMap == null
                ? patternMatchMap![k]
                : stringMatchMap![ks],
          ),
        );
      }
      final resultMatchIndex = matchValueIndex(m);
      if (resultMatchIndex != null && onMatchIndex != null) {
        matchIndex.add(resultMatchIndex);
        onMatchIndex!(matchIndex);
      }

      return (onMatch(List<String>.unmodifiable(matches)) ?? '');
    },
  );

  _lastValue = text;
  return TextSpan(style: style, children: children);
}