Skip to content

Commit f18549b

Browse files
author
Simon Lammer
authored
Merge pull request #26 from SimonLammer/webstorage-api
Webstorage api
2 parents 6cb4683 + f883a6b commit f18549b

File tree

9 files changed

+131
-54
lines changed

9 files changed

+131
-54
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ install:
1212
script:
1313
- printf "// $VERSION - $GH_SCRIPT_URL\n$(cat script.js)" > script.js
1414
- cat script.js
15-
- java -jar closure-compiler/closure-compiler-*.jar --js script.js --js_output_file minified.js
15+
- 'curl -X POST -s --data-urlencode "input@script.js" https://javascript-minifier.com/raw > minified.js'
1616
- printf "$(head -n 1 script.js)\n$(cat minified.js)" > minified.js
1717
- cat minified.js
1818
- npm test

README.md

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,42 +14,41 @@ It could also be used completely different as well. To let the user input someth
1414
This example shows how anki-persistence can be used to display the same random number on both sides of an Anki flash card. **All of these images depict the same note!** You can try it out yourself with [this exported Anki deck](examples/random-number/anki-persistence.apkg).
1515

1616
### Result
17-
| Client | Front | Back |
18-
| ----------------------:|:-----:|:----:|
19-
| Web | ![Random number example on the web client - Front](examples/random-number/Web-Front.jpg) | ![Random number example on the web client - Back](examples/random-number/Web-Back.jpg) |
20-
| Android | ![Random number example on the Android client - Front](examples/random-number/AnkiDroid-Front.jpg) | ![Random number example on the Android client - Back](examples/random-number/AnkiDroid-Back.jpg) |
17+
| Client | Front | Back |
18+
| -------:|:-----:|:----:|
19+
| Web | ![Random number example on the web client - Front](examples/random-number/Web-Front.jpg) | ![Random number example on the web client - Back](examples/random-number/Web-Back.jpg) |
20+
| Android | ![Random number example on the Android client - Front](examples/random-number/AnkiDroid-Front.jpg) | ![Random number example on the Android client - Back](examples/random-number/AnkiDroid-Back.jpg) |
2121
| Android (card preview) | ![Random number example on the Android client (card preview) - Front](examples/random-number/AnkiDroid_Preview-Front.jpg) | ![Random number example on the Android client (card preview) - Back](examples/random-number/AnkiDroid_Preview-Back.jpg) |
22-
| iOS | ![Random number example on the iOS client - Front](examples/random-number/iOS-Front.jpg) | ![Random number example on the iOS client - Back](examples/random-number/iOS-Back.jpg) |
22+
| iOS | ![Random number example on the iOS client - Front](examples/random-number/iOS-Front.jpg) | ![Random number example on the iOS client - Back](examples/random-number/iOS-Back.jpg) |
2323
| iOS (card preview) | ![Random number example on the iOS client (card preview) - Front](examples/random-number/iOS_Preview-Front.jpg) | ![Random number example on the iOS client (card preview) - Back](examples/random-number/iOS_Preview-Back.jpg) |
24-
| Mac | ![Random number example on the Mac client - Front](examples/random-number/Mac-Front.png) | ![Random number example on the Mac client - Back](examples/random-number/Mac-Back.png) |
24+
| Mac | ![Random number example on the Mac client - Front](examples/random-number/Mac-Front.png) | ![Random number example on the Mac client - Back](examples/random-number/Mac-Back.png) |
2525
| Mac (card preview) | ![Random number example on the Mac client (card preview) - Front](examples/random-number/Mac_Preview-Front.png) | ![Random number example on the Mac client (card preview) - Back](examples/random-number/Mac_Preview-Back.png) |
26-
| Windows | ![Random number example on the Windows client - Front](examples/random-number/Windows-Front.jpg) | ![Random number example on the Windows client - Back](examples/random-number/Windows-Back.jpg) |
27-
| Windows (card preview) | ![Random number example on the Windows client (card preview) - Front](examples/random-number/Windows_Preview-Front.jpg) | ![Random number example on the Windows client (card preview) - Back](examples/random-number/Windows_Preview-Back.jpg) |
28-
| Linux | ![Random number example on the Linux client - Front](examples/random-number/Linux-Front.png) | ![Random number example on the Linux client - Back](examples/random-number/Linux-Back.png) |
29-
| Linux (card preview) | ![Random number example on the Linux client (card preview) - Front](examples/random-number/Linux_Preview-Front.png) | ![Random number example on the Linux client (card preview) - Back](examples/random-number/Linux_Preview-Back.png) |
26+
| Windows | ![Random number example on the Windows client - Front](examples/random-number/Windows-Front.jpg) | ![Random number example on the Windows client - Back](examples/random-number/Windows-Back.jpg) |
27+
| Windows (card type editor preview) | ![Random number example on the Windows client (card type editor preview) - Front](examples/random-number/Windows_ctePreview-Front.jpg) | ![Random number example on the Windows client (card type editor preview) - Back](examples/random-number/Windows_ctePreview-Back.jpg) |
28+
| Linux | ![Random number example on the Linux client - Front](examples/random-number/Linux-Front.png) | ![Random number example on the Linux client - Back](examples/random-number/Linux-Back.png) |
29+
| Linux (card preview) | ![Random number example on the Linux client (card preview) - Front](examples/random-number/Linux_Preview-Front.png) | ![Random number example on the Linux client (card preview) - Back](examples/random-number/Linux_Preview-Back.png) |
3030

