getFavicons method

Future<List<Favicon>> getFavicons()

Gets the list of all favicons for the current page.

Implementation

Future<List<Favicon>> getFavicons() async {
  List<Favicon> favicons = [];

  HttpClient client = new HttpClient();
  var webviewUrl = await getUrl();

  if (webviewUrl == null) {
    return favicons;
  }

  String? manifestUrl;

  var html = await getHtml();
  if (html == null || html.isEmpty) {
    return favicons;
  }
  var assetPathBase;

  if (webviewUrl.isScheme("file")) {
    var assetPathSplitted = webviewUrl.toString().split("/flutter_assets/");
    assetPathBase = assetPathSplitted[0] + "/flutter_assets/";
  }

  InAppWebViewGroupOptions? options = await getOptions();
  if (options != null && options.crossPlatform.javaScriptEnabled == true) {
    List<Map<dynamic, dynamic>> links = (await evaluateJavascript(source: """
(function() {
var linkNodes = document.head.getElementsByTagName("link");
var links = [];
for (var i = 0; i < linkNodes.length; i++) {
  var linkNode = linkNodes[i];
  if (linkNode.rel === 'manifest') {
    links.push(
      {
        rel: linkNode.rel,
        href: linkNode.href,
        sizes: null
      }
    );
  } else if (linkNode.rel != null && linkNode.rel.indexOf('icon') >= 0) {
    links.push(
      {
        rel: linkNode.rel,
        href: linkNode.href,
        sizes: linkNode.sizes != null && linkNode.sizes.value != "" ? linkNode.sizes.value : null
      }
    );
  }
}
return links;
})();
"""))?.cast<Map<dynamic, dynamic>>() ?? [];
    for (var link in links) {
      if (link["rel"] == "manifest") {
        manifestUrl = link["href"];
        if (!_isUrlAbsolute(manifestUrl!)) {
          if (manifestUrl.startsWith("/")) {
            manifestUrl = manifestUrl.substring(1);
          }
          manifestUrl = ((assetPathBase == null)
                  ? webviewUrl.scheme + "://" + webviewUrl.host + "/"
                  : assetPathBase) +
              manifestUrl;
        }
        continue;
      }
      favicons.addAll(_createFavicons(webviewUrl, assetPathBase, link["href"],
          link["rel"], link["sizes"], false));
    }
  }

  // try to get /favicon.ico
  try {
    var faviconUrl =
        webviewUrl.scheme + "://" + webviewUrl.host + "/favicon.ico";
    var faviconUri = Uri.parse(faviconUrl);
    var headRequest = await client.headUrl(faviconUri);
    var headResponse = await headRequest.close();
    if (headResponse.statusCode == 200) {
      favicons.add(Favicon(url: faviconUri, rel: "shortcut icon"));
    }
  } catch (e) {
    print("/favicon.ico file not found: " + e.toString());
    // print(stacktrace);
  }

  // try to get the manifest file
  HttpClientRequest? manifestRequest;
  HttpClientResponse? manifestResponse;
  bool manifestFound = false;
  if (manifestUrl == null) {
    manifestUrl =
        webviewUrl.scheme + "://" + webviewUrl.host + "/manifest.json";
  }
  try {
    manifestRequest = await client.getUrl(Uri.parse(manifestUrl));
    manifestResponse = await manifestRequest.close();
    manifestFound = manifestResponse.statusCode == 200 &&
        manifestResponse.headers.contentType?.mimeType == "application/json";
  } catch (e) {
    print("Manifest file not found: " + e.toString());
    // print(stacktrace);
  }

  if (manifestFound) {
    try {
      Map<String, dynamic> manifest = json
          .decode(await manifestResponse!.transform(Utf8Decoder()).join());
      if (manifest.containsKey("icons")) {
        for (Map<String, dynamic> icon in manifest["icons"]) {
          favicons.addAll(_createFavicons(webviewUrl, assetPathBase,
              icon["src"], icon["rel"], icon["sizes"], true));
        }
      }
    } on FormatException catch (_) {
      /// The [manifestResponse] might not has a valid JSON string, catch and
      /// ignore the error
    }
  }

  return favicons;
}