hadron-document 7.8.0 → 7.9.0

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/lib/element.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
3
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
4
4
 
5
5
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
6
6
 
@@ -12,9 +12,9 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
12
12
 
13
13
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
14
14
 
15
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
15
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
16
16
 
17
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
17
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
18
18
 
19
19
  function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
20
20
 
@@ -46,20 +46,11 @@ var TypeChecker = require('hadron-type-checker');
46
46
 
47
47
  var uuid = require('uuid');
48
48
 
49
- var DATE_FORMAT = 'YYYY-MM-DD HH:mm:ss.SSS';
50
- /**
51
- * The event constant.
52
- */
49
+ var DateEditor = require('./editor/date');
53
50
 
54
- var Events = {
55
- 'Added': 'Element::Added',
56
- 'Edited': 'Element::Edited',
57
- 'Removed': 'Element::Removed',
58
- 'Reverted': 'Element::Reverted',
59
- 'Converted': 'Element::Converted',
60
- 'Invalid': 'Element::Invalid',
61
- 'Valid': 'Element::Valid'
62
- };
51
+ var Events = require('./element-events');
52
+
53
+ var DATE_FORMAT = 'YYYY-MM-DD HH:mm:ss.SSS';
63
54
  /**
64
55
  * Id field constant.
65
56
  */
@@ -69,7 +60,7 @@ var ID = '_id';
69
60
  * Types that are not editable.
70
61
  */
71
62
 
72
- var UNEDITABLE_TYPES = ['Binary', 'Code', 'MinKey', 'MaxKey', 'Timestamp', 'BSONRegExp', 'Undefined', 'Null'];
63
+ var UNEDITABLE_TYPES = ['Binary', 'Code', 'MinKey', 'MaxKey', 'Timestamp', 'BSONRegExp', 'Undefined', 'Null', 'DBRef'];
73
64
  /**
74
65
  * Curly brace constant.
75
66
  */
@@ -120,6 +111,7 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
120
111
  _this.removed = false;
121
112
  _this.type = TypeChecker.type(value);
122
113
  _this.currentType = _this.type;
114
+ _this.level = _this._getLevel();
123
115
 
124
116
  _this.setValid();
125
117
 
@@ -133,12 +125,6 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
133
125
 
134
126
  return _this;
135
127
  }
136
- /**
137
- * Edit the element.
138
- *
139
- * @param {Object} value - The new value.
140
- */
141
-
142
128
 
