import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'types.dart'; ///Class that implements a singleton object (shared instance) which manages the web storage used by WebView instances. ///On Android, it is implemented using [WebStorage](https://developer.android.com/reference/android/webkit/WebStorage.html). ///On iOS, it is implemented using [WKWebsiteDataStore.default()](https://developer.apple.com/documentation/webkit/wkwebsitedatastore). /// ///**NOTE for iOS**: available from iOS 9.0+. class WebStorageManager { static WebStorageManager _instance; static const MethodChannel _channel = const MethodChannel( 'com.pichillilorenzo/flutter_inappwebview_webstoragemanager'); AndroidWebStorageManager android = AndroidWebStorageManager(); IOSWebStorageManager ios = IOSWebStorageManager(); ///Gets the WebStorage manager shared instance. static WebStorageManager instance() { return (_instance != null) ? _instance : _init(); } static WebStorageManager _init() { _channel.setMethodCallHandler(_handleMethod); _instance = new WebStorageManager(); return _instance; } static Future _handleMethod(MethodCall call) async {} } ///Class that is used to manage the JavaScript storage APIs provided by the WebView. ///It manages the Application Cache API, the Web SQL Database API and the HTML5 Web Storage API. class AndroidWebStorageManager { ///Gets the origins currently using either the Application Cache or Web SQL Database APIs. Future> getOrigins() async { List originsList = []; Map args = {}; List> origins = (await WebStorageManager._channel.invokeMethod('getOrigins', args)) .cast>(); for (var origin in origins) { originsList.add(AndroidWebStorageOrigin( origin: origin["origin"], quota: origin["quota"], usage: origin["usage"])); } return originsList; } ///Clears all storage currently being used by the JavaScript storage APIs. ///This includes the Application Cache, Web SQL Database and the HTML5 Web Storage APIs. Future deleteAllData() async { Map args = {}; await WebStorageManager._channel.invokeMethod('deleteAllData', args); } ///Clears the storage currently being used by both the Application Cache and Web SQL Database APIs by the given [origin]. ///The origin is specified using its string representation. Future deleteOrigin({@required String origin}) async { assert(origin != null); Map args = {}; args.putIfAbsent("origin", () => origin); await WebStorageManager._channel.invokeMethod('deleteOrigin', args); } ///Gets the storage quota for the Web SQL Database API for the given [origin]. ///The quota is given in bytes and the origin is specified using its string representation. ///Note that a quota is not enforced on a per-origin basis for the Application Cache API. Future getQuotaForOrigin({@required String origin}) async { assert(origin != null); Map args = {}; args.putIfAbsent("origin", () => origin); return await WebStorageManager._channel .invokeMethod('getQuotaForOrigin', args); } ///Gets the amount of storage currently being used by both the Application Cache and Web SQL Database APIs by the given [origin]. ///The amount is given in bytes and the origin is specified using its string representation. Future getUsageForOrigin({@required String origin}) async { assert(origin != null); Map args = {}; args.putIfAbsent("origin", () => origin); return await WebStorageManager._channel .invokeMethod('getUsageForOrigin', args); } } ///Class that represents various types of data that a website might make use of. ///This includes cookies, disk and memory caches, and persistent data such as WebSQL, IndexedDB databases, and local storage. /// ///**NOTE**: available on iOS 9.0+. class IOSWebStorageManager { ///Fetches data records containing the given website data types. /// ///[dataTypes] represents the website data types to fetch records for. Future> fetchDataRecords( {@required Set dataTypes}) async { assert(dataTypes != null); List recordList = []; List dataTypesList = []; for (var dataType in dataTypes) { dataTypesList.add(dataType.toValue()); } Map args = {}; args.putIfAbsent("dataTypes", () => dataTypesList); List> records = (await WebStorageManager._channel .invokeMethod('fetchDataRecords', args)) .cast>(); for (var record in records) { List dataTypesString = record["dataTypes"].cast(); Set dataTypes = Set(); for (var dataType in dataTypesString) { dataTypes.add(IOSWKWebsiteDataType.fromValue(dataType)); } recordList.add(IOSWKWebsiteDataRecord( displayName: record["displayName"], dataTypes: dataTypes)); } return recordList; } ///Removes website data of the given types for the given data records. /// ///[dataTypes] represents the website data types that should be removed. /// ///[dataRecords] represents the website data records to delete website data for. Future removeDataFor( {@required Set dataTypes, @required List dataRecords}) async { assert(dataTypes != null && dataRecords != null); List dataTypesList = []; for (var dataType in dataTypes) { dataTypesList.add(dataType.toValue()); } List> recordList = []; for (var record in dataRecords) { recordList.add(record.toMap()); } Map args = {}; args.putIfAbsent("dataTypes", () => dataTypesList); args.putIfAbsent("recordList", () => recordList); await WebStorageManager._channel.invokeMethod('removeDataFor', args); } ///Removes all website data of the given types that has been modified since the given date. /// ///[dataTypes] represents the website data types that should be removed. /// ///[date] represents a date. All website data modified after this date will be removed. Future removeDataModifiedSince( {@required Set dataTypes, @required DateTime date}) async { assert(dataTypes != null && date != null); List dataTypesList = []; for (var dataType in dataTypes) { dataTypesList.add(dataType.toValue()); } var timestamp = date.millisecondsSinceEpoch; Map args = {}; args.putIfAbsent("dataTypes", () => dataTypesList); args.putIfAbsent("timestamp", () => timestamp); await WebStorageManager._channel .invokeMethod('removeDataModifiedSince', args); } }