diff --git a/Shared/Favicons/FaviconDownloader.swift b/Shared/Favicons/FaviconDownloader.swift index 447012cd6..94b562e85 100644 --- a/Shared/Favicons/FaviconDownloader.swift +++ b/Shared/Favicons/FaviconDownloader.swift @@ -208,7 +208,9 @@ private extension FaviconDownloader { return } - FaviconURLFinder.findFaviconURLs(homePageURL) { (faviconURLs) in + let ignoredTypes = [kUTTypeScalableVectorGraphics as String] + + FaviconURLFinder.findFaviconURLs(with: homePageURL, ignoredTypes: ignoredTypes) { (faviconURLs) in var defaultFaviconURL: String? = nil if let scheme = url.scheme, let host = url.host { diff --git a/Shared/Favicons/FaviconURLFinder.swift b/Shared/Favicons/FaviconURLFinder.swift index 654dd1f3b..fc05dd66c 100644 --- a/Shared/Favicons/FaviconURLFinder.swift +++ b/Shared/Favicons/FaviconURLFinder.swift @@ -13,15 +13,50 @@ import RSParser struct FaviconURLFinder { - static func findFaviconURLs(_ homePageURL: String, _ completion: @escaping ([String]?) -> Void) { + /// Finds favicon URLs in a web page. + /// - Parameters: + /// - homePageURL: The page to search. + /// - ignoredTypes: An array of uniform type identifiers to ignore. + /// - completion: A closure called when the links have been found. + /// - urls: An array of favicon URLs as strings. + static func findFaviconURLs(with homePageURL: String, ignoredTypes ignoredTypes: [String]? = nil, _ completion: @escaping (_ urls:[String]?) -> Void) { guard let _ = URL(string: homePageURL) else { completion(nil) return } + var ignoredMimeTypes = [String]() + var ignoredExtensions = [String]() + + if let ignoredTypes = ignoredTypes { + for type in ignoredTypes { + if let mimeTypes = UTTypeCopyAllTagsWithClass(type as CFString, kUTTagClassMIMEType)?.takeRetainedValue() { + ignoredMimeTypes.append(contentsOf: mimeTypes as! [String]) + } + if let extensions = UTTypeCopyAllTagsWithClass(type as CFString, kUTTagClassFilenameExtension)?.takeRetainedValue() { + ignoredExtensions.append(contentsOf: extensions as! [String]) + } + } + } + + // If the favicon has an explicit type, check that for an ignored type; otherwise, check the file extension. HTMLMetadataDownloader.downloadMetadata(for: homePageURL) { (htmlMetadata) in - completion(htmlMetadata?.faviconLinks) + let faviconURLs = htmlMetadata?.faviconLinks.filter({ (faviconLink) -> Bool in + if faviconLink.type != nil { + if ignoredMimeTypes.contains(faviconLink.type) { + return false + } + } else { + if let url = URL(string: faviconLink.urlString!), ignoredExtensions.contains(url.pathExtension) { + return false + } + } + + return true + }).map { $0.urlString! } + + completion(faviconURLs) } } }