iosWebViewFix/lib/src/web_storage.dart

160 lines
4.8 KiB
Dart

import 'dart:convert';
import 'in_app_webview_controller.dart';
import 'types.dart';
///Class that provides access to the JavaScript [Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API): `window.sessionStorage` and `window.localStorage`.
///It used by [InAppWebViewController.webStorage].
class WebStorage {
///Represents `window.localStorage`.
LocalStorage localStorage;
///Represents `window.sessionStorage`.
SessionStorage sessionStorage;
WebStorage({required this.localStorage, required this.sessionStorage});
}
///Class that represents a single web storage item of the JavaScript `window.sessionStorage` and `window.localStorage` objects.
class WebStorageItem {
///Item key.
String? key;
///Item value.
dynamic value;
WebStorageItem({this.key, this.value});
Map<String, dynamic> toMap() {
return {
"key": key,
"value": value,
};
}
Map<String, dynamic> toJson() {
return this.toMap();
}
@override
String toString() {
return toMap().toString();
}
}
///Class that provides methods to manage the JavaScript [Storage](https://developer.mozilla.org/en-US/docs/Web/API/Storage) object.
///It is used by [LocalStorage] and [SessionStorage].
class Storage {
late InAppWebViewController _controller;
///The web storage type: `window.sessionStorage` or `window.localStorage`.
WebStorageType webStorageType;
Storage(InAppWebViewController controller, this.webStorageType) {
this._controller = controller;
}
///Returns an integer representing the number of data items stored in the Storage object.
Future<int?> length() async {
var result = await _controller.evaluateJavascript(source: """
window.$webStorageType.length;
""");
return result != null ? int.parse(json.decode(result)) : null;
}
///When passed a [key] name and [value], will add that key to the storage, or update that key's value if it already exists.
Future<void> setItem({required String key, required dynamic value}) async {
var encodedValue = json.encode(value);
await _controller.evaluateJavascript(source: """
window.$webStorageType.setItem("$key", ${value is String ? encodedValue : "JSON.stringify($encodedValue)"});
""");
}
///When passed a [key] name, will return that key's value, or `null` if the key does not exist, in the given Storage object.
Future<dynamic> getItem({required String key}) async {
var itemValue = await _controller.evaluateJavascript(source: """
window.$webStorageType.getItem("$key");
""");
if (itemValue == null) {
return null;
}
try {
return json.decode(itemValue);
} catch (e) {}
return itemValue;
}
///When passed a [key] name, will remove that key from the given Storage object if it exists.
Future<void> removeItem({required String key}) async {
await _controller.evaluateJavascript(source: """
window.$webStorageType.removeItem("$key");
""");
}
///Returns the list of all items from the given Storage object.
Future<List<WebStorageItem>> getItems() async {
var webStorageItems = <WebStorageItem>[];
List<Map<dynamic, dynamic>> items =
(await _controller.evaluateJavascript(source: """
(function() {
var webStorageItems = [];
for(var i = 0; i < window.$webStorageType.length; i++){
var key = window.$webStorageType.key(i);
webStorageItems.push(
{
key: key,
value: window.$webStorageType.getItem(key)
}
);
}
return webStorageItems;
})();
""")).cast<Map<dynamic, dynamic>>();
if (items == null) {
return webStorageItems;
}
for (var item in items) {
webStorageItems
.add(WebStorageItem(key: item["key"], value: item["value"]));
}
return webStorageItems;
}
///Clears all keys stored in a given Storage object.
Future<void> clear() async {
await _controller.evaluateJavascript(source: """
window.$webStorageType.clear();
""");
}
///When passed a number [index], returns the name of the nth key in a given Storage object.
///The order of keys is user-agent defined, so you should not rely on it.
Future<String> key({required int index}) async {
var result = await _controller.evaluateJavascript(source: """
window.$webStorageType.key($index);
""");
return result != null ? json.decode(result) : null;
}
}
///Class that provides methods to manage the JavaScript `window.localStorage` object.
///It used by [WebStorage].
class LocalStorage extends Storage {
LocalStorage(InAppWebViewController controller)
: super(controller, WebStorageType.LOCAL_STORAGE);
}
///Class that provides methods to manage the JavaScript `window.sessionStorage` object.
///It used by [WebStorage].
class SessionStorage extends Storage {
SessionStorage(InAppWebViewController controller)
: super(controller, WebStorageType.SESSION_STORAGE);
}