143
129
  _createClass(Element, [{
144
130
  key: "bulkEdit",
@@ -152,7 +138,7 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
152
138
  if (value.match(ARRAY_OR_OBJECT)) {
153
139
  this.edit(JSON.parse(value));
154
140
 
155
- this._bubbleUp(Events.Converted);
141
+ this._bubbleUp(Events.Converted, this);
156
142
  } else {
157
143
  this.edit(value);
158
144
  }
@@ -165,18 +151,11 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
165
151
  key: "cancel",
166
152
  value: function cancel() {
167
153
  if (this.elements) {
168
- var _iterator = _createForOfIteratorHelper(this.elements),
169
- _step;
170
-
171
- try {
172
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
173
- var element = _step.value;
174
- element.cancel();
175
- }
176
- } catch (err) {
177
- _iterator.e(err);
178
- } finally {
179
- _iterator.f();
154
+ // Cancel will remove elements from iterator, clone it before iterating
155
+ // otherwise we will skip items
156
+ for (var _i = 0, _Array$from = Array.from(this.elements); _i < _Array$from.length; _i++) {
157
+ var element = _Array$from[_i];
158
+ element.cancel();
180
159
  }
181
160
  }
182
161
 
@@ -184,6 +163,25 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
184
163
  this.revert();
185
164
  }
186
165
  }
166
+ }, {
167
+ key: "_getLevel",
168
+ value: function _getLevel() {
169
+ var level = -1;
170
+ var parent = this.parent;
171
+
172
+ while (parent) {
173
+ level++;
174
+ parent = parent.parent;
175
+ }
176
+
177
+ return level;
178
+ }
179
+ /**
180
+ * Edit the element.
181
+ *
182
+ * @param {Object} value - The new value.
183
+ */
184
+
187
185
  }, {
188
186
  key: "edit",
189
187
  value: function edit(value) {
@@ -201,7 +199,45 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
201
199
 
202
200
  this.setValid();
203
201
 
204
- this._bubbleUp(Events.Edited);
202
+ this._bubbleUp(Events.Edited, this);
203
+ }
204
+ /**
205
+ * @param {import('hadron-type-checker').TypeCastTypes} newType
206
+ */
207
+
208
+ }, {
209
+ key: "changeType",
210
+ value: function changeType(newType) {
211
+ if (newType === 'Object') {
212
+ this.edit('{');
213
+ this.next();
214
+ } else if (newType === 'Array') {
215
+ this.edit('[');
216
+ this.next();
217
+ } else {
218
+ try {
219
+ if (newType === 'Date') {
220
+ var editor = new DateEditor(this);
221
+ editor.edit(this.generateObject());
222
+ editor.complete();
223
+ } else {
224
+ this.edit(TypeChecker.cast(this.generateObject(), newType));
225
+ }
226
+ } catch (e) {
227
+ this.setInvalid(this.currentValue, newType, e.message);
228
+ }
229
+ }
230
+ }
231
+ }, {
232
+ key: "getRoot",
233
+ value: function getRoot() {
234
+ var parent = this.parent;
235
+
236
+ while (parent.parent) {
237
+ parent = parent.parent;
238
+ }
239
+
240
+ return parent;
205
241
  }
206
242
  /**
207
243
  * Get an element by its key.
@@ -265,7 +301,7 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
265
301
 
266
302
  this.currentKey = key;
267
303
 
268
- this._bubbleUp(Events.Edited);
304
+ this._bubbleUp(Events.Edited, this);
269
305
  }
270
306
  /**
271
307
  * Generate the javascript object for this element.
@@ -280,7 +316,7 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
280
316
  return ObjectGenerator.generateArray(this.elements);
281
317
  }
282
318
 
283
- if (this.elements) {
319
+ if (this.currentType === 'Object') {
284
320
  return ObjectGenerator.generate(this.elements);
285
321
  }
286
322
 
@@ -339,7 +375,7 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
339
375
  this.elements.updateKeys(newElement, 1);
340
376
  }
341
377
 
342
- this._bubbleUp(Events.Added);
378
+ newElement._bubbleUp(Events.Added, newElement, this);
343
379
 
344
380
  return newElement;
345
381
  }
@@ -370,7 +406,7 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
370
406
 
371
407
  var newElement = this.elements.insertEnd(key, value, true, this);
372
408
 
373
- this._bubbleUp(Events.Added);
409
+ this._bubbleUp(Events.Adde, newElement);
374
410
 
375
411
  return newElement;
376
412
  }
@@ -383,11 +419,12 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
383
419
  }, {
384
420
  key: "insertPlaceholder",
385
421
  value: function insertPlaceholder() {
386
- var newElement = this.elements.insertEnd('', '', true, this);
387
-
388
- this._bubbleUp(Events.Added);
389
-
390
- return newElement;
422
+ return this.insertEnd('', '');
423
+ }
424
+ }, {
425
+ key: "insertSiblingPlaceholder",
426
+ value: function insertSiblingPlaceholder() {
427
+ return this.parent.insertAfter(this, '', '');
391
428
  }
392
429
  /**
393
430
  * Is the element a newly added element?
@@ -432,7 +469,7 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
432
469
  this.currentTypeValid = true;
433
470
  this.invalidTypeMessage = undefined;
434
471
 
435
- this._bubbleUp(Events.Valid, this.uuid);
472
+ this._bubbleUp(Events.Valid, this);
436
473
  }
437
474
  /**
438
475
  * Set the element as invalid.
@@ -450,7 +487,7 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
450
487
  this.currentTypeValid = false;
451
488
  this.invalidTypeMessage = message;
452
489
 
453
- this._bubbleUp(Events.Invalid, this.uuid);
490
+ this._bubbleUp(Events.Invalid, this);
454
491
  }
455
492
  /**
456
493
  * Determine if the key is a duplicate.
@@ -463,25 +500,25 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
463
500
  }, {
464
501
  key: "isDuplicateKey",
465
502
  value: function isDuplicateKey(value) {
466
- if (value === this.currentKey) {
503
+ if (value === '') {
467
504
  return false;
468
505
  }
469
506
 
470
- var _iterator2 = _createForOfIteratorHelper(this.parent.elements),
471
- _step2;
507
+ var _iterator = _createForOfIteratorHelper(this.parent.elements),
508
+ _step;
472
509
 
473
510
  try {
474
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
475
- var element = _step2.value;
511
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
512
+ var element = _step.value;
476
513
 
477
- if (element.currentKey === value) {
514
+ if (element.uuid !== this.uuid && element.currentKey === value) {
478
515
  return true;
479
516
  }
480
517
  }
481
518
  } catch (err) {
482
- _iterator2.e(err);
519
+ _iterator.e(err);
483
520
  } finally {
484
- _iterator2.f();
521
+ _iterator.f();
485
522
  }
486
523
 
487
524
  return false;
@@ -632,21 +669,21 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
632
669
  key: "isModified",
633
670
  value: function isModified() {
634
671
  if (this.elements) {
635
- var _iterator3 = _createForOfIteratorHelper(this.elements),
636
- _step3;
672
+ var _iterator2 = _createForOfIteratorHelper(this.elements),
673
+ _step2;
637
674
 
638
675
  try {
639
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
640
- var element = _step3.value;
676
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
677
+ var element = _step2.value;
641
678
 
642
679
  if (element.isModified()) {
643
680
  return true;
644
681
  }
645
682
  }
646
683
  } catch (err) {
647
- _iterator3.e(err);
684
+ _iterator2.e(err);
648
685
  } finally {
649
- _iterator3.f();
686
+ _iterator2.f();
650
687
  }
651
688
  }
652
689
 
@@ -684,7 +721,9 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
684
721
  this.revert();
685
722
  this.removed = true;
686
723
 
687
- this._bubbleUp(Events.Removed);
724
+ if (this.parent) {
725
+ this._bubbleUp(Events.Removed, this, this.parent);
726
+ }
688
727
  }
689
728
  /**
690
729
  * Revert the changes to the element.
@@ -699,7 +738,9 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
699
738
  }
700
739
 
701
740
  this.parent.elements.remove(this);
702
- this.parent.emit(Events.Removed);
741
+
742
+ this._bubbleUp(Events.Removed, this, this.parent);
743
+
703
744
  this.parent = null;
704
745
  } else {
705
746
  if (this.originalExpandableValue) {
@@ -722,7 +763,7 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
722
763
 
723
764
  this.setValid();
724
765
 
725
- this._bubbleUp(Events.Reverted);
766
+ this._bubbleUp(Events.Reverted, this);
726
767
  }
727
768
  /**
728
769
  * Fire and bubble up the event.
@@ -733,15 +774,19 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
733
774
 
734
775
  }, {
735
776
  key: "_bubbleUp",
736
- value: function _bubbleUp(evt, data) {
737
- this.emit(evt, data);
777
+ value: function _bubbleUp(evt) {
778
+ for (var _len = arguments.length, data = new Array(_len > 1 ? _len - 1 : 0), _key2 = 1; _key2 < _len; _key2++) {
779
+ data[_key2 - 1] = arguments[_key2];
780
+ }
781
+
782
+ this.emit.apply(this, [evt].concat(data));
738
783
  var element = this.parent;
739
784
 
740
785
  if (element) {
741
786
  if (element.isRoot()) {
742
- element.emit(evt, data);
787
+ element.emit.apply(element, [evt].concat(data));
743
788
  } else {
744
- element._bubbleUp(evt, data);
789
+ element._bubbleUp.apply(element, [evt].concat(data));
745
790
  }
746
791
  }
747
792
  }
@@ -837,21 +882,21 @@ var Element = /*#__PURE__*/function (_EventEmitter) {
837
882
  key: "_removeAddedElements",
838
883
  value: function _removeAddedElements() {
839
884
  if (this.elements) {
840
- var _iterator4 = _createForOfIteratorHelper(this.elements),
841
- _step4;
885
+ var _iterator3 = _createForOfIteratorHelper(this.elements),
886
+ _step3;
842
887
 
843
888
  try {
844
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
845
- var element = _step4.value;
889
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
890
+ var element = _step3.value;
846
891
 
847
892
  if (element.isAdded()) {
848
893
  this.elements.remove(element);
849
894
  }
850
895
  }
851
896
  } catch (err) {
852
- _iterator4.e(err);
897
+ _iterator3.e(err);
853
898
  } finally {
854
- _iterator4.f();
899
+ _iterator3.f();
855
900
  }
856
901
  }
857
902
  }
@@ -1046,21 +1091,21 @@ var LinkedList = /*#__PURE__*/function (_Symbol$iterator) {
1046
1091
  value: function flush() {
1047
1092
  if (this.loaded < this.size) {
1048
1093
  // Only iterate from the loaded index to the size.
1049
- var _iterator5 = _createForOfIteratorHelper(this),
1050
- _step5;
1094
+ var _iterator4 = _createForOfIteratorHelper(this),
1095
+ _step4;
1051
1096
 
1052
1097
  try {
1053
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
1054
- var element = _step5.value;
1098
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
1099
+ var element = _step4.value;
1055
1100
 
1056
1101
  if (element && element.elements) {
1057
1102
  element.elements.flush();
1058
1103
  }
1059
1104
  }
1060
1105
  } catch (err) {
1061
- _iterator5.e(err);
1106
+ _iterator4.e(err);
1062
1107
  } finally {
1063
- _iterator5.f();
1108
+ _iterator4.f();
1064
1109
  }
1065
1110
  }
1066
1111
  }
@@ -1225,12 +1270,38 @@ var LinkedList = /*#__PURE__*/function (_Symbol$iterator) {
1225
1270
  this.loaded -= 1;
1226
1271
  return this;
1227
1272
  }
1273
+ }, {
1274
+ key: "findIndex",
1275
+ value: function findIndex(el) {
1276
+ var idx = 0;
1277
+
1278
+ var _iterator5 = _createForOfIteratorHelper(this),
1279
+ _step5;
1280
+
1281
+ try {
1282
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
1283
+ var item = _step5.value;
1284
+
1285
+ if (item === el) {
1286
+ return idx;
1287
+ }
1288
+
1289
+ idx++;
1290
+ }
1291
+ } catch (err) {
1292
+ _iterator5.e(err);
1293
+ } finally {
1294
+ _iterator5.f();
1295
+ }
1296
+
1297
+ return -1;
1298
+ }
1228
1299
  }]);
