- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
import * as event from "./event.js";
/**
* allow to access and manage the device localStorage
* @example
* // Initialize "score" and "lives" with default values
* // This loads the properties from localStorage if they exist, else it sets the given defaults
* me.save.add({ score : 0, lives : 3 });
*
* // Print all
* // On first load, this prints { score : 0, lives : 3 }
* // On further reloads, it prints { score : 31337, lives : 3, complexObject : ... }
* // Because the following changes will be saved to localStorage
* console.log(JSON.stringify(me.save));
*
* // Save score
* me.save.score = 31337;
*
* // Also supports complex objects thanks to the JSON backend
* me.save.add({ complexObject : {} })
* me.save.complexObject = { a : "b", c : [ 1, 2, 3, "d" ], e : { f : [{}] } };
*
* // WARNING: Do not set any child properties of complex objects directly!
* // Changes made that way will not save. Always set the entire object value at once.
* // If you cannot live with this limitation, there's a workaround:
* me.save.complexObject.c.push("foo"); // Modify a child property
* me.save.complexObject = me.save.complexObject; // Save the entire object!
*
* // Remove "lives" from localStorage
* me.save.remove("lives");
* @namespace save
*/
// Variable to hold the object data
let data = {};
let hasLocalStorage = false;
try {
// true if localStorage is supported
hasLocalStorage = typeof globalThis !== "undefined" && typeof globalThis.localStorage !== "undefined";
} catch (e) {
// the above generates an exception when cookies are blocked
hasLocalStorage = false;
}
/**
* a function to check if the given key is a reserved word
* @ignore
*/
function isReserved(key) {
return (key === "add" || key === "remove");
}
// Initialize me.save on Boot event
event.on(event.BOOT, () => {
// Load previous data if local Storage is supported
if (hasLocalStorage === true) {
let me_save_content = globalThis.localStorage.getItem("me.save");
if (typeof me_save_content === "string" && me_save_content.length > 0) {
let keys = JSON.parse(me_save_content) || [];
keys.forEach((key) => {
data[key] = JSON.parse(globalThis.localStorage.getItem("me.save." + key));
});
}
}
});
let save = {
/**
* Add new keys to localStorage and set them to the given default values if they do not exist
* @name add
* @memberof save
* @param {object} props - key and corresponding values
* @example
* // Initialize "score" and "lives" with default values
* me.save.add({ score : 0, lives : 3 });
* // get or set the value through me.save
* me.save.score = 1000;
*/
add(props) {
let obj = save;
Object.keys(props).forEach((key) => {
if (isReserved(key)) {
return;
}
(function (prop) {
Object.defineProperty(obj, prop, {
configurable : true,
enumerable : true,
/**
* @ignore
*/
get () {
return data[prop];
},
/**
* @ignore
*/
set (value) {
data[prop] = value;
if (hasLocalStorage === true) {
globalThis.localStorage.setItem("me.save." + prop, JSON.stringify(value));
}
}
});
})(key);
// Set default value for key
if (!(key in data)) {
obj[key] = props[key];
}
});
// Save keys
if (hasLocalStorage === true) {
globalThis.localStorage.setItem("me.save", JSON.stringify(Object.keys(data)));
}
},
/**
* Remove a key from localStorage
* @name remove
* @memberof save
* @param {string} key - key to be removed
* @example
* // Remove the "score" key from localStorage
* me.save.remove("score");
*/
remove (key) {
if (!isReserved(key)) {
if (typeof data[key] !== "undefined") {
delete data[key];
if (hasLocalStorage === true) {
globalThis.localStorage.removeItem("me.save." + key);
globalThis.localStorage.setItem("me.save", JSON.stringify(Object.keys(data)));
}
}
}
}
};
export default save;