Introduced state class for simple reactive state propagation
Change-Id: I3c98751ff124b289499d179bf3fff4bee9350e7e
diff --git a/Changes b/Changes
index 0027b2e..b43f219 100755
--- a/Changes
+++ b/Changes
@@ -1,4 +1,4 @@
-0.37 2019-11-19
+0.37 2019-12-05
- Removed deprecated 'kalamar_test_port' helper.
- Separated KalamarHelpers and KalamarPages.
- Renamed 'doc_link_to' to 'embedded_link_to'
@@ -16,6 +16,7 @@
- Added 'navi->set' and 'navi->add' helper.
- Added settings skeleton.
- Added query panel for query views.
+ - Added state object.
0.36 2019-09-19
- Rename all cookies to be independent
diff --git a/dev/js/runner/all.html b/dev/js/runner/all.html
index f0a71ad..1d3349c 100644
--- a/dev/js/runner/all.html
+++ b/dev/js/runner/all.html
@@ -48,7 +48,8 @@
'spec/statSpec',
'spec/vcSpec',
'spec/tourSpec',
- 'spec/utilSpec'
+ 'spec/utilSpec',
+ 'spec/stateSpec'
],
function () {
window.onload();
diff --git a/dev/js/spec/stateSpec.js b/dev/js/spec/stateSpec.js
new file mode 100644
index 0000000..865691e
--- /dev/null
+++ b/dev/js/spec/stateSpec.js
@@ -0,0 +1,57 @@
+define(['state'], function (stateClass) {
+
+ describe('KorAP.State', function () {
+ it('should be initializable', function () {
+ let s = stateClass.create();
+ expect(s.get()).toBeFalsy();
+
+ s = stateClass.create(true);
+ expect(s.get()).toBeTruthy();
+ });
+
+ it('should be settable and gettable', function () {
+ let s = stateClass.create();
+ expect(s.get()).toBeFalsy();
+ s.set(true);
+ expect(s.get()).toBeTruthy();
+ });
+
+ it('should be associatable', function () {
+ let s = stateClass.create();
+
+ // Create
+ let obj1 = {
+ x : false,
+ setState : function (value) {
+ this.x = value;
+ }
+ };
+
+ // Create
+ let obj2 = {
+ x : true,
+ setState : function (value) {
+ this.x = value;
+ }
+ };
+
+ expect(s.get()).toBeFalsy();
+ expect(obj1.x).toBeFalsy();
+ expect(obj2.x).toBeTruthy();
+
+ // Associate object with state
+ s.associate(obj1);
+ s.associate(obj2);
+
+ expect(s.get()).toBeFalsy();
+ expect(obj1.x).toBeFalsy();
+ expect(obj2.x).toBeFalsy();
+
+ s.set(true);
+
+ expect(s.get()).toBeTruthy();
+ expect(obj1.x).toBeTruthy();
+ expect(obj2.x).toBeTruthy();
+ });
+ });
+});
diff --git a/dev/js/src/state.js b/dev/js/src/state.js
new file mode 100644
index 0000000..013ae10
--- /dev/null
+++ b/dev/js/src/state.js
@@ -0,0 +1,64 @@
+/**
+ * Create a state object, that can have a single value
+ * (mostly boolean) and multiple objects associated to it.
+ * Whenever the state changes, all objects are informed
+ * by their setState() method of the value change.
+ *
+ * @author Nils Diewald
+ */
+define(function () {
+
+ "use strict";
+
+ return {
+
+ /**
+ * Constructor
+ */
+ create : function (value) {
+ return Object.create(this)._init(value);
+ },
+
+ // Initialize
+ _init : function (value) {
+ this._assoc = [];
+ this.value = value;
+ return this;
+ },
+
+
+ /**
+ * Associate the state with some objects.
+ */
+ associate : function (obj) {
+
+ // Check if the object has a setState() method
+ if (obj.hasOwnProperty("setState")) {
+ this._assoc.push(obj);
+ obj.setState(this.value);
+ } else {
+ console.log("Object " + obj + " has no setState() method");
+ }
+ },
+
+ /**
+ * Set the state to a certain value.
+ * This will set the state to all associated objects as well.
+ */
+ set : function (value) {
+ if (value != this.value) {
+ this.value = value;
+ for (let i in this._assoc) {
+ this._assoc[i].setState(value);
+ }
+ };
+ },
+
+ /**
+ * Get the state value
+ */
+ get : function () {
+ return this.value;
+ }
+ }
+});