Dactyloidae/mobile/ios/Client/Frontend/Settings/Clearables.swift
2026-06-26 21:04:09 -07:00

149 lines
5.1 KiB
Swift

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import Foundation
import Shared
import WebKit
import Deferred
import SDWebImage
import CoreSpotlight
private let log = Logger.browserLogger
// Removed Clearables as part of Bug 1226654, but keeping the string around.
private let removedSavedLoginsLabel = NSLocalizedString("Saved Logins", tableName: "ClearPrivateData", comment: "Settings item for clearing passwords and login data")
// A base protocol for something that can be cleared.
protocol Clearable {
func clear() -> Success
var label: String { get }
}
class ClearableError: MaybeErrorType {
fileprivate let msg: String
init(msg: String) {
self.msg = msg
}
var description: String { return msg }
}
// Clears our browsing history, including favicons and thumbnails.
class HistoryClearable: Clearable {
let profile: Profile
init(profile: Profile) {
self.profile = profile
}
var label: String {
return NSLocalizedString("Browsing History", tableName: "ClearPrivateData", comment: "Settings item for clearing browsing history")
}
func clear() -> Success {
return profile.history.clearHistory().bindQueue(.main) { success in
SDImageCache.shared().clearDisk()
SDImageCache.shared().clearMemory()
self.profile.recentlyClosedTabs.clearTabs()
CSSearchableIndex.default().deleteAllSearchableItems()
NotificationCenter.default.post(name: NotificationPrivateDataClearedHistory, object: nil)
log.debug("HistoryClearable succeeded: \(success).")
return Deferred(value: success)
}
}
}
struct ClearableErrorType: MaybeErrorType {
let err: Error
init(err: Error) {
self.err = err
}
var description: String {
return "Couldn't clear: \(err)."
}
}
// Clear the web cache. Note, this has to close all open tabs in order to ensure the data
// cached in them isn't flushed to disk.
class CacheClearable: Clearable {
let tabManager: TabManager
init(tabManager: TabManager) {
self.tabManager = tabManager
}
var label: String {
return NSLocalizedString("Cache", tableName: "ClearPrivateData", comment: "Settings item for clearing the cache")
}
func clear() -> Success {
let dataTypes = Set([WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache])
WKWebsiteDataStore.default().removeData(ofTypes: dataTypes, modifiedSince: Date.distantPast, completionHandler: {})
log.debug("CacheClearable succeeded.")
return succeed()
}
}
private func deleteLibraryFolderContents(_ folder: String) throws {
let manager = FileManager.default
let library = manager.urls(for: FileManager.SearchPathDirectory.libraryDirectory, in: .userDomainMask)[0]
let dir = library.appendingPathComponent(folder)
let contents = try manager.contentsOfDirectory(atPath: dir.path)
for content in contents {
do {
try manager.removeItem(at: dir.appendingPathComponent(content))
} catch where ((error as NSError).userInfo[NSUnderlyingErrorKey] as? NSError)?.code == Int(EPERM) {
// "Not permitted". We ignore this.
log.debug("Couldn't delete some library contents.")
}
}
}
private func deleteLibraryFolder(_ folder: String) throws {
let manager = FileManager.default
let library = manager.urls(for: FileManager.SearchPathDirectory.libraryDirectory, in: .userDomainMask)[0]
let dir = library.appendingPathComponent(folder)
try manager.removeItem(at: dir)
}
// Removes all app cache storage.
class SiteDataClearable: Clearable {
let tabManager: TabManager
init(tabManager: TabManager) {
self.tabManager = tabManager
}
var label: String {
return NSLocalizedString("Offline Website Data", tableName: "ClearPrivateData", comment: "Settings item for clearing website data")
}
func clear() -> Success {
let dataTypes = Set([WKWebsiteDataTypeOfflineWebApplicationCache])
WKWebsiteDataStore.default().removeData(ofTypes: dataTypes, modifiedSince: Date.distantPast, completionHandler: {})
log.debug("SiteDataClearable succeeded.")
return succeed()
}
}
// Remove all cookies stored by the site. This includes localStorage, sessionStorage, and WebSQL/IndexedDB.
class CookiesClearable: Clearable {
let tabManager: TabManager
init(tabManager: TabManager) {
self.tabManager = tabManager
}
var label: String {
return NSLocalizedString("Cookies", tableName: "ClearPrivateData", comment: "Settings item for clearing cookies")
}
func clear() -> Success {
let dataTypes = Set([WKWebsiteDataTypeCookies, WKWebsiteDataTypeLocalStorage, WKWebsiteDataTypeSessionStorage, WKWebsiteDataTypeWebSQLDatabases, WKWebsiteDataTypeIndexedDBDatabases])
WKWebsiteDataStore.default().removeData(ofTypes: dataTypes, modifiedSince: Date.distantPast, completionHandler: {})
log.debug("CookiesClearable succeeded.")
return succeed()
}
}