sanitize static method

OpAttributes sanitize(
  1. OpAttributes dirtyAttrs,
  2. OpAttributeSanitizerOptions sanitizeOptions
)

Implementation

static OpAttributes sanitize(
  OpAttributes dirtyAttrs,
  OpAttributeSanitizerOptions sanitizeOptions,
) {
  OpAttributes cleanAttrs = OpAttributes();

  if (dirtyAttrs.attrs.isEmpty) {
    return cleanAttrs;
  }

  const List<String> booleanAttrs = <String>[
    'bold',
    'italic',
    'underline',
    'strike',
    'code',
    'blockquote',
    'code-block',
    'renderAsBlock',
  ];

  const List<String> colorAttrs = <String>['background', 'color'];

  final String? font = dirtyAttrs.font;
  final String? size = dirtyAttrs.size;
  final String? link = dirtyAttrs.link;
  final ScriptType? script = dirtyAttrs.script;
  final ListType? list = dirtyAttrs.list;
  final num? header = dirtyAttrs.header;
  final AlignType? align = dirtyAttrs.align;
  final DirectionType? direction = dirtyAttrs.direction;
  final num? indent = dirtyAttrs.indent;
  final bool? mentions = dirtyAttrs.mentions;
  final Mention? mention = dirtyAttrs.mention;
  final String? width = dirtyAttrs.width;
  final String? lineHeight = dirtyAttrs.lineHeight;
  final String? target = dirtyAttrs.target;
  final String? rel = dirtyAttrs.rel;
  final codeBlock = dirtyAttrs['code-block'];

  const List<String> sanitizedAttrs = <String>[
    ...booleanAttrs,
    ...colorAttrs,
    'font',
    'size',
    'line-height',
    'link',
    'script',
    'list',
    'header',
    'align',
    'direction',
    'indent',
    'mentions',
    'mention',
    'width',
    'target',
    'rel',
    'code-block',
  ];

  for (String prop in booleanAttrs) {
    final v = dirtyAttrs[prop];
    if (isTruthy(v)) {
      cleanAttrs[prop] = true;
    }
  }

  for (String prop in colorAttrs) {
    final val = dirtyAttrs[prop];
    if (isTruthy(val)) {
      if (OpAttributeSanitizer.isValidColorLiteral(val.toString()) || OpAttributeSanitizer.isValidRGBColor(val.toString())) {
        cleanAttrs[prop] = val;
      }
      if (OpAttributeSanitizer.isValidHexColor(val.toString())) {
        if (val.toString().length == 9) {
          if (sanitizeOptions.allow8DigitHexColors) {
            cleanAttrs[prop] = '#${val.toString().substring(3)}${val.toString().substring(1, 3)}';
          }
        } else {
          cleanAttrs[prop] = val;
        }
      }
    }
  }

  if (isTruthy(font) && OpAttributeSanitizer.isValidFontName(font.toString())) {
    cleanAttrs.font = font;
  }

  if (isTruthy(size) && OpAttributeSanitizer.isValidSize(size.toString())) {
    cleanAttrs.size = size;
  }

  if (isTruthy(width) && OpAttributeSanitizer.isValidWidth(width.toString())) {
    cleanAttrs.width = width;
  }

  if (OpAttributeSanitizer.isValidLineheight(lineHeight.toString())) {
    cleanAttrs.lineHeight = lineHeight;
  }

  if (isTruthy(link)) {
    cleanAttrs.link = OpLinkSanitizer.sanitize(link.toString(), sanitizeOptions);
  }

  if (isTruthy(target) && OpAttributeSanitizer.isValidTarget(target.toString())) {
    cleanAttrs.target = target;
  }

  if (isTruthy(rel) && OpAttributeSanitizer.isValidRel(rel.toString())) {
    cleanAttrs.rel = rel;
  }

  if (isTruthy(codeBlock)) {
    if (OpAttributeSanitizer.isValidLang(codeBlock)) {
      cleanAttrs['code-block'] = codeBlock;
    } else {
      cleanAttrs['code-block'] = isTruthy(codeBlock);
    }
  }

  if (script == ScriptType.subscript || ScriptType.superscript == script) {
    cleanAttrs.script = script;
  }

  if (list == ListType.bullet || list == ListType.ordered || list == ListType.checked || list == ListType.unchecked) {
    cleanAttrs.list = list;
  }

  if (isTruthy(header)) {
    cleanAttrs.header = min(header!, 6);
  }

  const List<AlignType> alignments = <AlignType>[AlignType.center, AlignType.right, AlignType.justify, AlignType.left];
  if (alignments.contains(align)) {
    cleanAttrs.align = align;
  }

  if (direction == DirectionType.rtl) {
    cleanAttrs.direction = direction;
  }

  if (isTruthy(indent)) {
    cleanAttrs.indent = min(indent!, 30);
  }

  if (isTruthy(mentions) && isTruthy(mention)) {
    final Mention sanitizedMention = MentionSanitizer.sanitize(mention!, sanitizeOptions);
    if (sanitizedMention.attrs.isNotEmpty) {
      cleanAttrs.mentions = mentions!;
      cleanAttrs.mention = sanitizedMention;
    }
  }

  // this is a custom attr, put it back
  cleanAttrs.attrs.addEntries(dirtyAttrs.attrs.entries.where((MapEntry<String, dynamic> entry) => !sanitizedAttrs.contains(entry.key)));
  return cleanAttrs;
}