otsdaq_utilities  v2_05_02_indev
reactive_data.js
1 /* Tabulator v4.5.3 (c) Oliver Folkerd */
2 
3 var ReactiveData = function ReactiveData(table) {
4  this.table = table; //hold Tabulator object
5  this.data = false;
6  this.blocked = false; //block reactivity while performing update
7  this.origFuncs = {}; // hold original data array functions to allow replacement after data is done with
8  this.currentVersion = 0;
9 };
10 
11 ReactiveData.prototype.watchData = function (data) {
12  var self = this,
13  pushFunc,
14  version;
15 
16  this.currentVersion++;
17 
18  version = this.currentVersion;
19 
20  self.unwatchData();
21 
22  self.data = data;
23 
24  //override array push function
25  self.origFuncs.push = data.push;
26 
27  Object.defineProperty(self.data, "push", {
28  enumerable: false,
29  configurable: true,
30  value: function value() {
31  var args = Array.from(arguments);
32 
33  if (!self.blocked && version === self.currentVersion) {
34  args.forEach(function (arg) {
35  self.table.rowManager.addRowActual(arg, false);
36  });
37  }
38 
39  return self.origFuncs.push.apply(data, arguments);
40  }
41  });
42 
43  //override array unshift function
44  self.origFuncs.unshift = data.unshift;
45 
46  Object.defineProperty(self.data, "unshift", {
47  enumerable: false,
48  configurable: true,
49  value: function value() {
50  var args = Array.from(arguments);
51 
52  if (!self.blocked && version === self.currentVersion) {
53  args.forEach(function (arg) {
54  self.table.rowManager.addRowActual(arg, true);
55  });
56  }
57 
58  return self.origFuncs.unshift.apply(data, arguments);
59  }
60  });
61 
62  //override array shift function
63  self.origFuncs.shift = data.shift;
64 
65  Object.defineProperty(self.data, "shift", {
66  enumerable: false,
67  configurable: true,
68  value: function value() {
69  var row;
70 
71  if (!self.blocked && version === self.currentVersion) {
72  if (self.data.length) {
73  row = self.table.rowManager.getRowFromDataObject(self.data[0]);
74 
75  if (row) {
76  row.deleteActual();
77  }
78  }
79  }
80 
81  return self.origFuncs.shift.call(data);
82  }
83  });
84 
85  //override array pop function
86  self.origFuncs.pop = data.pop;
87 
88  Object.defineProperty(self.data, "pop", {
89  enumerable: false,
90  configurable: true,
91  value: function value() {
92  var row;
93  if (!self.blocked && version === self.currentVersion) {
94  if (self.data.length) {
95  row = self.table.rowManager.getRowFromDataObject(self.data[self.data.length - 1]);
96 
97  if (row) {
98  row.deleteActual();
99  }
100  }
101  }
102  return self.origFuncs.pop.call(data);
103  }
104  });
105 
106  //override array splice function
107  self.origFuncs.splice = data.splice;
108 
109  Object.defineProperty(self.data, "splice", {
110  enumerable: false,
111  configurable: true,
112  value: function value() {
113  var args = Array.from(arguments),
114  start = args[0] < 0 ? data.length + args[0] : args[0],
115  end = args[1],
116  newRows = args[2] ? args.slice(2) : false,
117  startRow;
118 
119  if (!self.blocked && version === self.currentVersion) {
120 
121  //add new rows
122  if (newRows) {
123  startRow = data[start] ? self.table.rowManager.getRowFromDataObject(data[start]) : false;
124 
125  if (startRow) {
126  newRows.forEach(function (rowData) {
127  self.table.rowManager.addRowActual(rowData, true, startRow, true);
128  });
129  } else {
130  newRows = newRows.slice().reverse();
131 
132  newRows.forEach(function (rowData) {
133  self.table.rowManager.addRowActual(rowData, true, false, true);
134  });
135  }
136  }
137 
138  //delete removed rows
139  if (end !== 0) {
140  var oldRows = data.slice(start, typeof args[1] === "undefined" ? args[1] : start + end);
141 
142  oldRows.forEach(function (rowData, i) {
143  var row = self.table.rowManager.getRowFromDataObject(rowData);
144 
145  if (row) {
146  row.deleteActual(i !== oldRows.length - 1);
147  }
148  });
149  }
150 
151  if (newRows || end !== 0) {
152  self.table.rowManager.reRenderInPosition();
153  }
154  }
155 
156  return self.origFuncs.splice.apply(data, arguments);
157  }
158  });
159 };
160 
161 ReactiveData.prototype.unwatchData = function () {
162  if (this.data !== false) {
163  for (var key in this.origFuncs) {
164  Object.defineProperty(this.data, key, {
165  enumerable: true,
166  configurable: true,
167  writable: true,
168  value: this.origFuncs.key
169  });
170  }
171  }
172 };
173 
174 ReactiveData.prototype.watchRow = function (row) {
175  var self = this,
176  data = row.getData();
177 
178  this.blocked = true;
179 
180  for (var key in data) {
181  this.watchKey(row, data, key);
182  }
183 
184  this.blocked = false;
185 };
186 
187 ReactiveData.prototype.watchKey = function (row, data, key) {
188  var self = this,
189  props = Object.getOwnPropertyDescriptor(data, key),
190  value = data[key],
191  version = this.currentVersion;
192 
193  Object.defineProperty(data, key, {
194  set: function set(newValue) {
195  value = newValue;
196  if (!self.blocked && version === self.currentVersion) {
197  var update = {};
198  update[key] = newValue;
199  row.updateData(update);
200  }
201 
202  if (props.set) {
203  props.set(newValue);
204  }
205  },
206  get: function get() {
207 
208  if (props.get) {
209  props.get();
210  }
211 
212  return value;
213  }
214  });
215 };
216 
217 ReactiveData.prototype.unwatchRow = function (row) {
218  var data = row.getData();
219 
220  for (var key in data) {
221  Object.defineProperty(data, key, {
222  value: data[key]
223  });
224  }
225 };
226 
227 ReactiveData.prototype.block = function () {
228  this.blocked = true;
229 };
230 
231 ReactiveData.prototype.unblock = function () {
232  this.blocked = false;
233 };
234 
235 Tabulator.prototype.registerModule("reactiveData", ReactiveData);