31-
**Note that Persistence is not available for Windows card preview (```Persistence.isAvailable()``` returns ```false```), thus a default (0.4) is chosen.**
31+
**Note that Persistence is not available for Windows card type editor preview (```Persistence.isAvailable()``` returns ```false```), thus a default (0.4) is chosen.**
3232

3333
### Setup
3434
#### Front side
3535
~~~html
3636
<script>
37-
// v0.2.1 - https://github.com/SimonLammer/anki-persistence/blob/8a3648baa02a9cd5c1f51e5adf3772dd5d494757/script.js
38-
"undefined"===typeof window.Persistence&&(window.Persistence=new function(){var a=!1;try{"object"===typeof window.sessionStorage&&(a=!0,this.store=function(a){sessionStorage.setItem("github.com/SimonLammer/anki-persistence",JSON.stringify(a))},this.load=function(){return JSON.parse(sessionStorage.getItem("github.com/SimonLammer/anki-persistence"))})}catch(e){}for(var d=["py","qt"],b=0;!a&&b<d.length;b++){var c=window[d[b]];"object"===typeof c&&(a=!0,this.store=function(a){c["github.com/SimonLammer/anki-persistence"]=
39-
a},this.load=function(){return c["github.com/SimonLammer/anki-persistence"]||null})}this.isAvailable=function(){return a}});
37+
// v0.3.0 - https://github.com/SimonLammer/anki-persistence/blob/54444f7b58de784c781dcc904f6ce559f7ce3ed2/script.js
38+
if(void 0===window.Persistence){var _persistenceKey="github.com/SimonLammer/anki-persistence/",_defaultKey="_default";window.Persistence_sessionStorage=function(){var e=!1;try{"object"==typeof window.sessionStorage&&(e=!0,this.clear=function(){for(var e=0;e<sessionStorage.length;e++){var t=sessionStorage.key(e);0==t.indexOf(_persistenceKey)&&(sessionStorage.removeItem(t),e--)}},this.setItem=function(e,t){void 0==t&&(t=e,e=_defaultKey),sessionStorage.setItem(_persistenceKey+e,JSON.stringify(t))},this.getItem=function(e){return void 0==e&&(e=_defaultKey),JSON.parse(sessionStorage.getItem(_persistenceKey+e))},this.removeItem=function(e){void 0==e&&(e=_defaultKey),sessionStorage.removeItem(_persistenceKey+e)})}catch(e){}this.isAvailable=function(){return e}},window.Persistence_windowKey=function(e){var t=window[e],s=!1;"object"==typeof t&&(s=!0,this.clear=function(){t[_persistenceKey]={}},this.setItem=function(e,s){void 0==s&&(s=e,e=_defaultKey),t[_persistenceKey][e]=s},this.getItem=function(e){return void 0==e&&(e=_defaultKey),t[_persistenceKey][e]||null},this.removeItem=function(e){void 0==e&&(e=_defaultKey),delete t[_persistenceKey][e]},void 0==t[_persistenceKey]&&this.clear()),this.isAvailable=function(){return s}};for(var persistentKeys=["py","qt"],i=0;i<persistentKeys.length&&(window.Persistence=new Persistence_windowKey(persistentKeys[i]),!window.Persistence.isAvailable());i++);window.Persistence.isAvailable()||(window.Persistence=new Persistence_sessionStorage)}
4039
</script>
4140