1229
1300
 
1230
1301
  return LinkedList;
1231
1302
  }(Symbol.iterator);
1232
1303
 
1233
- module.exports = Element;
1234
- module.exports.LinkedList = LinkedList;
1235
- module.exports.Events = Events;
1236
- module.exports.DATE_FORMAT = DATE_FORMAT;
1304
+ Element.LinkedList = LinkedList;
1305
+ Element.Events = Events;
1306
+ Element.DATE_FORMAT = DATE_FORMAT;
1307
+ module.exports = Element;
package/lib/index.js CHANGED
@@ -1,4 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  module.exports = require('./document');
4
- module.exports.Element = require('./element');
4
+ module.exports.DocumentEvents = module.exports.Events;
5
+ module.exports.Element = require('./element');
6
+ module.exports.ElementEvents = module.exports.Element.Events;
7
+ module.exports.ElementEditor = require('./editor');
@@ -13,7 +13,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
13
13
 
14
14
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
15
15
 
16
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
16
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
17
17
 
18
18
  var ObjectGenerator = /*#__PURE__*/function () {
19
19
  function ObjectGenerator() {
package/lib/utils.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ var fieldStringLen = function fieldStringLen(value) {
4
+ var length = String(value).length;
5
+ return length === 0 ? 1 : length;
6
+ };
7
+
8
+ module.exports = {
9
+ fieldStringLen: fieldStringLen
10
+ };
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "email": "compass@mongodb.com"
8
8
  },
9
9
  "homepage": "https://github.com/mongodb-js/compass",
10
- "version": "7.8.0",
10
+ "version": "7.9.0",
11
11
  "repository": {
12
12
  "type": "git",
13
13
  "url": "https://github.com/mongodb-js/compass.git"
@@ -17,6 +17,7 @@
17
17
  "mongodb-js"
18
18
  ],
19
19
  "main": "index.js",
20
+ "types": "./index.d.ts",
20
21
  "exports": {
21
22
  "webpack": "./src/index.js",
22
23
  "require": "./index.js"
@@ -36,15 +37,13 @@
36
37
  "dependencies": {
37
38
  "debug": "4.3.0",
38
39
  "eventemitter3": "^4.0.0",
39
- "hadron-type-checker": "^6.7.0",
40
+ "hadron-type-checker": "^6.8.0",
40
41
  "lodash.foreach": "^4.5.0",
41
42
  "lodash.isarray": "^4.0.0",
42
43
  "lodash.isequal": "^4.5.0",
43
44
  "lodash.isplainobject": "^4.0.6",
44
45
  "lodash.isstring": "^4.0.1",
45
46
  "lodash.keys": "^4.2.0",
46
- "react": "^16.14.0",
47
- "react-dom": "^16.14.0",
48
47
  "uuid": "^7.0.3"
49
48
  },
50
49
  "devDependencies": {
@@ -64,5 +63,5 @@
64
63
  "mocha": "^7.0.1",
65
64
  "moment": "^2.27.0"
66
65
  },
67
- "gitHead": "2bb63cdb1d4e825f280c0d2af14b7298c5769490"
66
+ "gitHead": "a1283df32eb52881cc00eb73f8d435f772cdbfde"
68
67
  }
package/src/document.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const EventEmitter = require('eventemitter3');
4
+ const uuid = require('uuid');
4
5
  const Element = require('./element');
5
6
  const LinkedList = Element.LinkedList;
6
7
  const ObjectGenerator = require('./object-generator');
@@ -25,7 +26,9 @@ class Document extends EventEmitter {
25
26
  * Send cancel event.
26
27
  */
27
28
  cancel() {
28
- for (let element of this.elements) {
29
+ // Cancel will remove elements from iterator, clone it before iterating
30
+ // otherwise we will skip items
31
+ for (let element of Array.from(this.elements)) {
29
32
  element.cancel();
30
33
  }
31
34
  this.emit(Events.Cancel);
@@ -39,10 +42,34 @@ class Document extends EventEmitter {
39
42
  */
40
43
  constructor(doc, cloned) {
41
44
  super();
45
+ this.uuid = uuid.v4();
42
46
  this.doc = doc;
43
47
  this.cloned = cloned || false;
44
48
  this.isUpdatable = true;
45
49
  this.elements = this._generateElements();
50
+ this.type = 'Document';
51
+ this.currentType = 'Document';
52
+ }
53
+
54
+ apply(doc) {
55
+ let updatedKeys = [];
56
+ let prevKey = null;
57
+ for (const [key, value] of Object.entries(doc)) {
58
+ if (this.get(key)) {
59
+ this.get(key).edit(value);
60
+ } else if (prevKey) {
61
+ this.insertAfter(this.get(prevKey), key, value);
62
+ } else {
63
+ this.insertBeginning(key, value);
64
+ }
65
+ prevKey = key;
66
+ updatedKeys.push(key);
67
+ }
68
+ for (const el of [...this.elements]) {
69
+ if (!updatedKeys.includes(el.currentKey)) {
70
+ el.remove();
71
+ }
72
+ }
46
73
  }
47
74
 
48
75
  /**
@@ -290,6 +317,20 @@ class Document extends EventEmitter {
290
317
  return this.insertEnd('', '');
291
318
  }
292
319
 
320
+ /**
321
+ * Add a new element to this document.
322
+ *
323
+ * @param {String} key - The element key.
324
+ * @param {Object} value - The value.
325
+ *
326
+ * @returns {Element} The new element.
327
+ */
328
+ insertBeginning(key, value) {
329
+ var newElement = this.elements.insertBeginning(key, value, true, this);
330
+ newElement._bubbleUp(Element.Events.Added, newElement, this);
331
+ return newElement;
332
+ }
333
+
293
334
  /**
294
335
  * Add a new element to this document.
295
336
  *
@@ -300,7 +341,7 @@ class Document extends EventEmitter {
300
341
  */
301
342
  insertEnd(key, value) {
302
343
  var newElement = this.elements.insertEnd(key, value, true, this);
303
- this.emit(Element.Events.Added);
344
+ newElement._bubbleUp(Element.Events.Added, newElement, this);
304
345
  return newElement;
305
346
  }
306
347
 
@@ -315,7 +356,7 @@ class Document extends EventEmitter {
315
356
  */
316
357
  insertAfter(element, key, value) {
317
358
  var newElement = this.elements.insertAfter(element, key, value, true, this);
318
- this.emit(Element.Events.Added);
359
+ newElement._bubbleUp(Element.Events.Added, newElement, this);
319
360
  return newElement;
320
361
  }
321
362