rewriteHtmlResourceUrlsForProxy static method

String rewriteHtmlResourceUrlsForProxy(
  1. String html, {
  2. required String originalUrl,
  3. required String proxyBase,
})

Rewrites external resource URLs (src, href, poster, srcset) and import-map values to use the selected proxy endpoint.

Implementation

static String rewriteHtmlResourceUrlsForProxy(
  String html, {
  required String originalUrl,
  required String proxyBase,
}) {
  if (html.isEmpty) return html;
  final baseUri = Uri.tryParse(originalUrl);
  if (baseUri == null) return html;

  String proxify(String candidate) {
    final value = candidate.trim();
    if (value.isEmpty ||
        value.startsWith('#') ||
        value.startsWith('data:') ||
        value.startsWith('blob:') ||
        value.startsWith('javascript:') ||
        value.startsWith('mailto:') ||
        value.startsWith('tel:') ||
        value.startsWith('about:')) {
      return candidate;
    }

    final resolved = baseUri.resolve(value).toString();
    return buildProxiedUrl(proxyBase, resolved);
  }

  var updated = html.replaceAllMapped(
    RegExp(
      r"""\b(href|src|poster)\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)""",
      caseSensitive: false,
    ),
    (match) {
      final attr = match.group(1)!;
      final token = match.group(2)!;
      String rawValue = token;
      String quote = '';

      if ((token.startsWith('"') && token.endsWith('"')) ||
          (token.startsWith("'") && token.endsWith("'"))) {
        quote = token[0];
        rawValue = token.substring(1, token.length - 1);
      }

      final rewritten = proxify(rawValue);
      final valueWithQuotes =
          quote.isEmpty ? rewritten : '$quote$rewritten$quote';
      return '$attr=$valueWithQuotes';
    },
  );

  updated = updated.replaceAllMapped(
    RegExp(
      r"""\bsrcset\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)""",
      caseSensitive: false,
    ),
    (match) {
      final token = match.group(1)!;
      String rawValue = token;
      String quote = '';

      if ((token.startsWith('"') && token.endsWith('"')) ||
          (token.startsWith("'") && token.endsWith("'"))) {
        quote = token[0];
        rawValue = token.substring(1, token.length - 1);
      }

      final rewrittenEntries = rawValue.split(',').map((entry) {
        final trimmed = entry.trim();
        if (trimmed.isEmpty) return trimmed;

        final parts = trimmed.split(RegExp(r'\s+'));
        final urlPart = parts.first;
        final descriptor =
            parts.length > 1 ? ' ${parts.sublist(1).join(' ')}' : '';
        return '${proxify(urlPart)}$descriptor';
      }).join(', ');

      final valueWithQuotes =
          quote.isEmpty ? rewrittenEntries : '$quote$rewrittenEntries$quote';
      return 'srcset=$valueWithQuotes';
    },
  );

  updated = updated.replaceAllMapped(_importMapTag, (match) {
    final rawJson = (match.group(1) ?? '').trim();
    if (rawJson.isEmpty) return match.group(0)!;

    try {
      final dynamic decoded = json.decode(rawJson);
      if (decoded is! Map) return match.group(0)!;

      final imports = decoded['imports'];
      if (imports is Map) {
        imports.forEach((key, value) {
          if (value is String) {
            imports[key] = proxify(value);
          }
        });
      }

      final encoded = json.encode(decoded);
      return match.group(0)!.replaceFirst(rawJson, encoded);
    } catch (_) {
      return match.group(0)!;
    }
  });

  return updated;
}