4241
{{Front}}
4342

4443
<div id="front"></div>
4544

4645
<script>
47-
var number = 0.4; // Default to 0.4.
48-
if (Persistence.isAvailable()) { // Check whether Persistence works on the client.
49-
number = Persistence.load(); // Load a previously stored number. (In case {{FrontSide}} is used)
50-
if (number == null) { // If there was a previously stored number:
51-
number = Math.random(); // 1. Create a random number.
52-
Persistence.store(number); // 2. Store that number
46+
var number = 0.4; // Default to 0.4.
47+
if (Persistence.isAvailable()) { // Check whether Persistence works on the client.
48+
number = Persistence.getItem(); // Retrieve a previously stored number and override the default. (In case this is executed on the backside as well by {{FrontSide}})
49+
if (number == null) { // If there was no number stored previously:
50+
number = Math.random(); // 1. Create a random number and override the default.
51+
Persistence.setItem(number); // 2. Store that number
5352
}
5453
}
5554
window.front.appendChild(document.createTextNode(number)); // Print the number.
@@ -60,20 +59,19 @@ window.front.appendChild(document.createTextNode(number)); // Print the number.
6059

6160
~~~html
6261
<script>
63-
// v0.2.1 - https://github.com/SimonLammer/anki-persistence/blob/8a3648baa02a9cd5c1f51e5adf3772dd5d494757/script.js
64-
"undefined"===typeof window.Persistence&&(window.Persistence=new function(){var a=!1;try{"object"===typeof window.sessionStorage&&(a=!0,this.store=function(a){sessionStorage.setItem("github.com/SimonLammer/anki-persistence",JSON.stringify(a))},this.load=function(){return JSON.parse(sessionStorage.getItem("github.com/SimonLammer/anki-persistence"))})}catch(e){}for(var d=["py","qt"],b=0;!a&&b<d.length;b++){var c=window[d[b]];"object"===typeof c&&(a=!0,this.store=function(a){c["github.com/SimonLammer/anki-persistence"]=
65-
a},this.load=function(){return c["github.com/SimonLammer/anki-persistence"]||null})}this.isAvailable=function(){return a}});
62+
// v0.3.0 - https://github.com/SimonLammer/anki-persistence/blob/54444f7b58de784c781dcc904f6ce559f7ce3ed2/script.js
63+
if(void 0===window.Persistence){var _persistenceKey="github.com/SimonLammer/anki-persistence/",_defaultKey="_default";window.Persistence_sessionStorage=function(){var e=!1;try{"object"==typeof window.sessionStorage&&(e=!0,this.clear=function(){for(var e=0;e<sessionStorage.length;e++){var t=sessionStorage.key(e);0==t.indexOf(_persistenceKey)&&(sessionStorage.removeItem(t),e--)}},this.setItem=function(e,t){void 0==t&&(t=e,e=_defaultKey),sessionStorage.setItem(_persistenceKey+e,JSON.stringify(t))},this.getItem=function(e){return void 0==e&&(e=_defaultKey),JSON.parse(sessionStorage.getItem(_persistenceKey+e))},this.removeItem=function(e){void 0==e&&(e=_defaultKey),sessionStorage.removeItem(_persistenceKey+e)})}catch(e){}this.isAvailable=function(){return e}},window.Persistence_windowKey=function(e){var t=window[e],s=!1;"object"==typeof t&&(s=!0,this.clear=function(){t[_persistenceKey]={}},this.setItem=function(e,s){void 0==s&&(s=e,e=_defaultKey),t[_persistenceKey][e]=s},this.getItem=function(e){return void 0==e&&(e=_defaultKey),t[_persistenceKey][e]||null},this.removeItem=function(e){void 0==e&&(e=_defaultKey),delete t[_persistenceKey][e]},void 0==t[_persistenceKey]&&this.clear()),this.isAvailable=function(){return s}};for(var persistentKeys=["py","qt"],i=0;i<persistentKeys.length&&(window.Persistence=new Persistence_windowKey(persistentKeys[i]),!window.Persistence.isAvailable());i++);window.Persistence.isAvailable()||(window.Persistence=new Persistence_sessionStorage)}
6664
</script>
6765

6866
{{Back}}
6967

7068
<div id="back"></dv>
7169

7270
<script>
73-
var number = 0.4; // Default to 0.4.
74-
if (Persistence.isAvailable()) { // Check whether Persistence works on the client.
75-
number = Persistence.load(); // Load the previously stored number
76-
Persistence.store(null); // Clear the storage, so a new random number will be created on the next card.
71+
var number = 0.4; // Default to 0.4.
72+
if (Persistence.isAvailable()) { // Check whether Persistence works on the client.
73+
number = Persistence.getItem(); // Retrieve the previously stored number and override the default.
74+
Persistence.clear(); // Clear the storage, so a new random number will be created on the next card.
7775
}
7876
window.back.appendChild(document.createTextNode(number)); // Print the number.
7977
</script>
@@ -107,14 +105,19 @@ Other methods:
107105

108106
| Name | Description |
109107
| -----------------------------:|:----------- |
110-
| ```Persistence.store(data)``` | Persists the data, so it can be retrieved later. |
111-
| ```Persistence.load()``` | Retrieves previously stored data. If no data has been stored yet, null is returned. |
108+
| ```Persistence.clear()``` | Removes all previously persisted key-value pairs. |
109+
| ```Persistence.getItem(key)``` | Retrieves the data associated with the key. If no data is associated to the given key, null is returned. |
110+
| ```Persistence.getItem())``` | Retrieves the data associated with a default key. |
111+
| ```Persistence.setItem(key, data)``` | Persists the key-value pair. |
112+
| ```Persistence.setItem(data)``` | Persists the value using a default key. |
113+
| ```Persistence.removeItem(key)``` | Removes the data associated with the key. If no data is associated to the given key, nothing happens. |
114+
| ```Persistence.removeItem()``` | Removes the data associated with a default key. |
112115

113116
*Some implementations of Persistence may use JSON.stringify and JSON.parse in the process of persisting and retrieving data.*
114117

115118
### Clear storage
116119

117-
```Persistence.store``` may persist data across cards, this should be stopped by calling ```Persistence.store(null)``` at the end of the backside. (If this gets called on the frontside's beginning instead, you cannot use anki's ```{{FrontSide}}``` special field in the backside *- because this would delete the persisted data*)
120+
```Persistence.setItem``` may persist data across cards, this should be stopped by calling ```Persistence.clear()``` at the end of the backside. (If this gets called on the frontside's beginning instead, you cannot use anki's ```{{FrontSide}}``` special field in the backside *- because this would delete the persisted data*)
118121

119122
# Acknowledgements
120123

4.51 KB
Binary file not shown.
3.99 KB
Binary file not shown.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "anki-persistence",
3-
"version": "0.2.2",
3+
"version": "0.3.0",
44
"description": "Persist data between both sides of an anki flashcard.",
55
"main": "script.js",
66
"directories": {

script.js

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,76 @@
11
if (typeof(window.Persistence) === 'undefined') {
2-
var _persistenceKey = 'github.com/SimonLammer/anki-persistence';
2+
var _persistenceKey = 'github.com/SimonLammer/anki-persistence/';
3+
var _defaultKey = '_default';
34
window.Persistence_sessionStorage = function() { // used in android
45
var isAvailable = false;
56
try {
67
if (typeof(window.sessionStorage) === 'object') {
78
isAvailable = true;
8-
this.store = function(data) {
9-
sessionStorage.setItem(_persistenceKey, JSON.stringify(data));
9+
this.clear = function() {
10+
for (var i = 0; i < sessionStorage.length; i++) {
11+
var k = sessionStorage.key(i);
12+
if (k.indexOf(_persistenceKey) == 0) {
13+
sessionStorage.removeItem(k);
14+
i--;
15+
}
16+
};
17+
};
18+
this.setItem = function(key, data) {
19+
if (data == undefined) {
20+
data = key;
21+
key = _defaultKey;
22+
}
23+
sessionStorage.setItem(_persistenceKey + key, JSON.stringify(data));
24+
};
25+
this.getItem = function(key) {
26+
if (key == undefined) {
27+
key = _defaultKey;
28+
}
29+
return JSON.parse(sessionStorage.getItem(_persistenceKey + key));
30+
};
31+
this.removeItem = function(key) {
32+
if (key == undefined) {
33+
key = _defaultKey;
34+
}
35+
sessionStorage.removeItem(_persistenceKey + key);
1036
};
11-
this.load = function() {
12-
return JSON.parse(sessionStorage.getItem(_persistenceKey));
13-
}
1437
}
1538
} catch(err) {}
1639
this.isAvailable = function() {
1740
return isAvailable;
18-
}
41+
};
1942
};
20-
window.Persistence_windowKey = function(persistentKey) {
43+
window.Persistence_windowKey = function(persistentKey) {
2144
var obj = window[persistentKey];
2245
var isAvailable = false;
2346
if (typeof(obj) === 'object') {
2447
isAvailable = true;
25-
this.store = function(data) {
26-
obj[_persistenceKey] = data;
48+
this.clear = function() {
49+
obj[_persistenceKey] = {};
2750
};
28-
this.load = function() {
29-
return obj[_persistenceKey] || null;
51+
this.setItem = function(key, data) {
52+
if (data == undefined) {
53+
data = key;
54+
key = _defaultKey;
55+
}
56+
obj[_persistenceKey][key] = data;
57+
};
58+
this.getItem = function(key) {
59+
if (key == undefined) {
60+
key = _defaultKey;
61+
}
62+
return obj[_persistenceKey][key] || null;
3063
};
64+
this.removeItem = function(key) {
65+
if (key == undefined) {
66+
key = _defaultKey;
67+
}
68+
delete obj[_persistenceKey][key];
69+
};
70+
71+
if (obj[_persistenceKey] == undefined) {
72+
this.clear();
73+
}
3174
}
3275
this.isAvailable = function() {
3376
return isAvailable;

test/persistence.js

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,51 @@
1313
}].forEach(function(args) {
1414
describe(args.constructor, function() {
1515
var persistence = args.generator();
16+
var data = [
17+
1,
18+
2.2,
19+
'3',
20+
{"value": 4}
21+
];
1622
it('is available', function() {
17-
expect(persistence).not.toBeUndefined();
1823
expect(persistence.isAvailable()).toEqual(true);
1924
});
20-
it('.load before .store returns null', function() {
21-
expect(persistence).not.toBeUndefined();
22-
expect(persistence.load()).toBeNull();
25+
it('works without key', function() {
26+
expect(persistence.getItem()).toBeNull();
27+
persistence.removeItem();
28+
29+
for (var i = 0; i < data.length; i++) {
30+
persistence.setItem(data[i]);
31+
expect(persistence.getItem()).toEqual(data[i]);
32+
}
33+
34+
persistence.removeItem();
35+
expect(persistence.getItem()).toBeNull();
36+
37+
persistence.setItem(data[0]);
38+
persistence.clear();
39+
expect(persistence.getItem()).toBeNull();
2340
});
24-
it('.store, .load', function() {
25-
expect(persistence).not.toBeUndefined();
26-
var data = 4;
27-
persistence.store(data);
28-
expect(persistence.load()).toEqual(data);
29-
persistence.store(null);
41+
it('works with key', function() {
42+
for (var i = 0; i < data.length; i++) {
43+
expect(persistence.getItem('' + i)).toBeNull();
44+
persistence.removeItem('' + i); // shouldn't throw an error
45+
}
46+
47+
for (var i = 0; i < data.length; i++) {
48+
persistence.setItem('' + i, data[i]);
49+
expect(persistence.getItem('' + i)).toEqual(data[i]);
50+
}
51+
52+
for (var i = 0; i < data.length; i++) {
53+
persistence.removeItem('' + i);
54+
expect(persistence.getItem('' + i)).toBeNull();
55+
persistence.setItem('' + i, data[i]);
56+
}
57+
persistence.clear();
58+
for (var i = 0; i < data.length; i++) {
59+
expect(persistence.getItem('' + i)).toBeNull();
60+
}
3061
});
3162
});
3263
});

0 commit comments

Comments
 (0)