refs, complex saveOperation' and validateSavedOperations`
This commit is contained in:
+138
-35
File diff suppressed because one or more lines are too long
+138
-35
File diff suppressed because one or more lines are too long
@@ -154,32 +154,67 @@ module.exports = function() {
|
|||||||
return json;
|
return json;
|
||||||
};
|
};
|
||||||
|
|
||||||
Operation.prototype.saveOperation = function(name, op) {
|
Operation.prototype.saveOperation = function(name, op, base) {
|
||||||
|
var base1, dest, j, last_path, len, path, paths;
|
||||||
|
if (base == null) {
|
||||||
|
base = "this";
|
||||||
|
}
|
||||||
if (op == null) {
|
if (op == null) {
|
||||||
|
|
||||||
} else if ((op.execute != null) || !((op.op_number != null) && (op.creator != null))) {
|
} else if ((op.execute != null) || !((op.op_number != null) && (op.creator != null))) {
|
||||||
return this[name] = op;
|
if (base === "this") {
|
||||||
|
return this[name] = op;
|
||||||
|
} else {
|
||||||
|
dest = this[base];
|
||||||
|
paths = name.split("/");
|
||||||
|
last_path = paths.pop();
|
||||||
|
for (j = 0, len = paths.length; j < len; j++) {
|
||||||
|
path = paths[j];
|
||||||
|
dest = dest[path];
|
||||||
|
}
|
||||||
|
return dest[last_path] = op;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.unchecked == null) {
|
if (this.unchecked == null) {
|
||||||
this.unchecked = {};
|
this.unchecked = {};
|
||||||
}
|
}
|
||||||
return this.unchecked[name] = op;
|
if ((base1 = this.unchecked)[base] == null) {
|
||||||
|
base1[base] = {};
|
||||||
|
}
|
||||||
|
return this.unchecked[base][name] = op;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Operation.prototype.validateSavedOperations = function() {
|
Operation.prototype.validateSavedOperations = function() {
|
||||||
var name, op, op_uid, ref, success, uninstantiated;
|
var base, base_name, dest, j, last_path, len, name, op, op_uid, path, paths, ref, success, uninstantiated;
|
||||||
uninstantiated = {};
|
uninstantiated = {};
|
||||||
success = this;
|
success = this;
|
||||||
ref = this.unchecked;
|
ref = this.unchecked;
|
||||||
for (name in ref) {
|
for (base_name in ref) {
|
||||||
op_uid = ref[name];
|
base = ref[base_name];
|
||||||
op = this.HB.getOperation(op_uid);
|
for (name in base) {
|
||||||
if (op) {
|
op_uid = base[name];
|
||||||
this[name] = op;
|
op = this.HB.getOperation(op_uid);
|
||||||
} else {
|
if (op) {
|
||||||
uninstantiated[name] = op_uid;
|
if (base_name === "this") {
|
||||||
success = false;
|
this[name] = op;
|
||||||
|
} else {
|
||||||
|
dest = this[base_name];
|
||||||
|
paths = name.split("/");
|
||||||
|
last_path = paths.pop();
|
||||||
|
for (j = 0, len = paths.length; j < len; j++) {
|
||||||
|
path = paths[j];
|
||||||
|
dest = dest[path];
|
||||||
|
}
|
||||||
|
dest[last_path] = op;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (uninstantiated[base_name] == null) {
|
||||||
|
uninstantiated[base_name] = {};
|
||||||
|
}
|
||||||
|
uninstantiated[base_name][name] = op_uid;
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete this.unchecked;
|
delete this.unchecked;
|
||||||
@@ -253,7 +288,8 @@ module.exports = function() {
|
|||||||
ops.Insert = (function(superClass) {
|
ops.Insert = (function(superClass) {
|
||||||
extend(Insert, superClass);
|
extend(Insert, superClass);
|
||||||
|
|
||||||
function Insert(custom_type, content, parent, uid, prev_cl, next_cl, origin) {
|
function Insert(custom_type, content, content_operations, parent, uid, prev_cl, next_cl, origin) {
|
||||||
|
var name, op;
|
||||||
if (content === void 0) {
|
if (content === void 0) {
|
||||||
|
|
||||||
} else if ((content != null) && (content.creator != null)) {
|
} else if ((content != null) && (content.creator != null)) {
|
||||||
@@ -261,6 +297,13 @@ module.exports = function() {
|
|||||||
} else {
|
} else {
|
||||||
this.content = content;
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
if (content_operations != null) {
|
||||||
|
this.content_operations = {};
|
||||||
|
for (name in content_operations) {
|
||||||
|
op = content_operations[name];
|
||||||
|
this.saveOperation(name, op, 'content_operations');
|
||||||
|
}
|
||||||
|
}
|
||||||
this.saveOperation('parent', parent);
|
this.saveOperation('parent', parent);
|
||||||
this.saveOperation('prev_cl', prev_cl);
|
this.saveOperation('prev_cl', prev_cl);
|
||||||
this.saveOperation('next_cl', next_cl);
|
this.saveOperation('next_cl', next_cl);
|
||||||
@@ -275,8 +318,28 @@ module.exports = function() {
|
|||||||
Insert.prototype.type = "Insert";
|
Insert.prototype.type = "Insert";
|
||||||
|
|
||||||
Insert.prototype.val = function() {
|
Insert.prototype.val = function() {
|
||||||
if ((this.content != null) && (this.content.getCustomType != null)) {
|
var content, n, ref, ref1, v;
|
||||||
return this.content.getCustomType();
|
if (this.content != null) {
|
||||||
|
if (this.content.getCustomType != null) {
|
||||||
|
return this.content.getCustomType();
|
||||||
|
} else if (this.content.constructor === Object) {
|
||||||
|
content = {};
|
||||||
|
ref = this.content;
|
||||||
|
for (n in ref) {
|
||||||
|
v = ref[n];
|
||||||
|
content[n] = v;
|
||||||
|
}
|
||||||
|
if (this.content_operations != null) {
|
||||||
|
ref1 = this.content_operations;
|
||||||
|
for (n in ref1) {
|
||||||
|
v = ref1[n];
|
||||||
|
content[n] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
} else {
|
||||||
|
return this.content;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return this.content;
|
return this.content;
|
||||||
}
|
}
|
||||||
@@ -380,14 +443,14 @@ module.exports = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Insert.prototype.execute = function() {
|
Insert.prototype.execute = function() {
|
||||||
var base, distance_to_origin, i, o;
|
var base1, distance_to_origin, i, o;
|
||||||
if (!this.validateSavedOperations()) {
|
if (!this.validateSavedOperations()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (this.content instanceof ops.Operation) {
|
if (this.content instanceof ops.Operation) {
|
||||||
this.content.insert_parent = this;
|
this.content.insert_parent = this;
|
||||||
if ((base = this.content).referenced_by == null) {
|
if ((base1 = this.content).referenced_by == null) {
|
||||||
base.referenced_by = 0;
|
base1.referenced_by = 0;
|
||||||
}
|
}
|
||||||
this.content.referenced_by++;
|
this.content.referenced_by++;
|
||||||
}
|
}
|
||||||
@@ -461,7 +524,7 @@ module.exports = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Insert.prototype._encode = function(json) {
|
Insert.prototype._encode = function(json) {
|
||||||
var ref;
|
var n, o, operations, ref, ref1;
|
||||||
if (json == null) {
|
if (json == null) {
|
||||||
json = {};
|
json = {};
|
||||||
}
|
}
|
||||||
@@ -474,9 +537,18 @@ module.exports = function() {
|
|||||||
}
|
}
|
||||||
json.parent = this.parent.getUid();
|
json.parent = this.parent.getUid();
|
||||||
if (((ref = this.content) != null ? ref.getUid : void 0) != null) {
|
if (((ref = this.content) != null ? ref.getUid : void 0) != null) {
|
||||||
json['content'] = this.content.getUid();
|
json.content = this.content.getUid();
|
||||||
} else {
|
} else {
|
||||||
json['content'] = JSON.stringify(this.content);
|
json.content = JSON.stringify(this.content);
|
||||||
|
}
|
||||||
|
if (this.content_operations != null) {
|
||||||
|
operations = {};
|
||||||
|
ref1 = this.content_operations;
|
||||||
|
for (n in ref1) {
|
||||||
|
o = ref1[n];
|
||||||
|
operations[n] = o.getUid();
|
||||||
|
}
|
||||||
|
json.content_operations = operations;
|
||||||
}
|
}
|
||||||
return Insert.__super__._encode.call(this, json);
|
return Insert.__super__._encode.call(this, json);
|
||||||
};
|
};
|
||||||
@@ -485,12 +557,12 @@ module.exports = function() {
|
|||||||
|
|
||||||
})(ops.Operation);
|
})(ops.Operation);
|
||||||
ops.Insert.parse = function(json) {
|
ops.Insert.parse = function(json) {
|
||||||
var content, next, origin, parent, prev, uid;
|
var content, content_operations, next, origin, parent, prev, uid;
|
||||||
content = json['content'], uid = json['uid'], prev = json['prev'], next = json['next'], origin = json['origin'], parent = json['parent'];
|
content = json['content'], content_operations = json['content_operations'], uid = json['uid'], prev = json['prev'], next = json['next'], origin = json['origin'], parent = json['parent'];
|
||||||
if (typeof content === "string") {
|
if (typeof content === "string") {
|
||||||
content = JSON.parse(content);
|
content = JSON.parse(content);
|
||||||
}
|
}
|
||||||
return new this(null, content, parent, uid, prev, next, origin);
|
return new this(null, content, content_operations, parent, uid, prev, next, origin);
|
||||||
};
|
};
|
||||||
ops.Delimiter = (function(superClass) {
|
ops.Delimiter = (function(superClass) {
|
||||||
extend(Delimiter, superClass);
|
extend(Delimiter, superClass);
|
||||||
|
|||||||
@@ -281,14 +281,14 @@ module.exports = function() {
|
|||||||
}
|
}
|
||||||
left = right.prev_cl;
|
left = right.prev_cl;
|
||||||
if (contents instanceof ops.Operation) {
|
if (contents instanceof ops.Operation) {
|
||||||
(new ops.Insert(null, content, void 0, void 0, left, right)).execute();
|
(new ops.Insert(null, content, null, void 0, void 0, left, right)).execute();
|
||||||
} else {
|
} else {
|
||||||
for (j = 0, len = contents.length; j < len; j++) {
|
for (j = 0, len = contents.length; j < len; j++) {
|
||||||
c = contents[j];
|
c = contents[j];
|
||||||
if ((c != null) && (c._name != null) && (c._getModel != null)) {
|
if ((c != null) && (c._name != null) && (c._getModel != null)) {
|
||||||
c = c._getModel(this.custom_types, this.operations);
|
c = c._getModel(this.custom_types, this.operations);
|
||||||
}
|
}
|
||||||
tmp = (new ops.Insert(null, c, void 0, void 0, left, right)).execute();
|
tmp = (new ops.Insert(null, c, null, void 0, void 0, left, right)).execute();
|
||||||
left = tmp;
|
left = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,7 +337,7 @@ module.exports = function() {
|
|||||||
position: op.getPosition(),
|
position: op.getPosition(),
|
||||||
object: this.getCustomType(),
|
object: this.getCustomType(),
|
||||||
changedBy: op.uid.creator,
|
changedBy: op.uid.creator,
|
||||||
value: getContentType(op.content)
|
value: getContentType(op.val())
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
@@ -366,17 +366,38 @@ module.exports = function() {
|
|||||||
ops.Composition = (function(superClass) {
|
ops.Composition = (function(superClass) {
|
||||||
extend(Composition, superClass);
|
extend(Composition, superClass);
|
||||||
|
|
||||||
function Composition(custom_type, composition_value, uid, tmp_composition_ref) {
|
function Composition(custom_type, _composition_value, composition_value_operations, uid, tmp_composition_ref) {
|
||||||
|
var n, o;
|
||||||
|
this._composition_value = _composition_value;
|
||||||
|
console.log("delete this ...");
|
||||||
|
this.constructed_with = [custom_type, this._composition_value, composition_value_operations, uid, tmp_composition_ref];
|
||||||
Composition.__super__.constructor.call(this, custom_type, uid);
|
Composition.__super__.constructor.call(this, custom_type, uid);
|
||||||
if (tmp_composition_ref != null) {
|
if (tmp_composition_ref != null) {
|
||||||
this.tmp_composition_ref = tmp_composition_ref;
|
this.tmp_composition_ref = tmp_composition_ref;
|
||||||
} else {
|
} else {
|
||||||
this.composition_ref = this.end.prev_cl;
|
this.composition_ref = this.end.prev_cl;
|
||||||
}
|
}
|
||||||
|
if (composition_value_operations != null) {
|
||||||
|
this.composition_value_operations = {};
|
||||||
|
for (n in composition_value_operations) {
|
||||||
|
o = composition_value_operations[n];
|
||||||
|
this.saveOperation(n, o, '_composition_value');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Composition.prototype.type = "Composition";
|
Composition.prototype.type = "Composition";
|
||||||
|
|
||||||
|
Composition.prototype.execute = function() {
|
||||||
|
if (this.validateSavedOperations()) {
|
||||||
|
this.getCustomType()._setCompositionValue(this._composition_value);
|
||||||
|
delete this._composition_value;
|
||||||
|
return Composition.__super__.execute.apply(this, arguments);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Composition.prototype.callOperationSpecificInsertEvents = function(op) {
|
Composition.prototype.callOperationSpecificInsertEvents = function(op) {
|
||||||
var o;
|
var o;
|
||||||
if (this.tmp_composition_ref != null) {
|
if (this.tmp_composition_ref != null) {
|
||||||
@@ -394,7 +415,7 @@ module.exports = function() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.composition_ref.next_cl === op) {
|
if (this.composition_ref.next_cl === op) {
|
||||||
op.undo_delta = this.getCustomType()._apply(op.content);
|
op.undo_delta = this.getCustomType()._apply(op.val());
|
||||||
} else {
|
} else {
|
||||||
o = this.end.prev_cl;
|
o = this.end.prev_cl;
|
||||||
while (o !== op) {
|
while (o !== op) {
|
||||||
@@ -402,7 +423,7 @@ module.exports = function() {
|
|||||||
o = o.prev_cl;
|
o = o.prev_cl;
|
||||||
}
|
}
|
||||||
while (o !== this.end) {
|
while (o !== this.end) {
|
||||||
o.undo_delta = this.getCustomType()._apply(o.content);
|
o.undo_delta = this.getCustomType()._apply(o.val());
|
||||||
o = o.next_cl;
|
o = o.next_cl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -418,16 +439,26 @@ module.exports = function() {
|
|||||||
|
|
||||||
Composition.prototype.callOperationSpecificDeleteEvents = function(op, del_op) {};
|
Composition.prototype.callOperationSpecificDeleteEvents = function(op, del_op) {};
|
||||||
|
|
||||||
Composition.prototype.applyDelta = function(delta) {
|
Composition.prototype.applyDelta = function(delta, operations) {
|
||||||
(new ops.Insert(null, delta, this, null, this.end.prev_cl, this.end)).execute();
|
(new ops.Insert(null, delta, operations, this, null, this.end.prev_cl, this.end)).execute();
|
||||||
return void 0;
|
return void 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
Composition.prototype._encode = function(json) {
|
Composition.prototype._encode = function(json) {
|
||||||
|
var custom, n, o, ref;
|
||||||
if (json == null) {
|
if (json == null) {
|
||||||
json = {};
|
json = {};
|
||||||
}
|
}
|
||||||
json.composition_value = JSON.stringify(this.getCustomType()._getCompositionValue());
|
custom = this.getCustomType()._getCompositionValue();
|
||||||
|
json.composition_value = custom.composition_value;
|
||||||
|
if (custom.composition_value_operations != null) {
|
||||||
|
json.composition_value_operations = {};
|
||||||
|
ref = custom.composition_value_operations;
|
||||||
|
for (n in ref) {
|
||||||
|
o = ref[n];
|
||||||
|
json.composition_value_operations[n] = o.getUid();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (this.composition_ref != null) {
|
if (this.composition_ref != null) {
|
||||||
json.composition_ref = this.composition_ref.getUid();
|
json.composition_ref = this.composition_ref.getUid();
|
||||||
} else {
|
} else {
|
||||||
@@ -440,9 +471,9 @@ module.exports = function() {
|
|||||||
|
|
||||||
})(ops.ListManager);
|
})(ops.ListManager);
|
||||||
ops.Composition.parse = function(json) {
|
ops.Composition.parse = function(json) {
|
||||||
var composition_ref, composition_value, custom_type, uid;
|
var composition_ref, composition_value, composition_value_operations, custom_type, uid;
|
||||||
uid = json['uid'], custom_type = json['custom_type'], composition_value = json['composition_value'], composition_ref = json['composition_ref'];
|
uid = json['uid'], custom_type = json['custom_type'], composition_value = json['composition_value'], composition_value_operations = json['composition_value_operations'], composition_ref = json['composition_ref'];
|
||||||
return new this(custom_type, JSON.parse(composition_value), uid, composition_ref);
|
return new this(custom_type, composition_value, composition_value_operations, uid, composition_ref);
|
||||||
};
|
};
|
||||||
ops.ReplaceManager = (function(superClass) {
|
ops.ReplaceManager = (function(superClass) {
|
||||||
extend(ReplaceManager, superClass);
|
extend(ReplaceManager, superClass);
|
||||||
@@ -516,7 +547,7 @@ module.exports = function() {
|
|||||||
ReplaceManager.prototype.replace = function(content, replaceable_uid) {
|
ReplaceManager.prototype.replace = function(content, replaceable_uid) {
|
||||||
var o, relp;
|
var o, relp;
|
||||||
o = this.getLastOperation();
|
o = this.getLastOperation();
|
||||||
relp = (new ops.Insert(null, content, this, replaceable_uid, o, o.next_cl)).execute();
|
relp = (new ops.Insert(null, content, null, this, replaceable_uid, o, o.next_cl)).execute();
|
||||||
return void 0;
|
return void 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+138
-35
File diff suppressed because one or more lines are too long
+138
-35
File diff suppressed because one or more lines are too long
+3096
-663
File diff suppressed because one or more lines are too long
+217
-62
File diff suppressed because one or more lines are too long
+138
-35
File diff suppressed because one or more lines are too long
+138
-35
File diff suppressed because one or more lines are too long
+56
-16
@@ -182,7 +182,7 @@ module.exports = ()->
|
|||||||
# @param {String} name The name of the operation. After calling this function op is accessible via this[name].
|
# @param {String} name The name of the operation. After calling this function op is accessible via this[name].
|
||||||
# @param {Operation} op An Operation object
|
# @param {Operation} op An Operation object
|
||||||
#
|
#
|
||||||
saveOperation: (name, op)->
|
saveOperation: (name, op, base = "this")->
|
||||||
|
|
||||||
#
|
#
|
||||||
# Every instance of $Operation must have an $execute function.
|
# Every instance of $Operation must have an $execute function.
|
||||||
@@ -194,11 +194,20 @@ module.exports = ()->
|
|||||||
else if op.execute? or not (op.op_number? and op.creator?)
|
else if op.execute? or not (op.op_number? and op.creator?)
|
||||||
# is instantiated, or op is string. Currently "Delimiter" is saved as string
|
# is instantiated, or op is string. Currently "Delimiter" is saved as string
|
||||||
# (in combination with @parent you can retrieve the delimiter..)
|
# (in combination with @parent you can retrieve the delimiter..)
|
||||||
@[name] = op
|
if base is "this"
|
||||||
|
@[name] = op
|
||||||
|
else
|
||||||
|
dest = @[base]
|
||||||
|
paths = name.split("/")
|
||||||
|
last_path = paths.pop()
|
||||||
|
for path in paths
|
||||||
|
dest = dest[path]
|
||||||
|
dest[last_path] = op
|
||||||
else
|
else
|
||||||
# not initialized. Do it when calling $validateSavedOperations()
|
# not initialized. Do it when calling $validateSavedOperations()
|
||||||
@unchecked ?= {}
|
@unchecked ?= {}
|
||||||
@unchecked[name] = op
|
@unchecked[base] ?= {}
|
||||||
|
@unchecked[base][name] = op
|
||||||
|
|
||||||
#
|
#
|
||||||
# @private
|
# @private
|
||||||
@@ -210,13 +219,23 @@ module.exports = ()->
|
|||||||
validateSavedOperations: ()->
|
validateSavedOperations: ()->
|
||||||
uninstantiated = {}
|
uninstantiated = {}
|
||||||
success = @
|
success = @
|
||||||
for name, op_uid of @unchecked
|
for base_name, base of @unchecked
|
||||||
op = @HB.getOperation op_uid
|
for name, op_uid of base
|
||||||
if op
|
op = @HB.getOperation op_uid
|
||||||
@[name] = op
|
if op
|
||||||
else
|
if base_name is "this"
|
||||||
uninstantiated[name] = op_uid
|
@[name] = op
|
||||||
success = false
|
else
|
||||||
|
dest = @[base_name]
|
||||||
|
paths = name.split("/")
|
||||||
|
last_path = paths.pop()
|
||||||
|
for path in paths
|
||||||
|
dest = dest[path]
|
||||||
|
dest[last_path] = op
|
||||||
|
else
|
||||||
|
uninstantiated[base_name] ?= {}
|
||||||
|
uninstantiated[base_name][name] = op_uid
|
||||||
|
success = false
|
||||||
delete @unchecked
|
delete @unchecked
|
||||||
if not success
|
if not success
|
||||||
@unchecked = uninstantiated
|
@unchecked = uninstantiated
|
||||||
@@ -305,7 +324,7 @@ module.exports = ()->
|
|||||||
# @param {Operation} prev_cl The predecessor of this operation in the complete-list (cl)
|
# @param {Operation} prev_cl The predecessor of this operation in the complete-list (cl)
|
||||||
# @param {Operation} next_cl The successor of this operation in the complete-list (cl)
|
# @param {Operation} next_cl The successor of this operation in the complete-list (cl)
|
||||||
#
|
#
|
||||||
constructor: (custom_type, content, parent, uid, prev_cl, next_cl, origin)->
|
constructor: (custom_type, content, content_operations, parent, uid, prev_cl, next_cl, origin)->
|
||||||
# see encode to see, why we are doing it this way
|
# see encode to see, why we are doing it this way
|
||||||
if content is undefined
|
if content is undefined
|
||||||
# nop
|
# nop
|
||||||
@@ -313,6 +332,10 @@ module.exports = ()->
|
|||||||
@saveOperation 'content', content
|
@saveOperation 'content', content
|
||||||
else
|
else
|
||||||
@content = content
|
@content = content
|
||||||
|
if content_operations?
|
||||||
|
@content_operations = {}
|
||||||
|
for name, op of content_operations
|
||||||
|
@saveOperation name, op, 'content_operations'
|
||||||
@saveOperation 'parent', parent
|
@saveOperation 'parent', parent
|
||||||
@saveOperation 'prev_cl', prev_cl
|
@saveOperation 'prev_cl', prev_cl
|
||||||
@saveOperation 'next_cl', next_cl
|
@saveOperation 'next_cl', next_cl
|
||||||
@@ -325,8 +348,19 @@ module.exports = ()->
|
|||||||
type: "Insert"
|
type: "Insert"
|
||||||
|
|
||||||
val: ()->
|
val: ()->
|
||||||
if @content? and @content.getCustomType?
|
if @content?
|
||||||
@content.getCustomType()
|
if @content.getCustomType?
|
||||||
|
@content.getCustomType()
|
||||||
|
else if @content.constructor is Object
|
||||||
|
content = {}
|
||||||
|
for n,v of @content
|
||||||
|
content[n] = v
|
||||||
|
if @content_operations?
|
||||||
|
for n,v of @content_operations
|
||||||
|
content[n] = v
|
||||||
|
content
|
||||||
|
else
|
||||||
|
@content
|
||||||
else
|
else
|
||||||
@content
|
@content
|
||||||
|
|
||||||
@@ -518,14 +552,20 @@ module.exports = ()->
|
|||||||
json.parent = @parent.getUid()
|
json.parent = @parent.getUid()
|
||||||
|
|
||||||
if @content?.getUid?
|
if @content?.getUid?
|
||||||
json['content'] = @content.getUid()
|
json.content = @content.getUid()
|
||||||
else
|
else
|
||||||
json['content'] = JSON.stringify @content
|
json.content = JSON.stringify @content
|
||||||
|
if @content_operations?
|
||||||
|
operations = {}
|
||||||
|
for n,o of @content_operations
|
||||||
|
operations[n] = o.getUid()
|
||||||
|
json.content_operations = operations
|
||||||
super json
|
super json
|
||||||
|
|
||||||
ops.Insert.parse = (json)->
|
ops.Insert.parse = (json)->
|
||||||
{
|
{
|
||||||
'content' : content
|
'content' : content
|
||||||
|
'content_operations' : content_operations
|
||||||
'uid' : uid
|
'uid' : uid
|
||||||
'prev': prev
|
'prev': prev
|
||||||
'next': next
|
'next': next
|
||||||
@@ -534,7 +574,7 @@ module.exports = ()->
|
|||||||
} = json
|
} = json
|
||||||
if typeof content is "string"
|
if typeof content is "string"
|
||||||
content = JSON.parse(content)
|
content = JSON.parse(content)
|
||||||
new this null, content, parent, uid, prev, next, origin
|
new this null, content, content_operations, parent, uid, prev, next, origin
|
||||||
|
|
||||||
#
|
#
|
||||||
# @nodoc
|
# @nodoc
|
||||||
|
|||||||
@@ -238,12 +238,12 @@ module.exports = ()->
|
|||||||
|
|
||||||
# TODO: always expect an array as content. Then you can combine this with the other option (else)
|
# TODO: always expect an array as content. Then you can combine this with the other option (else)
|
||||||
if contents instanceof ops.Operation
|
if contents instanceof ops.Operation
|
||||||
(new ops.Insert null, content, undefined, undefined, left, right).execute()
|
(new ops.Insert null, content, null, undefined, undefined, left, right).execute()
|
||||||
else
|
else
|
||||||
for c in contents
|
for c in contents
|
||||||
if c? and c._name? and c._getModel?
|
if c? and c._name? and c._getModel?
|
||||||
c = c._getModel(@custom_types, @operations)
|
c = c._getModel(@custom_types, @operations)
|
||||||
tmp = (new ops.Insert null, c, undefined, undefined, left, right).execute()
|
tmp = (new ops.Insert null, c, null, undefined, undefined, left, right).execute()
|
||||||
left = tmp
|
left = tmp
|
||||||
@
|
@
|
||||||
|
|
||||||
@@ -290,7 +290,7 @@ module.exports = ()->
|
|||||||
position: op.getPosition()
|
position: op.getPosition()
|
||||||
object: @getCustomType()
|
object: @getCustomType()
|
||||||
changedBy: op.uid.creator
|
changedBy: op.uid.creator
|
||||||
value: getContentType op.content
|
value: getContentType op.val()
|
||||||
]
|
]
|
||||||
|
|
||||||
callOperationSpecificDeleteEvents: (op, del_op)->
|
callOperationSpecificDeleteEvents: (op, del_op)->
|
||||||
@@ -316,31 +316,60 @@ module.exports = ()->
|
|||||||
|
|
||||||
class ops.Composition extends ops.ListManager
|
class ops.Composition extends ops.ListManager
|
||||||
|
|
||||||
constructor: (custom_type, @composition_value, uid, composition_ref)->
|
constructor: (custom_type, @_composition_value, composition_value_operations, uid, tmp_composition_ref)->
|
||||||
|
# we can't use @seveOperation 'composition_ref', tmp_composition_ref here,
|
||||||
|
# because then there is a "loop" (insertion refers to parant, refers to insertion..)
|
||||||
|
# This is why we have to check in @callOperationSpecificInsertEvents until we find it
|
||||||
|
console.log("delete this ...")
|
||||||
|
this.constructed_with = [custom_type, @_composition_value, composition_value_operations, uid, tmp_composition_ref] # debug!
|
||||||
super custom_type, uid
|
super custom_type, uid
|
||||||
if composition_ref
|
if tmp_composition_ref?
|
||||||
@saveOperation 'composition_ref', composition_ref
|
@tmp_composition_ref = tmp_composition_ref
|
||||||
else
|
else
|
||||||
@composition_ref = @beginning
|
@composition_ref = @end.prev_cl
|
||||||
|
if composition_value_operations?
|
||||||
|
@composition_value_operations = {}
|
||||||
|
for n,o of composition_value_operations
|
||||||
|
@saveOperation n, o, '_composition_value'
|
||||||
|
|
||||||
type: "Composition"
|
type: "Composition"
|
||||||
|
|
||||||
val: ()->
|
#
|
||||||
@composition_value
|
# @private
|
||||||
|
# @see Operation.execute
|
||||||
|
#
|
||||||
|
execute: ()->
|
||||||
|
if @validateSavedOperations()
|
||||||
|
@getCustomType()._setCompositionValue @_composition_value
|
||||||
|
delete @_composition_value
|
||||||
|
super
|
||||||
|
else
|
||||||
|
false
|
||||||
|
|
||||||
#
|
#
|
||||||
# This is called, when the Insert-operation was successfully executed.
|
# This is called, when the Insert-operation was successfully executed.
|
||||||
#
|
#
|
||||||
callOperationSpecificInsertEvents: (op)->
|
callOperationSpecificInsertEvents: (op)->
|
||||||
|
if @tmp_composition_ref?
|
||||||
|
if op.uid.creator is @tmp_composition_ref.creator and op.uid.op_number is @tmp_composition_ref.op_number
|
||||||
|
@composition_ref = op
|
||||||
|
delete @tmp_composition_ref
|
||||||
|
o = op.next_cl
|
||||||
|
while o.next_cl?
|
||||||
|
if not o.isDeleted()
|
||||||
|
@callOperationSpecificInsertEvents o
|
||||||
|
o = o.next_cl
|
||||||
|
return
|
||||||
|
|
||||||
if @composition_ref.next_cl is op
|
if @composition_ref.next_cl is op
|
||||||
op.undo_delta = @getCustomType()._apply op.content
|
op.undo_delta = @getCustomType()._apply op.val()
|
||||||
else
|
else
|
||||||
o = @end.prev_cl
|
o = @end.prev_cl
|
||||||
while o isnt op
|
while o isnt op
|
||||||
@getCustomType()._unapply o.undo_delta
|
@getCustomType()._unapply o.undo_delta
|
||||||
o = o.prev_cl
|
o = o.prev_cl
|
||||||
while o isnt @end
|
while o isnt @end
|
||||||
o.undo_delta = @getCustomType()._apply o.content
|
o.undo_delta = @getCustomType()._apply o.val()
|
||||||
o = o.next_cl
|
o = o.next_cl
|
||||||
@composition_ref = @end.prev_cl
|
@composition_ref = @end.prev_cl
|
||||||
|
|
||||||
@@ -361,16 +390,24 @@ module.exports = ()->
|
|||||||
#
|
#
|
||||||
# @param delta The delta that is applied to the composition_value
|
# @param delta The delta that is applied to the composition_value
|
||||||
#
|
#
|
||||||
applyDelta: (delta)->
|
applyDelta: (delta, operations)->
|
||||||
(new ops.Insert null, delta, @, null, @end.prev_cl, @end).execute()
|
(new ops.Insert null, delta, operations, @, null, @end.prev_cl, @end).execute()
|
||||||
undefined
|
undefined
|
||||||
|
|
||||||
#
|
#
|
||||||
# Encode this operation in such a way that it can be parsed by remote peers.
|
# Encode this operation in such a way that it can be parsed by remote peers.
|
||||||
#
|
#
|
||||||
_encode: (json = {})->
|
_encode: (json = {})->
|
||||||
json.composition_value = JSON.stringify @composition_value
|
custom = @getCustomType()._getCompositionValue()
|
||||||
json.composition_ref = @composition_ref.getUid()
|
json.composition_value = custom.composition_value
|
||||||
|
if custom.composition_value_operations?
|
||||||
|
json.composition_value_operations = {}
|
||||||
|
for n,o of custom.composition_value_operations
|
||||||
|
json.composition_value_operations[n] = o.getUid()
|
||||||
|
if @composition_ref?
|
||||||
|
json.composition_ref = @composition_ref.getUid()
|
||||||
|
else
|
||||||
|
json.composition_ref = @tmp_composition_ref
|
||||||
super json
|
super json
|
||||||
|
|
||||||
ops.Composition.parse = (json)->
|
ops.Composition.parse = (json)->
|
||||||
@@ -378,9 +415,10 @@ module.exports = ()->
|
|||||||
'uid' : uid
|
'uid' : uid
|
||||||
'custom_type': custom_type
|
'custom_type': custom_type
|
||||||
'composition_value' : composition_value
|
'composition_value' : composition_value
|
||||||
|
'composition_value_operations' : composition_value_operations
|
||||||
'composition_ref' : composition_ref
|
'composition_ref' : composition_ref
|
||||||
} = json
|
} = json
|
||||||
new this(custom_type, JSON.parse(composition_value), uid, composition_ref)
|
new this(custom_type, composition_value, composition_value_operations, uid, composition_ref)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -465,7 +503,7 @@ module.exports = ()->
|
|||||||
#
|
#
|
||||||
replace: (content, replaceable_uid)->
|
replace: (content, replaceable_uid)->
|
||||||
o = @getLastOperation()
|
o = @getLastOperation()
|
||||||
relp = (new ops.Insert null, content, @, replaceable_uid, o, o.next_cl).execute()
|
relp = (new ops.Insert null, content, null, @, replaceable_uid, o, o.next_cl).execute()
|
||||||
# TODO: delete repl (for debugging)
|
# TODO: delete repl (for debugging)
|
||||||
undefined
|
undefined
|
||||||
|
|
||||||
|
|||||||
+2
-2
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user