@lowdefy/engine 3.23.2 → 4.0.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Blocks.js CHANGED
@@ -1,625 +1,575 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _helpers = require("@lowdefy/helpers");
9
-
10
- var _Events = _interopRequireDefault(require("./Events"));
11
-
12
- var _getFieldValues = _interopRequireDefault(require("./getFieldValues"));
13
-
14
- var _excluded = ["blocks"];
15
-
16
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
-
18
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
19
-
20
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
21
-
22
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
23
-
24
- function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
25
-
26
- function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
27
-
28
- class Blocks {
29
- constructor(_ref) {
30
- var {
31
- arrayIndices,
32
- areas,
33
- context
34
- } = _ref;
35
- this.id = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
36
- this.areas = _helpers.serializer.copy(areas || []);
37
- this.arrayIndices = _helpers.type.isArray(arrayIndices) ? arrayIndices : [];
38
- this.context = context;
39
- this.map = {};
40
- this.recCount = 0;
41
- this.subBlocks = {};
42
- this.generateBlockId = this.generateBlockId.bind(this);
43
- this.getValidateRec = this.getValidateRec.bind(this);
44
- this.init = this.init.bind(this);
45
- this.newBlocks = this.newBlocks.bind(this);
46
- this.recContainerDelState = this.recContainerDelState.bind(this);
47
- this.recEval = this.recEval.bind(this);
48
- this.recRemoveBlocksFromMap = this.recRemoveBlocksFromMap.bind(this);
49
- this.recSetUndefined = this.recSetUndefined.bind(this);
50
- this.recUpdateArrayIndices = this.recUpdateArrayIndices.bind(this);
51
- this.reset = this.reset.bind(this);
52
- this.resetValidation = this.resetValidation.bind(this);
53
- this.resetValidationRec = this.resetValidationRec.bind(this);
54
- this.setBlocksCache = this.setBlocksCache.bind(this);
55
- this.setBlocksLoadingCache = this.setBlocksLoadingCache.bind(this);
56
- this.update = this.update.bind(this);
57
- this.updateState = this.updateState.bind(this);
58
- this.updateStateFromRoot = this.updateStateFromRoot.bind(this);
59
- this.validate = this.validate.bind(this);
60
- }
61
-
62
- loopBlocks(fn) {
63
- if (_helpers.type.isObject(this.areas)) {
64
- Object.keys(this.areas).forEach(key => {
65
- if (_helpers.type.isArray(this.areas[key].blocks)) {
66
- this.areas[key].blocks.forEach(fn);
1
+ /* eslint-disable no-param-reassign */ /*
2
+ Copyright 2020-2021 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import { applyArrayIndices, get, serializer, swap, type } from '@lowdefy/helpers';
16
+ import Events from './Events.js';
17
+ import getFieldValues from './getFieldValues.js';
18
+ let Blocks = class Blocks {
19
+ loopBlocks(fn) {
20
+ if (type.isObject(this.areas)) {
21
+ Object.keys(this.areas).forEach((key)=>{
22
+ if (type.isArray(this.areas[key].blocks)) {
23
+ this.areas[key].blocks.forEach(fn);
24
+ }
25
+ });
67
26
  }
68
- });
69
27
  }
70
- }
71
-
72
- init(initState) {
73
- this.loopBlocks(block => {
74
- block.blockIdPattern = block.blockId;
75
- block.id = this.generateBlockId(block.blockIdPattern);
76
- block.fieldPattern = block.field;
77
- block.blockId = (0, _helpers.applyArrayIndices)(this.arrayIndices, block.blockIdPattern);
78
- this.context.RootBlocks.map[block.blockId] = block;
79
- block.field = !_helpers.type.isNone(block.fieldPattern) ? (0, _helpers.applyArrayIndices)(this.arrayIndices, block.fieldPattern) : block.blockId;
80
- block.visible = _helpers.type.isNone(block.visible) ? true : block.visible;
81
- block.required = _helpers.type.isNone(block.required) ? false : block.required;
82
- block.validate = _helpers.type.isArray(block.validate) ? block.validate : [];
83
- block.properties = _helpers.type.isNone(block.properties) ? {} : block.properties;
84
- block.style = _helpers.type.isNone(block.style) ? {} : block.style;
85
- block.layout = _helpers.type.isNone(block.layout) ? {} : block.layout;
86
- block.events = _helpers.type.isNone(block.events) ? {} : block.events;
87
- block.areasLayoutEval = {};
88
- block.layoutEval = {};
89
- block.propertiesEval = {};
90
- block.requiredEval = {};
91
- block.styleEval = {};
92
- block.validationEval = {};
93
- block.visibleEval = {};
94
-
95
- if (!_helpers.type.isNone(block.areas)) {
96
- block.areasLayout = {};
97
- Object.keys(block.areas).forEach(key => {
98
- // eslint-disable-next-line no-unused-vars
99
- var _block$areas$key = block.areas[key],
100
- {
101
- blocks
102
- } = _block$areas$key,
103
- areaLayout = _objectWithoutProperties(_block$areas$key, _excluded);
104
-
105
- block.areasLayout[key] = _objectSpread({}, areaLayout);
106
- });
107
- } else {
108
- block.areasLayout = {};
109
- }
110
-
111
- block.requestKeys = (0, _getFieldValues.default)('_request', block.style, block.properties, block.validate, block.visible, block.required);
112
- block.methods = {};
113
-
114
- block.registerMethod = (methodName, method) => {
115
- block.methods[methodName] = method;
116
- }; // TODO: add callMethod on block to be used by actions and accessible in blocks
117
-
118
-
119
- if ((0, _helpers.get)(block, 'meta.category') === 'list') {
120
- // TODO: to initialize new object in array, the new value should be passed by method to unshiftItem and pushItem
121
- block.unshiftItem = () => {
122
- this.subBlocks[block.id].forEach((bl, i) => {
123
- bl.recUpdateArrayIndices(this.arrayIndices.concat([i]), this.arrayIndices.concat([i + 1]));
124
- });
125
- this.subBlocks[block.id].unshift(this.newBlocks({
126
- arrayIndices: this.arrayIndices.concat([0]),
127
- block,
128
- initState: {}
129
- }));
130
- this.context.State.set(block.field, undefined); // set block and subBlock values undefined, so as not to pass values to new blocks
131
-
132
- this.subBlocks[block.id][0].recSetUndefined();
133
- block.update = true;
134
- this.context.update();
135
- };
136
-
137
- block.pushItem = () => {
138
- this.subBlocks[block.id].push(this.newBlocks({
139
- arrayIndices: this.arrayIndices.concat([this.subBlocks[block.id].length]),
140
- block,
141
- initState: {}
142
- }));
143
- block.update = true;
144
- this.context.update();
145
- };
146
-
147
- block.removeItem = index => {
148
- this.context.State.removeItem(block.blockId, index);
149
- var lastBlock = this.subBlocks[block.id][this.subBlocks[block.id].length - 1];
150
- lastBlock.recRemoveBlocksFromMap();
151
- var largerBlocks = this.subBlocks[block.id].slice(index + 1);
152
- largerBlocks.forEach((bl, i) => {
153
- bl.recUpdateArrayIndices(this.arrayIndices.concat([index + i + 1]), this.arrayIndices.concat([index + i]));
154
- });
155
- this.subBlocks[block.id].splice(index, 1);
156
- block.update = true;
157
- this.context.update();
158
- };
159
-
160
- block.moveItemUp = index => {
161
- if (index === 0) return;
162
- this.context.State.swapItems(block.blockId, index - 1, index);
163
- this.subBlocks[block.id][index - 1].recUpdateArrayIndices(this.arrayIndices.concat([index - 1]), this.arrayIndices.concat([index]));
164
- this.subBlocks[block.id][index].recUpdateArrayIndices(this.arrayIndices.concat([index]), this.arrayIndices.concat([index - 1]));
165
- (0, _helpers.swap)(this.subBlocks[block.id], index - 1, index);
166
- block.update = true;
167
- this.context.update();
168
- };
169
-
170
- block.moveItemDown = index => {
171
- if (index === this.subBlocks[block.id].length - 1) return;
172
- this.context.State.swapItems(block.blockId, index, index + 1);
173
- this.subBlocks[block.id][index + 1].recUpdateArrayIndices(this.arrayIndices.concat([index + 1]), this.arrayIndices.concat([index]));
174
- this.subBlocks[block.id][index].recUpdateArrayIndices(this.arrayIndices.concat([index]), this.arrayIndices.concat([index + 1]));
175
- (0, _helpers.swap)(this.subBlocks[block.id], index, index + 1);
176
- block.update = true;
177
- this.context.update();
178
- };
179
- }
180
-
181
- if ((0, _helpers.get)(block, 'meta.category') === 'input') {
182
- block.setValue = value => {
183
- block.value = _helpers.type.enforceType(block.meta.valueType, value);
184
- this.context.State.set(block.field, block.value);
185
- block.update = true;
186
- this.context.update();
187
- };
188
- }
189
-
190
- block.Events = new _Events.default({
191
- arrayIndices: this.arrayIndices,
192
- block,
193
- context: this.context
194
- });
195
- block.triggerEvent = block.Events.triggerEvent;
196
- block.registerEvent = block.Events.registerEvent;
197
- });
198
- this.reset(initState); // set initial values to blocks.
199
- }
200
-
201
- reset(initWithState) {
202
- var initState = _helpers.serializer.copy(initWithState || this.context.state);
203
-
204
- this.loopBlocks(block => {
205
- block.update = true;
206
- block.showValidation = false;
207
-
208
- if ((0, _helpers.get)(block, 'meta.category') === 'input' || (0, _helpers.get)(block, 'meta.category') === 'list') {
209
- var blockValue = (0, _helpers.get)(initState, block.field);
210
-
211
- if (_helpers.type.isUndefined(blockValue)) {
212
- // default null value for block type
213
- blockValue = _helpers.type.isUndefined(block.meta.initValue) ? _helpers.type.enforceType(block.meta.valueType, null) : block.meta.initValue;
214
- this.context.State.set(block.field, block.value);
215
- }
216
-
217
- if ((0, _helpers.get)(block, 'meta.category') === 'list') {
218
- // load list value into list blocks
219
- if (!_helpers.type.isArray(this.subBlocks[block.id])) {
220
- this.subBlocks[block.id] = [];
221
- }
222
-
223
- if (_helpers.type.isArray(blockValue)) {
224
- blockValue.forEach((item, i) => {
225
- if (!this.subBlocks[block.id][i]) {
226
- this.subBlocks[block.id].push(this.newBlocks({
227
- arrayIndices: this.arrayIndices.concat([i]),
228
- block,
229
- initState
230
- }));
231
- } else {
232
- this.subBlocks[block.id][i].reset(initState);
233
- }
28
+ init(initState) {
29
+ this.loopBlocks((block)=>{
30
+ block.idPattern = block.id;
31
+ block.blockIdPattern = block.blockId;
32
+ block.fieldPattern = block.field;
33
+ block.id = applyArrayIndices(this.arrayIndices, block.idPattern);
34
+ block.blockId = applyArrayIndices(this.arrayIndices, block.blockIdPattern);
35
+ block.field = !type.isNone(block.fieldPattern) ? applyArrayIndices(this.arrayIndices, block.fieldPattern) : block.blockId;
36
+ this.context._internal.RootBlocks.map[block.id] = block;
37
+ block.visible = type.isNone(block.visible) ? true : block.visible;
38
+ block.required = type.isNone(block.required) ? false : block.required;
39
+ block.validate = type.isArray(block.validate) ? block.validate : [];
40
+ block.properties = type.isNone(block.properties) ? {} : block.properties;
41
+ block.style = type.isNone(block.style) ? {} : block.style;
42
+ block.layout = type.isNone(block.layout) ? {} : block.layout;
43
+ block.events = type.isNone(block.events) ? {} : block.events;
44
+ block.areasLayoutEval = {};
45
+ block.layoutEval = {};
46
+ block.propertiesEval = {};
47
+ block.requiredEval = {};
48
+ block.styleEval = {};
49
+ block.validationEval = {};
50
+ block.visibleEval = {};
51
+ block.meta = this.context._internal.lowdefy._internal.blockComponents[block.type].meta;
52
+ if (!type.isNone(block.areas)) {
53
+ block.areasLayout = {};
54
+ Object.keys(block.areas).forEach((key)=>{
55
+ // eslint-disable-next-line no-unused-vars
56
+ const { blocks , ...areaLayout } = block.areas[key];
57
+ block.areasLayout[key] = {
58
+ ...areaLayout
59
+ };
60
+ });
61
+ } else {
62
+ block.areasLayout = {};
63
+ }
64
+ block.requestKeys = getFieldValues('_request', block.style, block.properties, block.validate, block.visible, block.required);
65
+ block.methods = {};
66
+ block.registerMethod = (methodName, method)=>{
67
+ block.methods[methodName] = method;
68
+ };
69
+ // TODO: add callMethod on block to be used by actions and accessible in blocks
70
+ if (get(block, 'meta.category') === 'list') {
71
+ // TODO: to initialize new object in array, the new value should be passed by method to unshiftItem and pushItem
72
+ block.unshiftItem = ()=>{
73
+ this.subBlocks[block.id].forEach((bl, i)=>{
74
+ bl.recUpdateArrayIndices(this.arrayIndices.concat([
75
+ i
76
+ ]), this.arrayIndices.concat([
77
+ i + 1
78
+ ]));
79
+ });
80
+ this.subBlocks[block.id].unshift(this.newBlocks({
81
+ arrayIndices: this.arrayIndices.concat([
82
+ 0
83
+ ]),
84
+ block,
85
+ initState: {}
86
+ }));
87
+ this.context._internal.State.set(block.field, undefined);
88
+ // set block and subBlock values undefined, so as not to pass values to new blocks
89
+ this.subBlocks[block.id][0].recSetUndefined();
90
+ block.update = true;
91
+ this.context._internal.update();
92
+ };
93
+ block.pushItem = ()=>{
94
+ this.subBlocks[block.id].push(this.newBlocks({
95
+ arrayIndices: this.arrayIndices.concat([
96
+ this.subBlocks[block.id].length
97
+ ]),
98
+ block,
99
+ initState: {}
100
+ }));
101
+ block.update = true;
102
+ this.context._internal.update();
103
+ };
104
+ block.removeItem = (index)=>{
105
+ this.context._internal.State.removeItem(block.blockId, index);
106
+ const lastBlock = this.subBlocks[block.id][this.subBlocks[block.id].length - 1];
107
+ lastBlock.recRemoveBlocksFromMap();
108
+ const largerBlocks = this.subBlocks[block.id].slice(index + 1);
109
+ largerBlocks.forEach((bl, i)=>{
110
+ bl.recUpdateArrayIndices(this.arrayIndices.concat([
111
+ index + i + 1
112
+ ]), this.arrayIndices.concat([
113
+ index + i
114
+ ]));
115
+ });
116
+ this.subBlocks[block.id].splice(index, 1);
117
+ block.update = true;
118
+ this.context._internal.update();
119
+ };
120
+ block.moveItemUp = (index)=>{
121
+ if (index === 0) return;
122
+ this.context._internal.State.swapItems(block.blockId, index - 1, index);
123
+ this.subBlocks[block.id][index - 1].recUpdateArrayIndices(this.arrayIndices.concat([
124
+ index - 1
125
+ ]), this.arrayIndices.concat([
126
+ index
127
+ ]));
128
+ this.subBlocks[block.id][index].recUpdateArrayIndices(this.arrayIndices.concat([
129
+ index
130
+ ]), this.arrayIndices.concat([
131
+ index - 1
132
+ ]));
133
+ swap(this.subBlocks[block.id], index - 1, index);
134
+ block.update = true;
135
+ this.context._internal.update();
136
+ };
137
+ block.moveItemDown = (index)=>{
138
+ if (index === this.subBlocks[block.id].length - 1) return;
139
+ this.context._internal.State.swapItems(block.blockId, index, index + 1);
140
+ this.subBlocks[block.id][index + 1].recUpdateArrayIndices(this.arrayIndices.concat([
141
+ index + 1
142
+ ]), this.arrayIndices.concat([
143
+ index
144
+ ]));
145
+ this.subBlocks[block.id][index].recUpdateArrayIndices(this.arrayIndices.concat([
146
+ index
147
+ ]), this.arrayIndices.concat([
148
+ index + 1
149
+ ]));
150
+ swap(this.subBlocks[block.id], index, index + 1);
151
+ block.update = true;
152
+ this.context._internal.update();
153
+ };
154
+ }
155
+ if (get(block, 'meta.category') === 'input') {
156
+ block.setValue = (value)=>{
157
+ block.value = type.enforceType(block.meta.valueType, value);
158
+ this.context._internal.State.set(block.field, block.value);
159
+ block.update = true;
160
+ this.context._internal.update();
161
+ };
162
+ }
163
+ block.Events = new Events({
164
+ arrayIndices: this.arrayIndices,
165
+ block,
166
+ context: this.context
234
167
  });
235
- this.subBlocks[block.id].splice(blockValue.length);
236
- }
237
- } else {
238
- block.value = blockValue;
239
- }
240
- } else if ((0, _helpers.get)(block, 'meta.category') === 'container' || // do not make sub blocks for sub contexts
241
- (0, _helpers.get)(block, 'meta.category') === 'context' && this === this.context.RootBlocks) {
242
- if (!_helpers.type.isArray(this.subBlocks[block.id])) {
243
- this.subBlocks[block.id] = [];
244
- }
245
-
246
- if (!this.subBlocks[block.id][0]) {
247
- this.subBlocks[block.id].push(this.newBlocks({
248
- arrayIndices: this.arrayIndices,
249
- block,
250
- initState
251
- }));
252
- } else {
253
- this.subBlocks[block.id][0].reset(initState);
254
- }
255
- }
256
- });
257
- }
258
-
259
- newBlocks(_ref2) {
260
- var {
261
- arrayIndices,
262
- block,
263
- initState
264
- } = _ref2;
265
- var SubBlocks = new Blocks({
266
- arrayIndices,
267
- areas: block.areas,
268
- context: this.context
269
- });
270
- SubBlocks.init(initState);
271
- return SubBlocks;
272
- } // used for update comparison
273
-
274
-
275
- static blockEvalToString(block) {
276
- return _helpers.serializer.serializeToString({
277
- areasLayoutEval: block.areasLayoutEval,
278
- layoutEval: block.layoutEval,
279
- propertiesEval: block.propertiesEval,
280
- requiredEval: block.requiredEval,
281
- styleEval: block.styleEval,
282
- validationEval: block.validationEval,
283
- value: block.value,
284
- visibleEval: block.visibleEval
285
- });
286
- }
287
-
288
- recEval(visibleParent) {
289
- var repeat = false;
290
- this.loopBlocks(block => {
291
- if (block.meta.category === 'input') {
292
- var stateValue = (0, _helpers.get)(this.context.state, block.field); // TODO: related to #345
293
- // enforce type here? should we reassign value here??
294
-
295
- block.value = _helpers.type.isUndefined(stateValue) ? block.value : stateValue;
296
- }
297
-
298
- var beforeVisible = block.visibleEval ? block.visibleEval.output : true;
299
-
300
- if (visibleParent === false) {
301
- block.visibleEval.output = false;
302
- } else {
303
- block.visibleEval = this.context.parser.parse({
304
- input: block.visible,
305
- location: block.blockId,
306
- arrayIndices: this.arrayIndices
307
- }); // run parser on index combinations to get visible value object
308
- }
309
-
310
- if (beforeVisible !== block.visibleEval.output) {
311
- repeat = true;
312
- } // only evaluate visible blocks
313
-
314
-
315
- if (block.visibleEval.output !== false) {
316
- block.propertiesEval = this.context.parser.parse({
317
- input: block.properties,
318
- location: block.blockId,
319
- arrayIndices: this.arrayIndices
168
+ block.triggerEvent = block.Events.triggerEvent;
169
+ block.registerEvent = block.Events.registerEvent;
170
+ });
171
+ this.reset(initState); // set initial values to blocks.
172
+ }
173
+ reset(initWithState) {
174
+ const initState = serializer.copy(initWithState || this.context.state);
175
+ this.loopBlocks((block)=>{
176
+ block.update = true;
177
+ block.showValidation = false;
178
+ if (get(block, 'meta.category') === 'input' || get(block, 'meta.category') === 'list') {
179
+ let blockValue = get(initState, block.field);
180
+ if (type.isUndefined(blockValue)) {
181
+ // default null value for block type
182
+ blockValue = type.isUndefined(block.meta.initValue) ? type.enforceType(block.meta.valueType, null) : block.meta.initValue;
183
+ this.context._internal.State.set(block.field, block.value);
184
+ }
185
+ if (get(block, 'meta.category') === 'list') {
186
+ // load list value into list blocks
187
+ if (!type.isArray(this.subBlocks[block.id])) {
188
+ this.subBlocks[block.id] = [];
189
+ }
190
+ if (type.isArray(blockValue)) {
191
+ blockValue.forEach((item, i)=>{
192
+ if (!this.subBlocks[block.id][i]) {
193
+ this.subBlocks[block.id].push(this.newBlocks({
194
+ arrayIndices: this.arrayIndices.concat([
195
+ i
196
+ ]),
197
+ block,
198
+ initState
199
+ }));
200
+ } else {
201
+ this.subBlocks[block.id][i].reset(initState);
202
+ }
203
+ });
204
+ this.subBlocks[block.id].splice(blockValue.length);
205
+ }
206
+ } else {
207
+ block.value = blockValue;
208
+ }
209
+ } else if (get(block, 'meta.category') === 'container') {
210
+ if (!type.isArray(this.subBlocks[block.id])) {
211
+ this.subBlocks[block.id] = [];
212
+ }
213
+ if (!this.subBlocks[block.id][0]) {
214
+ this.subBlocks[block.id].push(this.newBlocks({
215
+ arrayIndices: this.arrayIndices,
216
+ block,
217
+ initState
218
+ }));
219
+ } else {
220
+ this.subBlocks[block.id][0].reset(initState);
221
+ }
222
+ }
320
223
  });
321
- block.requiredEval = this.context.parser.parse({
322
- input: block.required,
323
- location: block.blockId,
324
- arrayIndices: this.arrayIndices
224
+ }
225
+ newBlocks({ arrayIndices , block , initState }) {
226
+ const SubBlocks = new Blocks({
227
+ arrayIndices,
228
+ areas: block.areas,
229
+ context: this.context
230
+ });
231
+ SubBlocks.init(initState);
232
+ return SubBlocks;
233
+ }
234
+ // used for update comparison
235
+ static blockEvalToString(block) {
236
+ return serializer.serializeToString({
237
+ areasLayoutEval: block.areasLayoutEval,
238
+ layoutEval: block.layoutEval,
239
+ propertiesEval: block.propertiesEval,
240
+ requiredEval: block.requiredEval,
241
+ styleEval: block.styleEval,
242
+ validationEval: block.validationEval,
243
+ value: block.value,
244
+ visibleEval: block.visibleEval
325
245
  });
326
- var requiredValidation = {
327
- pass: {
328
- _not: {
329
- _type: 'none'
246
+ }
247
+ recEval(visibleParent) {
248
+ let repeat = false;
249
+ this.loopBlocks((block)=>{
250
+ if (block.meta.category === 'input') {
251
+ const stateValue = get(this.context.state, block.field);
252
+ // TODO: related to #345
253
+ // enforce type here? should we reassign value here??
254
+ block.value = type.isUndefined(stateValue) ? block.value : stateValue;
330
255
  }
331
- },
332
- status: 'error',
333
- message: _helpers.type.isString(block.requiredEval.output) ? block.requiredEval.output : 'This field is required'
334
- };
335
- var validation = block.required === false ? block.validate : [requiredValidation, ...block.validate];
336
- block.validationEval = {
337
- output: {
338
- status: null,
339
- errors: [],
340
- warnings: []
341
- },
342
- errors: []
343
- };
344
- var validationError = false;
345
- var validationWarning = false;
346
- validation.forEach(test => {
347
- var parsed = this.context.parser.parse({
348
- input: test,
349
- location: block.blockId,
350
- arrayIndices: this.arrayIndices
351
- }); // for parser errors
352
-
353
- if (parsed.errors.length > 0) {
354
- block.validationEval.output.errors.push(parsed.output.message);
355
- block.validationEval.errors.push(parsed.errors);
356
- validationError = true;
357
- return;
358
- } // failed validation
359
-
360
-
361
- if (!parsed.output.pass) {
362
- // no status indication on validation tests defaults to error
363
- if (!test.status || test.status === 'error') {
364
- block.validationEval.output.errors.push(parsed.output.message);
365
- validationError = true;
256
+ const beforeVisible = block.visibleEval ? block.visibleEval.output : true;
257
+ if (visibleParent === false) {
258
+ block.visibleEval.output = false;
259
+ } else {
260
+ block.visibleEval = this.context._internal.parser.parse({
261
+ input: block.visible,
262
+ location: block.blockId,
263
+ arrayIndices: this.arrayIndices
264
+ }); // run parser on index combinations to get visible value object
366
265
  }
367
-
368
- if (test.status === 'warning') {
369
- block.validationEval.output.warnings.push(parsed.output.message);
370
- validationWarning = true;
266
+ if (beforeVisible !== block.visibleEval.output) {
267
+ repeat = true;
268
+ }
269
+ // only evaluate visible blocks
270
+ if (block.visibleEval.output !== false) {
271
+ block.propertiesEval = this.context._internal.parser.parse({
272
+ input: block.properties,
273
+ location: block.blockId,
274
+ arrayIndices: this.arrayIndices
275
+ });
276
+ block.requiredEval = this.context._internal.parser.parse({
277
+ input: block.required,
278
+ location: block.blockId,
279
+ arrayIndices: this.arrayIndices
280
+ });
281
+ const requiredValidation = {
282
+ pass: {
283
+ _not: {
284
+ _type: 'none'
285
+ }
286
+ },
287
+ status: 'error',
288
+ message: type.isString(block.requiredEval.output) ? block.requiredEval.output : 'This field is required'
289
+ };
290
+ const validation = block.required === false ? block.validate : [
291
+ requiredValidation,
292
+ ...block.validate
293
+ ];
294
+ block.validationEval = {
295
+ output: {
296
+ status: null,
297
+ errors: [],
298
+ warnings: []
299
+ },
300
+ errors: []
301
+ };
302
+ let validationError = false;
303
+ let validationWarning = false;
304
+ validation.forEach((test)=>{
305
+ const parsed = this.context._internal.parser.parse({
306
+ input: test,
307
+ location: block.blockId,
308
+ arrayIndices: this.arrayIndices
309
+ });
310
+ // for parser errors
311
+ if (parsed.errors.length > 0) {
312
+ block.validationEval.output.errors.push(parsed.output.message);
313
+ block.validationEval.errors.push(parsed.errors);
314
+ validationError = true;
315
+ return;
316
+ }
317
+ // failed validation
318
+ if (!parsed.output.pass) {
319
+ // no status indication on validation tests defaults to error
320
+ if (!test.status || test.status === 'error') {
321
+ block.validationEval.output.errors.push(parsed.output.message);
322
+ validationError = true;
323
+ }
324
+ if (test.status === 'warning') {
325
+ block.validationEval.output.warnings.push(parsed.output.message);
326
+ validationWarning = true;
327
+ }
328
+ }
329
+ });
330
+ if (validation.length > 0) {
331
+ block.validationEval.output.status = 'success';
332
+ }
333
+ if (validationWarning) {
334
+ block.validationEval.output.status = 'warning';
335
+ }
336
+ if (validationError) {
337
+ block.validationEval.output.status = 'error';
338
+ }
339
+ block.styleEval = this.context._internal.parser.parse({
340
+ input: block.style,
341
+ location: block.blockId,
342
+ arrayIndices: this.arrayIndices
343
+ });
344
+ block.layoutEval = this.context._internal.parser.parse({
345
+ input: block.layout,
346
+ location: block.blockId,
347
+ arrayIndices: this.arrayIndices
348
+ });
349
+ block.areasLayoutEval = this.context._internal.parser.parse({
350
+ input: block.areasLayout,
351
+ location: block.blockId,
352
+ arrayIndices: this.arrayIndices
353
+ });
354
+ }
355
+ if (get(block, 'meta.category') === 'container' || get(block, 'meta.category') === 'list') {
356
+ if (this.subBlocks[block.id] && this.subBlocks[block.id].length > 0) {
357
+ this.subBlocks[block.id].forEach((blockClass)=>{
358
+ repeat = blockClass.recEval(block.visibleEval.output) || repeat;
359
+ });
360
+ }
361
+ }
362
+ const after = Blocks.blockEvalToString(block);
363
+ if (block.before !== after) {
364
+ block.update = true;
365
+ block.before = after;
371
366
  }
372
- }
373
367
  });
374
-
375
- if (validation.length > 0) {
376
- block.validationEval.output.status = 'success';
377
- }
378
-
379
- if (validationWarning) {
380
- block.validationEval.output.status = 'warning';
381
- }
382
-
383
- if (validationError) {
384
- block.validationEval.output.status = 'error';
385
- }
386
-
387
- block.styleEval = this.context.parser.parse({
388
- input: block.style,
389
- location: block.blockId,
390
- arrayIndices: this.arrayIndices
368
+ return repeat;
369
+ }
370
+ updateState() {
371
+ const toSet = new Set();
372
+ const toDelete = new Set();
373
+ this.loopBlocks((block)=>{
374
+ if (block.visibleEval.output !== false) {
375
+ if (get(block, 'meta.category') === 'container' || get(block, 'meta.category') === 'list') {
376
+ if (this.subBlocks[block.id] && this.subBlocks[block.id].length > 0) {
377
+ this.subBlocks[block.id].forEach((blockClass)=>{
378
+ blockClass.updateState();
379
+ });
380
+ } else {
381
+ toSet.add(block.field);
382
+ this.context._internal.State.set(block.field, type.enforceType(block.meta.valueType, null));
383
+ }
384
+ } else if (get(block, 'meta.category') === 'input') {
385
+ toSet.add(block.field);
386
+ this.context._internal.State.set(block.field, block.value);
387
+ }
388
+ } else if (get(block, 'meta.category') === 'container') {
389
+ this.subBlocks[block.id].forEach((blockClass)=>{
390
+ blockClass.recContainerDelState(toDelete);
391
+ });
392
+ } else {
393
+ toDelete.add(block.field);
394
+ }
391
395
  });
392
- block.layoutEval = this.context.parser.parse({
393
- input: block.layout,
394
- location: block.blockId,
395
- arrayIndices: this.arrayIndices
396
+ toDelete.forEach((field)=>{
397
+ if (!toSet.has(field)) {
398
+ this.context._internal.State.del(field);
399
+ }
396
400
  });
397
- block.areasLayoutEval = this.context.parser.parse({
398
- input: block.areasLayout,
399
- location: block.blockId,
400
- arrayIndices: this.arrayIndices
401
+ }
402
+ recContainerDelState(toDelete) {
403
+ this.loopBlocks((block)=>{
404
+ if (get(block, 'meta.category') === 'container') {
405
+ this.subBlocks[block.id].forEach((blockClass)=>{
406
+ blockClass.recContainerDelState(toDelete);
407
+ });
408
+ } else {
409
+ toDelete.add(block.field);
410
+ }
401
411
  });
402
- }
403
-
404
- if ((0, _helpers.get)(block, 'meta.category') === 'container' || (0, _helpers.get)(block, 'meta.category') === 'context' || (0, _helpers.get)(block, 'meta.category') === 'list') {
405
- if (this.subBlocks[block.id] && this.subBlocks[block.id].length > 0) {
406
- this.subBlocks[block.id].forEach(blockClass => {
407
- repeat = blockClass.recEval(block.visibleEval.output) || repeat;
408
- });
412
+ }
413
+ updateStateFromRoot() {
414
+ const repeat = this.recEval(true);
415
+ this.updateState();
416
+ if (repeat && this.recCount < 20) {
417
+ this.recCount += 1;
418
+ this.updateStateFromRoot();
409
419
  }
410
- }
411
-
412
- var after = Blocks.blockEvalToString(block);
413
-
414
- if (block.before !== after) {
415
- block.update = true;
416
- block.before = after;
417
- }
418
- });
419
- return repeat;
420
- }
421
-
422
- updateState() {
423
- var toSet = new Set();
424
- var toDelete = new Set();
425
- this.loopBlocks(block => {
426
- if (block.visibleEval.output !== false) {
427
- if ((0, _helpers.get)(block, 'meta.category') === 'container' || (0, _helpers.get)(block, 'meta.category') === 'context' || (0, _helpers.get)(block, 'meta.category') === 'list') {
428
- if (this.subBlocks[block.id] && this.subBlocks[block.id].length > 0) {
429
- this.subBlocks[block.id].forEach(blockClass => {
430
- blockClass.updateState();
420
+ this.recCount = 0;
421
+ }
422
+ recUpdateArrayIndices(oldIndices, newIndices) {
423
+ newIndices.forEach((index, i)=>{
424
+ this.arrayIndices[i] = newIndices[i];
425
+ });
426
+ this.loopBlocks((block)=>{
427
+ block.blockId = applyArrayIndices(this.arrayIndices, block.blockIdPattern);
428
+ this.context._internal.RootBlocks.map[block.blockId] = block;
429
+ block.field = !type.isNone(block.fieldPattern) ? applyArrayIndices(this.arrayIndices, block.fieldPattern) : block.blockId;
430
+ });
431
+ Object.keys(this.subBlocks).forEach((subKey)=>{
432
+ this.subBlocks[subKey].forEach((subBlock)=>{
433
+ subBlock.recUpdateArrayIndices(oldIndices, newIndices);
431
434
  });
432
- } else {
433
- toSet.add(block.field);
434
- this.context.State.set(block.field, _helpers.type.enforceType(block.meta.valueType, null));
435
- }
436
- } else if ((0, _helpers.get)(block, 'meta.category') === 'input') {
437
- toSet.add(block.field);
438
- this.context.State.set(block.field, block.value);
439
- }
440
- } else if ((0, _helpers.get)(block, 'meta.category') === 'container' || (0, _helpers.get)(block, 'meta.category') === 'context') {
441
- this.subBlocks[block.id].forEach(blockClass => {
442
- blockClass.recContainerDelState(toDelete);
443
435
  });
444
- } else {
445
- toDelete.add(block.field);
446
- }
447
- });
448
- toDelete.forEach(field => {
449
- if (!toSet.has(field)) {
450
- this.context.State.del(field);
451
- }
452
- });
453
- }
454
-
455
- recContainerDelState(toDelete) {
456
- this.loopBlocks(block => {
457
- if ((0, _helpers.get)(block, 'meta.category') === 'container' || (0, _helpers.get)(block, 'meta.category') === 'context') {
458
- this.subBlocks[block.id].forEach(blockClass => {
459
- blockClass.recContainerDelState(toDelete);
436
+ }
437
+ getValidateRec(match, result) {
438
+ this.loopBlocks((block)=>{
439
+ if (match(block.blockId)) {
440
+ block.showValidation = true;
441
+ block.update = true;
442
+ if (block.visibleEval.output !== false && block.validationEval.output && block.validationEval.output.status === 'error') {
443
+ result.push({
444
+ blockId: block.blockId,
445
+ validation: block.validationEval.output
446
+ });
447
+ }
448
+ }
460
449
  });
461
- } else {
462
- toDelete.add(block.field);
463
- }
464
- });
465
- }
466
-
467
- updateStateFromRoot() {
468
- var repeat = this.recEval(true);
469
- this.updateState();
470
-
471
- if (repeat && this.recCount < 20) {
472
- this.recCount += 1;
473
- this.updateStateFromRoot();
450
+ Object.keys(this.subBlocks).forEach((subKey)=>{
451
+ this.subBlocks[subKey].forEach((subBlock)=>{
452
+ subBlock.getValidateRec(match, result);
453
+ });
454
+ });
455
+ return result;
474
456
  }
475
-
476
- this.recCount = 0;
477
- }
478
-
479
- recUpdateArrayIndices(oldIndices, newIndices) {
480
- newIndices.forEach((index, i) => {
481
- this.arrayIndices[i] = newIndices[i];
482
- });
483
- this.loopBlocks(block => {
484
- block.blockId = (0, _helpers.applyArrayIndices)(this.arrayIndices, block.blockIdPattern);
485
- this.context.RootBlocks.map[block.blockId] = block;
486
- block.field = !_helpers.type.isNone(block.fieldPattern) ? (0, _helpers.applyArrayIndices)(this.arrayIndices, block.fieldPattern) : block.blockId;
487
- });
488
- Object.keys(this.subBlocks).forEach(subKey => {
489
- this.subBlocks[subKey].forEach(subBlock => {
490
- subBlock.recUpdateArrayIndices(oldIndices, newIndices);
491
- });
492
- });
493
- }
494
-
495
- getValidateRec(match, result) {
496
- this.loopBlocks(block => {
497
- if (match(block.blockId)) {
498
- block.showValidation = true;
499
- block.update = true;
500
-
501
- if (block.visibleEval.output !== false && block.validationEval.output && block.validationEval.output.status === 'error') {
502
- result.push({
503
- blockId: block.blockId,
504
- validation: block.validationEval.output
505
- });
506
- }
507
- }
508
- });
509
- Object.keys(this.subBlocks).forEach(subKey => {
510
- this.subBlocks[subKey].forEach(subBlock => {
511
- subBlock.getValidateRec(match, result);
512
- });
513
- });
514
- return result;
515
- }
516
-
517
- recSetUndefined() {
518
- this.loopBlocks(block => {
519
- this.context.State.set(block.field, undefined);
520
- });
521
- Object.keys(this.subBlocks).forEach(subKey => {
522
- this.subBlocks[subKey].forEach(subBlock => {
523
- subBlock.recSetUndefined();
524
- });
525
- });
526
- }
527
-
528
- recRemoveBlocksFromMap() {
529
- this.loopBlocks(block => {
530
- delete this.context.RootBlocks.map[block.blockId];
531
- });
532
- Object.keys(this.subBlocks).forEach(subKey => {
533
- this.subBlocks[subKey].forEach(subBlock => {
534
- subBlock.recRemoveBlocksFromMap();
535
- });
536
- });
537
- }
538
-
539
- validate(match) {
540
- this.updateStateFromRoot(); // update to recalculate validationEval to raise block errors
541
-
542
- var validationErrors = this.getValidateRec(match, []); // get all relevant raised block errors and set showValidation
543
-
544
- this.setBlocksCache(); // update cache to render
545
-
546
- return validationErrors;
547
- }
548
-
549
- resetValidationRec(match) {
550
- this.loopBlocks(block => {
551
- if (match(block.blockId)) {
552
- block.showValidation = false;
553
- block.update = true;
554
- }
555
- });
556
- Object.keys(this.subBlocks).forEach(subKey => {
557
- this.subBlocks[subKey].forEach(subBlock => {
558
- subBlock.resetValidationRec(match);
559
- });
560
- });
561
- }
562
-
563
- resetValidation(match) {
564
- this.resetValidationRec(match);
565
- this.setBlocksCache();
566
- }
567
-
568
- update() {
569
- this.updateStateFromRoot(); // update all the blocks
570
-
571
- this.setBlocksCache(); // finally update cache
572
- }
573
-
574
- setBlocksCache() {
575
- this.loopBlocks(block => {
576
- if (block.update) {
577
- block.update = false;
578
- block.loading = block.requestKeys.reduce((acc, key) => acc || (this.context.requests[key] ? this.context.requests[key].loading : true), false);
579
- block.eval = {
580
- areas: block.areasLayoutEval.output,
581
- events: _helpers.type.isNone(block.Events.events) ? null : block.Events.events,
582
- properties: block.propertiesEval.output,
583
- required: block.requiredEval.output,
584
- layout: block.layoutEval.output,
585
- style: block.styleEval.output,
586
- validation: _objectSpread(_objectSpread({}, block.validationEval.output || {}), {}, {
587
- status: block.showValidation ? (block.validationEval.output || {}).status : null
588
- }),
589
- value: _helpers.type.isNone(block.value) ? null : block.value,
590
- visible: block.visibleEval.output
591
- };
592
- this.context.lowdefy.updateBlock(block.id);
593
- }
594
- });
595
- Object.keys(this.subBlocks).forEach(subKey => {
596
- this.subBlocks[subKey].forEach(subBlock => {
597
- subBlock.setBlocksCache();
598
- });
599
- });
600
- }
601
-
602
- setBlocksLoadingCache() {
603
- this.loopBlocks(block => {
604
- block.loading_prev = block.loading;
605
- block.loading = block.requestKeys.reduce((acc, key) => acc || (this.context.requests[key] ? this.context.requests[key].loading : true), false);
606
-
607
- if (block.loading_prev !== block.loading) {
608
- this.context.lowdefy.updateBlock(block.id);
609
- }
610
- });
611
- Object.keys(this.subBlocks).forEach(subKey => {
612
- this.subBlocks[subKey].forEach(subBlock => {
613
- subBlock.setBlocksLoadingCache();
614
- });
615
- });
616
- }
617
-
618
- generateBlockId(blockIdPattern) {
619
- return "".concat(this.context.pageId, ":").concat(blockIdPattern, ":").concat(Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5));
620
- }
621
-
622
- }
623
-
624
- var _default = Blocks;
625
- exports.default = _default;
457
+ recSetUndefined() {
458
+ this.loopBlocks((block)=>{
459
+ this.context._internal.State.set(block.field, undefined);
460
+ });
461
+ Object.keys(this.subBlocks).forEach((subKey)=>{
462
+ this.subBlocks[subKey].forEach((subBlock)=>{
463
+ subBlock.recSetUndefined();
464
+ });
465
+ });
466
+ }
467
+ recRemoveBlocksFromMap() {
468
+ this.loopBlocks((block)=>{
469
+ delete this.context._internal.RootBlocks.map[block.blockId];
470
+ });
471
+ Object.keys(this.subBlocks).forEach((subKey)=>{
472
+ this.subBlocks[subKey].forEach((subBlock)=>{
473
+ subBlock.recRemoveBlocksFromMap();
474
+ });
475
+ });
476
+ }
477
+ validate(match) {
478
+ this.updateStateFromRoot(); // update to recalculate validationEval to raise block errors
479
+ const validationErrors = this.getValidateRec(match, []); // get all relevant raised block errors and set showValidation
480
+ this.setBlocksCache(); // update cache to render
481
+ return validationErrors;
482
+ }
483
+ resetValidationRec(match) {
484
+ this.loopBlocks((block)=>{
485
+ if (match(block.blockId)) {
486
+ block.showValidation = false;
487
+ block.update = true;
488
+ }
489
+ });
490
+ Object.keys(this.subBlocks).forEach((subKey)=>{
491
+ this.subBlocks[subKey].forEach((subBlock)=>{
492
+ subBlock.resetValidationRec(match);
493
+ });
494
+ });
495
+ }
496
+ resetValidation(match) {
497
+ this.resetValidationRec(match);
498
+ this.setBlocksCache();
499
+ }
500
+ update() {
501
+ this.updateStateFromRoot(); // update all the blocks
502
+ this.setBlocksCache(); // finally update cache
503
+ }
504
+ setBlocksCache() {
505
+ this.loopBlocks((block)=>{
506
+ if (block.update) {
507
+ block.update = false;
508
+ block.loading = block.requestKeys.reduce((acc, key)=>acc || (this.context.requests[key] ? this.context.requests[key].loading : true)
509
+ , false);
510
+ block.eval = {
511
+ areas: block.areasLayoutEval.output,
512
+ events: type.isNone(block.Events.events) ? null : block.Events.events,
513
+ properties: block.propertiesEval.output,
514
+ required: block.requiredEval.output,
515
+ layout: block.layoutEval.output,
516
+ style: block.styleEval.output,
517
+ validation: {
518
+ ...block.validationEval.output || {},
519
+ status: block.showValidation ? (block.validationEval.output || {}).status : null
520
+ },
521
+ value: type.isNone(block.value) ? null : block.value,
522
+ visible: block.visibleEval.output
523
+ };
524
+ this.context._internal.lowdefy._internal.updateBlock(block.id);
525
+ }
526
+ });
527
+ Object.keys(this.subBlocks).forEach((subKey)=>{
528
+ this.subBlocks[subKey].forEach((subBlock)=>{
529
+ subBlock.setBlocksCache();
530
+ });
531
+ });
532
+ }
533
+ setBlocksLoadingCache() {
534
+ this.loopBlocks((block)=>{
535
+ block.loading_prev = block.loading;
536
+ block.loading = block.requestKeys.reduce((acc, key)=>acc || (this.context.requests[key] ? this.context.requests[key].loading : true)
537
+ , false);
538
+ if (block.loading_prev !== block.loading) {
539
+ this.context._internal.lowdefy._internal.updateBlock(block.id);
540
+ }
541
+ });
542
+ Object.keys(this.subBlocks).forEach((subKey)=>{
543
+ this.subBlocks[subKey].forEach((subBlock)=>{
544
+ subBlock.setBlocksLoadingCache();
545
+ });
546
+ });
547
+ }
548
+ constructor({ arrayIndices , areas , context }){
549
+ this.id = Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
550
+ this.areas = serializer.copy(areas || []);
551
+ this.arrayIndices = type.isArray(arrayIndices) ? arrayIndices : [];
552
+ this.context = context;
553
+ this.map = {};
554
+ this.recCount = 0;
555
+ this.subBlocks = {};
556
+ this.getValidateRec = this.getValidateRec.bind(this);
557
+ this.init = this.init.bind(this);
558
+ this.newBlocks = this.newBlocks.bind(this);
559
+ this.recContainerDelState = this.recContainerDelState.bind(this);
560
+ this.recEval = this.recEval.bind(this);
561
+ this.recRemoveBlocksFromMap = this.recRemoveBlocksFromMap.bind(this);
562
+ this.recSetUndefined = this.recSetUndefined.bind(this);
563
+ this.recUpdateArrayIndices = this.recUpdateArrayIndices.bind(this);
564
+ this.reset = this.reset.bind(this);
565
+ this.resetValidation = this.resetValidation.bind(this);
566
+ this.resetValidationRec = this.resetValidationRec.bind(this);
567
+ this.setBlocksCache = this.setBlocksCache.bind(this);
568
+ this.setBlocksLoadingCache = this.setBlocksLoadingCache.bind(this);
569
+ this.update = this.update.bind(this);
570
+ this.updateState = this.updateState.bind(this);
571
+ this.updateStateFromRoot = this.updateStateFromRoot.bind(this);
572
+ this.validate = this.validate.bind(this);
573
+ }
574
+ };
575
+ export default Blocks;