Introduce state manager (fixes #119)
Change-Id: Idfd71ea53a898c57e676a197776e2b019ef08561
diff --git a/Changes b/Changes
index c3356f3..6bcc53d 100755
--- a/Changes
+++ b/Changes
@@ -41,6 +41,7 @@
- Introduce pagination panel.
- Support for inactive buttongroup items.
- Support default values for state.
+ - Introduce state manager (#119).
0.42 2021-06-18
- Added GitHub based CI for perl.
diff --git a/dev/js/spec/stateSpec.js b/dev/js/spec/stateSpec.js
index 09ab274..286cb1c 100644
--- a/dev/js/spec/stateSpec.js
+++ b/dev/js/spec/stateSpec.js
@@ -1,4 +1,4 @@
-define(['state'], function (stateClass) {
+define(['state','state/manager'], function (stateClass, stateManagerClass) {
describe('KorAP.State', function () {
it('should be initializable', function () {
@@ -137,4 +137,47 @@
expect(s.get()).toEqual('mann');
});
});
+
+ describe('KorAP.State.Manager', function () {
+
+ const el = document.createElement('input');
+
+ it('should be initializable', function () {
+
+ let sm = stateManagerClass.create(el);
+ expect(sm).toBeTruthy();
+
+ expect(sm.toString()).toEqual("{}");
+ });
+
+
+ it('should be extensible', function () {
+ const sm = stateManagerClass.create(el);
+ expect(sm).toBeTruthy();
+
+ const s1 = sm.newState('test', [1,2,3]);
+
+ expect(sm.toString()).toEqual("{}");
+
+ s1.set(2);
+
+ expect(sm.toString()).toEqual("{\"test\":2}");
+
+ s1.set(3);
+
+ expect(sm.toString()).toEqual("{\"test\":3}");
+
+ const s2 = sm.newState('glemm', [true,false]);
+
+ let serial = JSON.parse(sm.toString());
+ expect(serial["test"]).toEqual(3);
+ expect(serial["glemm"]).toBeUndefined();
+
+ s2.set(false);
+
+ serial = JSON.parse(sm.toString());
+ expect(serial["test"]).toEqual(3);
+ expect(serial["glemm"]).toEqual(false);
+ });
+ });
});
diff --git a/dev/js/src/state/manager.js b/dev/js/src/state/manager.js
new file mode 100644
index 0000000..26cb482
--- /dev/null
+++ b/dev/js/src/state/manager.js
@@ -0,0 +1,79 @@
+/**
+ * Create a state manager object, that can deserialize and
+ * serialize states of associated states.
+ * At the moment this requires an element for serialization,
+ * but it may very well serialize in a cookie.
+ *
+ * @author Nils Diewald
+ */
+
+"use strict";
+
+define(['state'], function(stateClass) {
+
+ return {
+ // Create new state amanger.
+ // Expects an object with a value
+ // to contain the serialization of all states.
+ create : function (element) {
+ return Object.create(this)._init(element);
+ },
+
+
+ // Initialize state manager
+ _init : function (element) {
+ this._e = element;
+ this._states = {};
+ this._parse(element.value);
+
+ return this;
+ },
+
+
+ // Parse a value and populate states
+ _parse : function (value) {
+ if (value === undefined || value === '')
+ return;
+
+
+
+ this._states = JSON.parse(value);
+ },
+
+
+ // Return the string representation of all states
+ toString : function () {
+ return JSON.stringify(this._states);
+ },
+
+
+ // Update the query component for states
+ _update : function () {
+ this._e.value = this.toString();
+ },
+
+
+ // Create new state that is automatically associated
+ // with the state manager
+ newState : function (name, values) {
+
+ const t = this;
+ let s = stateClass.create(values);
+
+ // Load state
+ if (t._states[name] !== undefined) {
+ s.set(t._states[name]);
+ };
+
+ // Associate with dummy object
+ s.associate({
+ setState : function (value) {
+ t._states[name] = value;
+ t._update();
+ }
+ });
+
+ return s;
+ }
+ };
+});