testing observers, refactoring some Basic Types
This commit is contained in:
@@ -4,3 +4,5 @@
|
|||||||
.directory
|
.directory
|
||||||
.c9
|
.c9
|
||||||
myftppass
|
myftppass
|
||||||
|
.codio
|
||||||
|
.settings
|
||||||
+179
-292
File diff suppressed because one or more lines are too long
@@ -0,0 +1,209 @@
|
|||||||
|
(function() {
|
||||||
|
var HistoryBuffer,
|
||||||
|
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
||||||
|
|
||||||
|
HistoryBuffer = (function() {
|
||||||
|
function HistoryBuffer(user_id) {
|
||||||
|
this.user_id = user_id;
|
||||||
|
this.emptyGarbage = __bind(this.emptyGarbage, this);
|
||||||
|
this.operation_counter = {};
|
||||||
|
this.buffer = {};
|
||||||
|
this.change_listeners = [];
|
||||||
|
this.garbage = [];
|
||||||
|
this.trash = [];
|
||||||
|
this.performGarbageCollection = true;
|
||||||
|
this.garbageCollectTimeout = 1000;
|
||||||
|
this.reserved_identifier_counter = 0;
|
||||||
|
setTimeout(this.emptyGarbage, this.garbageCollectTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryBuffer.prototype.emptyGarbage = function() {
|
||||||
|
var o, _i, _len, _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 o, _i, _len, _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++),
|
||||||
|
doSync: false
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
HistoryBuffer.prototype.getOperationCounter = function(user_id) {
|
||||||
|
var ctn, res, user, _ref;
|
||||||
|
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._encode = function(state_vector) {
|
||||||
|
var json, o, o_json, o_next, o_number, o_prev, u_name, unknown, user, _ref;
|
||||||
|
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];
|
||||||
|
for (o_number in user) {
|
||||||
|
o = user[o_number];
|
||||||
|
if (o.uid.doSync && 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],
|
||||||
|
'doSync': true
|
||||||
|
};
|
||||||
|
this.operation_counter[user_id]++;
|
||||||
|
return uid;
|
||||||
|
};
|
||||||
|
|
||||||
|
HistoryBuffer.prototype.getOperation = function(uid) {
|
||||||
|
var _ref;
|
||||||
|
if (uid.uid != null) {
|
||||||
|
uid = uid.uid;
|
||||||
|
}
|
||||||
|
return (_ref = this.buffer[uid.creator]) != null ? _ref[uid.op_number] : void 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
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!");
|
||||||
|
}
|
||||||
|
this.buffer[o.uid.creator][o.uid.op_number] = o;
|
||||||
|
if (this.number_of_operations_added_to_HB == null) {
|
||||||
|
this.number_of_operations_added_to_HB = 0;
|
||||||
|
}
|
||||||
|
this.number_of_operations_added_to_HB++;
|
||||||
|
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.addToCounter = function(o) {
|
||||||
|
var _results;
|
||||||
|
if (this.operation_counter[o.uid.creator] == null) {
|
||||||
|
this.operation_counter[o.uid.creator] = 0;
|
||||||
|
}
|
||||||
|
if (typeof o.uid.op_number === 'number' && o.uid.creator !== this.getUserId()) {
|
||||||
|
if (o.uid.op_number === this.operation_counter[o.uid.creator]) {
|
||||||
|
this.operation_counter[o.uid.creator]++;
|
||||||
|
_results = [];
|
||||||
|
while (this.getOperation({
|
||||||
|
creator: o.uid.creator,
|
||||||
|
op_number: this.operation_counter[o.uid.creator]
|
||||||
|
}) != null) {
|
||||||
|
_results.push(this.operation_counter[o.uid.creator]++);
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return HistoryBuffer;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
module.exports = HistoryBuffer;
|
||||||
|
|
||||||
|
}).call(this);
|
||||||
|
|
||||||
|
//# sourceMappingURL=HistoryBuffer.js.map
|
||||||
@@ -0,0 +1,458 @@
|
|||||||
|
(function() {
|
||||||
|
var __slice = [].slice,
|
||||||
|
__hasProp = {}.hasOwnProperty,
|
||||||
|
__extends = 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; };
|
||||||
|
|
||||||
|
module.exports = function(HB) {
|
||||||
|
var Delete, Delimiter, ImmutableObject, Insert, Operation, execution_listener, parser;
|
||||||
|
parser = {};
|
||||||
|
execution_listener = [];
|
||||||
|
Operation = (function() {
|
||||||
|
function Operation(uid) {
|
||||||
|
this.is_deleted = false;
|
||||||
|
this.garbage_collected = false;
|
||||||
|
this.event_listeners = [];
|
||||||
|
if (uid != null) {
|
||||||
|
this.uid = uid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Operation.prototype.type = "Insert";
|
||||||
|
|
||||||
|
Operation.prototype.observe = function(f) {
|
||||||
|
return this.event_listeners.push(f);
|
||||||
|
};
|
||||||
|
|
||||||
|
Operation.prototype.unobserve = function(f) {
|
||||||
|
return this.event_listeners.filter(function(g) {
|
||||||
|
return f !== g;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Operation.prototype.deleteAllObservers = function() {
|
||||||
|
return this.event_listeners = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
Operation.prototype.callEvent = function() {
|
||||||
|
return this.forwardEvent.apply(this, [this].concat(__slice.call(arguments)));
|
||||||
|
};
|
||||||
|
|
||||||
|
Operation.prototype.forwardEvent = function() {
|
||||||
|
var args, f, op, _i, _len, _ref, _results;
|
||||||
|
op = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
||||||
|
_ref = this.event_listeners;
|
||||||
|
_results = [];
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
f = _ref[_i];
|
||||||
|
_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 HB.addToGarbageCollector(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Operation.prototype.cleanup = function() {
|
||||||
|
HB.removeOperation(this);
|
||||||
|
return this.deleteAllObservers();
|
||||||
|
};
|
||||||
|
|
||||||
|
Operation.prototype.setParent = function(parent) {
|
||||||
|
this.parent = parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
Operation.prototype.getParent = function() {
|
||||||
|
return this.parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
Operation.prototype.getUid = function() {
|
||||||
|
return this.uid;
|
||||||
|
};
|
||||||
|
|
||||||
|
Operation.prototype.dontSync = function() {
|
||||||
|
return this.uid.doSync = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Operation.prototype.execute = function() {
|
||||||
|
var l, _i, _len;
|
||||||
|
this.is_executed = true;
|
||||||
|
if (this.uid == null) {
|
||||||
|
this.uid = HB.getNextOperationIdentifier();
|
||||||
|
}
|
||||||
|
HB.addOperation(this);
|
||||||
|
for (_i = 0, _len = execution_listener.length; _i < _len; _i++) {
|
||||||
|
l = execution_listener[_i];
|
||||||
|
l(this._encode());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Operation.prototype.saveOperation = function(name, op) {
|
||||||
|
if ((op != null ? op.execute : void 0) != null) {
|
||||||
|
return this[name] = op;
|
||||||
|
} else if (op != null) {
|
||||||
|
if (this.unchecked == null) {
|
||||||
|
this.unchecked = {};
|
||||||
|
}
|
||||||
|
return this.unchecked[name] = op;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Operation.prototype.validateSavedOperations = function() {
|
||||||
|
var name, op, op_uid, success, uninstantiated, _ref;
|
||||||
|
uninstantiated = {};
|
||||||
|
success = this;
|
||||||
|
_ref = this.unchecked;
|
||||||
|
for (name in _ref) {
|
||||||
|
op_uid = _ref[name];
|
||||||
|
op = HB.getOperation(op_uid);
|
||||||
|
if (op) {
|
||||||
|
this[name] = op;
|
||||||
|
} else {
|
||||||
|
uninstantiated[name] = op_uid;
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete this.unchecked;
|
||||||
|
if (!success) {
|
||||||
|
this.unchecked = uninstantiated;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
};
|
||||||
|
|
||||||
|
return Operation;
|
||||||
|
|
||||||
|
})();
|
||||||
|
Delete = (function(_super) {
|
||||||
|
__extends(Delete, _super);
|
||||||
|
|
||||||
|
function Delete(uid, deletes) {
|
||||||
|
this.saveOperation('deletes', deletes);
|
||||||
|
Delete.__super__.constructor.call(this, uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
Delete.prototype.type = "Delete";
|
||||||
|
|
||||||
|
Delete.prototype._encode = function() {
|
||||||
|
return {
|
||||||
|
'type': "Delete",
|
||||||
|
'uid': this.getUid(),
|
||||||
|
'deletes': this.deletes.getUid()
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Delete.prototype.execute = function() {
|
||||||
|
if (this.validateSavedOperations()) {
|
||||||
|
this.deletes.applyDelete(this);
|
||||||
|
return Delete.__super__.execute.apply(this, arguments);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return Delete;
|
||||||
|
|
||||||
|
})(Operation);
|
||||||
|
parser['Delete'] = function(o) {
|
||||||
|
var deletes_uid, uid;
|
||||||
|
uid = o['uid'], deletes_uid = o['deletes'];
|
||||||
|
return new Delete(uid, deletes_uid);
|
||||||
|
};
|
||||||
|
Insert = (function(_super) {
|
||||||
|
__extends(Insert, _super);
|
||||||
|
|
||||||
|
function Insert(uid, prev_cl, next_cl, origin) {
|
||||||
|
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, uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
Insert.prototype.type = "Insert";
|
||||||
|
|
||||||
|
Insert.prototype.applyDelete = function(o) {
|
||||||
|
var callLater, garbagecollect, _ref;
|
||||||
|
if (this.deleted_by == null) {
|
||||||
|
this.deleted_by = [];
|
||||||
|
}
|
||||||
|
callLater = false;
|
||||||
|
if ((this.parent != null) && !this.isDeleted() && (o != null)) {
|
||||||
|
callLater = true;
|
||||||
|
}
|
||||||
|
if (o != null) {
|
||||||
|
this.deleted_by.push(o);
|
||||||
|
}
|
||||||
|
garbagecollect = false;
|
||||||
|
if (!((this.prev_cl != null) && (this.next_cl != null)) || this.prev_cl.isDeleted()) {
|
||||||
|
garbagecollect = true;
|
||||||
|
}
|
||||||
|
Insert.__super__.applyDelete.call(this, garbagecollect);
|
||||||
|
if (callLater) {
|
||||||
|
this.parent.callEvent([
|
||||||
|
{
|
||||||
|
type: "insert",
|
||||||
|
position: this.getPosition(),
|
||||||
|
object: this.parent,
|
||||||
|
changed_by: o.uid.creator
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if ((_ref = this.next_cl) != null ? _ref.isDeleted() : void 0) {
|
||||||
|
return this.next_cl.applyDelete();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Insert.prototype.cleanup = function() {
|
||||||
|
var d, o, _i, _len, _ref, _ref1;
|
||||||
|
if ((_ref = this.prev_cl) != null ? _ref.isDeleted() : void 0) {
|
||||||
|
_ref1 = this.deleted_by;
|
||||||
|
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||||||
|
d = _ref1[_i];
|
||||||
|
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;
|
||||||
|
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 distance_to_origin, i, o;
|
||||||
|
if (!this.validateSavedOperations()) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
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.callOperationSpecificEvents();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Insert.prototype.callOperationSpecificEvents = function() {
|
||||||
|
var _ref;
|
||||||
|
return (_ref = this.parent) != null ? _ref.callEvent([
|
||||||
|
{
|
||||||
|
type: "insert",
|
||||||
|
position: this.getPosition(),
|
||||||
|
object: this.parent,
|
||||||
|
changed_by: this.uid.creator
|
||||||
|
}
|
||||||
|
]) : void 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Insert.prototype.getPosition = function() {
|
||||||
|
var position, prev;
|
||||||
|
position = 0;
|
||||||
|
prev = this.prev_cl;
|
||||||
|
while (true) {
|
||||||
|
if (prev instanceof Delimiter) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!prev.isDeleted()) {
|
||||||
|
position++;
|
||||||
|
}
|
||||||
|
prev = prev.prev_cl;
|
||||||
|
}
|
||||||
|
return position;
|
||||||
|
};
|
||||||
|
|
||||||
|
return Insert;
|
||||||
|
|
||||||
|
})(Operation);
|
||||||
|
ImmutableObject = (function(_super) {
|
||||||
|
__extends(ImmutableObject, _super);
|
||||||
|
|
||||||
|
function ImmutableObject(uid, content, prev, next, origin) {
|
||||||
|
this.content = content;
|
||||||
|
ImmutableObject.__super__.constructor.call(this, uid, prev, next, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImmutableObject.prototype.type = "ImmutableObject";
|
||||||
|
|
||||||
|
ImmutableObject.prototype.val = function() {
|
||||||
|
return this.content;
|
||||||
|
};
|
||||||
|
|
||||||
|
ImmutableObject.prototype._encode = function() {
|
||||||
|
var json;
|
||||||
|
json = {
|
||||||
|
'type': "ImmutableObject",
|
||||||
|
'uid': this.getUid(),
|
||||||
|
'content': this.content
|
||||||
|
};
|
||||||
|
if (this.prev_cl != null) {
|
||||||
|
json['prev'] = this.prev_cl.getUid();
|
||||||
|
}
|
||||||
|
if (this.next_cl != null) {
|
||||||
|
json['next'] = this.next_cl.getUid();
|
||||||
|
}
|
||||||
|
if (this.origin != null) {
|
||||||
|
json["origin"] = this.origin().getUid();
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
};
|
||||||
|
|
||||||
|
return ImmutableObject;
|
||||||
|
|
||||||
|
})(Operation);
|
||||||
|
parser['ImmutableObject'] = function(json) {
|
||||||
|
var content, next, origin, prev, uid;
|
||||||
|
uid = json['uid'], content = json['content'], prev = json['prev'], next = json['next'], origin = json['origin'];
|
||||||
|
return new ImmutableObject(uid, content, prev, next, origin);
|
||||||
|
};
|
||||||
|
Delimiter = (function(_super) {
|
||||||
|
__extends(Delimiter, _super);
|
||||||
|
|
||||||
|
function Delimiter(uid, 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, uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
Delimiter.prototype.type = "Delimiter";
|
||||||
|
|
||||||
|
Delimiter.prototype.applyDelete = function() {
|
||||||
|
var o;
|
||||||
|
Delimiter.__super__.applyDelete.call(this);
|
||||||
|
o = this.next_cl;
|
||||||
|
while (o != null) {
|
||||||
|
o.applyDelete();
|
||||||
|
o = o.next_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': "Delimiter",
|
||||||
|
'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;
|
||||||
|
|
||||||
|
})(Operation);
|
||||||
|
parser['Delimiter'] = function(json) {
|
||||||
|
var next, prev, uid;
|
||||||
|
uid = json['uid'], prev = json['prev'], next = json['next'];
|
||||||
|
return new Delimiter(uid, prev, next);
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
'types': {
|
||||||
|
'Delete': Delete,
|
||||||
|
'Insert': Insert,
|
||||||
|
'Delimiter': Delimiter,
|
||||||
|
'Operation': Operation,
|
||||||
|
'ImmutableObject': ImmutableObject
|
||||||
|
},
|
||||||
|
'parser': parser,
|
||||||
|
'execution_listener': execution_listener
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(this);
|
||||||
|
|
||||||
|
//# sourceMappingURL=../Types/BasicTypes.js.map
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,246 @@
|
|||||||
|
(function() {
|
||||||
|
var text_types_uninitialized,
|
||||||
|
__hasProp = {}.hasOwnProperty,
|
||||||
|
__extends = 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; };
|
||||||
|
|
||||||
|
text_types_uninitialized = require("./TextTypes");
|
||||||
|
|
||||||
|
module.exports = function(HB) {
|
||||||
|
var JsonType, createJsonTypeWrapper, parser, text_types, types;
|
||||||
|
text_types = text_types_uninitialized(HB);
|
||||||
|
types = text_types.types;
|
||||||
|
parser = text_types.parser;
|
||||||
|
createJsonTypeWrapper = function(_jsonType) {
|
||||||
|
var JsonTypeWrapper;
|
||||||
|
JsonTypeWrapper = (function() {
|
||||||
|
function JsonTypeWrapper(jsonType) {
|
||||||
|
var name, obj, _fn, _ref;
|
||||||
|
_ref = jsonType.map;
|
||||||
|
_fn = function(name, obj) {
|
||||||
|
return Object.defineProperty(JsonTypeWrapper.prototype, name, {
|
||||||
|
get: function() {
|
||||||
|
var x;
|
||||||
|
x = obj.val();
|
||||||
|
if (x instanceof JsonType) {
|
||||||
|
return createJsonTypeWrapper(x);
|
||||||
|
} else if (x instanceof types.ImmutableObject) {
|
||||||
|
return x.val();
|
||||||
|
} else {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set: function(o) {
|
||||||
|
var o_name, o_obj, overwrite, _results;
|
||||||
|
overwrite = jsonType.val(name);
|
||||||
|
if (o.constructor === {}.constructor && overwrite instanceof types.Operation) {
|
||||||
|
_results = [];
|
||||||
|
for (o_name in o) {
|
||||||
|
o_obj = o[o_name];
|
||||||
|
_results.push(overwrite.val(o_name, o_obj, 'immutable'));
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
} else {
|
||||||
|
return jsonType.val(name, o, 'immutable');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: false
|
||||||
|
});
|
||||||
|
};
|
||||||
|
for (name in _ref) {
|
||||||
|
obj = _ref[name];
|
||||||
|
_fn(name, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return JsonTypeWrapper;
|
||||||
|
|
||||||
|
})();
|
||||||
|
return new JsonTypeWrapper(_jsonType);
|
||||||
|
};
|
||||||
|
JsonType = (function(_super) {
|
||||||
|
__extends(JsonType, _super);
|
||||||
|
|
||||||
|
function JsonType() {
|
||||||
|
return JsonType.__super__.constructor.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonType.prototype.type = "JsonType";
|
||||||
|
|
||||||
|
JsonType.prototype.applyDelete = function() {
|
||||||
|
return JsonType.__super__.applyDelete.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
JsonType.prototype.cleanup = function() {
|
||||||
|
return JsonType.__super__.cleanup.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
JsonType.prototype.toJson = function() {
|
||||||
|
var json, name, o, that, val;
|
||||||
|
if ((this.bound_json == null) || (Object.observe == null) || true) {
|
||||||
|
val = this.val();
|
||||||
|
json = {};
|
||||||
|
for (name in val) {
|
||||||
|
o = val[name];
|
||||||
|
if (o == null) {
|
||||||
|
json[name] = o;
|
||||||
|
} else if (o.constructor === {}.constructor) {
|
||||||
|
json[name] = this.val(name).toJson();
|
||||||
|
} else if (o instanceof types.Operation) {
|
||||||
|
while (o instanceof types.Operation) {
|
||||||
|
o = o.val();
|
||||||
|
}
|
||||||
|
json[name] = o;
|
||||||
|
} else {
|
||||||
|
json[name] = o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.bound_json = json;
|
||||||
|
if (Object.observe != null) {
|
||||||
|
that = this;
|
||||||
|
Object.observe(this.bound_json, function(events) {
|
||||||
|
var event, _i, _len, _results;
|
||||||
|
_results = [];
|
||||||
|
for (_i = 0, _len = events.length; _i < _len; _i++) {
|
||||||
|
event = events[_i];
|
||||||
|
if ((event.changed_by == null) && (event.type === "add" || (event.type = "update"))) {
|
||||||
|
_results.push(that.val(event.name, event.object[event.name]));
|
||||||
|
} else {
|
||||||
|
_results.push(void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
});
|
||||||
|
this.observe(function(events) {
|
||||||
|
var event, notifier, oldVal, _i, _len, _results;
|
||||||
|
_results = [];
|
||||||
|
for (_i = 0, _len = events.length; _i < _len; _i++) {
|
||||||
|
event = events[_i];
|
||||||
|
if (event.created_ !== HB.getUserId()) {
|
||||||
|
notifier = Object.getNotifier(that.bound_json);
|
||||||
|
oldVal = that.bound_json[event.name];
|
||||||
|
if (oldVal != null) {
|
||||||
|
notifier.performChange('update', function() {
|
||||||
|
return that.bound_json[event.name] = that.val(event.name);
|
||||||
|
}, that.bound_json);
|
||||||
|
_results.push(notifier.notify({
|
||||||
|
object: that.bound_json,
|
||||||
|
type: 'update',
|
||||||
|
name: event.name,
|
||||||
|
oldValue: oldVal,
|
||||||
|
changed_by: event.changed_by
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
notifier.performChange('add', function() {
|
||||||
|
return that.bound_json[event.name] = that.val(event.name);
|
||||||
|
}, that.bound_json);
|
||||||
|
_results.push(notifier.notify({
|
||||||
|
object: that.bound_json,
|
||||||
|
type: 'add',
|
||||||
|
name: event.name,
|
||||||
|
oldValue: oldVal,
|
||||||
|
changed_by: event.changed_by
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_results.push(void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.bound_json;
|
||||||
|
};
|
||||||
|
|
||||||
|
JsonType.prototype.mutable_default = true;
|
||||||
|
|
||||||
|
JsonType.prototype.setMutableDefault = function(mutable) {
|
||||||
|
if (mutable === true || mutable === 'mutable') {
|
||||||
|
JsonType.prototype.mutable_default = true;
|
||||||
|
} else if (mutable === false || mutable === 'immutable') {
|
||||||
|
JsonType.prototype.mutable_default = false;
|
||||||
|
} else {
|
||||||
|
throw new Error('Set mutable either "mutable" or "immutable"!');
|
||||||
|
}
|
||||||
|
return 'OK';
|
||||||
|
};
|
||||||
|
|
||||||
|
JsonType.prototype.val = function(name, content, mutable) {
|
||||||
|
var json, n, o, word;
|
||||||
|
if ((name != null) && arguments.length > 1) {
|
||||||
|
if (mutable != null) {
|
||||||
|
if (mutable === true || mutable === 'mutable') {
|
||||||
|
mutable = true;
|
||||||
|
} else {
|
||||||
|
mutable = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mutable = this.mutable_default;
|
||||||
|
}
|
||||||
|
if (typeof content === 'function') {
|
||||||
|
return this;
|
||||||
|
} else if ((content == null) || (((!mutable) || typeof content === 'number') && content.constructor !== Object)) {
|
||||||
|
return JsonType.__super__.val.call(this, name, (new types.ImmutableObject(void 0, content)).execute());
|
||||||
|
} else {
|
||||||
|
if (typeof content === 'string') {
|
||||||
|
word = (new types.WordType(void 0)).execute();
|
||||||
|
word.insertText(0, content);
|
||||||
|
return JsonType.__super__.val.call(this, name, word);
|
||||||
|
} else if (content.constructor === Object) {
|
||||||
|
json = new JsonType().execute();
|
||||||
|
for (n in content) {
|
||||||
|
o = content[n];
|
||||||
|
json.val(n, o, mutable);
|
||||||
|
}
|
||||||
|
return JsonType.__super__.val.call(this, name, json);
|
||||||
|
} else {
|
||||||
|
throw new Error("You must not set " + (typeof content) + "-types in collaborative Json-objects!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return JsonType.__super__.val.call(this, name, content);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.defineProperty(JsonType.prototype, 'value', {
|
||||||
|
get: function() {
|
||||||
|
return createJsonTypeWrapper(this);
|
||||||
|
},
|
||||||
|
set: function(o) {
|
||||||
|
var o_name, o_obj, _results;
|
||||||
|
if (o.constructor === {}.constructor) {
|
||||||
|
_results = [];
|
||||||
|
for (o_name in o) {
|
||||||
|
o_obj = o[o_name];
|
||||||
|
_results.push(this.val(o_name, o_obj, 'immutable'));
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
} else {
|
||||||
|
throw new Error("You must only set Object values!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonType.prototype._encode = function() {
|
||||||
|
return {
|
||||||
|
'type': "JsonType",
|
||||||
|
'uid': this.getUid()
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return JsonType;
|
||||||
|
|
||||||
|
})(types.MapManager);
|
||||||
|
parser['JsonType'] = function(json) {
|
||||||
|
var uid;
|
||||||
|
uid = json['uid'];
|
||||||
|
return new JsonType(uid);
|
||||||
|
};
|
||||||
|
types['JsonType'] = JsonType;
|
||||||
|
return text_types;
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(this);
|
||||||
|
|
||||||
|
//# sourceMappingURL=../Types/JsonTypes.js.map
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,401 @@
|
|||||||
|
(function() {
|
||||||
|
var basic_types_uninitialized,
|
||||||
|
__hasProp = {}.hasOwnProperty,
|
||||||
|
__extends = 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; };
|
||||||
|
|
||||||
|
basic_types_uninitialized = require("./BasicTypes");
|
||||||
|
|
||||||
|
module.exports = function(HB) {
|
||||||
|
var AddName, ListManager, MapManager, ReplaceManager, Replaceable, basic_types, parser, types;
|
||||||
|
basic_types = basic_types_uninitialized(HB);
|
||||||
|
types = basic_types.types;
|
||||||
|
parser = basic_types.parser;
|
||||||
|
MapManager = (function(_super) {
|
||||||
|
__extends(MapManager, _super);
|
||||||
|
|
||||||
|
function MapManager(uid) {
|
||||||
|
this.map = {};
|
||||||
|
MapManager.__super__.constructor.call(this, uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
MapManager.prototype.type = "MapManager";
|
||||||
|
|
||||||
|
MapManager.prototype.applyDelete = function() {
|
||||||
|
var name, p, _ref;
|
||||||
|
_ref = this.map;
|
||||||
|
for (name in _ref) {
|
||||||
|
p = _ref[name];
|
||||||
|
p.applyDelete();
|
||||||
|
}
|
||||||
|
return MapManager.__super__.applyDelete.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
MapManager.prototype.cleanup = function() {
|
||||||
|
return MapManager.__super__.cleanup.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
MapManager.prototype.val = function(name, content) {
|
||||||
|
var o, obj, qqq, result, x, _ref, _ref1;
|
||||||
|
if (content != null) {
|
||||||
|
if (this.map[name] == null) {
|
||||||
|
(new AddName(void 0, this, name)).execute();
|
||||||
|
}
|
||||||
|
if (this.map[name] === null) {
|
||||||
|
qqq = this;
|
||||||
|
x = new AddName(void 0, this, name);
|
||||||
|
x.execute();
|
||||||
|
}
|
||||||
|
this.map[name].replace(content);
|
||||||
|
return this;
|
||||||
|
} else if (name != null) {
|
||||||
|
obj = (_ref = this.map[name]) != null ? _ref.val() : void 0;
|
||||||
|
if (obj instanceof types.ImmutableObject) {
|
||||||
|
return obj.val();
|
||||||
|
} else {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = {};
|
||||||
|
_ref1 = this.map;
|
||||||
|
for (name in _ref1) {
|
||||||
|
o = _ref1[name];
|
||||||
|
obj = o.val();
|
||||||
|
if (obj instanceof types.ImmutableObject || obj instanceof MapManager) {
|
||||||
|
obj = obj.val();
|
||||||
|
}
|
||||||
|
result[name] = obj;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return MapManager;
|
||||||
|
|
||||||
|
})(types.Operation);
|
||||||
|
AddName = (function(_super) {
|
||||||
|
__extends(AddName, _super);
|
||||||
|
|
||||||
|
function AddName(uid, map_manager, name) {
|
||||||
|
this.name = name;
|
||||||
|
this.saveOperation('map_manager', map_manager);
|
||||||
|
AddName.__super__.constructor.call(this, uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddName.prototype.type = "AddName";
|
||||||
|
|
||||||
|
AddName.prototype.applyDelete = function() {
|
||||||
|
return AddName.__super__.applyDelete.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
AddName.prototype.cleanup = function() {
|
||||||
|
return AddName.__super__.cleanup.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
AddName.prototype.execute = function() {
|
||||||
|
var beg, clone, end, event_properties, event_this, uid_beg, uid_end, uid_r, _base;
|
||||||
|
if (!this.validateSavedOperations()) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
clone = function(o) {
|
||||||
|
var name, p, value;
|
||||||
|
p = {};
|
||||||
|
for (name in o) {
|
||||||
|
value = o[name];
|
||||||
|
p[name] = value;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
};
|
||||||
|
uid_r = clone(this.map_manager.getUid());
|
||||||
|
uid_r.doSync = false;
|
||||||
|
uid_r.op_number = "_" + uid_r.op_number + "_RM_" + this.name;
|
||||||
|
if (HB.getOperation(uid_r) == null) {
|
||||||
|
uid_beg = clone(uid_r);
|
||||||
|
uid_beg.op_number = "" + uid_r.op_number + "_beginning";
|
||||||
|
uid_end = clone(uid_r);
|
||||||
|
uid_end.op_number = "" + uid_r.op_number + "_end";
|
||||||
|
beg = (new types.Delimiter(uid_beg, void 0, uid_end)).execute();
|
||||||
|
end = (new types.Delimiter(uid_end, beg, void 0)).execute();
|
||||||
|
event_properties = {
|
||||||
|
name: this.name
|
||||||
|
};
|
||||||
|
event_this = this.map_manager;
|
||||||
|
this.map_manager.map[this.name] = new ReplaceManager(event_properties, event_this, uid_r, beg, end);
|
||||||
|
this.map_manager.map[this.name].setParent(this.map_manager, this.name);
|
||||||
|
((_base = this.map_manager.map[this.name]).add_name_ops != null ? _base.add_name_ops : _base.add_name_ops = []).push(this);
|
||||||
|
this.map_manager.map[this.name].execute();
|
||||||
|
}
|
||||||
|
return AddName.__super__.execute.apply(this, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AddName.prototype._encode = function() {
|
||||||
|
return {
|
||||||
|
'type': "AddName",
|
||||||
|
'uid': this.getUid(),
|
||||||
|
'map_manager': this.map_manager.getUid(),
|
||||||
|
'name': this.name
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return AddName;
|
||||||
|
|
||||||
|
})(types.Operation);
|
||||||
|
parser['AddName'] = function(json) {
|
||||||
|
var map_manager, name, uid;
|
||||||
|
map_manager = json['map_manager'], uid = json['uid'], name = json['name'];
|
||||||
|
return new AddName(uid, map_manager, name);
|
||||||
|
};
|
||||||
|
ListManager = (function(_super) {
|
||||||
|
__extends(ListManager, _super);
|
||||||
|
|
||||||
|
function ListManager(uid, beginning, end, prev, next, origin) {
|
||||||
|
if ((beginning != null) && (end != null)) {
|
||||||
|
this.saveOperation('beginning', beginning);
|
||||||
|
this.saveOperation('end', end);
|
||||||
|
} else {
|
||||||
|
this.beginning = new types.Delimiter(void 0, void 0, void 0);
|
||||||
|
this.end = new types.Delimiter(void 0, this.beginning, void 0);
|
||||||
|
this.beginning.next_cl = this.end;
|
||||||
|
this.beginning.execute();
|
||||||
|
this.end.execute();
|
||||||
|
}
|
||||||
|
ListManager.__super__.constructor.call(this, uid, prev, next, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
ListManager.prototype.type = "ListManager";
|
||||||
|
|
||||||
|
ListManager.prototype.execute = function() {
|
||||||
|
if (this.validateSavedOperations()) {
|
||||||
|
this.beginning.setParent(this);
|
||||||
|
this.end.setParent(this);
|
||||||
|
return ListManager.__super__.execute.apply(this, arguments);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ListManager.prototype.getLastOperation = function() {
|
||||||
|
return this.end.prev_cl;
|
||||||
|
};
|
||||||
|
|
||||||
|
ListManager.prototype.getFirstOperation = function() {
|
||||||
|
return this.beginning.next_cl;
|
||||||
|
};
|
||||||
|
|
||||||
|
ListManager.prototype.toArray = function() {
|
||||||
|
var o, result;
|
||||||
|
o = this.beginning.next_cl;
|
||||||
|
result = [];
|
||||||
|
while (o !== this.end) {
|
||||||
|
result.push(o);
|
||||||
|
o = o.next_cl;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
ListManager.prototype.getOperationByPosition = function(position) {
|
||||||
|
var o;
|
||||||
|
o = this.beginning.next_cl;
|
||||||
|
if ((position > 0 || o.isDeleted()) && !(o instanceof types.Delimiter)) {
|
||||||
|
while (o.isDeleted() && !(o instanceof types.Delimiter)) {
|
||||||
|
o = o.next_cl;
|
||||||
|
}
|
||||||
|
while (true) {
|
||||||
|
if (o instanceof types.Delimiter) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (position <= 0 && !o.isDeleted()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
o = o.next_cl;
|
||||||
|
if (!o.isDeleted()) {
|
||||||
|
position -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
};
|
||||||
|
|
||||||
|
return ListManager;
|
||||||
|
|
||||||
|
})(types.Operation);
|
||||||
|
ReplaceManager = (function(_super) {
|
||||||
|
__extends(ReplaceManager, _super);
|
||||||
|
|
||||||
|
function ReplaceManager(event_porperties, event_this, uid, beginning, end, prev, next, origin) {
|
||||||
|
this.event_porperties = event_porperties;
|
||||||
|
this.event_this = event_this;
|
||||||
|
ReplaceManager.__super__.constructor.call(this, uid, beginning, end, prev, next, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReplaceManager.prototype.type = "ReplaceManager";
|
||||||
|
|
||||||
|
ReplaceManager.prototype.applyDelete = function() {
|
||||||
|
var o, _i, _len, _ref;
|
||||||
|
o = this.beginning;
|
||||||
|
while (o != null) {
|
||||||
|
o.applyDelete();
|
||||||
|
o = o.next_cl;
|
||||||
|
}
|
||||||
|
if (this.add_name_ops != null) {
|
||||||
|
_ref = this.add_name_ops;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
o = _ref[_i];
|
||||||
|
o.applyDelete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ReplaceManager.__super__.applyDelete.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
ReplaceManager.prototype.cleanup = function() {
|
||||||
|
return ReplaceManager.__super__.cleanup.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
ReplaceManager.prototype.callEventDecorator = function(events) {
|
||||||
|
var event, name, prop, _i, _len, _ref;
|
||||||
|
if (!this.isDeleted()) {
|
||||||
|
_ref = this.event_porperties;
|
||||||
|
for (name in _ref) {
|
||||||
|
prop = _ref[name];
|
||||||
|
for (_i = 0, _len = events.length; _i < _len; _i++) {
|
||||||
|
event = events[_i];
|
||||||
|
event[name] = prop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.event_this.callEvent(events);
|
||||||
|
}
|
||||||
|
return void 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
ReplaceManager.prototype.replace = function(content, replaceable_uid) {
|
||||||
|
var o;
|
||||||
|
o = this.getLastOperation();
|
||||||
|
(new Replaceable(content, this, replaceable_uid, o, o.next_cl)).execute();
|
||||||
|
return void 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
ReplaceManager.prototype.val = function() {
|
||||||
|
var o;
|
||||||
|
o = this.getLastOperation();
|
||||||
|
return typeof o.val === "function" ? o.val() : void 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
ReplaceManager.prototype._encode = function() {
|
||||||
|
var json;
|
||||||
|
json = {
|
||||||
|
'type': "ReplaceManager",
|
||||||
|
'uid': this.getUid(),
|
||||||
|
'beginning': this.beginning.getUid(),
|
||||||
|
'end': this.end.getUid()
|
||||||
|
};
|
||||||
|
if ((this.prev_cl != null) && (this.next_cl != null)) {
|
||||||
|
json['prev'] = this.prev_cl.getUid();
|
||||||
|
json['next'] = this.next_cl.getUid();
|
||||||
|
}
|
||||||
|
if (this.origin != null) {
|
||||||
|
json["origin"] = this.origin().getUid();
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
};
|
||||||
|
|
||||||
|
return ReplaceManager;
|
||||||
|
|
||||||
|
})(ListManager);
|
||||||
|
parser["ReplaceManager"] = function(json) {
|
||||||
|
var beginning, end, next, origin, prev, uid;
|
||||||
|
uid = json['uid'], prev = json['prev'], next = json['next'], origin = json['origin'], beginning = json['beginning'], end = json['end'];
|
||||||
|
return new ReplaceManager(uid, beginning, end, prev, next, origin);
|
||||||
|
};
|
||||||
|
Replaceable = (function(_super) {
|
||||||
|
__extends(Replaceable, _super);
|
||||||
|
|
||||||
|
function Replaceable(content, parent, uid, prev, next, origin) {
|
||||||
|
this.saveOperation('content', content);
|
||||||
|
this.saveOperation('parent', parent);
|
||||||
|
if (!((prev != null) && (next != null))) {
|
||||||
|
throw new Error("You must define prev, and next for Replaceable-types!");
|
||||||
|
}
|
||||||
|
Replaceable.__super__.constructor.call(this, uid, prev, next, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
Replaceable.prototype.type = "Replaceable";
|
||||||
|
|
||||||
|
Replaceable.prototype.val = function() {
|
||||||
|
return this.content;
|
||||||
|
};
|
||||||
|
|
||||||
|
Replaceable.prototype.applyDelete = function() {
|
||||||
|
if (this.content != null) {
|
||||||
|
if (this.next_cl.type !== "Delimiter") {
|
||||||
|
this.content.deleteAllObservers();
|
||||||
|
}
|
||||||
|
this.content.applyDelete();
|
||||||
|
this.content.dontSync();
|
||||||
|
}
|
||||||
|
this.content = null;
|
||||||
|
return Replaceable.__super__.applyDelete.apply(this, arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
Replaceable.prototype.cleanup = function() {
|
||||||
|
return Replaceable.__super__.cleanup.apply(this, arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
Replaceable.prototype.callOperationSpecificEvents = function() {
|
||||||
|
var old_value;
|
||||||
|
if (this.next_cl.type === "Delimiter" && this.prev_cl.type !== "Delimiter") {
|
||||||
|
old_value = this.prev_cl.content;
|
||||||
|
this.prev_cl.applyDelete();
|
||||||
|
this.parent.callEventDecorator([
|
||||||
|
{
|
||||||
|
type: "update",
|
||||||
|
changed_by: this.uid.creator,
|
||||||
|
oldValue: old_value
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
} else if (this.next_cl.type !== "Delimiter") {
|
||||||
|
this.applyDelete();
|
||||||
|
} else {
|
||||||
|
this.parent.callEventDecorator([
|
||||||
|
{
|
||||||
|
type: "add",
|
||||||
|
changed_by: this.uid.creator
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
return void 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Replaceable.prototype._encode = function() {
|
||||||
|
var json, _ref;
|
||||||
|
json = {
|
||||||
|
'type': "Replaceable",
|
||||||
|
'content': (_ref = this.content) != null ? _ref.getUid() : void 0,
|
||||||
|
'ReplaceManager': this.parent.getUid(),
|
||||||
|
'prev': this.prev_cl.getUid(),
|
||||||
|
'next': this.next_cl.getUid(),
|
||||||
|
'uid': this.getUid()
|
||||||
|
};
|
||||||
|
if ((this.origin != null) && this.origin !== this.prev_cl) {
|
||||||
|
json["origin"] = this.origin.getUid();
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
};
|
||||||
|
|
||||||
|
return Replaceable;
|
||||||
|
|
||||||
|
})(types.Insert);
|
||||||
|
parser["Replaceable"] = function(json) {
|
||||||
|
var content, next, origin, parent, prev, uid;
|
||||||
|
content = json['content'], parent = json['ReplaceManager'], uid = json['uid'], prev = json['prev'], next = json['next'], origin = json['origin'];
|
||||||
|
return new Replaceable(content, parent, uid, prev, next, origin);
|
||||||
|
};
|
||||||
|
types['ListManager'] = ListManager;
|
||||||
|
types['MapManager'] = MapManager;
|
||||||
|
types['ReplaceManager'] = ReplaceManager;
|
||||||
|
types['Replaceable'] = Replaceable;
|
||||||
|
return basic_types;
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(this);
|
||||||
|
|
||||||
|
//# sourceMappingURL=../Types/StructuredTypes.js.map
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,342 @@
|
|||||||
|
(function() {
|
||||||
|
var structured_types_uninitialized,
|
||||||
|
__hasProp = {}.hasOwnProperty,
|
||||||
|
__extends = 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; };
|
||||||
|
|
||||||
|
structured_types_uninitialized = require("./StructuredTypes");
|
||||||
|
|
||||||
|
module.exports = function(HB) {
|
||||||
|
var TextDelete, TextInsert, WordType, parser, structured_types, types;
|
||||||
|
structured_types = structured_types_uninitialized(HB);
|
||||||
|
types = structured_types.types;
|
||||||
|
parser = structured_types.parser;
|
||||||
|
TextDelete = (function(_super) {
|
||||||
|
__extends(TextDelete, _super);
|
||||||
|
|
||||||
|
function TextDelete() {
|
||||||
|
return TextDelete.__super__.constructor.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TextDelete;
|
||||||
|
|
||||||
|
})(types.Delete);
|
||||||
|
parser["TextDelete"] = parser["Delete"];
|
||||||
|
TextInsert = (function(_super) {
|
||||||
|
__extends(TextInsert, _super);
|
||||||
|
|
||||||
|
function TextInsert(content, uid, prev, next, origin) {
|
||||||
|
var _ref;
|
||||||
|
if (content != null ? (_ref = content.uid) != null ? _ref.creator : void 0 : void 0) {
|
||||||
|
this.saveOperation('content', content);
|
||||||
|
} else {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
if (!((prev != null) && (next != null))) {
|
||||||
|
throw new Error("You must define prev, and next for TextInsert-types!");
|
||||||
|
}
|
||||||
|
TextInsert.__super__.constructor.call(this, uid, prev, next, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextInsert.prototype.type = "TextInsert";
|
||||||
|
|
||||||
|
TextInsert.prototype.getLength = function() {
|
||||||
|
if (this.isDeleted()) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return this.content.length;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TextInsert.prototype.applyDelete = function() {
|
||||||
|
TextInsert.__super__.applyDelete.apply(this, arguments);
|
||||||
|
if (this.content instanceof types.Operation) {
|
||||||
|
this.content.applyDelete();
|
||||||
|
}
|
||||||
|
return this.content = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
TextInsert.prototype.execute = function() {
|
||||||
|
if (!this.validateSavedOperations()) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if (this.content instanceof types.Operation) {
|
||||||
|
this.content.insert_parent = this;
|
||||||
|
}
|
||||||
|
return TextInsert.__super__.execute.call(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TextInsert.prototype.val = function(current_position) {
|
||||||
|
if (this.isDeleted() || (this.content == null)) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return this.content;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TextInsert.prototype._encode = function() {
|
||||||
|
var json, _ref;
|
||||||
|
json = {
|
||||||
|
'type': "TextInsert",
|
||||||
|
'uid': this.getUid(),
|
||||||
|
'prev': this.prev_cl.getUid(),
|
||||||
|
'next': this.next_cl.getUid()
|
||||||
|
};
|
||||||
|
if (((_ref = this.content) != null ? _ref.getUid : void 0) != null) {
|
||||||
|
json['content'] = this.content.getUid();
|
||||||
|
} else {
|
||||||
|
json['content'] = this.content;
|
||||||
|
}
|
||||||
|
if (this.origin !== this.prev_cl) {
|
||||||
|
json["origin"] = this.origin.getUid();
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
};
|
||||||
|
|
||||||
|
return TextInsert;
|
||||||
|
|
||||||
|
})(types.Insert);
|
||||||
|
parser["TextInsert"] = function(json) {
|
||||||
|
var content, next, origin, prev, uid;
|
||||||
|
content = json['content'], uid = json['uid'], prev = json['prev'], next = json['next'], origin = json['origin'];
|
||||||
|
return new TextInsert(content, uid, prev, next, origin);
|
||||||
|
};
|
||||||
|
WordType = (function(_super) {
|
||||||
|
__extends(WordType, _super);
|
||||||
|
|
||||||
|
function WordType(uid, beginning, end, prev, next, origin) {
|
||||||
|
WordType.__super__.constructor.call(this, uid, beginning, end, prev, next, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
WordType.prototype.type = "WordType";
|
||||||
|
|
||||||
|
WordType.prototype.applyDelete = function() {
|
||||||
|
var o;
|
||||||
|
o = this.beginning;
|
||||||
|
while (o != null) {
|
||||||
|
o.applyDelete();
|
||||||
|
o = o.next_cl;
|
||||||
|
}
|
||||||
|
return WordType.__super__.applyDelete.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
WordType.prototype.cleanup = function() {
|
||||||
|
return WordType.__super__.cleanup.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
WordType.prototype.push = function(content) {
|
||||||
|
return this.insertAfter(this.end.prev_cl, content);
|
||||||
|
};
|
||||||
|
|
||||||
|
WordType.prototype.insertAfter = function(left, content) {
|
||||||
|
var c, right, tmp, _i, _len;
|
||||||
|
while (left.isDeleted()) {
|
||||||
|
left = left.prev_cl;
|
||||||
|
}
|
||||||
|
right = left.next_cl;
|
||||||
|
if (content.type != null) {
|
||||||
|
(new TextInsert(content, void 0, left, right)).execute();
|
||||||
|
} else {
|
||||||
|
for (_i = 0, _len = content.length; _i < _len; _i++) {
|
||||||
|
c = content[_i];
|
||||||
|
tmp = (new TextInsert(c, void 0, left, right)).execute();
|
||||||
|
left = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
WordType.prototype.insertText = function(position, content) {
|
||||||
|
var ith, left;
|
||||||
|
ith = this.getOperationByPosition(position);
|
||||||
|
left = ith.prev_cl;
|
||||||
|
return this.insertAfter(left, content);
|
||||||
|
};
|
||||||
|
|
||||||
|
WordType.prototype.deleteText = function(position, length) {
|
||||||
|
var d, delete_ops, i, o, _i;
|
||||||
|
o = this.getOperationByPosition(position);
|
||||||
|
delete_ops = [];
|
||||||
|
for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) {
|
||||||
|
if (o instanceof types.Delimiter) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
d = (new TextDelete(void 0, o)).execute();
|
||||||
|
o = o.next_cl;
|
||||||
|
while (!(o instanceof types.Delimiter) && o.isDeleted()) {
|
||||||
|
o = o.next_cl;
|
||||||
|
}
|
||||||
|
delete_ops.push(d._encode());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
WordType.prototype.val = function() {
|
||||||
|
var c, o;
|
||||||
|
c = (function() {
|
||||||
|
var _i, _len, _ref, _results;
|
||||||
|
_ref = this.toArray();
|
||||||
|
_results = [];
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
o = _ref[_i];
|
||||||
|
if (o.val != null) {
|
||||||
|
_results.push(o.val());
|
||||||
|
} else {
|
||||||
|
_results.push("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
}).call(this);
|
||||||
|
return c.join('');
|
||||||
|
};
|
||||||
|
|
||||||
|
WordType.prototype.toString = function() {
|
||||||
|
return this.val();
|
||||||
|
};
|
||||||
|
|
||||||
|
WordType.prototype.bind = function(textfield) {
|
||||||
|
var word;
|
||||||
|
word = this;
|
||||||
|
textfield.value = this.val();
|
||||||
|
this.on("insert", function(event, op) {
|
||||||
|
var fix, left, o_pos, right;
|
||||||
|
o_pos = op.getPosition();
|
||||||
|
fix = function(cursor) {
|
||||||
|
if (cursor <= o_pos) {
|
||||||
|
return cursor;
|
||||||
|
} else {
|
||||||
|
cursor += 1;
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
left = fix(textfield.selectionStart);
|
||||||
|
right = fix(textfield.selectionEnd);
|
||||||
|
textfield.value = word.val();
|
||||||
|
return textfield.setSelectionRange(left, right);
|
||||||
|
});
|
||||||
|
this.on("delete", function(event, op) {
|
||||||
|
var fix, left, o_pos, right;
|
||||||
|
o_pos = op.getPosition();
|
||||||
|
fix = function(cursor) {
|
||||||
|
if (cursor < o_pos) {
|
||||||
|
return cursor;
|
||||||
|
} else {
|
||||||
|
cursor -= 1;
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
left = fix(textfield.selectionStart);
|
||||||
|
right = fix(textfield.selectionEnd);
|
||||||
|
textfield.value = word.val();
|
||||||
|
return textfield.setSelectionRange(left, right);
|
||||||
|
});
|
||||||
|
textfield.onkeypress = function(event) {
|
||||||
|
var char, diff, new_pos, pos;
|
||||||
|
char = null;
|
||||||
|
if (event.key != null) {
|
||||||
|
if (event.charCode === 32) {
|
||||||
|
char = " ";
|
||||||
|
} else if (event.keyCode === 13) {
|
||||||
|
char = '\n';
|
||||||
|
} else {
|
||||||
|
char = event.key;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
char = String.fromCharCode(event.keyCode);
|
||||||
|
}
|
||||||
|
if (char.length > 0) {
|
||||||
|
pos = Math.min(textfield.selectionStart, textfield.selectionEnd);
|
||||||
|
diff = Math.abs(textfield.selectionEnd - textfield.selectionStart);
|
||||||
|
word.deleteText(pos, diff);
|
||||||
|
word.insertText(pos, char);
|
||||||
|
new_pos = pos + char.length;
|
||||||
|
textfield.setSelectionRange(new_pos, new_pos);
|
||||||
|
return event.preventDefault();
|
||||||
|
} else {
|
||||||
|
return event.preventDefault();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
textfield.onpaste = function(event) {
|
||||||
|
return event.preventDefault();
|
||||||
|
};
|
||||||
|
textfield.oncut = function(event) {
|
||||||
|
return event.preventDefault();
|
||||||
|
};
|
||||||
|
return textfield.onkeydown = function(event) {
|
||||||
|
var del_length, diff, new_pos, pos, val;
|
||||||
|
pos = Math.min(textfield.selectionStart, textfield.selectionEnd);
|
||||||
|
diff = Math.abs(textfield.selectionEnd - textfield.selectionStart);
|
||||||
|
if ((event.keyCode != null) && event.keyCode === 8) {
|
||||||
|
if (diff > 0) {
|
||||||
|
word.deleteText(pos, diff);
|
||||||
|
textfield.setSelectionRange(pos, pos);
|
||||||
|
} else {
|
||||||
|
if ((event.ctrlKey != null) && event.ctrlKey) {
|
||||||
|
val = textfield.value;
|
||||||
|
new_pos = pos;
|
||||||
|
del_length = 0;
|
||||||
|
if (pos > 0) {
|
||||||
|
new_pos--;
|
||||||
|
del_length++;
|
||||||
|
}
|
||||||
|
while (new_pos > 0 && val[new_pos] !== " " && val[new_pos] !== '\n') {
|
||||||
|
new_pos--;
|
||||||
|
del_length++;
|
||||||
|
}
|
||||||
|
word.deleteText(new_pos, pos - new_pos);
|
||||||
|
textfield.setSelectionRange(new_pos, new_pos);
|
||||||
|
} else {
|
||||||
|
word.deleteText(pos - 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return event.preventDefault();
|
||||||
|
} else if ((event.keyCode != null) && event.keyCode === 46) {
|
||||||
|
if (diff > 0) {
|
||||||
|
word.deleteText(pos, diff);
|
||||||
|
textfield.setSelectionRange(pos, pos);
|
||||||
|
} else {
|
||||||
|
word.deleteText(pos, 1);
|
||||||
|
textfield.setSelectionRange(pos, pos);
|
||||||
|
}
|
||||||
|
return event.preventDefault();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
WordType.prototype._encode = function() {
|
||||||
|
var json;
|
||||||
|
json = {
|
||||||
|
'type': "WordType",
|
||||||
|
'uid': this.getUid(),
|
||||||
|
'beginning': this.beginning.getUid(),
|
||||||
|
'end': this.end.getUid()
|
||||||
|
};
|
||||||
|
if (this.prev_cl != null) {
|
||||||
|
json['prev'] = this.prev_cl.getUid();
|
||||||
|
}
|
||||||
|
if (this.next_cl != null) {
|
||||||
|
json['next'] = this.next_cl.getUid();
|
||||||
|
}
|
||||||
|
if (this.origin != null) {
|
||||||
|
json["origin"] = this.origin().getUid();
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
};
|
||||||
|
|
||||||
|
return WordType;
|
||||||
|
|
||||||
|
})(types.ListManager);
|
||||||
|
parser['WordType'] = function(json) {
|
||||||
|
var beginning, end, next, origin, prev, uid;
|
||||||
|
uid = json['uid'], beginning = json['beginning'], end = json['end'], prev = json['prev'], next = json['next'], origin = json['origin'];
|
||||||
|
return new WordType(uid, beginning, end, prev, next, origin);
|
||||||
|
};
|
||||||
|
types['TextInsert'] = TextInsert;
|
||||||
|
types['TextDelete'] = TextDelete;
|
||||||
|
types['WordType'] = WordType;
|
||||||
|
return structured_types;
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(this);
|
||||||
|
|
||||||
|
//# sourceMappingURL=../Types/TextTypes.js.map
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,409 @@
|
|||||||
|
(function() {
|
||||||
|
var dont_proxy, json_types_uninitialized, proxy_token, _proxy,
|
||||||
|
__hasProp = {}.hasOwnProperty,
|
||||||
|
__extends = 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; };
|
||||||
|
|
||||||
|
json_types_uninitialized = require("./JsonTypes");
|
||||||
|
|
||||||
|
proxy_token = false;
|
||||||
|
|
||||||
|
dont_proxy = function(f) {
|
||||||
|
var e;
|
||||||
|
proxy_token = true;
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
} catch (_error) {
|
||||||
|
e = _error;
|
||||||
|
proxy_token = false;
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
return proxy_token = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
_proxy = function(f_name, f) {
|
||||||
|
var old_f;
|
||||||
|
old_f = this[f_name];
|
||||||
|
if (old_f != null) {
|
||||||
|
return this[f_name] = function() {
|
||||||
|
var args, that, _ref;
|
||||||
|
if (!proxy_token && !((_ref = this._yatta) != null ? _ref.isDeleted() : void 0)) {
|
||||||
|
that = this;
|
||||||
|
args = arguments;
|
||||||
|
return dont_proxy(function() {
|
||||||
|
f.apply(that, args);
|
||||||
|
return old_f.apply(that, args);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return old_f.apply(this, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (typeof Element !== "undefined" && Element !== null) {
|
||||||
|
Element.prototype._proxy = _proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function(HB) {
|
||||||
|
var TextNodeType, XmlType, json_types, parser, types;
|
||||||
|
json_types = json_types_uninitialized(HB);
|
||||||
|
types = json_types.types;
|
||||||
|
parser = json_types.parser;
|
||||||
|
XmlType = (function(_super) {
|
||||||
|
__extends(XmlType, _super);
|
||||||
|
|
||||||
|
function XmlType(uid, tagname, attributes, elements, xml) {
|
||||||
|
var attr, d, element, i, n, word, _i, _j, _len, _ref, _ref1, _ref2;
|
||||||
|
this.tagname = tagname;
|
||||||
|
this.xml = xml;
|
||||||
|
|
||||||
|
/* In case you make this instanceof Insert again
|
||||||
|
if prev? and (not next?) and prev.type?
|
||||||
|
* adjust what you actually mean. you want to insert after prev, then
|
||||||
|
* next is not defined. but we only insert after non-deleted elements.
|
||||||
|
* This is also handled in TextInsert.
|
||||||
|
while prev.isDeleted()
|
||||||
|
prev = prev.prev_cl
|
||||||
|
next = prev.next_cl
|
||||||
|
*/
|
||||||
|
XmlType.__super__.constructor.call(this, uid);
|
||||||
|
if (((_ref = this.xml) != null ? _ref._yatta : void 0) != null) {
|
||||||
|
d = new types.Delete(void 0, this.xml._yatta);
|
||||||
|
HB.addOperation(d).execute();
|
||||||
|
this.xml._yatta = null;
|
||||||
|
}
|
||||||
|
if ((attributes != null) && (elements != null)) {
|
||||||
|
this.saveOperation('attributes', attributes);
|
||||||
|
this.saveOperation('elements', elements);
|
||||||
|
} else if ((attributes == null) && (elements == null)) {
|
||||||
|
this.attributes = new types.JsonType();
|
||||||
|
this.attributes.setMutableDefault('immutable');
|
||||||
|
HB.addOperation(this.attributes).execute();
|
||||||
|
this.elements = new types.WordType();
|
||||||
|
this.elements.parent = this;
|
||||||
|
HB.addOperation(this.elements).execute();
|
||||||
|
} else {
|
||||||
|
throw new Error("Either define attribute and elements both, or none of them");
|
||||||
|
}
|
||||||
|
if (this.xml != null) {
|
||||||
|
this.tagname = this.xml.tagName;
|
||||||
|
for (i = _i = 0, _ref1 = this.xml.attributes.length; 0 <= _ref1 ? _i < _ref1 : _i > _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
|
||||||
|
attr = xml.attributes[i];
|
||||||
|
this.attributes.val(attr.name, attr.value);
|
||||||
|
}
|
||||||
|
_ref2 = this.xml.childNodes;
|
||||||
|
for (_j = 0, _len = _ref2.length; _j < _len; _j++) {
|
||||||
|
n = _ref2[_j];
|
||||||
|
if (n.nodeType === n.TEXT_NODE) {
|
||||||
|
word = new TextNodeType(void 0, n);
|
||||||
|
HB.addOperation(word).execute();
|
||||||
|
this.elements.push(word);
|
||||||
|
} else if (n.nodeType === n.ELEMENT_NODE) {
|
||||||
|
element = new XmlType(void 0, void 0, void 0, void 0, n);
|
||||||
|
HB.addOperation(element).execute();
|
||||||
|
this.elements.push(element);
|
||||||
|
} else {
|
||||||
|
throw new Error("I don't know Node-type " + n.nodeType + "!!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.setXmlProxy();
|
||||||
|
}
|
||||||
|
void 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlType.prototype.type = "XmlType";
|
||||||
|
|
||||||
|
XmlType.prototype.applyDelete = function(op) {
|
||||||
|
if ((this.insert_parent != null) && !this.insert_parent.isDeleted()) {
|
||||||
|
return this.insert_parent.applyDelete(op);
|
||||||
|
} else {
|
||||||
|
this.attributes.applyDelete();
|
||||||
|
this.elements.applyDelete();
|
||||||
|
return XmlType.__super__.applyDelete.apply(this, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
XmlType.prototype.cleanup = function() {
|
||||||
|
return XmlType.__super__.cleanup.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
XmlType.prototype.setXmlProxy = function() {
|
||||||
|
var findNode, insertBefore, removeChild, renewClassList, that;
|
||||||
|
this.xml._yatta = this;
|
||||||
|
that = this;
|
||||||
|
this.elements.on('insert', function(event, op) {
|
||||||
|
var newNode, right, rightNode;
|
||||||
|
if (op.creator !== HB.getUserId() && this === that.elements) {
|
||||||
|
newNode = op.content.val();
|
||||||
|
right = op.next_cl;
|
||||||
|
while ((right != null) && right.isDeleted()) {
|
||||||
|
right = right.next_cl;
|
||||||
|
}
|
||||||
|
rightNode = null;
|
||||||
|
if (right.type !== 'Delimiter') {
|
||||||
|
rightNode = right.val().val();
|
||||||
|
}
|
||||||
|
return dont_proxy(function() {
|
||||||
|
return that.xml.insertBefore(newNode, rightNode);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.elements.on('delete', function(event, op) {
|
||||||
|
var del_op, deleted;
|
||||||
|
del_op = op.deleted_by[0];
|
||||||
|
if ((del_op != null) && del_op.creator !== HB.getUserId() && this === that.elements) {
|
||||||
|
deleted = op.content.val();
|
||||||
|
return dont_proxy(function() {
|
||||||
|
return that.xml.removeChild(deleted);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.attributes.on(['add', 'update'], function(event, property_name, op) {
|
||||||
|
if (op.creator !== HB.getUserId() && this === that.attributes) {
|
||||||
|
return dont_proxy(function() {
|
||||||
|
var newval;
|
||||||
|
newval = op.val().val();
|
||||||
|
if (newval != null) {
|
||||||
|
return that.xml.setAttribute(property_name, op.val().val());
|
||||||
|
} else {
|
||||||
|
return that.xml.removeAttribute(property_name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
findNode = function(child) {
|
||||||
|
var elem;
|
||||||
|
if (child == null) {
|
||||||
|
throw new Error("you must specify a parameter!");
|
||||||
|
}
|
||||||
|
child = child._yatta;
|
||||||
|
elem = that.elements.beginning.next_cl;
|
||||||
|
while (elem.type !== 'Delimiter' && elem.content !== child) {
|
||||||
|
elem = elem.next_cl;
|
||||||
|
}
|
||||||
|
if (elem.type === 'Delimiter') {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
insertBefore = function(insertedNode_s, adjacentNode) {
|
||||||
|
var child, element, inserted_nodes, next, prev, _results;
|
||||||
|
next = null;
|
||||||
|
if (adjacentNode != null) {
|
||||||
|
next = findNode(adjacentNode);
|
||||||
|
}
|
||||||
|
prev = null;
|
||||||
|
if (next) {
|
||||||
|
prev = next.prev_cl;
|
||||||
|
} else {
|
||||||
|
prev = this._yatta.elements.end.prev_cl;
|
||||||
|
while (prev.isDeleted()) {
|
||||||
|
prev = prev.prev_cl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inserted_nodes = null;
|
||||||
|
if (insertedNode_s.nodeType === insertedNode_s.DOCUMENT_FRAGMENT_NODE) {
|
||||||
|
child = insertedNode_s.lastChild;
|
||||||
|
_results = [];
|
||||||
|
while (child != null) {
|
||||||
|
element = new XmlType(void 0, void 0, void 0, void 0, child);
|
||||||
|
HB.addOperation(element).execute();
|
||||||
|
that.elements.insertAfter(prev, element);
|
||||||
|
_results.push(child = child.previousSibling);
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
} else {
|
||||||
|
element = new XmlType(void 0, void 0, void 0, void 0, insertedNode_s);
|
||||||
|
HB.addOperation(element).execute();
|
||||||
|
return that.elements.insertAfter(prev, element);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.xml._proxy('insertBefore', insertBefore);
|
||||||
|
this.xml._proxy('appendChild', insertBefore);
|
||||||
|
this.xml._proxy('removeAttribute', function(name) {
|
||||||
|
return that.attributes.val(name, void 0);
|
||||||
|
});
|
||||||
|
this.xml._proxy('setAttribute', function(name, value) {
|
||||||
|
return that.attributes.val(name, value);
|
||||||
|
});
|
||||||
|
renewClassList = function(newclass) {
|
||||||
|
var dont_do_it, elem, value, _i, _len;
|
||||||
|
dont_do_it = false;
|
||||||
|
if (newclass != null) {
|
||||||
|
for (_i = 0, _len = this.length; _i < _len; _i++) {
|
||||||
|
elem = this[_i];
|
||||||
|
if (newclass === elem) {
|
||||||
|
dont_do_it = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value = Array.prototype.join.call(this, " ");
|
||||||
|
if ((newclass != null) && !dont_do_it) {
|
||||||
|
value += " " + newclass;
|
||||||
|
}
|
||||||
|
return that.attributes.val('class', value);
|
||||||
|
};
|
||||||
|
_proxy.call(this.xml.classList, 'add', renewClassList);
|
||||||
|
_proxy.call(this.xml.classList, 'remove', renewClassList);
|
||||||
|
this.xml.__defineSetter__('className', function(val) {
|
||||||
|
return this.setAttribute('class', val);
|
||||||
|
});
|
||||||
|
this.xml.__defineGetter__('className', function() {
|
||||||
|
return that.attributes.val('class');
|
||||||
|
});
|
||||||
|
this.xml.__defineSetter__('textContent', function(val) {
|
||||||
|
var elem, remove, text_node;
|
||||||
|
elem = that.xml.firstChild;
|
||||||
|
while (elem != null) {
|
||||||
|
remove = elem;
|
||||||
|
elem = elem.nextSibling;
|
||||||
|
that.xml.removeChild(remove);
|
||||||
|
}
|
||||||
|
if (val !== "") {
|
||||||
|
text_node = document.createTextNode(val);
|
||||||
|
return that.xml.appendChild(text_node);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
removeChild = function(node) {
|
||||||
|
var d, elem;
|
||||||
|
elem = findNode(node);
|
||||||
|
if (!elem) {
|
||||||
|
throw new Error("You are only allowed to delete existing (direct) child elements!");
|
||||||
|
}
|
||||||
|
d = new types.Delete(void 0, elem);
|
||||||
|
HB.addOperation(d).execute();
|
||||||
|
return node._yatta = null;
|
||||||
|
};
|
||||||
|
this.xml._proxy('removeChild', removeChild);
|
||||||
|
return this.xml._proxy('replaceChild', function(insertedNode, replacedNode) {
|
||||||
|
insertBefore.call(this, insertedNode, replacedNode);
|
||||||
|
return removeChild.call(this, replacedNode);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
XmlType.prototype.val = function(enforce) {
|
||||||
|
var a, attr, attr_name, e, n, text_node, value;
|
||||||
|
if (enforce == null) {
|
||||||
|
enforce = false;
|
||||||
|
}
|
||||||
|
if (typeof document !== "undefined" && document !== null) {
|
||||||
|
if ((this.xml == null) || enforce) {
|
||||||
|
this.xml = document.createElement(this.tagname);
|
||||||
|
attr = this.attributes.val();
|
||||||
|
for (attr_name in attr) {
|
||||||
|
value = attr[attr_name];
|
||||||
|
if (value != null) {
|
||||||
|
a = document.createAttribute(attr_name);
|
||||||
|
a.value = value;
|
||||||
|
this.xml.setAttributeNode(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e = this.elements.beginning.next_cl;
|
||||||
|
while (e.type !== "Delimiter") {
|
||||||
|
n = e.content;
|
||||||
|
if (!e.isDeleted() && (e.content != null)) {
|
||||||
|
if (n.type === "XmlType") {
|
||||||
|
this.xml.appendChild(n.val(enforce));
|
||||||
|
} else if (n.type === "TextNodeType") {
|
||||||
|
text_node = n.val();
|
||||||
|
this.xml.appendChild(text_node);
|
||||||
|
} else {
|
||||||
|
throw new Error("Internal structure cannot be transformed to dom");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e = e.next_cl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.setXmlProxy();
|
||||||
|
return this.xml;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
XmlType.prototype.execute = function() {
|
||||||
|
return XmlType.__super__.execute.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
if not @validateSavedOperations()
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
|
||||||
|
return true
|
||||||
|
*/
|
||||||
|
|
||||||
|
XmlType.prototype.getParent = function() {
|
||||||
|
return this.parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
XmlType.prototype._encode = function() {
|
||||||
|
var json;
|
||||||
|
json = {
|
||||||
|
'type': this.type,
|
||||||
|
'attributes': this.attributes.getUid(),
|
||||||
|
'elements': this.elements.getUid(),
|
||||||
|
'tagname': this.tagname,
|
||||||
|
'uid': this.getUid()
|
||||||
|
};
|
||||||
|
return json;
|
||||||
|
};
|
||||||
|
|
||||||
|
return XmlType;
|
||||||
|
|
||||||
|
})(types.Insert);
|
||||||
|
parser['XmlType'] = function(json) {
|
||||||
|
var attributes, elements, tagname, uid;
|
||||||
|
uid = json['uid'], attributes = json['attributes'], elements = json['elements'], tagname = json['tagname'];
|
||||||
|
return new XmlType(uid, tagname, attributes, elements, void 0);
|
||||||
|
};
|
||||||
|
TextNodeType = (function(_super) {
|
||||||
|
__extends(TextNodeType, _super);
|
||||||
|
|
||||||
|
function TextNodeType(uid, content) {
|
||||||
|
var d;
|
||||||
|
if (content._yatta != null) {
|
||||||
|
d = new types.Delete(void 0, content._yatta);
|
||||||
|
HB.addOperation(d).execute();
|
||||||
|
content._yatta = null;
|
||||||
|
}
|
||||||
|
content._yatta = this;
|
||||||
|
TextNodeType.__super__.constructor.call(this, uid, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextNodeType.prototype.applyDelete = function(op) {
|
||||||
|
if ((this.insert_parent != null) && !this.insert_parent.isDeleted()) {
|
||||||
|
return this.insert_parent.applyDelete(op);
|
||||||
|
} else {
|
||||||
|
return TextNodeType.__super__.applyDelete.apply(this, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TextNodeType.prototype.type = "TextNodeType";
|
||||||
|
|
||||||
|
TextNodeType.prototype._encode = function() {
|
||||||
|
var json;
|
||||||
|
json = {
|
||||||
|
'type': this.type,
|
||||||
|
'uid': this.getUid(),
|
||||||
|
'content': this.content.textContent
|
||||||
|
};
|
||||||
|
return json;
|
||||||
|
};
|
||||||
|
|
||||||
|
return TextNodeType;
|
||||||
|
|
||||||
|
})(types.ImmutableObject);
|
||||||
|
parser['TextNodeType'] = function(json) {
|
||||||
|
var content, textnode, uid;
|
||||||
|
uid = json['uid'], content = json['content'];
|
||||||
|
textnode = document.createTextNode(content);
|
||||||
|
return new TextNodeType(uid, textnode);
|
||||||
|
};
|
||||||
|
types['XmlType'] = XmlType;
|
||||||
|
return json_types;
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(this);
|
||||||
|
|
||||||
|
//# sourceMappingURL=../Types/XmlTypes.js.map
|
||||||
File diff suppressed because one or more lines are too long
+27
-79
@@ -1,5 +1,7 @@
|
|||||||
(function() {
|
(function() {
|
||||||
var Engine, HistoryBuffer, Yatta, adaptConnector, json_types_uninitialized;
|
var Engine, HistoryBuffer, adaptConnector, createYatta, json_types_uninitialized,
|
||||||
|
__hasProp = {}.hasOwnProperty,
|
||||||
|
__extends = 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; };
|
||||||
|
|
||||||
json_types_uninitialized = require("./Types/JsonTypes");
|
json_types_uninitialized = require("./Types/JsonTypes");
|
||||||
|
|
||||||
@@ -9,89 +11,35 @@
|
|||||||
|
|
||||||
adaptConnector = require("./ConnectorAdapter");
|
adaptConnector = require("./ConnectorAdapter");
|
||||||
|
|
||||||
Yatta = (function() {
|
createYatta = function(connector) {
|
||||||
function Yatta(connector) {
|
var HB, Yatta, type_manager, types, user_id;
|
||||||
var beg, end, first_word, type_manager, uid_beg, uid_end, user_id;
|
user_id = connector.id;
|
||||||
this.connector = connector;
|
HB = new HistoryBuffer(user_id);
|
||||||
user_id = this.connector.id;
|
type_manager = json_types_uninitialized(HB);
|
||||||
this.HB = new HistoryBuffer(user_id);
|
types = type_manager.types;
|
||||||
type_manager = json_types_uninitialized(this.HB);
|
Yatta = (function(_super) {
|
||||||
this.types = type_manager.types;
|
__extends(Yatta, _super);
|
||||||
this.engine = new Engine(this.HB, type_manager.parser);
|
|
||||||
this.HB.engine = this.engine;
|
|
||||||
adaptConnector(this.connector, this.engine, this.HB, type_manager.execution_listener);
|
|
||||||
first_word = new this.types.JsonType(this.HB.getReservedUniqueIdentifier()).execute();
|
|
||||||
uid_beg = this.HB.getReservedUniqueIdentifier();
|
|
||||||
uid_end = this.HB.getReservedUniqueIdentifier();
|
|
||||||
beg = (new this.types.Delimiter(uid_beg, void 0, uid_end)).execute();
|
|
||||||
end = (new this.types.Delimiter(uid_end, beg, void 0)).execute();
|
|
||||||
this.root_element = (new this.types.ReplaceManager(void 0, this.HB.getReservedUniqueIdentifier(), beg, end)).execute();
|
|
||||||
this.root_element.replace(first_word, this.HB.getReservedUniqueIdentifier());
|
|
||||||
}
|
|
||||||
|
|
||||||
Yatta.prototype.getSharedObject = function() {
|
function Yatta() {
|
||||||
return this.root_element.val();
|
this.connector = connector;
|
||||||
};
|
this.HB = HB;
|
||||||
|
this.types = types;
|
||||||
Yatta.prototype.getConnector = function() {
|
this.engine = new Engine(this.HB, type_manager.parser);
|
||||||
return this.connector;
|
adaptConnector(this.connector, this.engine, this.HB, type_manager.execution_listener);
|
||||||
};
|
Yatta.__super__.constructor.apply(this, arguments);
|
||||||
|
|
||||||
Yatta.prototype.getHistoryBuffer = function() {
|
|
||||||
return this.HB;
|
|
||||||
};
|
|
||||||
|
|
||||||
Yatta.prototype.setMutableDefault = function(mutable) {
|
|
||||||
return this.getSharedObject().setMutableDefault(mutable);
|
|
||||||
};
|
|
||||||
|
|
||||||
Yatta.prototype.getUserId = function() {
|
|
||||||
return this.HB.getUserId();
|
|
||||||
};
|
|
||||||
|
|
||||||
Yatta.prototype.toJson = function() {
|
|
||||||
return this.getSharedObject().toJson();
|
|
||||||
};
|
|
||||||
|
|
||||||
Yatta.prototype.val = function() {
|
|
||||||
var _ref;
|
|
||||||
return (_ref = this.getSharedObject()).val.apply(_ref, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
Yatta.prototype.on = function() {
|
|
||||||
var _ref;
|
|
||||||
return (_ref = this.getSharedObject()).on.apply(_ref, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
Yatta.prototype.deleteListener = function() {
|
|
||||||
var _ref;
|
|
||||||
return (_ref = this.getSharedObject()).deleteListener.apply(_ref, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.defineProperty(Yatta.prototype, 'value', {
|
|
||||||
get: function() {
|
|
||||||
return this.getSharedObject().value;
|
|
||||||
},
|
|
||||||
set: function(o) {
|
|
||||||
var o_name, o_obj, _results;
|
|
||||||
if (o.constructor === {}.constructor) {
|
|
||||||
_results = [];
|
|
||||||
for (o_name in o) {
|
|
||||||
o_obj = o[o_name];
|
|
||||||
_results.push(this.val(o_name, o_obj, 'immutable'));
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
} else {
|
|
||||||
throw new Error("You must only set Object values!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
return Yatta;
|
Yatta.prototype.getConnector = function() {
|
||||||
|
return this.connector;
|
||||||
|
};
|
||||||
|
|
||||||
})();
|
return Yatta;
|
||||||
|
|
||||||
module.exports = Yatta;
|
})(types.JsonType);
|
||||||
|
return new Yatta(HB.getReservedUniqueIdentifier()).execute();
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = createYatta;
|
||||||
|
|
||||||
if ((typeof window !== "undefined" && window !== null) && (window.Yatta == null)) {
|
if ((typeof window !== "undefined" && window !== null) && (window.Yatta == null)) {
|
||||||
window.Yatta = Yatta;
|
window.Yatta = Yatta;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
+208
-334
File diff suppressed because one or more lines are too long
+463
-1106
File diff suppressed because one or more lines are too long
@@ -13,12 +13,13 @@
|
|||||||
mocha.ui('bdd');
|
mocha.ui('bdd');
|
||||||
mocha.reporter('html');
|
mocha.reporter('html');
|
||||||
</script>
|
</script>
|
||||||
<!--script src="TextYatta_test.js"></script-->
|
<script src="TextYatta_test.js"></script>
|
||||||
<script src="JsonYatta_test.js"></script>
|
<script src="JsonYatta_test.js"></script>
|
||||||
<!--script src="XmlYatta_test_browser.js"></script-->
|
<!--script src="XmlYatta_test_browser.js"></script-->
|
||||||
<script>
|
<script>
|
||||||
//mocha.checkLeaks();
|
//mocha.checkLeaks();
|
||||||
//mocha.run();
|
//mocha.run();
|
||||||
|
window.onerror = null;
|
||||||
if (window.mochaPhantomJS) { mochaPhantomJS.run(); }
|
if (window.mochaPhantomJS) { mochaPhantomJS.run(); }
|
||||||
else { mocha.run(); }
|
else { mocha.run(); }
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -178,7 +178,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
December 17, 14 22:46:39 by
|
December 22, 14 14:36:45 by
|
||||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||||
Codo
|
Codo
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -359,7 +359,7 @@ E.g.: let x = {a:[]}. Then x.a.push 1 wouldn't change anything</p>
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
December 17, 14 22:46:39 by
|
December 22, 14 14:36:45 by
|
||||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||||
Codo
|
Codo
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ console.log(w.newProperty == "Awesome") # true!</code></pre>
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
December 17, 14 22:46:39 by
|
December 22, 14 14:36:45 by
|
||||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||||
Codo
|
Codo
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ yatta.bind(textbox);</code></pre>
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
December 17, 14 22:46:39 by
|
December 22, 14 14:36:45 by
|
||||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||||
Codo
|
Codo
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
+9
-229
@@ -32,6 +32,12 @@
|
|||||||
<td>Defined in:</td>
|
<td>Defined in:</td>
|
||||||
<td>lib/Yatta.coffee</td>
|
<td>lib/Yatta.coffee</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Inherits:</td>
|
||||||
|
<td>
|
||||||
|
types.JsonType
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<h2>Overview</h2>
|
<h2>Overview</h2>
|
||||||
<div class='docstring'>
|
<div class='docstring'>
|
||||||
@@ -47,17 +53,6 @@ Known values that are supported:</p><ul>
|
|||||||
</div>
|
</div>
|
||||||
<h2>Instance Method Summary</h2>
|
<h2>Instance Method Summary</h2>
|
||||||
<ul class='summary'>
|
<ul class='summary'>
|
||||||
<li>
|
|
||||||
<span class='signature'>
|
|
||||||
<a href='#getSharedObject-dynamic'>
|
|
||||||
#
|
|
||||||
(?)
|
|
||||||
<b>getSharedObject</b><span>()</span>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<span class='desc'>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<span class='signature'>
|
<span class='signature'>
|
||||||
<a href='#getConnector-dynamic'>
|
<a href='#getConnector-dynamic'>
|
||||||
@@ -66,85 +61,6 @@ Known values that are supported:</p><ul>
|
|||||||
<b>getConnector</b><span>()</span>
|
<b>getConnector</b><span>()</span>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<span class='desc'>
|
|
||||||
Get the initialized connector.
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class='signature'>
|
|
||||||
<a href='#getHistoryBuffer-dynamic'>
|
|
||||||
#
|
|
||||||
(void)
|
|
||||||
<b>getHistoryBuffer</b><span>()</span>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<span class='desc'>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class='signature'>
|
|
||||||
<a href='#setMutableDefault-dynamic'>
|
|
||||||
#
|
|
||||||
(void)
|
|
||||||
<b>setMutableDefault</b><span>(mutable)</span>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<span class='desc'>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class='signature'>
|
|
||||||
<a href='#getUserId-dynamic'>
|
|
||||||
#
|
|
||||||
(void)
|
|
||||||
<b>getUserId</b><span>()</span>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<span class='desc'>
|
|
||||||
Get the UserId from the HistoryBuffer object.
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class='signature'>
|
|
||||||
<a href='#toJson-dynamic'>
|
|
||||||
#
|
|
||||||
(void)
|
|
||||||
<b>toJson</b><span>()</span>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<span class='desc'>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class='signature'>
|
|
||||||
<a href='#val-dynamic'>
|
|
||||||
#
|
|
||||||
(void)
|
|
||||||
<b>val</b><span>()</span>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<span class='desc'>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class='signature'>
|
|
||||||
<a href='#observe-dynamic'>
|
|
||||||
#
|
|
||||||
(void)
|
|
||||||
<b>observe</b><span>()</span>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<span class='desc'>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class='signature'>
|
|
||||||
<a href='#unobserve-dynamic'>
|
|
||||||
#
|
|
||||||
(void)
|
|
||||||
<b>unobserve</b><span>()</span>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
<span class='desc'>
|
<span class='desc'>
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
@@ -155,7 +71,7 @@ Known values that are supported:</p><ul>
|
|||||||
<p class='signature' id='constructor-dynamic'>
|
<p class='signature' id='constructor-dynamic'>
|
||||||
#
|
#
|
||||||
(void)
|
(void)
|
||||||
<b>constructor</b><span>(connector)</span>
|
<b>constructor</b><span>()</span>
|
||||||
<br>
|
<br>
|
||||||
</p>
|
</p>
|
||||||
<div class='tags'>
|
<div class='tags'>
|
||||||
@@ -187,27 +103,6 @@ Known values that are supported:</p><ul>
|
|||||||
</div>
|
</div>
|
||||||
<h2>Instance Method Details</h2>
|
<h2>Instance Method Details</h2>
|
||||||
<div class='methods'>
|
<div class='methods'>
|
||||||
<div class='method_details'>
|
|
||||||
<p class='signature' id='getSharedObject-dynamic'>
|
|
||||||
#
|
|
||||||
(?)
|
|
||||||
<b>getSharedObject</b><span>()</span>
|
|
||||||
<br>
|
|
||||||
</p>
|
|
||||||
<div class='tags'>
|
|
||||||
<h3>Returns:</h3>
|
|
||||||
<ul class='return'>
|
|
||||||
<li>
|
|
||||||
<span class='type'></span>
|
|
||||||
(
|
|
||||||
<tt>?</tt>
|
|
||||||
)
|
|
||||||
—
|
|
||||||
<span class='desc'>JsonType </span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class='method_details'>
|
<div class='method_details'>
|
||||||
<p class='signature' id='getConnector-dynamic'>
|
<p class='signature' id='getConnector-dynamic'>
|
||||||
#
|
#
|
||||||
@@ -215,127 +110,12 @@ Known values that are supported:</p><ul>
|
|||||||
<b>getConnector</b><span>()</span>
|
<b>getConnector</b><span>()</span>
|
||||||
<br>
|
<br>
|
||||||
</p>
|
</p>
|
||||||
<div class='docstring'>
|
|
||||||
<p>Get the initialized connector.</p>
|
|
||||||
</div>
|
|
||||||
<div class='tags'>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class='method_details'>
|
|
||||||
<p class='signature' id='getHistoryBuffer-dynamic'>
|
|
||||||
#
|
|
||||||
(void)
|
|
||||||
<b>getHistoryBuffer</b><span>()</span>
|
|
||||||
<br>
|
|
||||||
</p>
|
|
||||||
<div class='tags'>
|
|
||||||
<h3>See also:</h3>
|
|
||||||
<ul class='see'>
|
|
||||||
<li>
|
|
||||||
<a href='HistoryBuffer'>HistoryBuffer</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class='method_details'>
|
|
||||||
<p class='signature' id='setMutableDefault-dynamic'>
|
|
||||||
#
|
|
||||||
(void)
|
|
||||||
<b>setMutableDefault</b><span>(mutable)</span>
|
|
||||||
<br>
|
|
||||||
</p>
|
|
||||||
<div class='tags'>
|
|
||||||
<h3>See also:</h3>
|
|
||||||
<ul class='see'>
|
|
||||||
<li>
|
|
||||||
<a href='JsonType.setMutableDefault'>JsonType.setMutableDefault</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class='method_details'>
|
|
||||||
<p class='signature' id='getUserId-dynamic'>
|
|
||||||
#
|
|
||||||
(void)
|
|
||||||
<b>getUserId</b><span>()</span>
|
|
||||||
<br>
|
|
||||||
</p>
|
|
||||||
<div class='docstring'>
|
|
||||||
<p>Get the UserId from the HistoryBuffer object.
|
|
||||||
In most cases this will be the same as the user_id value with which
|
|
||||||
Yatta was initialized (Depending on the HistoryBuffer implementation).</p>
|
|
||||||
</div>
|
|
||||||
<div class='tags'>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class='method_details'>
|
|
||||||
<p class='signature' id='toJson-dynamic'>
|
|
||||||
#
|
|
||||||
(void)
|
|
||||||
<b>toJson</b><span>()</span>
|
|
||||||
<br>
|
|
||||||
</p>
|
|
||||||
<div class='tags'>
|
|
||||||
<h3>See also:</h3>
|
|
||||||
<ul class='see'>
|
|
||||||
<li>
|
|
||||||
<a href='JsonType.toJson'>JsonType.toJson</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class='method_details'>
|
|
||||||
<p class='signature' id='val-dynamic'>
|
|
||||||
#
|
|
||||||
(void)
|
|
||||||
<b>val</b><span>()</span>
|
|
||||||
<br>
|
|
||||||
</p>
|
|
||||||
<div class='tags'>
|
|
||||||
<h3>See also:</h3>
|
|
||||||
<ul class='see'>
|
|
||||||
<li>
|
|
||||||
<a href='JsonType.val'>JsonType.val</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class='method_details'>
|
|
||||||
<p class='signature' id='observe-dynamic'>
|
|
||||||
#
|
|
||||||
(void)
|
|
||||||
<b>observe</b><span>()</span>
|
|
||||||
<br>
|
|
||||||
</p>
|
|
||||||
<div class='tags'>
|
|
||||||
<h3>See also:</h3>
|
|
||||||
<ul class='see'>
|
|
||||||
<li>
|
|
||||||
<a href='Operation.on'>Operation.on</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class='method_details'>
|
|
||||||
<p class='signature' id='unobserve-dynamic'>
|
|
||||||
#
|
|
||||||
(void)
|
|
||||||
<b>unobserve</b><span>()</span>
|
|
||||||
<br>
|
|
||||||
</p>
|
|
||||||
<div class='tags'>
|
|
||||||
<h3>See also:</h3>
|
|
||||||
<ul class='see'>
|
|
||||||
<li>
|
|
||||||
<a href='Operation.deleteListener'>Operation.deleteListener</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
December 17, 14 22:46:39 by
|
December 22, 14 14:36:45 by
|
||||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||||
Codo
|
Codo
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -65,6 +65,10 @@
|
|||||||
<a href='class/Yatta.html' target='main'>
|
<a href='class/Yatta.html' target='main'>
|
||||||
Yatta
|
Yatta
|
||||||
</a>
|
</a>
|
||||||
|
<small class='parent'>
|
||||||
|
<
|
||||||
|
types.JsonType
|
||||||
|
</small>
|
||||||
<small class='namespace'>
|
<small class='namespace'>
|
||||||
|
|
||||||
</small>
|
</small>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
December 17, 14 22:46:39 by
|
December 22, 14 14:36:45 by
|
||||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||||
Codo
|
Codo
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ But I would become really motivated if you gave me some feedback :) (<a href="ht
|
|||||||
</ul>
|
</ul>
|
||||||
<h2 id="support">Support</h2><p>Please report <em>any</em> issues to the <a href="https://github.com/DadaMonad/Yatta/issues">Github issue page</a>!
|
<h2 id="support">Support</h2><p>Please report <em>any</em> issues to the <a href="https://github.com/DadaMonad/Yatta/issues">Github issue page</a>!
|
||||||
I would appreciate if developers gave me feedback on how <em>convenient</em> the framework is, and if it is easy to use. Particularly the XML-support may not support every DOM-methods - if you encounter a method that does not cause any change on other peers,
|
I would appreciate if developers gave me feedback on how <em>convenient</em> the framework is, and if it is easy to use. Particularly the XML-support may not support every DOM-methods - if you encounter a method that does not cause any change on other peers,
|
||||||
please state function name, and sample parameters. However, there are browser-specific features, that Yatta won't support.</p><h2 id="license">License</h2><p>Yatta! is licensed under the <a href="./LICENSE.txt">MIT License</a>.</p><a href="mailto:kevin.jahns@rwth-aachen.de">kevin.jahns@rwth-aachen.de</a>
|
please state function name, and sample parameters. However, there are browser-specific features, that Yatta won't support.</p><h2 id="license">License</h2><p>Yatta! is licensed under the <a href="./LICENSE.txt">MIT License</a>.</p><a href="mailto:kevin.jahns@rwth-aachen.de">kevin.jahns@rwth-aachen.de</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ please state function name, and sample parameters. However, there are browser-sp
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
December 17, 14 22:46:39 by
|
December 22, 14 14:36:45 by
|
||||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||||
Codo
|
Codo
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
December 17, 14 22:46:39 by
|
December 22, 14 14:36:45 by
|
||||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||||
Codo
|
Codo
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -72,7 +72,7 @@
|
|||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
December 17, 14 22:46:39 by
|
December 22, 14 14:36:45 by
|
||||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||||
Codo
|
Codo
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
December 17, 14 22:46:39 by
|
December 22, 14 14:36:45 by
|
||||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||||
Codo
|
Codo
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
December 17, 14 22:46:39 by
|
December 22, 14 14:36:45 by
|
||||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||||
Codo
|
Codo
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
December 17, 14 22:46:39 by
|
December 22, 14 14:36:45 by
|
||||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||||
Codo
|
Codo
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
December 17, 14 22:46:39 by
|
December 22, 14 14:36:45 by
|
||||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||||
Codo
|
Codo
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
December 17, 14 22:46:39 by
|
December 22, 14 14:36:45 by
|
||||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||||
Codo
|
Codo
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -34,16 +34,6 @@
|
|||||||
<td>Defined in:</td>
|
<td>Defined in:</td>
|
||||||
<td>lib</td>
|
<td>lib</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Classes:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href='../../class/Yatta.html'>
|
|
||||||
Yatta
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
</table>
|
||||||
<h2>Variables Summary</h2>
|
<h2>Variables Summary</h2>
|
||||||
<dl class='constants'>
|
<dl class='constants'>
|
||||||
@@ -52,13 +42,39 @@
|
|||||||
=
|
=
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<pre><code class='coffeescript'>Yatta</code></pre>
|
<pre><code class='coffeescript'>createYatta</code></pre>
|
||||||
|
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
<h2>Method Summary</h2>
|
||||||
|
<ul class='summary'>
|
||||||
|
<li>
|
||||||
|
<span class='signature'>
|
||||||
|
<a href='#createYatta-'>
|
||||||
|
~
|
||||||
|
(void)
|
||||||
|
<b>createYatta</b><span>(connector)</span>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
<span class='desc'>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h2>Method Details</h2>
|
||||||
|
<div class='methods'>
|
||||||
|
<div class='method_details'>
|
||||||
|
<p class='signature' id='createYatta-'>
|
||||||
|
~
|
||||||
|
(void)
|
||||||
|
<b>createYatta</b><span>(connector)</span>
|
||||||
|
<br>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id='footer'>
|
<div id='footer'>
|
||||||
December 17, 14 22:46:39 by
|
December 22, 14 14:36:45 by
|
||||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||||
Codo
|
Codo
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
window.searchData = [{"t":"JsonTypeWrapper","p":"class/JsonTypeWrapper.html"},{"t":"JsonType","p":"class/JsonType.html"},{"t":"WordType","p":"class/WordType.html"},{"t":"Yatta","p":"class/Yatta.html"},{"t":"lib/ConnectorAdapter.coffee","p":"file/lib/ConnectorAdapter.coffee.html"},{"t":"lib/Engine.coffee","p":"file/lib/Engine.coffee.html"},{"t":"lib/HistoryBuffer.coffee","p":"file/lib/HistoryBuffer.coffee.html"},{"t":"lib/Types/BasicTypes.coffee","p":"file/lib/Types/BasicTypes.coffee.html"},{"t":"lib/Types/JsonTypes.coffee","p":"file/lib/Types/JsonTypes.coffee.html"},{"t":"lib/Types/StructuredTypes.coffee","p":"file/lib/Types/StructuredTypes.coffee.html"},{"t":"lib/Types/TextTypes.coffee","p":"file/lib/Types/TextTypes.coffee.html"},{"t":"lib/Yatta.coffee","p":"file/lib/Yatta.coffee.html"},{"t":"README.md","p":"extra/README.md.html"},{"t":"LICENSE.txt","p":"extra/LICENSE.txt.html"},{"t":"JsonType#_encode","p":"class/JsonType.html#_encode-dynamic"},{"t":"WordType#_encode","p":"class/WordType.html#_encode-dynamic"},{"t":"lib/ConnectorAdapter.coffee~adaptConnector","p":"file/lib/ConnectorAdapter.coffee.html#adaptConnector-"},{"t":"WordType#applyDelete","p":"class/WordType.html#applyDelete-dynamic"},{"t":"JsonType#applyDelete","p":"class/JsonType.html#applyDelete-dynamic"},{"t":"WordType#bind","p":"class/WordType.html#bind-dynamic"},{"t":"JsonType#cleanup","p":"class/JsonType.html#cleanup-dynamic"},{"t":"WordType#cleanup","p":"class/WordType.html#cleanup-dynamic"},{"t":"Yatta#constructor","p":"class/Yatta.html#constructor-dynamic"},{"t":"WordType#constructor","p":"class/WordType.html#constructor-dynamic"},{"t":"JsonTypeWrapper#constructor","p":"class/JsonTypeWrapper.html#constructor-dynamic"},{"t":"WordType#deleteText","p":"class/WordType.html#deleteText-dynamic"},{"t":"Yatta#getConnector","p":"class/Yatta.html#getConnector-dynamic"},{"t":"Yatta#getHistoryBuffer","p":"class/Yatta.html#getHistoryBuffer-dynamic"},{"t":"Yatta#getSharedObject","p":"class/Yatta.html#getSharedObject-dynamic"},{"t":"Yatta#getUserId","p":"class/Yatta.html#getUserId-dynamic"},{"t":"WordType#insertAfter","p":"class/WordType.html#insertAfter-dynamic"},{"t":"WordType#insertText","p":"class/WordType.html#insertText-dynamic"},{"t":"Yatta#observe","p":"class/Yatta.html#observe-dynamic"},{"t":"WordType#push","p":"class/WordType.html#push-dynamic"},{"t":"Yatta#setMutableDefault","p":"class/Yatta.html#setMutableDefault-dynamic"},{"t":"JsonType#setMutableDefault","p":"class/JsonType.html#setMutableDefault-dynamic"},{"t":"JsonType#toJson","p":"class/JsonType.html#toJson-dynamic"},{"t":"Yatta#toJson","p":"class/Yatta.html#toJson-dynamic"},{"t":"WordType#toString","p":"class/WordType.html#toString-dynamic"},{"t":"Yatta#unobserve","p":"class/Yatta.html#unobserve-dynamic"},{"t":"Yatta#val","p":"class/Yatta.html#val-dynamic"},{"t":"WordType#val","p":"class/WordType.html#val-dynamic"},{"t":"JsonType#val","p":"class/JsonType.html#val-dynamic"}]
|
window.searchData = [{"t":"JsonTypeWrapper","p":"class/JsonTypeWrapper.html"},{"t":"JsonType","p":"class/JsonType.html"},{"t":"WordType","p":"class/WordType.html"},{"t":"Yatta","p":"class/Yatta.html"},{"t":"lib/ConnectorAdapter.coffee","p":"file/lib/ConnectorAdapter.coffee.html"},{"t":"lib/Engine.coffee","p":"file/lib/Engine.coffee.html"},{"t":"lib/HistoryBuffer.coffee","p":"file/lib/HistoryBuffer.coffee.html"},{"t":"lib/Types/BasicTypes.coffee","p":"file/lib/Types/BasicTypes.coffee.html"},{"t":"lib/Types/JsonTypes.coffee","p":"file/lib/Types/JsonTypes.coffee.html"},{"t":"lib/Types/StructuredTypes.coffee","p":"file/lib/Types/StructuredTypes.coffee.html"},{"t":"lib/Types/TextTypes.coffee","p":"file/lib/Types/TextTypes.coffee.html"},{"t":"lib/Yatta.coffee","p":"file/lib/Yatta.coffee.html"},{"t":"README.md","p":"extra/README.md.html"},{"t":"LICENSE.txt","p":"extra/LICENSE.txt.html"},{"t":"WordType#_encode","p":"class/WordType.html#_encode-dynamic"},{"t":"JsonType#_encode","p":"class/JsonType.html#_encode-dynamic"},{"t":"lib/ConnectorAdapter.coffee~adaptConnector","p":"file/lib/ConnectorAdapter.coffee.html#adaptConnector-"},{"t":"JsonType#applyDelete","p":"class/JsonType.html#applyDelete-dynamic"},{"t":"WordType#applyDelete","p":"class/WordType.html#applyDelete-dynamic"},{"t":"WordType#bind","p":"class/WordType.html#bind-dynamic"},{"t":"JsonType#cleanup","p":"class/JsonType.html#cleanup-dynamic"},{"t":"WordType#cleanup","p":"class/WordType.html#cleanup-dynamic"},{"t":"Yatta#constructor","p":"class/Yatta.html#constructor-dynamic"},{"t":"JsonTypeWrapper#constructor","p":"class/JsonTypeWrapper.html#constructor-dynamic"},{"t":"WordType#constructor","p":"class/WordType.html#constructor-dynamic"},{"t":"lib/Yatta.coffee~createYatta","p":"file/lib/Yatta.coffee.html#createYatta-"},{"t":"WordType#deleteText","p":"class/WordType.html#deleteText-dynamic"},{"t":"Yatta#getConnector","p":"class/Yatta.html#getConnector-dynamic"},{"t":"WordType#insertAfter","p":"class/WordType.html#insertAfter-dynamic"},{"t":"WordType#insertText","p":"class/WordType.html#insertText-dynamic"},{"t":"WordType#push","p":"class/WordType.html#push-dynamic"},{"t":"JsonType#setMutableDefault","p":"class/JsonType.html#setMutableDefault-dynamic"},{"t":"JsonType#toJson","p":"class/JsonType.html#toJson-dynamic"},{"t":"WordType#toString","p":"class/WordType.html#toString-dynamic"},{"t":"WordType#val","p":"class/WordType.html#val-dynamic"},{"t":"JsonType#val","p":"class/JsonType.html#val-dynamic"}]
|
||||||
+27
-83
@@ -29,14 +29,6 @@
|
|||||||
<input type='text'>
|
<input type='text'>
|
||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
|
||||||
<a href='class/JsonType.html#_encode-dynamic' target='main' title='_encode'>
|
|
||||||
#_encode
|
|
||||||
</a>
|
|
||||||
<small>
|
|
||||||
(JsonType)
|
|
||||||
</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<a href='class/WordType.html#_encode-dynamic' target='main' title='_encode'>
|
<a href='class/WordType.html#_encode-dynamic' target='main' title='_encode'>
|
||||||
#_encode
|
#_encode
|
||||||
@@ -45,6 +37,14 @@
|
|||||||
(WordType)
|
(WordType)
|
||||||
</small>
|
</small>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href='class/JsonType.html#_encode-dynamic' target='main' title='_encode'>
|
||||||
|
#_encode
|
||||||
|
</a>
|
||||||
|
<small>
|
||||||
|
(JsonType)
|
||||||
|
</small>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href='file/lib/ConnectorAdapter.coffee.html#adaptConnector-' target='main' title='adaptConnector'>
|
<a href='file/lib/ConnectorAdapter.coffee.html#adaptConnector-' target='main' title='adaptConnector'>
|
||||||
~adaptConnector
|
~adaptConnector
|
||||||
@@ -53,14 +53,6 @@
|
|||||||
(lib/ConnectorAdapter.coffee)
|
(lib/ConnectorAdapter.coffee)
|
||||||
</small>
|
</small>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<a href='class/WordType.html#applyDelete-dynamic' target='main' title='applyDelete'>
|
|
||||||
#applyDelete
|
|
||||||
</a>
|
|
||||||
<small>
|
|
||||||
(WordType)
|
|
||||||
</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<a href='class/JsonType.html#applyDelete-dynamic' target='main' title='applyDelete'>
|
<a href='class/JsonType.html#applyDelete-dynamic' target='main' title='applyDelete'>
|
||||||
#applyDelete
|
#applyDelete
|
||||||
@@ -69,6 +61,14 @@
|
|||||||
(JsonType)
|
(JsonType)
|
||||||
</small>
|
</small>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href='class/WordType.html#applyDelete-dynamic' target='main' title='applyDelete'>
|
||||||
|
#applyDelete
|
||||||
|
</a>
|
||||||
|
<small>
|
||||||
|
(WordType)
|
||||||
|
</small>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href='class/WordType.html#bind-dynamic' target='main' title='bind'>
|
<a href='class/WordType.html#bind-dynamic' target='main' title='bind'>
|
||||||
#bind
|
#bind
|
||||||
@@ -101,6 +101,14 @@
|
|||||||
(Yatta)
|
(Yatta)
|
||||||
</small>
|
</small>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href='class/JsonTypeWrapper.html#constructor-dynamic' target='main' title='constructor'>
|
||||||
|
#constructor
|
||||||
|
</a>
|
||||||
|
<small>
|
||||||
|
(JsonTypeWrapper)
|
||||||
|
</small>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href='class/WordType.html#constructor-dynamic' target='main' title='constructor'>
|
<a href='class/WordType.html#constructor-dynamic' target='main' title='constructor'>
|
||||||
#constructor
|
#constructor
|
||||||
@@ -110,11 +118,11 @@
|
|||||||
</small>
|
</small>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href='class/JsonTypeWrapper.html#constructor-dynamic' target='main' title='constructor'>
|
<a href='file/lib/Yatta.coffee.html#createYatta-' target='main' title='createYatta'>
|
||||||
#constructor
|
~createYatta
|
||||||
</a>
|
</a>
|
||||||
<small>
|
<small>
|
||||||
(JsonTypeWrapper)
|
(lib/Yatta.coffee)
|
||||||
</small>
|
</small>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@@ -133,30 +141,6 @@
|
|||||||
(Yatta)
|
(Yatta)
|
||||||
</small>
|
</small>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<a href='class/Yatta.html#getHistoryBuffer-dynamic' target='main' title='getHistoryBuffer'>
|
|
||||||
#getHistoryBuffer
|
|
||||||
</a>
|
|
||||||
<small>
|
|
||||||
(Yatta)
|
|
||||||
</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href='class/Yatta.html#getSharedObject-dynamic' target='main' title='getSharedObject'>
|
|
||||||
#getSharedObject
|
|
||||||
</a>
|
|
||||||
<small>
|
|
||||||
(Yatta)
|
|
||||||
</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href='class/Yatta.html#getUserId-dynamic' target='main' title='getUserId'>
|
|
||||||
#getUserId
|
|
||||||
</a>
|
|
||||||
<small>
|
|
||||||
(Yatta)
|
|
||||||
</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<a href='class/WordType.html#insertAfter-dynamic' target='main' title='insertAfter'>
|
<a href='class/WordType.html#insertAfter-dynamic' target='main' title='insertAfter'>
|
||||||
#insertAfter
|
#insertAfter
|
||||||
@@ -173,14 +157,6 @@
|
|||||||
(WordType)
|
(WordType)
|
||||||
</small>
|
</small>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<a href='class/Yatta.html#observe-dynamic' target='main' title='observe'>
|
|
||||||
#observe
|
|
||||||
</a>
|
|
||||||
<small>
|
|
||||||
(Yatta)
|
|
||||||
</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<a href='class/WordType.html#push-dynamic' target='main' title='push'>
|
<a href='class/WordType.html#push-dynamic' target='main' title='push'>
|
||||||
#push
|
#push
|
||||||
@@ -189,14 +165,6 @@
|
|||||||
(WordType)
|
(WordType)
|
||||||
</small>
|
</small>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<a href='class/Yatta.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'>
|
|
||||||
#setMutableDefault
|
|
||||||
</a>
|
|
||||||
<small>
|
|
||||||
(Yatta)
|
|
||||||
</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<a href='class/JsonType.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'>
|
<a href='class/JsonType.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'>
|
||||||
#setMutableDefault
|
#setMutableDefault
|
||||||
@@ -213,14 +181,6 @@
|
|||||||
(JsonType)
|
(JsonType)
|
||||||
</small>
|
</small>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<a href='class/Yatta.html#toJson-dynamic' target='main' title='toJson'>
|
|
||||||
#toJson
|
|
||||||
</a>
|
|
||||||
<small>
|
|
||||||
(Yatta)
|
|
||||||
</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<a href='class/WordType.html#toString-dynamic' target='main' title='toString'>
|
<a href='class/WordType.html#toString-dynamic' target='main' title='toString'>
|
||||||
#toString
|
#toString
|
||||||
@@ -229,22 +189,6 @@
|
|||||||
(WordType)
|
(WordType)
|
||||||
</small>
|
</small>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<a href='class/Yatta.html#unobserve-dynamic' target='main' title='unobserve'>
|
|
||||||
#unobserve
|
|
||||||
</a>
|
|
||||||
<small>
|
|
||||||
(Yatta)
|
|
||||||
</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href='class/Yatta.html#val-dynamic' target='main' title='val'>
|
|
||||||
#val
|
|
||||||
</a>
|
|
||||||
<small>
|
|
||||||
(Yatta)
|
|
||||||
</small>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<a href='class/WordType.html#val-dynamic' target='main' title='val'>
|
<a href='class/WordType.html#val-dynamic' target='main' title='val'>
|
||||||
#val
|
#val
|
||||||
|
|||||||
@@ -22,8 +22,17 @@ You don't have to use the proposed user_id.
|
|||||||
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
console.log("me is number 2")
|
// console.log("me is number 1");
|
||||||
yatta = new Y.JsonYatta(2, Connector);
|
// yatta = new JsonYatta(1, Connector);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Though, it is recommended to use the user_id
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
yatta = new Y.JsonYatta(user_id, Connector);
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-18
@@ -16,18 +16,18 @@ run = require 'gulp-run'
|
|||||||
ljs = require 'gulp-ljs'
|
ljs = require 'gulp-ljs'
|
||||||
plumber = require 'gulp-plumber'
|
plumber = require 'gulp-plumber'
|
||||||
mochaPhantomJS = require 'gulp-mocha-phantomjs'
|
mochaPhantomJS = require 'gulp-mocha-phantomjs'
|
||||||
|
cache = require 'gulp-cached'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gulp.task 'default', ['lint', 'browser', 'test', 'literate', 'lib', 'codo']
|
gulp.task 'default', ['deploy']
|
||||||
gulp.task 'build', ['lint', 'browser']
|
|
||||||
|
|
||||||
files =
|
files =
|
||||||
lib : ['./lib/**/*.coffee']
|
lib : ['./lib/**/*.coffee']
|
||||||
build : ['./build/**']
|
build : ['./build/**']
|
||||||
browser : './lib/Yatta.coffee'
|
browser : './lib/Yatta.coffee'
|
||||||
#test : ['./test/**/*_test.coffee']
|
#test : ['./test/**/*_test.coffee']
|
||||||
test : ['./test/JsonYatta_test.coffee']
|
test : ['./test/JsonYatta_test.coffee', './test/TextYatta_test.coffee']
|
||||||
gulp : ['./gulpfile.coffee']
|
gulp : ['./gulpfile.coffee']
|
||||||
examples : ['./examples/**/*.js']
|
examples : ['./examples/**/*.js']
|
||||||
other: ['./lib/**/*']
|
other: ['./lib/**/*']
|
||||||
@@ -37,7 +37,7 @@ for name,file_list of files
|
|||||||
if name isnt 'build'
|
if name isnt 'build'
|
||||||
files.all = files.all.concat file_list
|
files.all = files.all.concat file_list
|
||||||
|
|
||||||
gulp.task 'lib', ->
|
gulp.task 'deploy_nodejs', ->
|
||||||
gulp.src files.lib
|
gulp.src files.lib
|
||||||
.pipe sourcemaps.init()
|
.pipe sourcemaps.init()
|
||||||
.pipe coffee()
|
.pipe coffee()
|
||||||
@@ -45,7 +45,9 @@ gulp.task 'lib', ->
|
|||||||
.pipe gulp.dest 'build/node/'
|
.pipe gulp.dest 'build/node/'
|
||||||
.pipe gulpif '!**/', git.add({args : "-A"})
|
.pipe gulpif '!**/', git.add({args : "-A"})
|
||||||
|
|
||||||
gulp.task 'browser', ->
|
gulp.task 'deploy', ['mocha', 'build_browser', 'deploy_nodejs', 'lint', 'phantom_test', 'codo']
|
||||||
|
|
||||||
|
gulp.task 'build_browser', ->
|
||||||
gulp.src files.browser, { read: false }
|
gulp.src files.browser, { read: false }
|
||||||
.pipe plumber()
|
.pipe plumber()
|
||||||
.pipe browserify
|
.pipe browserify
|
||||||
@@ -69,12 +71,12 @@ gulp.task 'browser', ->
|
|||||||
extname: ".js"
|
extname: ".js"
|
||||||
.pipe gulp.dest './build/test'
|
.pipe gulp.dest './build/test'
|
||||||
|
|
||||||
gulp.task 'browser_test_watch', ['browser'], ->
|
gulp.task 'watch', ['build_browser','mocha'], ->
|
||||||
gulp.watch files.all, ['browser']
|
gulp.watch files.all, ['build_browser', 'mocha']
|
||||||
|
|
||||||
|
gulp.task 'mocha', ->
|
||||||
gulp.task 'test', ->
|
|
||||||
gulp.src files.test, { read: false }
|
gulp.src files.test, { read: false }
|
||||||
|
.pipe plumber()
|
||||||
.pipe mocha {reporter : 'list'}
|
.pipe mocha {reporter : 'list'}
|
||||||
.pipe ignore.include '**/*.coffee'
|
.pipe ignore.include '**/*.coffee'
|
||||||
.pipe browserify
|
.pipe browserify
|
||||||
@@ -95,11 +97,6 @@ gulp.task 'lint', ->
|
|||||||
}
|
}
|
||||||
.pipe coffeelint.reporter()
|
.pipe coffeelint.reporter()
|
||||||
|
|
||||||
gulp.task 'watch', ['default'], ->
|
|
||||||
gulp.watch files.lib, ['build', 'test']
|
|
||||||
gulp.watch files.test, ['test']
|
|
||||||
gulp.watch files.examples, ['literate']
|
|
||||||
|
|
||||||
gulp.task 'phantom_watch', ['phantom_test'], ->
|
gulp.task 'phantom_watch', ['phantom_test'], ->
|
||||||
gulp.watch files.all, ['phantom_test']
|
gulp.watch files.all, ['phantom_test']
|
||||||
|
|
||||||
@@ -112,14 +109,11 @@ gulp.task 'literate', ->
|
|||||||
.pipe gulp.dest 'examples/'
|
.pipe gulp.dest 'examples/'
|
||||||
.pipe gulpif '!**/', git.add({args : "-A"})
|
.pipe gulpif '!**/', git.add({args : "-A"})
|
||||||
|
|
||||||
gulp.task 'upload', [], ()->
|
|
||||||
run('scp -r ./build ./examples jahns@manet.informatik.rwth-aachen.de:/home/jahns/public_html/collaborative_preview/').exec()
|
|
||||||
|
|
||||||
gulp.task 'codo', [], ()->
|
gulp.task 'codo', [], ()->
|
||||||
command = 'codo -o "./doc" --name "Yatta!" --readme "README.md" --undocumented false --private true --title "Yatta! API" ./lib - LICENSE.txt '
|
command = 'codo -o "./doc" --name "Yatta!" --readme "README.md" --undocumented false --private true --title "Yatta! API" ./lib - LICENSE.txt '
|
||||||
run(command).exec()
|
run(command).exec()
|
||||||
|
|
||||||
gulp.task 'phantom_test', ['browser'], ()->
|
gulp.task 'phantom_test', ['build_browser'], ()->
|
||||||
gulp.src 'build/test/index.html'
|
gulp.src 'build/test/index.html'
|
||||||
.pipe mochaPhantomJS()
|
.pipe mochaPhantomJS()
|
||||||
|
|
||||||
|
|||||||
+26
-12
@@ -45,7 +45,7 @@ module.exports = (HB)->
|
|||||||
# @overload unobserve(event, f)
|
# @overload unobserve(event, f)
|
||||||
# @param f {Function} The function that you want to delete
|
# @param f {Function} The function that you want to delete
|
||||||
unobserve: (f)->
|
unobserve: (f)->
|
||||||
@event_listeners.filter (g)->
|
@event_listeners = @event_listeners.filter (g)->
|
||||||
f isnt g
|
f isnt g
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -59,7 +59,7 @@ module.exports = (HB)->
|
|||||||
#
|
#
|
||||||
# Fire an event.
|
# Fire an event.
|
||||||
# TODO: Do something with timeouts. You don't want this to fire for every operation (e.g. insert).
|
# TODO: Do something with timeouts. You don't want this to fire for every operation (e.g. insert).
|
||||||
#
|
# TODO: do you need callEvent+forwardEvent? Only one suffices probably
|
||||||
callEvent: ()->
|
callEvent: ()->
|
||||||
@forwardEvent @, arguments...
|
@forwardEvent @, arguments...
|
||||||
|
|
||||||
@@ -215,8 +215,10 @@ module.exports = (HB)->
|
|||||||
#
|
#
|
||||||
execute: ()->
|
execute: ()->
|
||||||
if @validateSavedOperations()
|
if @validateSavedOperations()
|
||||||
@deletes.applyDelete @
|
res = super
|
||||||
super
|
if res
|
||||||
|
@deletes.applyDelete @
|
||||||
|
res
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
|
|
||||||
@@ -275,7 +277,12 @@ module.exports = (HB)->
|
|||||||
garbagecollect = true
|
garbagecollect = true
|
||||||
super garbagecollect
|
super garbagecollect
|
||||||
if callLater
|
if callLater
|
||||||
@parent.callEvent "delete", @, o
|
@parent.callEvent [
|
||||||
|
type: "insert"
|
||||||
|
position: @getPosition()
|
||||||
|
object: @parent # TODO: You can combine getPosition + getParent in a more efficient manner! (only left Delimiter will hold @parent)
|
||||||
|
changed_by: o.uid.creator
|
||||||
|
]
|
||||||
if @next_cl?.isDeleted()
|
if @next_cl?.isDeleted()
|
||||||
# garbage collect next_cl
|
# garbage collect next_cl
|
||||||
@next_cl.applyDelete()
|
@next_cl.applyDelete()
|
||||||
@@ -317,8 +324,7 @@ module.exports = (HB)->
|
|||||||
#
|
#
|
||||||
# @private
|
# @private
|
||||||
# Include this operation in the associative lists.
|
# Include this operation in the associative lists.
|
||||||
# @param fire_event {boolean} Whether to fire the insert-event.
|
execute: ()->
|
||||||
execute: (fire_event = true)->
|
|
||||||
if not @validateSavedOperations()
|
if not @validateSavedOperations()
|
||||||
return false
|
return false
|
||||||
else
|
else
|
||||||
@@ -336,7 +342,8 @@ module.exports = (HB)->
|
|||||||
# therefore $this would be always to the right of o3
|
# therefore $this would be always to the right of o3
|
||||||
# case 2: $origin < $o.origin
|
# case 2: $origin < $o.origin
|
||||||
# if current $this insert_position > $o origin: $this ins
|
# if current $this insert_position > $o origin: $this ins
|
||||||
# else $insert_position will not change (maybe we encounter case 1 later, then this will be to the right of $o)
|
# else $insert_position will not change
|
||||||
|
# (maybe we encounter case 1 later, then this will be to the right of $o)
|
||||||
# case 3: $origin > $o.origin
|
# case 3: $origin > $o.origin
|
||||||
# $this insert_position is to the left of $o (forever!)
|
# $this insert_position is to the left of $o (forever!)
|
||||||
while true
|
while true
|
||||||
@@ -369,13 +376,20 @@ module.exports = (HB)->
|
|||||||
@prev_cl.next_cl = @
|
@prev_cl.next_cl = @
|
||||||
@next_cl.prev_cl = @
|
@next_cl.prev_cl = @
|
||||||
|
|
||||||
parent = @prev_cl?.getParent()
|
@setParent @prev_cl.getParent() # do Insertions always have a parent?
|
||||||
super # notify the execution_listeners
|
super # notify the execution_listeners
|
||||||
if parent? and fire_event
|
@callOperationSpecificEvents()
|
||||||
@setParent parent
|
|
||||||
@parent.callEvent "insert", @
|
|
||||||
@
|
@
|
||||||
|
|
||||||
|
callOperationSpecificEvents: ()->
|
||||||
|
@parent?.callEvent [
|
||||||
|
type: "insert"
|
||||||
|
position: @getPosition()
|
||||||
|
object: @parent
|
||||||
|
changed_by: @uid.creator
|
||||||
|
value: @content
|
||||||
|
]
|
||||||
|
|
||||||
#
|
#
|
||||||
# Compute the position of this operation.
|
# Compute the position of this operation.
|
||||||
#
|
#
|
||||||
|
|||||||
+25
-24
@@ -148,30 +148,31 @@ module.exports = (HB)->
|
|||||||
if not event.changed_by? and (event.type is "add" or event.type = "update")
|
if not event.changed_by? and (event.type is "add" or event.type = "update")
|
||||||
# this event is not created by Yatta.
|
# this event is not created by Yatta.
|
||||||
that.val(event.name, event.object[event.name])
|
that.val(event.name, event.object[event.name])
|
||||||
that.observe (event_name, property_name, op)->
|
@observe (events)->
|
||||||
if this is that and op.uid.creator isnt HB.getUserId()
|
for event in events
|
||||||
notifier = Object.getNotifier(that.bound_json)
|
if event.created_ isnt HB.getUserId()
|
||||||
oldVal = that.bound_json[property_name]
|
notifier = Object.getNotifier(that.bound_json)
|
||||||
if oldVal?
|
oldVal = that.bound_json[event.name]
|
||||||
notifier.performChange 'update', ()->
|
if oldVal?
|
||||||
that.bound_json[property_name] = that.val(property_name)
|
notifier.performChange 'update', ()->
|
||||||
, that.bound_json
|
that.bound_json[event.name] = that.val(event.name)
|
||||||
notifier.notify
|
, that.bound_json
|
||||||
object: that.bound_json
|
notifier.notify
|
||||||
type: 'update'
|
object: that.bound_json
|
||||||
name: property_name
|
type: 'update'
|
||||||
oldValue: oldVal
|
name: event.name
|
||||||
changed_by: op.uid.creator
|
oldValue: oldVal
|
||||||
else
|
changed_by: event.changed_by
|
||||||
notifier.performChange 'add', ()->
|
else
|
||||||
that.bound_json[property_name] = that.val(property_name)
|
notifier.performChange 'add', ()->
|
||||||
, that.bound_json
|
that.bound_json[event.name] = that.val(event.name)
|
||||||
notifier.notify
|
, that.bound_json
|
||||||
object: that.bound_json
|
notifier.notify
|
||||||
type: 'add'
|
object: that.bound_json
|
||||||
name: property_name
|
type: 'add'
|
||||||
oldValue: oldVal
|
name: event.name
|
||||||
changed_by: op.uid.creator
|
oldValue: oldVal
|
||||||
|
changed_by:event.changed_by
|
||||||
@bound_json
|
@bound_json
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -110,7 +110,10 @@ module.exports = (HB)->
|
|||||||
uid_end.op_number = "#{uid_r.op_number}_end"
|
uid_end.op_number = "#{uid_r.op_number}_end"
|
||||||
beg = (new types.Delimiter uid_beg, undefined, uid_end).execute()
|
beg = (new types.Delimiter uid_beg, undefined, uid_end).execute()
|
||||||
end = (new types.Delimiter uid_end, beg, undefined).execute()
|
end = (new types.Delimiter uid_end, beg, undefined).execute()
|
||||||
@map_manager.map[@name] = new ReplaceManager uid_r, beg, end
|
event_properties =
|
||||||
|
name: @name
|
||||||
|
event_this = @map_manager
|
||||||
|
@map_manager.map[@name] = new ReplaceManager event_properties, event_this, uid_r, beg, end
|
||||||
@map_manager.map[@name].setParent @map_manager, @name
|
@map_manager.map[@name].setParent @map_manager, @name
|
||||||
(@map_manager.map[@name].add_name_ops ?= []).push @
|
(@map_manager.map[@name].add_name_ops ?= []).push @
|
||||||
@map_manager.map[@name].execute()
|
@map_manager.map[@name].execute()
|
||||||
@@ -192,22 +195,27 @@ module.exports = (HB)->
|
|||||||
|
|
||||||
#
|
#
|
||||||
# Retrieves the x-th not deleted element.
|
# Retrieves the x-th not deleted element.
|
||||||
|
# e.g. "abc" : the 1th character is "a"
|
||||||
|
# the 0th character is the left Delimiter
|
||||||
#
|
#
|
||||||
getOperationByPosition: (position)->
|
getOperationByPosition: (position)->
|
||||||
o = @beginning.next_cl
|
o = @beginning
|
||||||
if (position > 0 or o.isDeleted()) and not (o instanceof types.Delimiter)
|
while true
|
||||||
while o.isDeleted() and not (o instanceof types.Delimiter)
|
# find the i-th op
|
||||||
# find first non deleted op
|
if o instanceof types.Delimiter and o.prev_cl?
|
||||||
o = o.next_cl
|
# the user or you gave a position parameter that is to big
|
||||||
while true
|
# for the current array. Therefore we reach a Delimiter.
|
||||||
# find the i-th op
|
# Then, we'll just return the last character.
|
||||||
if o instanceof types.Delimiter
|
o = o.prev_cl
|
||||||
break
|
while o.isDeleted() or not (o instanceof types.Delimiter)
|
||||||
if position <= 0 and not o.isDeleted()
|
o = o.prev_cl
|
||||||
break
|
break
|
||||||
o = o.next_cl
|
if position <= 0 and not o.isDeleted()
|
||||||
if not o.isDeleted()
|
break
|
||||||
position -= 1
|
|
||||||
|
o = o.next_cl
|
||||||
|
if not o.isDeleted()
|
||||||
|
position -= 1
|
||||||
o
|
o
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -220,12 +228,14 @@ module.exports = (HB)->
|
|||||||
#
|
#
|
||||||
class ReplaceManager extends ListManager
|
class ReplaceManager extends ListManager
|
||||||
#
|
#
|
||||||
|
# @param {Object} event_properties Decorates the event that is thrown by the RM
|
||||||
|
# @param {Object} event_this The object on which the event shall be executed
|
||||||
# @param {Operation} initial_content Initialize this with a Replaceable that holds the initial_content.
|
# @param {Operation} initial_content Initialize this with a Replaceable that holds the initial_content.
|
||||||
# @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.
|
# @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.
|
||||||
# @param {Delimiter} beginning Reference or Object.
|
# @param {Delimiter} beginning Reference or Object.
|
||||||
# @param {Delimiter} end Reference or Object.
|
# @param {Delimiter} end Reference or Object.
|
||||||
# constructor: (uid, beginning, end, prev, next, origin)->
|
constructor: (@event_porperties, @event_this, uid, beginning, end, prev, next, origin)->
|
||||||
# super uid, beginning, end, prev, next, origin
|
super uid, beginning, end, prev, next, origin
|
||||||
|
|
||||||
type: "ReplaceManager"
|
type: "ReplaceManager"
|
||||||
|
|
||||||
@@ -243,6 +253,21 @@ module.exports = (HB)->
|
|||||||
cleanup: ()->
|
cleanup: ()->
|
||||||
super()
|
super()
|
||||||
|
|
||||||
|
#
|
||||||
|
# This doesn't throw the same events as the ListManager. Therefore, the
|
||||||
|
# Replaceables also not throw the same events.
|
||||||
|
# So, ReplaceManager and ListManager both implement
|
||||||
|
# these functions that are called when an Insertion is executed (at the end).
|
||||||
|
#
|
||||||
|
#
|
||||||
|
callEventDecorator: (events)->
|
||||||
|
if not @isDeleted()
|
||||||
|
for name,prop of @event_porperties
|
||||||
|
for event in events
|
||||||
|
event[name] = prop
|
||||||
|
@event_this.callEvent events
|
||||||
|
undefined
|
||||||
|
|
||||||
#
|
#
|
||||||
# Replace the existing word with a new word.
|
# Replace the existing word with a new word.
|
||||||
#
|
#
|
||||||
@@ -278,7 +303,7 @@ module.exports = (HB)->
|
|||||||
if @prev_cl? and @next_cl?
|
if @prev_cl? and @next_cl?
|
||||||
json['prev'] = @prev_cl.getUid()
|
json['prev'] = @prev_cl.getUid()
|
||||||
json['next'] = @next_cl.getUid()
|
json['next'] = @next_cl.getUid()
|
||||||
if @origin? # and @origin isnt @prev_cl
|
if @origin? # TODO: do this everywhere: and @origin isnt @prev_cl
|
||||||
json["origin"] = @origin().getUid()
|
json["origin"] = @origin().getUid()
|
||||||
json
|
json
|
||||||
|
|
||||||
@@ -334,23 +359,30 @@ module.exports = (HB)->
|
|||||||
super
|
super
|
||||||
|
|
||||||
#
|
#
|
||||||
|
# This is called, when the Insert-type was successfully executed.
|
||||||
|
# TODO: consider doing this in a more consistent manner. This could also be
|
||||||
|
# done with execute. But currently, there are no specital Insert-types for ListManager.
|
||||||
#
|
#
|
||||||
execute: ()->
|
callOperationSpecificEvents: ()->
|
||||||
if not @validateSavedOperations()
|
if @next_cl.type is "Delimiter" and @prev_cl.type isnt "Delimiter"
|
||||||
return false
|
# this replaces another Replaceable
|
||||||
else
|
old_value = @prev_cl.content
|
||||||
# only fire 'insert-event' (which will result in addProperty and change events),
|
@prev_cl.applyDelete()
|
||||||
# when content is added.
|
@parent.callEventDecorator [
|
||||||
# In case of Json, empty content means that this is not the last update,
|
type: "update"
|
||||||
# since content is deleted when 'applyDelete' was exectuted.
|
changed_by: @uid.creator
|
||||||
ins_result = super(@content?) # @content? whether to fire or not
|
oldValue: old_value
|
||||||
if ins_result
|
]
|
||||||
if @next_cl.type is "Delimiter" and @prev_cl.type isnt "Delimiter"
|
else if @next_cl.type isnt "Delimiter"
|
||||||
@prev_cl.applyDelete()
|
# This will never be recognized by the user, because another
|
||||||
else if @next_cl.type isnt "Delimiter"
|
# concurrent operation is set as the current value of the RM
|
||||||
@applyDelete()
|
@applyDelete()
|
||||||
|
else # prev _and_ next are Delimiters. This is the first created Replaceable in the RM
|
||||||
return ins_result
|
@parent.callEventDecorator [
|
||||||
|
type: "add"
|
||||||
|
changed_by: @uid.creator
|
||||||
|
]
|
||||||
|
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.
|
||||||
|
|||||||
@@ -152,10 +152,10 @@ module.exports = (HB)->
|
|||||||
# @return {WordType} This WordType object.
|
# @return {WordType} This WordType object.
|
||||||
#
|
#
|
||||||
insertText: (position, content)->
|
insertText: (position, content)->
|
||||||
# TODO: getOperationByPosition should return "(i-2)th" character
|
ith = @getOperationByPosition position
|
||||||
ith = @getOperationByPosition position # the (i-1)th character. e.g. "abc" a is the 0th character
|
# the (i-1)th character. e.g. "abc" the 1th character is "a"
|
||||||
left = ith.prev_cl # left is the non-deleted charather to the left of ith
|
# the 0th character is the left Delimiter
|
||||||
@insertAfter left, content
|
@insertAfter ith, content
|
||||||
|
|
||||||
#
|
#
|
||||||
# Deletes a part of the word.
|
# Deletes a part of the word.
|
||||||
@@ -163,7 +163,7 @@ module.exports = (HB)->
|
|||||||
# @return {WordType} This WordType object
|
# @return {WordType} This WordType object
|
||||||
#
|
#
|
||||||
deleteText: (position, length)->
|
deleteText: (position, length)->
|
||||||
o = @getOperationByPosition position
|
o = @getOperationByPosition(position+1) # position 0 in this case is the deletion of the first character
|
||||||
|
|
||||||
delete_ops = []
|
delete_ops = []
|
||||||
for i in [0...length]
|
for i in [0...length]
|
||||||
|
|||||||
+27
-96
@@ -4,107 +4,38 @@ HistoryBuffer = require "./HistoryBuffer"
|
|||||||
Engine = require "./Engine"
|
Engine = require "./Engine"
|
||||||
adaptConnector = require "./ConnectorAdapter"
|
adaptConnector = require "./ConnectorAdapter"
|
||||||
|
|
||||||
#
|
createYatta = (connector)->
|
||||||
# Framework for Json data-structures.
|
user_id = connector.id # TODO: change to getUniqueId()
|
||||||
# Known values that are supported:
|
HB = new HistoryBuffer user_id
|
||||||
# * String
|
type_manager = json_types_uninitialized HB
|
||||||
# * Integer
|
types = type_manager.types
|
||||||
# * Array
|
|
||||||
#
|
|
||||||
class Yatta
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# @param {String} user_id Unique id of the peer.
|
# Framework for Json data-structures.
|
||||||
# @param {Connector} Connector the connector class.
|
# Known values that are supported:
|
||||||
|
# * String
|
||||||
|
# * Integer
|
||||||
|
# * Array
|
||||||
#
|
#
|
||||||
constructor: (@connector)->
|
class Yatta extends types.JsonType
|
||||||
user_id = @connector.id # TODO: change to getUniqueId()
|
|
||||||
@HB = new HistoryBuffer user_id
|
|
||||||
type_manager = json_types_uninitialized @HB
|
|
||||||
@types = type_manager.types
|
|
||||||
@engine = new Engine @HB, type_manager.parser
|
|
||||||
@HB.engine = @engine # TODO: !! only for debugging
|
|
||||||
adaptConnector @connector, @engine, @HB, type_manager.execution_listener
|
|
||||||
#first_word =
|
|
||||||
@root_element = new @types.JsonType(@HB.getReservedUniqueIdentifier()).execute()
|
|
||||||
###
|
|
||||||
uid_beg = @HB.getReservedUniqueIdentifier()
|
|
||||||
uid_end = @HB.getReservedUniqueIdentifier()
|
|
||||||
beg = (new @types.Delimiter uid_beg, undefined, uid_end).execute()
|
|
||||||
end = (new @types.Delimiter uid_end, beg, undefined).execute()
|
|
||||||
|
|
||||||
@root_element = (new @types.ReplaceManager @HB.getReservedUniqueIdentifier(), beg, end).execute()
|
#
|
||||||
@root_element.replace first_word, @HB.getReservedUniqueIdentifier()
|
# @param {String} user_id Unique id of the peer.
|
||||||
###
|
# @param {Connector} Connector the connector class.
|
||||||
|
#
|
||||||
|
constructor: ()->
|
||||||
|
@connector = connector
|
||||||
|
@HB = HB
|
||||||
|
@types = types
|
||||||
|
@engine = new Engine @HB, type_manager.parser
|
||||||
|
adaptConnector @connector, @engine, @HB, type_manager.execution_listener
|
||||||
|
super
|
||||||
|
|
||||||
#
|
getConnector: ()->
|
||||||
# @return JsonType
|
@connector
|
||||||
#
|
|
||||||
getSharedObject: ()->
|
|
||||||
@root_element
|
|
||||||
|
|
||||||
#
|
return new Yatta(HB.getReservedUniqueIdentifier()).execute()
|
||||||
# Get the initialized connector.
|
|
||||||
#
|
|
||||||
getConnector: ()->
|
|
||||||
@connector
|
|
||||||
|
|
||||||
#
|
module.exports = createYatta
|
||||||
# @see HistoryBuffer
|
|
||||||
#
|
|
||||||
getHistoryBuffer: ()->
|
|
||||||
@HB
|
|
||||||
|
|
||||||
#
|
|
||||||
# @see JsonType.setMutableDefault
|
|
||||||
#
|
|
||||||
setMutableDefault: (mutable)->
|
|
||||||
@getSharedObject().setMutableDefault(mutable)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Get the UserId from the HistoryBuffer object.
|
|
||||||
# In most cases this will be the same as the user_id value with which
|
|
||||||
# Yatta was initialized (Depending on the HistoryBuffer implementation).
|
|
||||||
#
|
|
||||||
getUserId: ()->
|
|
||||||
@HB.getUserId()
|
|
||||||
|
|
||||||
#
|
|
||||||
# @see JsonType.toJson
|
|
||||||
#
|
|
||||||
toJson : ()->
|
|
||||||
@getSharedObject().toJson()
|
|
||||||
|
|
||||||
#
|
|
||||||
# @see JsonType.val
|
|
||||||
#
|
|
||||||
val : ()->
|
|
||||||
@getSharedObject().val arguments...
|
|
||||||
|
|
||||||
#
|
|
||||||
# @see Operation.on
|
|
||||||
#
|
|
||||||
observe: ()->
|
|
||||||
@getSharedObject().observe arguments...
|
|
||||||
|
|
||||||
#
|
|
||||||
# @see Operation.deleteListener
|
|
||||||
#
|
|
||||||
unobserve: ()->
|
|
||||||
@getSharedObject().unobserve arguments...
|
|
||||||
|
|
||||||
#
|
|
||||||
# @see JsonType.value
|
|
||||||
#
|
|
||||||
Object.defineProperty Yatta.prototype, 'value',
|
|
||||||
get : -> @getSharedObject().value
|
|
||||||
set : (o)->
|
|
||||||
if o.constructor is {}.constructor
|
|
||||||
for o_name,o_obj of o
|
|
||||||
@val(o_name, o_obj, 'immutable')
|
|
||||||
else
|
|
||||||
throw new Error "You must only set Object values!"
|
|
||||||
|
|
||||||
module.exports = Yatta
|
|
||||||
if window? and not window.Yatta?
|
if window? and not window.Yatta?
|
||||||
window.Yatta = Yatta
|
window.Yatta = createYatta
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
"coffeeify": "^0.6.0",
|
"coffeeify": "^0.6.0",
|
||||||
"gulp": "^3.8.7",
|
"gulp": "^3.8.7",
|
||||||
"gulp-browserify": "^0.5.0",
|
"gulp-browserify": "^0.5.0",
|
||||||
|
"gulp-cached": "^1.0.1",
|
||||||
"gulp-coffee": "^2.1.1",
|
"gulp-coffee": "^2.1.1",
|
||||||
"gulp-coffeelint": "^0.3.3",
|
"gulp-coffeelint": "^0.3.3",
|
||||||
"gulp-concat": "^2.3.4",
|
"gulp-concat": "^2.3.4",
|
||||||
@@ -57,6 +58,7 @@
|
|||||||
"gulp-run": "^1.6.3",
|
"gulp-run": "^1.6.3",
|
||||||
"gulp-sourcemaps": "^1.1.1",
|
"gulp-sourcemaps": "^1.1.1",
|
||||||
"gulp-uglify": "^0.3.1",
|
"gulp-uglify": "^0.3.1",
|
||||||
|
"gulp-watch": "^3.0.0",
|
||||||
"jquery": "^2.1.1",
|
"jquery": "^2.1.1",
|
||||||
"mocha": "^1.21.4",
|
"mocha": "^1.21.4",
|
||||||
"sinon": "^1.10.2",
|
"sinon": "^1.10.2",
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class JsonTest extends Test
|
|||||||
type: "JsonTest"
|
type: "JsonTest"
|
||||||
|
|
||||||
getRandomRoot: (user_num, root)->
|
getRandomRoot: (user_num, root)->
|
||||||
root ?= @users[user_num].getSharedObject()
|
root ?= @users[user_num]
|
||||||
types = @users[user_num].types
|
types = @users[user_num].types
|
||||||
if _.random(0,1) is 1 # take root
|
if _.random(0,1) is 1 # take root
|
||||||
root
|
root
|
||||||
@@ -98,7 +98,7 @@ describe "JsonFramework", ->
|
|||||||
###
|
###
|
||||||
|
|
||||||
it "has a JsonTypeWrapper", ->
|
it "has a JsonTypeWrapper", ->
|
||||||
y = this.yTest.getSomeUser().getSharedObject()
|
y = this.yTest.getSomeUser()
|
||||||
y.val('x',"dtrn", 'immutable')
|
y.val('x',"dtrn", 'immutable')
|
||||||
y.val('set',{x:"x"}, 'immutable')
|
y.val('set',{x:"x"}, 'immutable')
|
||||||
w = y.value
|
w = y.value
|
||||||
|
|||||||
+5
-10
@@ -13,12 +13,12 @@ module.exports = class Test
|
|||||||
constructor: (@name_suffix = "")->
|
constructor: (@name_suffix = "")->
|
||||||
@number_of_test_cases_multiplier = 1
|
@number_of_test_cases_multiplier = 1
|
||||||
@repeat_this = 1 * @number_of_test_cases_multiplier
|
@repeat_this = 1 * @number_of_test_cases_multiplier
|
||||||
@doSomething_amount = 50 + @number_of_test_cases_multiplier
|
@doSomething_amount = 50 * @number_of_test_cases_multiplier
|
||||||
@number_of_engines = 5 + @number_of_test_cases_multiplier - 1
|
@number_of_engines = 4 + @number_of_test_cases_multiplier - 1
|
||||||
|
|
||||||
@time = 0
|
@time = 0 # denotes to the time when run was started
|
||||||
@ops = 0
|
@ops = 0 # number of operations (used with @time)
|
||||||
@time_now = 0
|
@time_now = 0 # current time
|
||||||
|
|
||||||
@debug = false
|
@debug = false
|
||||||
|
|
||||||
@@ -85,11 +85,6 @@ module.exports = class Test
|
|||||||
ops1 = y.deleteText pos, length
|
ops1 = y.deleteText pos, length
|
||||||
undefined
|
undefined
|
||||||
types : [types.WordType]
|
types : [types.WordType]
|
||||||
,
|
|
||||||
f : (y)=> # REPLACE TEXT
|
|
||||||
y.replaceText @getRandomText()
|
|
||||||
null
|
|
||||||
types: [types.WordType]
|
|
||||||
]
|
]
|
||||||
getRandomRoot: (user_num)->
|
getRandomRoot: (user_num)->
|
||||||
throw new Error "overwrite me!"
|
throw new Error "overwrite me!"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ _ = require("underscore")
|
|||||||
|
|
||||||
chai.use(sinonChai)
|
chai.use(sinonChai)
|
||||||
|
|
||||||
Y = require "../lib/index"
|
Yatta = require "../lib/Yatta"
|
||||||
Connector = require "../bower_components/connector/lib/test-connector/test-connector.coffee"
|
Connector = require "../bower_components/connector/lib/test-connector/test-connector.coffee"
|
||||||
|
|
||||||
Test = require "./TestSuite"
|
Test = require "./TestSuite"
|
||||||
@@ -15,14 +15,17 @@ class TextTest extends Test
|
|||||||
|
|
||||||
type: "TextTest"
|
type: "TextTest"
|
||||||
|
|
||||||
makeNewUser: (user, conn)->
|
makeNewUser: (userId)->
|
||||||
super new Y.TextFramework user, conn
|
conn = new Connector userId
|
||||||
|
y = new Yatta conn
|
||||||
|
y.val("TextTest","","mutable")
|
||||||
|
y
|
||||||
|
|
||||||
getRandomRoot: (user_num)->
|
getRandomRoot: (user_num)->
|
||||||
@users[user_num].getSharedObject()
|
@users[user_num].val("TextTest")
|
||||||
|
|
||||||
getContent: (user_num)->
|
getContent: (user_num)->
|
||||||
@users[user_num].val()
|
@users[user_num].val("TextTest").val()
|
||||||
|
|
||||||
describe "TextFramework", ->
|
describe "TextFramework", ->
|
||||||
beforeEach (done)->
|
beforeEach (done)->
|
||||||
@@ -35,13 +38,81 @@ describe "TextFramework", ->
|
|||||||
done()
|
done()
|
||||||
|
|
||||||
it "simple multi-char insert", ->
|
it "simple multi-char insert", ->
|
||||||
u = @yTest.users[0]
|
u = @yTest.users[0].val("TextTest")
|
||||||
u.insertText 0, "abc"
|
u.insertText 0, "abc"
|
||||||
u = @yTest.users[1]
|
u = @yTest.users[1].val("TextTest")
|
||||||
u.insertText 0, "xyz"
|
u.insertText 0, "xyz"
|
||||||
@yTest.compareAll()
|
@yTest.compareAll()
|
||||||
expect(u.val()).to.equal("abcxyz")
|
expect(u.val()).to.equal("abcxyz")
|
||||||
|
|
||||||
|
it "Observers work on shared Text (insert type observers, local and foreign)", ->
|
||||||
|
u = @yTest.users[0].val("TextTest","my awesome Text").val("TextTest")
|
||||||
|
@yTest.flushAll()
|
||||||
|
last_task = null
|
||||||
|
observer1 = (changes)->
|
||||||
|
expect(changes.length).to.equal(1)
|
||||||
|
change = changes[0]
|
||||||
|
expect(change.type).to.equal("insert")
|
||||||
|
expect(change.object).to.equal(u)
|
||||||
|
expect(change.value).to.equal("a")
|
||||||
|
expect(change.position).to.equal(1)
|
||||||
|
expect(change.changed_by).to.equal('0')
|
||||||
|
last_task = "observer1"
|
||||||
|
u.observe observer1
|
||||||
|
u.insertText 1, "a"
|
||||||
|
expect(last_task).to.equal("observer1")
|
||||||
|
u.unobserve observer1
|
||||||
|
|
||||||
|
observer2 = (changes)->
|
||||||
|
expect(changes.length).to.equal(1)
|
||||||
|
change = changes[0]
|
||||||
|
expect(change.type).to.equal("insert")
|
||||||
|
expect(change.object).to.equal(u)
|
||||||
|
expect(change.value).to.equal("x")
|
||||||
|
expect(change.position).to.equal(0)
|
||||||
|
expect(change.changed_by).to.equal('1')
|
||||||
|
last_task = "observer2"
|
||||||
|
u.observe observer2
|
||||||
|
v = @yTest.users[1].val("TextTest")
|
||||||
|
v.insertText 0, "x"
|
||||||
|
@yTest.flushAll()
|
||||||
|
expect(last_task).to.equal("observer2")
|
||||||
|
u.unobserve observer2
|
||||||
|
|
||||||
|
it "Observers work on shared Text (delete type observers, local and foreign)", ->
|
||||||
|
u = @yTest.users[0].val("TextTest","my awesome Text").val("TextTest")
|
||||||
|
@yTest.flushAll()
|
||||||
|
last_task = null
|
||||||
|
observer1 = (changes)->
|
||||||
|
expect(changes.length).to.equal(1)
|
||||||
|
change = changes[0]
|
||||||
|
expect(change.type).to.equal("delete")
|
||||||
|
expect(change.object).to.equal(u)
|
||||||
|
expect(change.position).to.equal(1)
|
||||||
|
expect(change.length).to.equal(1)
|
||||||
|
expect(change.changed_by).to.equal('0')
|
||||||
|
last_task = "observer1"
|
||||||
|
u.observe observer1
|
||||||
|
u.deleteText 1
|
||||||
|
expect(last_task).to.equal("observer1")
|
||||||
|
u.unobserve observer1
|
||||||
|
|
||||||
|
observer2 = (changes)->
|
||||||
|
expect(changes.length).to.equal(1)
|
||||||
|
change = changes[0]
|
||||||
|
expect(change.type).to.equal("delete")
|
||||||
|
expect(change.object).to.equal(u)
|
||||||
|
expect(change.position).to.equal(0)
|
||||||
|
expect(change.length).to.equal(0)
|
||||||
|
expect(change.changed_by).to.equal('1')
|
||||||
|
last_task = "observer2"
|
||||||
|
u.observe observer2
|
||||||
|
v = @yTest.users[1].val("TextTest")
|
||||||
|
v.deleteText 0
|
||||||
|
@yTest.flushAll()
|
||||||
|
expect(last_task).to.equal("observer2")
|
||||||
|
u.unobserve observer2
|
||||||
|
|
||||||
it "can handle many engines, many operations, concurrently (random)", ->
|
it "can handle many engines, many operations, concurrently (random)", ->
|
||||||
@yTest.run()
|
@yTest.run()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user