removed phantom
This commit is contained in:
parent
b9cdbcc6fa
commit
7f6592a6b7
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,71 +0,0 @@
|
||||
var ConnectorClass, adaptConnector;
|
||||
|
||||
ConnectorClass = require("./ConnectorClass");
|
||||
|
||||
adaptConnector = function(connector, engine, HB, execution_listener) {
|
||||
var applyHB, encode_state_vector, f, getHB, getStateVector, name, parse_state_vector, send_;
|
||||
for (name in ConnectorClass) {
|
||||
f = ConnectorClass[name];
|
||||
connector[name] = f;
|
||||
}
|
||||
connector.setIsBoundToY();
|
||||
send_ = function(o) {
|
||||
if ((o.uid.creator === HB.getUserId()) && (typeof o.uid.op_number !== "string") && (HB.getUserId() !== "_temp")) {
|
||||
return connector.broadcast(o);
|
||||
}
|
||||
};
|
||||
if (connector.invokeSync != null) {
|
||||
HB.setInvokeSyncHandler(connector.invokeSync);
|
||||
}
|
||||
execution_listener.push(send_);
|
||||
encode_state_vector = function(v) {
|
||||
var results, value;
|
||||
results = [];
|
||||
for (name in v) {
|
||||
value = v[name];
|
||||
results.push({
|
||||
user: name,
|
||||
state: value
|
||||
});
|
||||
}
|
||||
return results;
|
||||
};
|
||||
parse_state_vector = function(v) {
|
||||
var i, len, s, state_vector;
|
||||
state_vector = {};
|
||||
for (i = 0, len = v.length; i < len; i++) {
|
||||
s = v[i];
|
||||
state_vector[s.user] = s.state;
|
||||
}
|
||||
return state_vector;
|
||||
};
|
||||
getStateVector = function() {
|
||||
return encode_state_vector(HB.getOperationCounter());
|
||||
};
|
||||
getHB = function(v) {
|
||||
var hb, json, state_vector;
|
||||
state_vector = parse_state_vector(v);
|
||||
hb = HB._encode(state_vector);
|
||||
json = {
|
||||
hb: hb,
|
||||
state_vector: encode_state_vector(HB.getOperationCounter())
|
||||
};
|
||||
return json;
|
||||
};
|
||||
applyHB = function(hb, fromHB) {
|
||||
return engine.applyOp(hb, fromHB);
|
||||
};
|
||||
connector.getStateVector = getStateVector;
|
||||
connector.getHB = getHB;
|
||||
connector.applyHB = applyHB;
|
||||
if (connector.receive_handlers == null) {
|
||||
connector.receive_handlers = [];
|
||||
}
|
||||
return connector.receive_handlers.push(function(sender, op) {
|
||||
if (op.uid.creator !== HB.getUserId()) {
|
||||
return engine.applyOp(op);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = adaptConnector;
|
@ -1,261 +0,0 @@
|
||||
var HistoryBuffer,
|
||||
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
||||
|
||||
HistoryBuffer = (function() {
|
||||
function HistoryBuffer(user_id1) {
|
||||
this.user_id = user_id1;
|
||||
this.emptyGarbage = bind(this.emptyGarbage, this);
|
||||
this.operation_counter = {};
|
||||
this.buffer = {};
|
||||
this.change_listeners = [];
|
||||
this.garbage = [];
|
||||
this.trash = [];
|
||||
this.performGarbageCollection = true;
|
||||
this.garbageCollectTimeout = 30000;
|
||||
this.reserved_identifier_counter = 0;
|
||||
setTimeout(this.emptyGarbage, this.garbageCollectTimeout);
|
||||
}
|
||||
|
||||
HistoryBuffer.prototype.resetUserId = function(id) {
|
||||
var o, o_name, own;
|
||||
own = this.buffer[this.user_id];
|
||||
if (own != null) {
|
||||
for (o_name in own) {
|
||||
o = own[o_name];
|
||||
if (o.uid.creator != null) {
|
||||
o.uid.creator = id;
|
||||
}
|
||||
if (o.uid.alt != null) {
|
||||
o.uid.alt.creator = id;
|
||||
}
|
||||
}
|
||||
if (this.buffer[id] != null) {
|
||||
throw new Error("You are re-assigning an old user id - this is not (yet) possible!");
|
||||
}
|
||||
this.buffer[id] = own;
|
||||
delete this.buffer[this.user_id];
|
||||
}
|
||||
if (this.operation_counter[this.user_id] != null) {
|
||||
this.operation_counter[id] = this.operation_counter[this.user_id];
|
||||
delete this.operation_counter[this.user_id];
|
||||
}
|
||||
return this.user_id = id;
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.emptyGarbage = function() {
|
||||
var i, len, o, ref;
|
||||
ref = this.garbage;
|
||||
for (i = 0, len = ref.length; i < len; i++) {
|
||||
o = ref[i];
|
||||
if (typeof o.cleanup === "function") {
|
||||
o.cleanup();
|
||||
}
|
||||
}
|
||||
this.garbage = this.trash;
|
||||
this.trash = [];
|
||||
if (this.garbageCollectTimeout !== -1) {
|
||||
this.garbageCollectTimeoutId = setTimeout(this.emptyGarbage, this.garbageCollectTimeout);
|
||||
}
|
||||
return void 0;
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.getUserId = function() {
|
||||
return this.user_id;
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.addToGarbageCollector = function() {
|
||||
var i, len, o, results;
|
||||
if (this.performGarbageCollection) {
|
||||
results = [];
|
||||
for (i = 0, len = arguments.length; i < len; i++) {
|
||||
o = arguments[i];
|
||||
if (o != null) {
|
||||
results.push(this.garbage.push(o));
|
||||
} else {
|
||||
results.push(void 0);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.stopGarbageCollection = function() {
|
||||
this.performGarbageCollection = false;
|
||||
this.setManualGarbageCollect();
|
||||
this.garbage = [];
|
||||
return this.trash = [];
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.setManualGarbageCollect = function() {
|
||||
this.garbageCollectTimeout = -1;
|
||||
clearTimeout(this.garbageCollectTimeoutId);
|
||||
return this.garbageCollectTimeoutId = void 0;
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.setGarbageCollectTimeout = function(garbageCollectTimeout) {
|
||||
this.garbageCollectTimeout = garbageCollectTimeout;
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.getReservedUniqueIdentifier = function() {
|
||||
return {
|
||||
creator: '_',
|
||||
op_number: "_" + (this.reserved_identifier_counter++)
|
||||
};
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.getOperationCounter = function(user_id) {
|
||||
var ctn, ref, res, user;
|
||||
if (user_id == null) {
|
||||
res = {};
|
||||
ref = this.operation_counter;
|
||||
for (user in ref) {
|
||||
ctn = ref[user];
|
||||
res[user] = ctn;
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return this.operation_counter[user_id];
|
||||
}
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.isExpectedOperation = function(o) {
|
||||
var base, name;
|
||||
if ((base = this.operation_counter)[name = o.uid.creator] == null) {
|
||||
base[name] = 0;
|
||||
}
|
||||
o.uid.op_number <= this.operation_counter[o.uid.creator];
|
||||
return true;
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype._encode = function(state_vector) {
|
||||
var json, o, o_json, o_next, o_number, o_prev, ref, u_name, unknown, user;
|
||||
if (state_vector == null) {
|
||||
state_vector = {};
|
||||
}
|
||||
json = [];
|
||||
unknown = function(user, o_number) {
|
||||
if ((user == null) || (o_number == null)) {
|
||||
throw new Error("dah!");
|
||||
}
|
||||
return (state_vector[user] == null) || state_vector[user] <= o_number;
|
||||
};
|
||||
ref = this.buffer;
|
||||
for (u_name in ref) {
|
||||
user = ref[u_name];
|
||||
if (u_name === "_") {
|
||||
continue;
|
||||
}
|
||||
for (o_number in user) {
|
||||
o = user[o_number];
|
||||
if ((o.uid.noOperation == null) && unknown(u_name, o_number)) {
|
||||
o_json = o._encode();
|
||||
if (o.next_cl != null) {
|
||||
o_next = o.next_cl;
|
||||
while ((o_next.next_cl != null) && unknown(o_next.uid.creator, o_next.uid.op_number)) {
|
||||
o_next = o_next.next_cl;
|
||||
}
|
||||
o_json.next = o_next.getUid();
|
||||
} else if (o.prev_cl != null) {
|
||||
o_prev = o.prev_cl;
|
||||
while ((o_prev.prev_cl != null) && unknown(o_prev.uid.creator, o_prev.uid.op_number)) {
|
||||
o_prev = o_prev.prev_cl;
|
||||
}
|
||||
o_json.prev = o_prev.getUid();
|
||||
}
|
||||
json.push(o_json);
|
||||
}
|
||||
}
|
||||
}
|
||||
return json;
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.getNextOperationIdentifier = function(user_id) {
|
||||
var uid;
|
||||
if (user_id == null) {
|
||||
user_id = this.user_id;
|
||||
}
|
||||
if (this.operation_counter[user_id] == null) {
|
||||
this.operation_counter[user_id] = 0;
|
||||
}
|
||||
uid = {
|
||||
'creator': user_id,
|
||||
'op_number': this.operation_counter[user_id]
|
||||
};
|
||||
this.operation_counter[user_id]++;
|
||||
return uid;
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.getOperation = function(uid) {
|
||||
var o, ref;
|
||||
if (uid.uid != null) {
|
||||
uid = uid.uid;
|
||||
}
|
||||
o = (ref = this.buffer[uid.creator]) != null ? ref[uid.op_number] : void 0;
|
||||
if ((uid.sub != null) && (o != null)) {
|
||||
return o.retrieveSub(uid.sub);
|
||||
} else {
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.addOperation = function(o) {
|
||||
if (this.buffer[o.uid.creator] == null) {
|
||||
this.buffer[o.uid.creator] = {};
|
||||
}
|
||||
if (this.buffer[o.uid.creator][o.uid.op_number] != null) {
|
||||
throw new Error("You must not overwrite operations!");
|
||||
}
|
||||
if ((o.uid.op_number.constructor !== String) && (!this.isExpectedOperation(o)) && (o.fromHB == null)) {
|
||||
throw new Error("this operation was not expected!");
|
||||
}
|
||||
this.addToCounter(o);
|
||||
this.buffer[o.uid.creator][o.uid.op_number] = o;
|
||||
return o;
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.removeOperation = function(o) {
|
||||
var ref;
|
||||
return (ref = this.buffer[o.uid.creator]) != null ? delete ref[o.uid.op_number] : void 0;
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.setInvokeSyncHandler = function(f) {
|
||||
return this.invokeSync = f;
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.invokeSync = function() {};
|
||||
|
||||
HistoryBuffer.prototype.renewStateVector = function(state_vector) {
|
||||
var results, state, user;
|
||||
results = [];
|
||||
for (user in state_vector) {
|
||||
state = state_vector[user];
|
||||
if (((this.operation_counter[user] == null) || (this.operation_counter[user] < state_vector[user])) && (state_vector[user] != null)) {
|
||||
results.push(this.operation_counter[user] = state_vector[user]);
|
||||
} else {
|
||||
results.push(void 0);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
HistoryBuffer.prototype.addToCounter = function(o) {
|
||||
var base, name;
|
||||
if ((base = this.operation_counter)[name = o.uid.creator] == null) {
|
||||
base[name] = 0;
|
||||
}
|
||||
if (o.uid.creator !== this.getUserId()) {
|
||||
if (o.uid.op_number === this.operation_counter[o.uid.creator]) {
|
||||
this.operation_counter[o.uid.creator]++;
|
||||
}
|
||||
while (this.buffer[o.uid.creator][this.operation_counter[o.uid.creator]] != null) {
|
||||
this.operation_counter[o.uid.creator]++;
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
};
|
||||
|
||||
return HistoryBuffer;
|
||||
|
||||
})();
|
||||
|
||||
module.exports = HistoryBuffer;
|
@ -1,663 +0,0 @@
|
||||
var slice = [].slice,
|
||||
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
||||
hasProp = {}.hasOwnProperty;
|
||||
|
||||
module.exports = function() {
|
||||
var execution_listener, ops;
|
||||
ops = {};
|
||||
execution_listener = [];
|
||||
ops.Operation = (function() {
|
||||
function Operation(custom_type, uid, content, content_operations) {
|
||||
var name, op;
|
||||
if (custom_type != null) {
|
||||
this.custom_type = custom_type;
|
||||
}
|
||||
this.is_deleted = false;
|
||||
this.garbage_collected = false;
|
||||
this.event_listeners = [];
|
||||
if (uid != null) {
|
||||
this.uid = uid;
|
||||
}
|
||||
if (content === void 0) {
|
||||
|
||||
} else if ((content != null) && (content.creator != null)) {
|
||||
this.saveOperation('content', content);
|
||||
} else {
|
||||
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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Operation.prototype.type = "Operation";
|
||||
|
||||
Operation.prototype.getContent = function(name) {
|
||||
var content, n, ref, ref1, v;
|
||||
if (this.content != null) {
|
||||
if (this.content.getCustomType != null) {
|
||||
return this.content.getCustomType();
|
||||
} else if (this.content.constructor === Object) {
|
||||
if (name != null) {
|
||||
if (this.content[name] != null) {
|
||||
return this.content[name];
|
||||
} else {
|
||||
return this.content_operations[name].getCustomType();
|
||||
}
|
||||
} else {
|
||||
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];
|
||||
v = v.getCustomType();
|
||||
content[n] = v;
|
||||
}
|
||||
}
|
||||
return content;
|
||||
}
|
||||
} else {
|
||||
return this.content;
|
||||
}
|
||||
} else {
|
||||
return this.content;
|
||||
}
|
||||
};
|
||||
|
||||
Operation.prototype.retrieveSub = function() {
|
||||
throw new Error("sub properties are not enable on this operation type!");
|
||||
};
|
||||
|
||||
Operation.prototype.observe = function(f) {
|
||||
return this.event_listeners.push(f);
|
||||
};
|
||||
|
||||
Operation.prototype.unobserve = function(f) {
|
||||
return this.event_listeners = this.event_listeners.filter(function(g) {
|
||||
return f !== g;
|
||||
});
|
||||
};
|
||||
|
||||
Operation.prototype.deleteAllObservers = function() {
|
||||
return this.event_listeners = [];
|
||||
};
|
||||
|
||||
Operation.prototype["delete"] = function() {
|
||||
(new ops.Delete(void 0, this)).execute();
|
||||
return null;
|
||||
};
|
||||
|
||||
Operation.prototype.callEvent = function() {
|
||||
var callon;
|
||||
if (this.custom_type != null) {
|
||||
callon = this.getCustomType();
|
||||
} else {
|
||||
callon = this;
|
||||
}
|
||||
return this.forwardEvent.apply(this, [callon].concat(slice.call(arguments)));
|
||||
};
|
||||
|
||||
Operation.prototype.forwardEvent = function() {
|
||||
var args, f, j, len, op, ref, results;
|
||||
op = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
||||
ref = this.event_listeners;
|
||||
results = [];
|
||||
for (j = 0, len = ref.length; j < len; j++) {
|
||||
f = ref[j];
|
||||
results.push(f.call.apply(f, [op].concat(slice.call(args))));
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
Operation.prototype.isDeleted = function() {
|
||||
return this.is_deleted;
|
||||
};
|
||||
|
||||
Operation.prototype.applyDelete = function(garbagecollect) {
|
||||
if (garbagecollect == null) {
|
||||
garbagecollect = true;
|
||||
}
|
||||
if (!this.garbage_collected) {
|
||||
this.is_deleted = true;
|
||||
if (garbagecollect) {
|
||||
this.garbage_collected = true;
|
||||
return this.HB.addToGarbageCollector(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Operation.prototype.cleanup = function() {
|
||||
this.HB.removeOperation(this);
|
||||
return this.deleteAllObservers();
|
||||
};
|
||||
|
||||
Operation.prototype.setParent = function(parent1) {
|
||||
this.parent = parent1;
|
||||
};
|
||||
|
||||
Operation.prototype.getParent = function() {
|
||||
return this.parent;
|
||||
};
|
||||
|
||||
Operation.prototype.getUid = function() {
|
||||
var map_uid;
|
||||
if (this.uid.noOperation == null) {
|
||||
return this.uid;
|
||||
} else {
|
||||
if (this.uid.alt != null) {
|
||||
map_uid = this.uid.alt.cloneUid();
|
||||
map_uid.sub = this.uid.sub;
|
||||
return map_uid;
|
||||
} else {
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Operation.prototype.cloneUid = function() {
|
||||
var n, ref, uid, v;
|
||||
uid = {};
|
||||
ref = this.getUid();
|
||||
for (n in ref) {
|
||||
v = ref[n];
|
||||
uid[n] = v;
|
||||
}
|
||||
return uid;
|
||||
};
|
||||
|
||||
Operation.prototype.execute = function() {
|
||||
var j, l, len;
|
||||
if (this.validateSavedOperations()) {
|
||||
this.is_executed = true;
|
||||
if (this.uid == null) {
|
||||
this.uid = this.HB.getNextOperationIdentifier();
|
||||
}
|
||||
if (this.uid.noOperation == null) {
|
||||
this.HB.addOperation(this);
|
||||
for (j = 0, len = execution_listener.length; j < len; j++) {
|
||||
l = execution_listener[j];
|
||||
l(this._encode());
|
||||
}
|
||||
}
|
||||
return this;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Operation.prototype.saveOperation = function(name, op, base) {
|
||||
var base1, dest, j, last_path, len, path, paths;
|
||||
if (base == null) {
|
||||
base = "this";
|
||||
}
|
||||
if ((op != null) && (op._getModel != null)) {
|
||||
op = op._getModel(this.custom_types, this.operations);
|
||||
}
|
||||
if (op == null) {
|
||||
|
||||
} else if ((op.execute != null) || !((op.op_number != null) && (op.creator != null))) {
|
||||
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 {
|
||||
if (this.unchecked == null) {
|
||||
this.unchecked = {};
|
||||
}
|
||||
if ((base1 = this.unchecked)[base] == null) {
|
||||
base1[base] = {};
|
||||
}
|
||||
return this.unchecked[base][name] = op;
|
||||
}
|
||||
};
|
||||
|
||||
Operation.prototype.validateSavedOperations = function() {
|
||||
var base, base_name, dest, j, last_path, len, name, op, op_uid, path, paths, ref, success, uninstantiated;
|
||||
uninstantiated = {};
|
||||
success = true;
|
||||
ref = this.unchecked;
|
||||
for (base_name in ref) {
|
||||
base = ref[base_name];
|
||||
for (name in base) {
|
||||
op_uid = base[name];
|
||||
op = this.HB.getOperation(op_uid);
|
||||
if (op) {
|
||||
if (base_name === "this") {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
this.unchecked = uninstantiated;
|
||||
return false;
|
||||
} else {
|
||||
delete this.unchecked;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
Operation.prototype.getCustomType = function() {
|
||||
var Type, j, len, ref, t;
|
||||
if (this.custom_type == null) {
|
||||
return this;
|
||||
} else {
|
||||
if (this.custom_type.constructor === String) {
|
||||
Type = this.custom_types;
|
||||
ref = this.custom_type.split(".");
|
||||
for (j = 0, len = ref.length; j < len; j++) {
|
||||
t = ref[j];
|
||||
Type = Type[t];
|
||||
}
|
||||
this.custom_type = new Type();
|
||||
this.custom_type._setModel(this);
|
||||
}
|
||||
return this.custom_type;
|
||||
}
|
||||
};
|
||||
|
||||
Operation.prototype._encode = function(json) {
|
||||
var n, o, operations, ref, ref1;
|
||||
if (json == null) {
|
||||
json = {};
|
||||
}
|
||||
json.type = this.type;
|
||||
json.uid = this.getUid();
|
||||
if (this.custom_type != null) {
|
||||
if (this.custom_type.constructor === String) {
|
||||
json.custom_type = this.custom_type;
|
||||
} else {
|
||||
json.custom_type = this.custom_type._name;
|
||||
}
|
||||
}
|
||||
if (((ref = this.content) != null ? ref.getUid : void 0) != null) {
|
||||
json.content = this.content.getUid();
|
||||
} else {
|
||||
json.content = this.content;
|
||||
}
|
||||
if (this.content_operations != null) {
|
||||
operations = {};
|
||||
ref1 = this.content_operations;
|
||||
for (n in ref1) {
|
||||
o = ref1[n];
|
||||
if (o._getModel != null) {
|
||||
o = o._getModel(this.custom_types, this.operations);
|
||||
}
|
||||
operations[n] = o.getUid();
|
||||
}
|
||||
json.content_operations = operations;
|
||||
}
|
||||
return json;
|
||||
};
|
||||
|
||||
return Operation;
|
||||
|
||||
})();
|
||||
ops.Delete = (function(superClass) {
|
||||
extend(Delete, superClass);
|
||||
|
||||
function Delete(custom_type, uid, deletes) {
|
||||
this.saveOperation('deletes', deletes);
|
||||
Delete.__super__.constructor.call(this, custom_type, uid);
|
||||
}
|
||||
|
||||
Delete.prototype.type = "Delete";
|
||||
|
||||
Delete.prototype._encode = function() {
|
||||
return {
|
||||
'type': "Delete",
|
||||
'uid': this.getUid(),
|
||||
'deletes': this.deletes.getUid()
|
||||
};
|
||||
};
|
||||
|
||||
Delete.prototype.execute = function() {
|
||||
var res;
|
||||
if (this.validateSavedOperations()) {
|
||||
res = Delete.__super__.execute.apply(this, arguments);
|
||||
if (res) {
|
||||
this.deletes.applyDelete(this);
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
return Delete;
|
||||
|
||||
})(ops.Operation);
|
||||
ops.Delete.parse = function(o) {
|
||||
var deletes_uid, uid;
|
||||
uid = o['uid'], deletes_uid = o['deletes'];
|
||||
return new this(null, uid, deletes_uid);
|
||||
};
|
||||
ops.Insert = (function(superClass) {
|
||||
extend(Insert, superClass);
|
||||
|
||||
function Insert(custom_type, content, content_operations, parent, uid, prev_cl, next_cl, origin) {
|
||||
this.saveOperation('parent', parent);
|
||||
this.saveOperation('prev_cl', prev_cl);
|
||||
this.saveOperation('next_cl', next_cl);
|
||||
if (origin != null) {
|
||||
this.saveOperation('origin', origin);
|
||||
} else {
|
||||
this.saveOperation('origin', prev_cl);
|
||||
}
|
||||
Insert.__super__.constructor.call(this, custom_type, uid, content, content_operations);
|
||||
}
|
||||
|
||||
Insert.prototype.type = "Insert";
|
||||
|
||||
Insert.prototype.val = function() {
|
||||
return this.getContent();
|
||||
};
|
||||
|
||||
Insert.prototype.getNext = function(i) {
|
||||
var n;
|
||||
if (i == null) {
|
||||
i = 1;
|
||||
}
|
||||
n = this;
|
||||
while (i > 0 && n.is_deleted && (n.next_cl != null)) {
|
||||
n = n.next_cl;
|
||||
if (!n.is_deleted) {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
};
|
||||
|
||||
Insert.prototype.getPrev = function(i) {
|
||||
var n;
|
||||
if (i == null) {
|
||||
i = 1;
|
||||
}
|
||||
n = this;
|
||||
while (i > 0 && n.is_deleted && (n.prev_cl != null)) {
|
||||
n = n.prev_cl;
|
||||
if (!n.is_deleted) {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
};
|
||||
|
||||
Insert.prototype.applyDelete = function(o) {
|
||||
var callLater, garbagecollect, ref;
|
||||
if (this.deleted_by == null) {
|
||||
this.deleted_by = [];
|
||||
}
|
||||
callLater = false;
|
||||
if ((this.parent != null) && !this.is_deleted && (o != null)) {
|
||||
callLater = true;
|
||||
}
|
||||
if (o != null) {
|
||||
this.deleted_by.push(o);
|
||||
}
|
||||
garbagecollect = false;
|
||||
if (this.next_cl.isDeleted()) {
|
||||
garbagecollect = true;
|
||||
}
|
||||
Insert.__super__.applyDelete.call(this, garbagecollect);
|
||||
if (callLater) {
|
||||
this.parent.callOperationSpecificDeleteEvents(this, o);
|
||||
}
|
||||
if ((ref = this.prev_cl) != null ? ref.isDeleted() : void 0) {
|
||||
return this.prev_cl.applyDelete();
|
||||
}
|
||||
};
|
||||
|
||||
Insert.prototype.cleanup = function() {
|
||||
var d, j, len, o, ref;
|
||||
if (this.next_cl.isDeleted()) {
|
||||
ref = this.deleted_by;
|
||||
for (j = 0, len = ref.length; j < len; j++) {
|
||||
d = ref[j];
|
||||
d.cleanup();
|
||||
}
|
||||
o = this.next_cl;
|
||||
while (o.type !== "Delimiter") {
|
||||
if (o.origin === this) {
|
||||
o.origin = this.prev_cl;
|
||||
}
|
||||
o = o.next_cl;
|
||||
}
|
||||
this.prev_cl.next_cl = this.next_cl;
|
||||
this.next_cl.prev_cl = this.prev_cl;
|
||||
if (this.content instanceof ops.Operation) {
|
||||
this.content.referenced_by--;
|
||||
if (this.content.referenced_by <= 0 && !this.content.is_deleted) {
|
||||
this.content.applyDelete();
|
||||
}
|
||||
}
|
||||
delete this.content;
|
||||
return Insert.__super__.cleanup.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
Insert.prototype.getDistanceToOrigin = function() {
|
||||
var d, o;
|
||||
d = 0;
|
||||
o = this.prev_cl;
|
||||
while (true) {
|
||||
if (this.origin === o) {
|
||||
break;
|
||||
}
|
||||
d++;
|
||||
o = o.prev_cl;
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
Insert.prototype.execute = function() {
|
||||
var base1, distance_to_origin, i, o;
|
||||
if (!this.validateSavedOperations()) {
|
||||
return false;
|
||||
} else {
|
||||
if (this.content instanceof ops.Operation) {
|
||||
this.content.insert_parent = this;
|
||||
if ((base1 = this.content).referenced_by == null) {
|
||||
base1.referenced_by = 0;
|
||||
}
|
||||
this.content.referenced_by++;
|
||||
}
|
||||
if (this.parent != null) {
|
||||
if (this.prev_cl == null) {
|
||||
this.prev_cl = this.parent.beginning;
|
||||
}
|
||||
if (this.origin == null) {
|
||||
this.origin = this.prev_cl;
|
||||
} else if (this.origin === "Delimiter") {
|
||||
this.origin = this.parent.beginning;
|
||||
}
|
||||
if (this.next_cl == null) {
|
||||
this.next_cl = this.parent.end;
|
||||
}
|
||||
}
|
||||
if (this.prev_cl != null) {
|
||||
distance_to_origin = this.getDistanceToOrigin();
|
||||
o = this.prev_cl.next_cl;
|
||||
i = distance_to_origin;
|
||||
while (true) {
|
||||
if (o !== this.next_cl) {
|
||||
if (o.getDistanceToOrigin() === i) {
|
||||
if (o.uid.creator < this.uid.creator) {
|
||||
this.prev_cl = o;
|
||||
distance_to_origin = i + 1;
|
||||
} else {
|
||||
|
||||
}
|
||||
} else if (o.getDistanceToOrigin() < i) {
|
||||
if (i - distance_to_origin <= o.getDistanceToOrigin()) {
|
||||
this.prev_cl = o;
|
||||
distance_to_origin = i + 1;
|
||||
} else {
|
||||
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
o = o.next_cl;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.next_cl = this.prev_cl.next_cl;
|
||||
this.prev_cl.next_cl = this;
|
||||
this.next_cl.prev_cl = this;
|
||||
}
|
||||
this.setParent(this.prev_cl.getParent());
|
||||
Insert.__super__.execute.apply(this, arguments);
|
||||
this.parent.callOperationSpecificInsertEvents(this);
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
Insert.prototype.getPosition = function() {
|
||||
var position, prev;
|
||||
position = 0;
|
||||
prev = this.prev_cl;
|
||||
while (true) {
|
||||
if (prev instanceof ops.Delimiter) {
|
||||
break;
|
||||
}
|
||||
if (!prev.isDeleted()) {
|
||||
position++;
|
||||
}
|
||||
prev = prev.prev_cl;
|
||||
}
|
||||
return position;
|
||||
};
|
||||
|
||||
Insert.prototype._encode = function(json) {
|
||||
if (json == null) {
|
||||
json = {};
|
||||
}
|
||||
json.prev = this.prev_cl.getUid();
|
||||
json.next = this.next_cl.getUid();
|
||||
if (this.origin.type === "Delimiter") {
|
||||
json.origin = "Delimiter";
|
||||
} else if (this.origin !== this.prev_cl) {
|
||||
json.origin = this.origin.getUid();
|
||||
}
|
||||
json.parent = this.parent.getUid();
|
||||
return Insert.__super__._encode.call(this, json);
|
||||
};
|
||||
|
||||
return Insert;
|
||||
|
||||
})(ops.Operation);
|
||||
ops.Insert.parse = function(json) {
|
||||
var content, content_operations, next, origin, parent, prev, uid;
|
||||
content = json['content'], content_operations = json['content_operations'], uid = json['uid'], prev = json['prev'], next = json['next'], origin = json['origin'], parent = json['parent'];
|
||||
return new this(null, content, content_operations, parent, uid, prev, next, origin);
|
||||
};
|
||||
ops.Delimiter = (function(superClass) {
|
||||
extend(Delimiter, superClass);
|
||||
|
||||
function Delimiter(prev_cl, next_cl, origin) {
|
||||
this.saveOperation('prev_cl', prev_cl);
|
||||
this.saveOperation('next_cl', next_cl);
|
||||
this.saveOperation('origin', prev_cl);
|
||||
Delimiter.__super__.constructor.call(this, null, {
|
||||
noOperation: true
|
||||
});
|
||||
}
|
||||
|
||||
Delimiter.prototype.type = "Delimiter";
|
||||
|
||||
Delimiter.prototype.applyDelete = function() {
|
||||
var o;
|
||||
Delimiter.__super__.applyDelete.call(this);
|
||||
o = this.prev_cl;
|
||||
while (o != null) {
|
||||
o.applyDelete();
|
||||
o = o.prev_cl;
|
||||
}
|
||||
return void 0;
|
||||
};
|
||||
|
||||
Delimiter.prototype.cleanup = function() {
|
||||
return Delimiter.__super__.cleanup.call(this);
|
||||
};
|
||||
|
||||
Delimiter.prototype.execute = function() {
|
||||
var ref, ref1;
|
||||
if (((ref = this.unchecked) != null ? ref['next_cl'] : void 0) != null) {
|
||||
return Delimiter.__super__.execute.apply(this, arguments);
|
||||
} else if ((ref1 = this.unchecked) != null ? ref1['prev_cl'] : void 0) {
|
||||
if (this.validateSavedOperations()) {
|
||||
if (this.prev_cl.next_cl != null) {
|
||||
throw new Error("Probably duplicated operations");
|
||||
}
|
||||
this.prev_cl.next_cl = this;
|
||||
return Delimiter.__super__.execute.apply(this, arguments);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if ((this.prev_cl != null) && (this.prev_cl.next_cl == null)) {
|
||||
delete this.prev_cl.unchecked.next_cl;
|
||||
this.prev_cl.next_cl = this;
|
||||
return Delimiter.__super__.execute.apply(this, arguments);
|
||||
} else if ((this.prev_cl != null) || (this.next_cl != null) || true) {
|
||||
return Delimiter.__super__.execute.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
Delimiter.prototype._encode = function() {
|
||||
var ref, ref1;
|
||||
return {
|
||||
'type': this.type,
|
||||
'uid': this.getUid(),
|
||||
'prev': (ref = this.prev_cl) != null ? ref.getUid() : void 0,
|
||||
'next': (ref1 = this.next_cl) != null ? ref1.getUid() : void 0
|
||||
};
|
||||
};
|
||||
|
||||
return Delimiter;
|
||||
|
||||
})(ops.Operation);
|
||||
ops.Delimiter.parse = function(json) {
|
||||
var next, prev, uid;
|
||||
uid = json['uid'], prev = json['prev'], next = json['next'];
|
||||
return new this(uid, prev, next);
|
||||
};
|
||||
return {
|
||||
'operations': ops,
|
||||
'execution_listener': execution_listener
|
||||
};
|
||||
};
|
@ -1,92 +0,0 @@
|
||||
var Y, bindToChildren;
|
||||
|
||||
Y = require('./y');
|
||||
|
||||
bindToChildren = function(that) {
|
||||
var attr, i, j, ref;
|
||||
for (i = j = 0, ref = that.children.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
|
||||
attr = that.children.item(i);
|
||||
if (attr.name != null) {
|
||||
attr.val = that.val.val(attr.name);
|
||||
}
|
||||
}
|
||||
return that.val.observe(function(events) {
|
||||
var event, k, len, newVal, results;
|
||||
results = [];
|
||||
for (k = 0, len = events.length; k < len; k++) {
|
||||
event = events[k];
|
||||
if (event.name != null) {
|
||||
results.push((function() {
|
||||
var l, ref1, results1;
|
||||
results1 = [];
|
||||
for (i = l = 0, ref1 = that.children.length; 0 <= ref1 ? l < ref1 : l > ref1; i = 0 <= ref1 ? ++l : --l) {
|
||||
attr = that.children.item(i);
|
||||
if ((attr.name != null) && attr.name === event.name) {
|
||||
newVal = that.val.val(attr.name);
|
||||
if (attr.val !== newVal) {
|
||||
results1.push(attr.val = newVal);
|
||||
} else {
|
||||
results1.push(void 0);
|
||||
}
|
||||
} else {
|
||||
results1.push(void 0);
|
||||
}
|
||||
}
|
||||
return results1;
|
||||
})());
|
||||
} else {
|
||||
results.push(void 0);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
});
|
||||
};
|
||||
|
||||
Polymer("y-object", {
|
||||
ready: function() {
|
||||
if (this.connector != null) {
|
||||
this.val = new Y(this.connector);
|
||||
return bindToChildren(this);
|
||||
} else if (this.val != null) {
|
||||
return bindToChildren(this);
|
||||
}
|
||||
},
|
||||
valChanged: function() {
|
||||
if ((this.val != null) && this.val.type === "Object") {
|
||||
return bindToChildren(this);
|
||||
}
|
||||
},
|
||||
connectorChanged: function() {
|
||||
if (this.val == null) {
|
||||
this.val = new Y(this.connector);
|
||||
return bindToChildren(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Polymer("y-property", {
|
||||
ready: function() {
|
||||
if ((this.val != null) && (this.name != null)) {
|
||||
if (this.val.constructor === Object) {
|
||||
this.val = this.parentElement.val(this.name, this.val).val(this.name);
|
||||
} else if (typeof this.val === "string") {
|
||||
this.parentElement.val(this.name, this.val);
|
||||
}
|
||||
if (this.val.type === "Object") {
|
||||
return bindToChildren(this);
|
||||
}
|
||||
}
|
||||
},
|
||||
valChanged: function() {
|
||||
var ref;
|
||||
if ((this.val != null) && (this.name != null)) {
|
||||
if (this.val.constructor === Object) {
|
||||
return this.val = this.parentElement.val.val(this.name, this.val).val(this.name);
|
||||
} else if (this.val.type === "Object") {
|
||||
return bindToChildren(this);
|
||||
} else if ((((ref = this.parentElement.val) != null ? ref.val : void 0) != null) && this.val !== this.parentElement.val.val(this.name)) {
|
||||
return this.parentElement.val.val(this.name, this.val);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
18654
build/test/list-test.js
18654
build/test/list-test.js
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
18674
build/test/text-test.js
18674
build/test/text-test.js
File diff suppressed because one or more lines are too long
28615
build/test/xml-test.js
28615
build/test/xml-test.js
File diff suppressed because one or more lines are too long
@ -15,7 +15,6 @@ mocha = require 'gulp-mocha'
|
||||
run = require 'gulp-run'
|
||||
ljs = require 'gulp-ljs'
|
||||
plumber = require 'gulp-plumber'
|
||||
mochaPhantomJS = require 'gulp-mocha-phantomjs'
|
||||
cache = require 'gulp-cached'
|
||||
coffeeify = require 'gulp-coffeeify'
|
||||
exit = require 'gulp-exit'
|
||||
@ -44,7 +43,7 @@ gulp.task 'deploy_nodejs', ->
|
||||
.pipe gulp.dest 'build/node/'
|
||||
.pipe gulpif '!**/', git.add({args : "-A"})
|
||||
|
||||
gulp.task 'deploy', ['mocha', 'build_browser', 'deploy_nodejs', 'lint', 'phantom_test', 'codo']
|
||||
gulp.task 'deploy', ['mocha', 'build_browser', 'deploy_nodejs', 'lint', 'codo']
|
||||
|
||||
gulp.task 'build_browser', ->
|
||||
gulp.src files.browser, { read: false }
|
||||
@ -95,9 +94,6 @@ gulp.task 'lint', ->
|
||||
}
|
||||
.pipe coffeelint.reporter()
|
||||
|
||||
gulp.task 'phantom_watch', ['phantom_test'], ->
|
||||
gulp.watch files.all, ['phantom_test']
|
||||
|
||||
gulp.task 'literate', ->
|
||||
gulp.src files.examples
|
||||
.pipe ljs { code : true }
|
||||
@ -111,13 +107,8 @@ gulp.task 'codo', [], ()->
|
||||
command = './node_modules/codo/bin/codo -o "./doc" --name "yjs" --readme "README.md" --undocumented false --private true --title "yjs API" ./lib - LICENSE.txt '
|
||||
run(command).exec()
|
||||
|
||||
gulp.task 'phantom_test', ['build_browser'], ()->
|
||||
gulp.src 'build/test/index.html'
|
||||
.pipe mochaPhantomJS()
|
||||
|
||||
gulp.task 'clean', ->
|
||||
gulp.src ['./build/{browser,test,node}/**/*.{js,map}','./doc/'], { read: false }
|
||||
.pipe rimraf()
|
||||
|
||||
gulp.task 'default', ['clean','build'], ->
|
||||
|
||||
|
@ -58,4 +58,4 @@ adaptConnector = (connector, engine, HB, execution_listener)->
|
||||
engine.applyOp op
|
||||
|
||||
|
||||
module.exports = adaptConnector
|
||||
module.exports = adaptConnector
|
||||
|
@ -48,7 +48,6 @@
|
||||
"gulp-ignore": "^1.2.0",
|
||||
"gulp-ljs": "^0.1.1",
|
||||
"gulp-mocha": "^0.5.2",
|
||||
"gulp-mocha-phantomjs": "^0.5.0",
|
||||
"gulp-plumber": "^0.6.6",
|
||||
"gulp-rename": "^1.2.0",
|
||||
"gulp-rimraf": "^0.1.0",
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user