2014-08-24 01:52:15 +02:00
|
|
|
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
|
|
|
|
var Engine;
|
|
|
|
|
|
|
|
|
|
Engine = (function() {
|
|
|
|
|
function Engine(HB, parser) {
|
|
|
|
|
this.HB = HB;
|
|
|
|
|
this.parser = parser;
|
|
|
|
|
this.unprocessed_ops = [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Engine.prototype.parseOperation = function(json) {
|
|
|
|
|
var typeParser;
|
|
|
|
|
typeParser = this.parser[json.type];
|
|
|
|
|
if (typeParser != null) {
|
|
|
|
|
return typeParser(json);
|
|
|
|
|
} else {
|
|
|
|
|
throw new Error("You forgot to specify a parser for type " + json.type + ". The message is " + (JSON.stringify(json)) + ".");
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Engine.prototype.applyOpsBundle = function(ops_json) {
|
|
|
|
|
var o, ops, _i, _j, _k, _len, _len1, _len2;
|
|
|
|
|
ops = [];
|
|
|
|
|
for (_i = 0, _len = ops_json.length; _i < _len; _i++) {
|
|
|
|
|
o = ops_json[_i];
|
|
|
|
|
ops.push(this.parseOperation(o));
|
|
|
|
|
}
|
|
|
|
|
for (_j = 0, _len1 = ops.length; _j < _len1; _j++) {
|
|
|
|
|
o = ops[_j];
|
|
|
|
|
this.HB.addOperation(o);
|
|
|
|
|
}
|
|
|
|
|
for (_k = 0, _len2 = ops.length; _k < _len2; _k++) {
|
|
|
|
|
o = ops[_k];
|
|
|
|
|
if (!o.execute()) {
|
|
|
|
|
this.unprocessed_ops.push(o);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return this.tryUnprocessed();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Engine.prototype.applyOpsCheckDouble = function(ops_json) {
|
|
|
|
|
var o, _i, _len, _results;
|
|
|
|
|
_results = [];
|
|
|
|
|
for (_i = 0, _len = ops_json.length; _i < _len; _i++) {
|
|
|
|
|
o = ops_json[_i];
|
|
|
|
|
if (this.HB.getOperation(o.uid) == null) {
|
|
|
|
|
_results.push(this.applyOp(o));
|
|
|
|
|
} else {
|
|
|
|
|
_results.push(void 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return _results;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Engine.prototype.applyOps = function(ops_json) {
|
|
|
|
|
var o, _i, _len, _results;
|
|
|
|
|
_results = [];
|
|
|
|
|
for (_i = 0, _len = ops_json.length; _i < _len; _i++) {
|
|
|
|
|
o = ops_json[_i];
|
|
|
|
|
_results.push(this.applyOp(o));
|
|
|
|
|
}
|
|
|
|
|
return _results;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Engine.prototype.applyOp = function(op_json) {
|
|
|
|
|
var o;
|
|
|
|
|
o = this.parseOperation(op_json);
|
|
|
|
|
this.HB.addToCounter(o);
|
|
|
|
|
if (!o.execute()) {
|
|
|
|
|
this.unprocessed_ops.push(o);
|
|
|
|
|
} else {
|
|
|
|
|
this.HB.addOperation(o);
|
|
|
|
|
}
|
|
|
|
|
return this.tryUnprocessed();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Engine.prototype.tryUnprocessed = function() {
|
|
|
|
|
var old_length, op, unprocessed, _i, _len, _ref, _results;
|
|
|
|
|
_results = [];
|
|
|
|
|
while (true) {
|
|
|
|
|
old_length = this.unprocessed_ops.length;
|
|
|
|
|
unprocessed = [];
|
|
|
|
|
_ref = this.unprocessed_ops;
|
|
|
|
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
|
|
|
op = _ref[_i];
|
|
|
|
|
if (!op.execute()) {
|
|
|
|
|
unprocessed.push(op);
|
|
|
|
|
} else {
|
|
|
|
|
this.HB.addOperation(op);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.unprocessed_ops = unprocessed;
|
|
|
|
|
if (this.unprocessed_ops.length === old_length) {
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
_results.push(void 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return _results;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return Engine;
|
|
|
|
|
|
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
module.exports = Engine;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
},{}],2:[function(require,module,exports){
|
|
|
|
|
var Engine, HistoryBuffer, TextFramework, text_types_uninitialized;
|
|
|
|
|
|
|
|
|
|
text_types_uninitialized = require("../Types/TextTypes");
|
|
|
|
|
|
|
|
|
|
HistoryBuffer = require("../HistoryBuffer");
|
|
|
|
|
|
|
|
|
|
Engine = require("../Engine");
|
|
|
|
|
|
|
|
|
|
TextFramework = (function() {
|
|
|
|
|
function TextFramework(user_id, Connector) {
|
|
|
|
|
var beg, beginning, end, first_word, text_types, uid_beg, uid_end, uid_r;
|
|
|
|
|
this.HB = new HistoryBuffer(user_id);
|
|
|
|
|
text_types = text_types_uninitialized(this.HB);
|
|
|
|
|
this.types = text_types.types;
|
|
|
|
|
this.engine = new Engine(this.HB, text_types.parser);
|
|
|
|
|
this.connector = new Connector(this.engine, this.HB, text_types.execution_listener, this);
|
|
|
|
|
beginning = this.HB.addOperation(new this.types.Delimiter({
|
|
|
|
|
creator: '_',
|
|
|
|
|
op_number: '_beginning'
|
|
|
|
|
}, void 0, void 0));
|
|
|
|
|
end = this.HB.addOperation(new this.types.Delimiter({
|
|
|
|
|
creator: '_',
|
|
|
|
|
op_number: '_end'
|
|
|
|
|
}, beginning, void 0));
|
|
|
|
|
beginning.next_cl = end;
|
|
|
|
|
beginning.execute();
|
|
|
|
|
end.execute();
|
|
|
|
|
first_word = new this.types.WordType({
|
|
|
|
|
creator: '_',
|
|
|
|
|
op_number: '_'
|
|
|
|
|
}, beginning, end);
|
|
|
|
|
this.HB.addOperation(first_word).execute();
|
|
|
|
|
uid_r = {
|
|
|
|
|
creator: '_',
|
|
|
|
|
op_number: "RM"
|
|
|
|
|
};
|
|
|
|
|
uid_beg = {
|
|
|
|
|
creator: '_',
|
|
|
|
|
op_number: "_RM_beginning"
|
|
|
|
|
};
|
|
|
|
|
uid_end = {
|
|
|
|
|
creator: '_',
|
|
|
|
|
op_number: "_RM_end"
|
|
|
|
|
};
|
|
|
|
|
beg = this.HB.addOperation(new this.types.Delimiter(uid_beg, void 0, uid_end)).execute();
|
|
|
|
|
end = this.HB.addOperation(new this.types.Delimiter(uid_end, beg, void 0)).execute();
|
|
|
|
|
this.root_element = this.HB.addOperation(new this.types.ReplaceManager(void 0, uid_r, beg, end)).execute();
|
|
|
|
|
this.root_element.replace(first_word, {
|
|
|
|
|
creator: '_',
|
|
|
|
|
op_number: 'Replaceable'
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TextFramework.prototype.getSharedObject = function() {
|
|
|
|
|
return this.root_element.val();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TextFramework.prototype.getConnector = function() {
|
|
|
|
|
return this.connector;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TextFramework.prototype.getHistoryBuffer = function() {
|
|
|
|
|
return this.HB;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TextFramework.prototype.getUserId = function() {
|
|
|
|
|
return this.HB.getUserId();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TextFramework.prototype.val = function() {
|
|
|
|
|
return this.getSharedObject().val();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TextFramework.prototype.insertText = function(pos, content) {
|
|
|
|
|
return this.getSharedObject().insertText(pos, content);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TextFramework.prototype.deleteText = function(pos, length) {
|
|
|
|
|
return this.getSharedObject().deleteText(pos, length);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TextFramework.prototype.bind = function(textarea) {
|
|
|
|
|
return this.getSharedObject().bind(textarea);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TextFramework.prototype.replaceText = function(text) {
|
|
|
|
|
return this.getSharedObject().replaceText(text);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TextFramework.prototype.on = function() {
|
|
|
|
|
var _ref;
|
|
|
|
|
return (_ref = this.root_element).on.apply(_ref, arguments);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return TextFramework;
|
|
|
|
|
|
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
module.exports = TextFramework;
|
|
|
|
|
|
|
|
|
|
if (typeof window !== "undefined" && window !== null) {
|
|
|
|
|
if (window.Y == null) {
|
|
|
|
|
window.Y = {};
|
|
|
|
|
}
|
|
|
|
|
window.Y.TextFramework = TextFramework;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
},{"../Engine":1,"../HistoryBuffer":3,"../Types/TextTypes":6}],3:[function(require,module,exports){
|
2014-09-17 16:10:41 +02:00
|
|
|
var HistoryBuffer,
|
|
|
|
|
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
2014-08-24 01:52:15 +02:00
|
|
|
|
|
|
|
|
HistoryBuffer = (function() {
|
|
|
|
|
function HistoryBuffer(user_id) {
|
|
|
|
|
this.user_id = user_id;
|
2014-09-17 16:10:41 +02:00
|
|
|
this.emptyGarbage = __bind(this.emptyGarbage, this);
|
2014-08-24 01:52:15 +02:00
|
|
|
this.operation_counter = {};
|
|
|
|
|
this.buffer = {};
|
|
|
|
|
this.change_listeners = [];
|
2014-09-17 16:10:41 +02:00
|
|
|
this.garbage = [];
|
|
|
|
|
this.trash = [];
|
|
|
|
|
this.performGarbageCollection = true;
|
|
|
|
|
this.garbageCollectTimeout = 1000;
|
|
|
|
|
this.reserved_identifier_counter = 0;
|
|
|
|
|
setTimeout(this.emptyGarbage, this.garbageCollectTimeout);
|
2014-08-24 01:52:15 +02:00
|
|
|
}
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
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;
|
|
|
|
|
};
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
HistoryBuffer.prototype.getUserId = function() {
|
|
|
|
|
return this.user_id;
|
|
|
|
|
};
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
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;
|
|
|
|
|
};
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
HistoryBuffer.prototype.getReservedUniqueIdentifier = function() {
|
|
|
|
|
return {
|
|
|
|
|
creator: '_',
|
2014-09-26 11:58:42 +02:00
|
|
|
op_number: "_" + (this.reserved_identifier_counter++),
|
|
|
|
|
doSync: false
|
2014-08-24 01:52:15 +02:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
HistoryBuffer.prototype.getOperationCounter = function(user_id) {
|
2014-08-24 01:52:15 +02:00
|
|
|
var ctn, res, user, _ref;
|
2014-09-17 16:10:41 +02:00
|
|
|
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];
|
2014-08-24 01:52:15 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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];
|
2014-09-17 16:10:41 +02:00
|
|
|
if (o.doSync && unknown(u_name, o_number)) {
|
2014-08-24 01:52:15 +02:00
|
|
|
o_json = o._encode();
|
|
|
|
|
if (o.next_cl != null) {
|
|
|
|
|
o_next = o.next_cl;
|
|
|
|
|
while ((o_next.next_cl != null) && unknown(o_next.creator, o_next.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.creator, o_prev.op_number)) {
|
|
|
|
|
o_prev = o_prev.prev_cl;
|
|
|
|
|
}
|
|
|
|
|
o_json.prev = o_prev.getUid();
|
|
|
|
|
}
|
|
|
|
|
json.push(o_json);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return json;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
HistoryBuffer.prototype.getNextOperationIdentifier = function(user_id) {
|
|
|
|
|
var uid;
|
|
|
|
|
if (user_id == null) {
|
|
|
|
|
user_id = this.user_id;
|
|
|
|
|
}
|
|
|
|
|
if (this.operation_counter[user_id] == null) {
|
|
|
|
|
this.operation_counter[user_id] = 0;
|
|
|
|
|
}
|
|
|
|
|
uid = {
|
|
|
|
|
'creator': user_id,
|
|
|
|
|
'op_number': this.operation_counter[user_id]
|
|
|
|
|
};
|
|
|
|
|
this.operation_counter[user_id]++;
|
|
|
|
|
return uid;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
HistoryBuffer.prototype.getOperation = function(uid) {
|
|
|
|
|
var _ref;
|
|
|
|
|
if (uid instanceof Object) {
|
|
|
|
|
return (_ref = this.buffer[uid.creator]) != null ? _ref[uid.op_number] : void 0;
|
|
|
|
|
} else if (uid == null) {
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
throw new Error("This type of uid is not defined!");
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
HistoryBuffer.prototype.addOperation = function(o) {
|
|
|
|
|
if (this.buffer[o.creator] == null) {
|
|
|
|
|
this.buffer[o.creator] = {};
|
|
|
|
|
}
|
|
|
|
|
if (this.buffer[o.creator][o.op_number] != null) {
|
|
|
|
|
throw new Error("You must not overwrite operations!");
|
|
|
|
|
}
|
|
|
|
|
this.buffer[o.creator][o.op_number] = o;
|
|
|
|
|
return o;
|
|
|
|
|
};
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
HistoryBuffer.prototype.removeOperation = function(o) {
|
|
|
|
|
var _ref;
|
|
|
|
|
return (_ref = this.buffer[o.creator]) != null ? delete _ref[o.op_number] : void 0;
|
|
|
|
|
};
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
HistoryBuffer.prototype.addToCounter = function(o) {
|
|
|
|
|
var _results;
|
|
|
|
|
if (this.operation_counter[o.creator] == null) {
|
|
|
|
|
this.operation_counter[o.creator] = 0;
|
|
|
|
|
}
|
|
|
|
|
if (typeof o.op_number === 'number' && o.creator !== this.getUserId()) {
|
|
|
|
|
if (o.op_number === this.operation_counter[o.creator]) {
|
|
|
|
|
this.operation_counter[o.creator]++;
|
|
|
|
|
_results = [];
|
|
|
|
|
while (this.getOperation({
|
|
|
|
|
creator: o.creator,
|
|
|
|
|
op_number: this.operation_counter[o.creator]
|
|
|
|
|
}) != null) {
|
|
|
|
|
_results.push(this.operation_counter[o.creator]++);
|
|
|
|
|
}
|
|
|
|
|
return _results;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return HistoryBuffer;
|
|
|
|
|
|
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
module.exports = HistoryBuffer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
},{}],4:[function(require,module,exports){
|
|
|
|
|
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) {
|
2014-09-17 16:10:41 +02:00
|
|
|
this.is_deleted = false;
|
|
|
|
|
this.doSync = true;
|
|
|
|
|
this.garbage_collected = false;
|
2014-09-26 11:58:42 +02:00
|
|
|
if (uid == null) {
|
2014-08-24 01:52:15 +02:00
|
|
|
uid = HB.getNextOperationIdentifier();
|
|
|
|
|
}
|
2014-09-26 11:58:42 +02:00
|
|
|
if (uid.doSync == null) {
|
|
|
|
|
uid.doSync = !isNaN(parseInt(uid.op_number));
|
|
|
|
|
}
|
|
|
|
|
this.creator = uid['creator'], this.op_number = uid['op_number'], this.doSync = uid['doSync'];
|
2014-08-24 01:52:15 +02:00
|
|
|
}
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
Operation.prototype.type = "Insert";
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
Operation.prototype.on = function(events, f) {
|
|
|
|
|
var e, _base, _i, _len, _results;
|
|
|
|
|
if (this.event_listeners == null) {
|
|
|
|
|
this.event_listeners = {};
|
|
|
|
|
}
|
|
|
|
|
if (events.constructor !== [].constructor) {
|
|
|
|
|
events = [events];
|
|
|
|
|
}
|
|
|
|
|
_results = [];
|
|
|
|
|
for (_i = 0, _len = events.length; _i < _len; _i++) {
|
|
|
|
|
e = events[_i];
|
|
|
|
|
if ((_base = this.event_listeners)[e] == null) {
|
|
|
|
|
_base[e] = [];
|
|
|
|
|
}
|
|
|
|
|
_results.push(this.event_listeners[e].push(f));
|
|
|
|
|
}
|
|
|
|
|
return _results;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Operation.prototype.deleteListener = function(events, f) {
|
|
|
|
|
var e, _i, _len, _ref, _results;
|
|
|
|
|
if (events.constructor !== [].constructor) {
|
|
|
|
|
events = [events];
|
|
|
|
|
}
|
|
|
|
|
_results = [];
|
|
|
|
|
for (_i = 0, _len = events.length; _i < _len; _i++) {
|
|
|
|
|
e = events[_i];
|
|
|
|
|
if (((_ref = this.event_listeners) != null ? _ref[e] : void 0) != null) {
|
|
|
|
|
_results.push(this.event_listeners[e] = this.event_listeners[e].filter(function(g) {
|
|
|
|
|
return f !== g;
|
|
|
|
|
}));
|
|
|
|
|
} else {
|
|
|
|
|
_results.push(void 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return _results;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Operation.prototype.callEvent = function() {
|
|
|
|
|
return this.forwardEvent.apply(this, [this].concat(__slice.call(arguments)));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Operation.prototype.forwardEvent = function() {
|
|
|
|
|
var args, event, f, op, _i, _len, _ref, _ref1, _results;
|
|
|
|
|
op = arguments[0], event = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
|
|
|
|
|
if (((_ref = this.event_listeners) != null ? _ref[event] : void 0) != null) {
|
|
|
|
|
_ref1 = this.event_listeners[event];
|
|
|
|
|
_results = [];
|
|
|
|
|
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
|
|
|
|
f = _ref1[_i];
|
|
|
|
|
_results.push(f.call.apply(f, [op, event].concat(__slice.call(args))));
|
|
|
|
|
}
|
|
|
|
|
return _results;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
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() {
|
|
|
|
|
return HB.removeOperation(this);
|
|
|
|
|
};
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
Operation.prototype.setParent = function(parent) {
|
|
|
|
|
this.parent = parent;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Operation.prototype.getParent = function() {
|
|
|
|
|
return this.parent;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Operation.prototype.getUid = function() {
|
|
|
|
|
return {
|
|
|
|
|
'creator': this.creator,
|
2014-09-17 16:10:41 +02:00
|
|
|
'op_number': this.op_number,
|
|
|
|
|
'sync': this.doSync
|
2014-08-24 01:52:15 +02:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
Operation.prototype.dontSync = function() {
|
|
|
|
|
return this.doSync = false;
|
|
|
|
|
};
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
Operation.prototype.execute = function() {
|
|
|
|
|
var l, _i, _len;
|
|
|
|
|
this.is_executed = true;
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
Delete.prototype.type = "Delete";
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
Insert.prototype.type = "Insert";
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
Insert.prototype.applyDelete = function(o) {
|
2014-09-29 09:58:44 +02:00
|
|
|
var garbagecollect, _ref;
|
2014-08-24 01:52:15 +02:00
|
|
|
if (this.deleted_by == null) {
|
|
|
|
|
this.deleted_by = [];
|
|
|
|
|
}
|
2014-09-17 16:10:41 +02:00
|
|
|
if ((this.parent != null) && !this.isDeleted()) {
|
2014-09-17 18:13:05 +02:00
|
|
|
this.parent.callEvent("delete", this, o);
|
2014-09-17 16:10:41 +02:00
|
|
|
}
|
|
|
|
|
if (o != null) {
|
|
|
|
|
this.deleted_by.push(o);
|
|
|
|
|
}
|
|
|
|
|
garbagecollect = false;
|
2014-09-29 09:58:44 +02:00
|
|
|
if (!((this.prev_cl != null) && (this.next_cl != null)) || this.prev_cl.isDeleted()) {
|
2014-09-17 16:10:41 +02:00
|
|
|
garbagecollect = true;
|
|
|
|
|
}
|
|
|
|
|
Insert.__super__.applyDelete.call(this, garbagecollect);
|
2014-09-29 09:58:44 +02:00
|
|
|
if ((_ref = this.next_cl) != null ? _ref.isDeleted() : void 0) {
|
2014-09-17 16:10:41 +02:00
|
|
|
return this.next_cl.applyDelete();
|
2014-08-24 01:52:15 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
Insert.prototype.cleanup = function() {
|
2014-09-29 09:58:44 +02:00
|
|
|
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];
|
2014-09-17 16:10:41 +02:00
|
|
|
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);
|
|
|
|
|
}
|
2014-08-24 01:52:15 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
};
|
|
|
|
|
|
2014-09-26 11:58:42 +02:00
|
|
|
Insert.prototype.execute = function(fire_event) {
|
2014-09-17 16:10:41 +02:00
|
|
|
var distance_to_origin, i, o, parent, _ref;
|
2014-09-26 11:58:42 +02:00
|
|
|
if (fire_event == null) {
|
|
|
|
|
fire_event = true;
|
|
|
|
|
}
|
2014-08-24 01:52:15 +02:00
|
|
|
if (!this.validateSavedOperations()) {
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
2014-09-17 16:10:41 +02:00
|
|
|
if (this.prev_cl != null) {
|
|
|
|
|
distance_to_origin = this.getDistanceToOrigin();
|
2014-08-24 01:52:15 +02:00
|
|
|
o = this.prev_cl.next_cl;
|
2014-09-17 16:10:41 +02:00
|
|
|
i = distance_to_origin;
|
2014-08-24 01:52:15 +02:00
|
|
|
while (true) {
|
|
|
|
|
if (o !== this.next_cl) {
|
|
|
|
|
if (o.getDistanceToOrigin() === i) {
|
|
|
|
|
if (o.creator < this.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;
|
|
|
|
|
}
|
2014-09-17 16:10:41 +02:00
|
|
|
parent = (_ref = this.prev_cl) != null ? _ref.getParent() : void 0;
|
2014-09-26 11:58:42 +02:00
|
|
|
if ((parent != null) && fire_event) {
|
2014-08-24 01:52:15 +02:00
|
|
|
this.setParent(parent);
|
|
|
|
|
this.parent.callEvent("insert", this);
|
|
|
|
|
}
|
|
|
|
|
return Insert.__super__.execute.apply(this, arguments);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Insert.prototype.getPosition = function() {
|
|
|
|
|
var position, prev;
|
|
|
|
|
position = 0;
|
|
|
|
|
prev = this.prev_cl;
|
|
|
|
|
while (true) {
|
|
|
|
|
if (prev instanceof Delimiter) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2014-09-17 16:10:41 +02:00
|
|
|
if (!prev.isDeleted()) {
|
2014-08-24 01:52:15 +02:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
ImmutableObject.prototype.type = "ImmutableObject";
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
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();
|
|
|
|
|
}
|
2014-09-17 16:10:41 +02:00
|
|
|
if (this.origin != null) {
|
|
|
|
|
json["origin"] = this.origin().getUid();
|
2014-08-24 01:52:15 +02:00
|
|
|
}
|
|
|
|
|
return json;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return ImmutableObject;
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
})(Operation);
|
2014-08-24 01:52:15 +02:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
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);
|
2014-08-24 01:52:15 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
delete this.prev_cl.unchecked.next_cl;
|
|
|
|
|
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;
|
|
|
|
|
return this.prev_cl.next_cl = this;
|
|
|
|
|
} else if ((this.prev_cl != null) || (this.next_cl != null)) {
|
|
|
|
|
return Delimiter.__super__.execute.apply(this, arguments);
|
|
|
|
|
} else {
|
|
|
|
|
throw new Error("Delimiter is unsufficient defined!");
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
},{}],5:[function(require,module,exports){
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
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);
|
|
|
|
|
};
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
MapManager.prototype.val = function(name, content) {
|
|
|
|
|
var o, obj, result, _ref, _ref1;
|
|
|
|
|
if (content != null) {
|
|
|
|
|
if (this.map[name] == null) {
|
|
|
|
|
HB.addOperation(new AddName(void 0, this, name)).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);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
AddName.prototype.type = "AddName";
|
|
|
|
|
|
|
|
|
|
AddName.prototype.applyDelete = function() {
|
|
|
|
|
return AddName.__super__.applyDelete.call(this);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
AddName.prototype.cleanup = function() {
|
|
|
|
|
return AddName.__super__.cleanup.call(this);
|
|
|
|
|
};
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
AddName.prototype.execute = function() {
|
2014-09-17 16:10:41 +02:00
|
|
|
var beg, end, uid_beg, uid_end, uid_r, _base;
|
2014-08-24 01:52:15 +02:00
|
|
|
if (!this.validateSavedOperations()) {
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
uid_r = this.map_manager.getUid();
|
|
|
|
|
uid_r.op_number = "_" + uid_r.op_number + "_RM_" + this.name;
|
|
|
|
|
if (HB.getOperation(uid_r) == null) {
|
|
|
|
|
uid_beg = this.map_manager.getUid();
|
|
|
|
|
uid_beg.op_number = "_" + uid_beg.op_number + "_RM_" + this.name + "_beginning";
|
|
|
|
|
uid_end = this.map_manager.getUid();
|
|
|
|
|
uid_end.op_number = "_" + uid_end.op_number + "_RM_" + this.name + "_end";
|
|
|
|
|
beg = HB.addOperation(new types.Delimiter(uid_beg, void 0, uid_end)).execute();
|
|
|
|
|
end = HB.addOperation(new types.Delimiter(uid_end, beg, void 0)).execute();
|
|
|
|
|
this.map_manager.map[this.name] = HB.addOperation(new ReplaceManager(void 0, uid_r, beg, end));
|
|
|
|
|
this.map_manager.map[this.name].setParent(this.map_manager, this.name);
|
2014-09-17 16:10:41 +02:00
|
|
|
((_base = this.map_manager.map[this.name]).add_name_ops != null ? _base.add_name_ops : _base.add_name_ops = []).push(this);
|
2014-08-24 01:52:15 +02:00
|
|
|
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 = HB.addOperation(new types.Delimiter(void 0, void 0, void 0));
|
|
|
|
|
this.end = HB.addOperation(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);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
ListManager.prototype.type = "ListManager";
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
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;
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
})(types.Operation);
|
2014-08-24 01:52:15 +02:00
|
|
|
ReplaceManager = (function(_super) {
|
|
|
|
|
__extends(ReplaceManager, _super);
|
|
|
|
|
|
|
|
|
|
function ReplaceManager(initial_content, uid, beginning, end, prev, next, origin) {
|
|
|
|
|
ReplaceManager.__super__.constructor.call(this, uid, beginning, end, prev, next, origin);
|
|
|
|
|
if (initial_content != null) {
|
|
|
|
|
this.replace(initial_content);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
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);
|
|
|
|
|
};
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
ReplaceManager.prototype.replace = function(content, replaceable_uid) {
|
|
|
|
|
var o, op;
|
|
|
|
|
o = this.getLastOperation();
|
|
|
|
|
op = new Replaceable(content, this, replaceable_uid, o, o.next_cl);
|
2014-09-17 16:10:41 +02:00
|
|
|
HB.addOperation(op).execute();
|
|
|
|
|
return void 0;
|
2014-08-24 01:52:15 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ReplaceManager.prototype.setParent = function(parent, property_name) {
|
2014-09-17 18:13:05 +02:00
|
|
|
var addPropertyListener, repl_manager;
|
|
|
|
|
repl_manager = this;
|
|
|
|
|
this.on('insert', function(event, op) {
|
|
|
|
|
if (op.next_cl instanceof types.Delimiter) {
|
|
|
|
|
return repl_manager.parent.callEvent('change', property_name, op);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
this.on('change', function(event, op) {
|
|
|
|
|
if (repl_manager !== this) {
|
|
|
|
|
return repl_manager.parent.callEvent('change', property_name, op);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
addPropertyListener = function(event, op) {
|
2014-09-26 11:58:42 +02:00
|
|
|
repl_manager.parent.callEvent('addProperty', property_name, op);
|
2014-09-17 18:13:05 +02:00
|
|
|
return repl_manager.deleteListener('addProperty', addPropertyListener);
|
|
|
|
|
};
|
2014-08-24 01:52:15 +02:00
|
|
|
this.on('insert', addPropertyListener);
|
|
|
|
|
return ReplaceManager.__super__.setParent.call(this, parent);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
2014-09-17 16:10:41 +02:00
|
|
|
if (this.origin != null) {
|
|
|
|
|
json["origin"] = this.origin().getUid();
|
2014-08-24 01:52:15 +02:00
|
|
|
}
|
|
|
|
|
return json;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return ReplaceManager;
|
|
|
|
|
|
|
|
|
|
})(ListManager);
|
|
|
|
|
parser["ReplaceManager"] = function(json) {
|
|
|
|
|
var beginning, content, end, next, origin, prev, uid;
|
|
|
|
|
content = json['content'], uid = json['uid'], prev = json['prev'], next = json['next'], origin = json['origin'], beginning = json['beginning'], end = json['end'];
|
|
|
|
|
return new ReplaceManager(content, 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);
|
2014-09-17 16:10:41 +02:00
|
|
|
if (!((prev != null) && (next != null))) {
|
|
|
|
|
throw new Error("You must define prev, and next for Replaceable-types!");
|
2014-08-24 01:52:15 +02:00
|
|
|
}
|
|
|
|
|
Replaceable.__super__.constructor.call(this, uid, prev, next, origin);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
Replaceable.prototype.type = "Replaceable";
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
Replaceable.prototype.val = function() {
|
|
|
|
|
return this.content;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Replaceable.prototype.replace = function(content) {
|
|
|
|
|
return this.parent.replace(content);
|
|
|
|
|
};
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
Replaceable.prototype.applyDelete = function() {
|
|
|
|
|
if (this.content != null) {
|
|
|
|
|
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);
|
|
|
|
|
};
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
Replaceable.prototype.execute = function() {
|
2014-09-17 16:10:41 +02:00
|
|
|
var ins_result, _ref;
|
2014-08-24 01:52:15 +02:00
|
|
|
if (!this.validateSavedOperations()) {
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
2014-09-17 16:10:41 +02:00
|
|
|
if ((_ref = this.content) != null) {
|
|
|
|
|
if (typeof _ref.setReplaceManager === "function") {
|
|
|
|
|
_ref.setReplaceManager(this.parent);
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-09-26 11:58:42 +02:00
|
|
|
ins_result = Replaceable.__super__.execute.call(this, this.content != null);
|
2014-09-17 16:10:41 +02:00
|
|
|
if (ins_result) {
|
|
|
|
|
if (this.next_cl.type === "Delimiter" && this.prev_cl.type !== "Delimiter") {
|
|
|
|
|
this.prev_cl.applyDelete();
|
|
|
|
|
} else if (this.next_cl.type !== "Delimiter") {
|
|
|
|
|
this.applyDelete();
|
|
|
|
|
}
|
2014-08-24 01:52:15 +02:00
|
|
|
}
|
2014-09-17 16:10:41 +02:00
|
|
|
return ins_result;
|
2014-08-24 01:52:15 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Replaceable.prototype._encode = function() {
|
2014-09-17 16:10:41 +02:00
|
|
|
var json, _ref;
|
2014-08-24 01:52:15 +02:00
|
|
|
json = {
|
|
|
|
|
'type': "Replaceable",
|
2014-09-17 16:10:41 +02:00
|
|
|
'content': (_ref = this.content) != null ? _ref.getUid() : void 0,
|
2014-08-24 01:52:15 +02:00
|
|
|
'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;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
},{"./BasicTypes":4}],6:[function(require,module,exports){
|
|
|
|
|
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) {
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
TextInsert.prototype.type = "TextInsert";
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
TextInsert.prototype.getLength = function() {
|
|
|
|
|
if (this.isDeleted()) {
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
return this.content.length;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
TextInsert.prototype.applyDelete = function() {
|
|
|
|
|
this.content = null;
|
|
|
|
|
return TextInsert.__super__.applyDelete.apply(this, arguments);
|
|
|
|
|
};
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
TextInsert.prototype.val = function(current_position) {
|
2014-09-17 16:10:41 +02:00
|
|
|
if (this.isDeleted() || (this.content == null)) {
|
2014-08-24 01:52:15 +02:00
|
|
|
return "";
|
|
|
|
|
} else {
|
|
|
|
|
return this.content;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TextInsert.prototype._encode = function() {
|
|
|
|
|
var json;
|
|
|
|
|
json = {
|
|
|
|
|
'type': "TextInsert",
|
|
|
|
|
'content': this.content,
|
|
|
|
|
'uid': this.getUid(),
|
|
|
|
|
'prev': this.prev_cl.getUid(),
|
|
|
|
|
'next': this.next_cl.getUid()
|
|
|
|
|
};
|
2014-09-17 16:10:41 +02:00
|
|
|
if (this.origin !== this.prev_cl) {
|
2014-08-24 01:52:15 +02:00
|
|
|
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";
|
|
|
|
|
|
2014-09-17 16:10:41 +02:00
|
|
|
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);
|
|
|
|
|
};
|
|
|
|
|
|
2014-09-29 09:58:44 +02:00
|
|
|
WordType.prototype.push = function(content) {
|
|
|
|
|
return this.insertAfter(this.end.prev_cl, content);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
WordType.prototype.insertAfter = function(left, content) {
|
|
|
|
|
var c, op, right, _i, _len;
|
2014-09-17 16:10:41 +02:00
|
|
|
while (left.isDeleted()) {
|
|
|
|
|
left = left.prev_cl;
|
|
|
|
|
}
|
|
|
|
|
right = left.next_cl;
|
2014-09-29 09:58:44 +02:00
|
|
|
if (content.type != null) {
|
|
|
|
|
op = new TextInsert(content, void 0, left, right);
|
2014-08-24 01:52:15 +02:00
|
|
|
HB.addOperation(op).execute();
|
2014-09-29 09:58:44 +02:00
|
|
|
} else {
|
|
|
|
|
for (_i = 0, _len = content.length; _i < _len; _i++) {
|
|
|
|
|
c = content[_i];
|
|
|
|
|
op = new TextInsert(c, void 0, left, right);
|
|
|
|
|
HB.addOperation(op).execute();
|
|
|
|
|
left = op;
|
|
|
|
|
}
|
2014-08-24 01:52:15 +02:00
|
|
|
}
|
|
|
|
|
return this;
|
|
|
|
|
};
|
|
|
|
|
|
2014-09-29 09:58:44 +02:00
|
|
|
WordType.prototype.insertText = function(position, content) {
|
|
|
|
|
var ith, left;
|
|
|
|
|
ith = this.getOperationByPosition(position);
|
|
|
|
|
left = ith.prev_cl;
|
|
|
|
|
return this.insertAfter(left, content);
|
|
|
|
|
};
|
|
|
|
|
|
2014-08-24 01:52:15 +02:00
|
|
|
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 = HB.addOperation(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.replaceText = function(text) {
|
|
|
|
|
var word;
|
|
|
|
|
if (this.replace_manager != null) {
|
|
|
|
|
word = HB.addOperation(new WordType(void 0)).execute();
|
|
|
|
|
word.insertText(0, text);
|
|
|
|
|
this.replace_manager.replace(word);
|
|
|
|
|
return word;
|
|
|
|
|
} else {
|
|
|
|
|
throw new Error("This type is currently not maintained by a ReplaceManager!");
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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.setReplaceManager = function(op) {
|
|
|
|
|
this.saveOperation('replace_manager', op);
|
|
|
|
|
this.validateSavedOperations();
|
2014-09-17 18:13:05 +02:00
|
|
|
this.on('insert', (function(_this) {
|
|
|
|
|
return function(event, ins) {
|
|
|
|
|
var _ref;
|
|
|
|
|
return (_ref = _this.replace_manager) != null ? _ref.forwardEvent(_this, 'change', ins) : void 0;
|
|
|
|
|
};
|
|
|
|
|
})(this));
|
|
|
|
|
return this.on('delete', (function(_this) {
|
|
|
|
|
return function(event, ins, del) {
|
2014-08-24 01:52:15 +02:00
|
|
|
var _ref;
|
2014-09-17 18:13:05 +02:00
|
|
|
return (_ref = _this.replace_manager) != null ? _ref.forwardEvent(_this, 'change', del) : void 0;
|
2014-08-24 01:52:15 +02:00
|
|
|
};
|
|
|
|
|
})(this));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
2014-09-17 16:10:41 +02:00
|
|
|
if (this.origin != null) {
|
|
|
|
|
json["origin"] = this.origin().getUid();
|
2014-08-24 01:52:15 +02:00
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
},{"./StructuredTypes":5}]},{},[2])
|
2014-09-29 09:58:44 +02:00
|
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9ub2RlX21vZHVsZXMvZ3VscC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbGliL0VuZ2luZS5jb2ZmZWUiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbGliL0ZyYW1ld29ya3MvVGV4dEZyYW1ld29yay5jb2ZmZWUiLCIvaG9tZS9kbW9uYWQvRHJvcGJveC9ZYXR0YSEvbGliL0hpc3RvcnlCdWZmZXIuY29mZmVlIiwiL2hvbWUvZG1vbmFkL0Ryb3Bib3gvWWF0dGEhL2xpYi9UeXBlcy9CYXNpY1R5cGVzLmNvZmZlZSIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9saWIvVHlwZXMvU3RydWN0dXJlZFR5cGVzLmNvZmZlZSIsIi9ob21lL2Rtb25hZC9Ecm9wYm94L1lhdHRhIS9saWIvVHlwZXMvVGV4dFR5cGVzLmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0tBLElBQUEsTUFBQTs7QUFBQTtBQU1lLEVBQUEsZ0JBQUUsRUFBRixFQUFPLE1BQVAsR0FBQTtBQUNYLElBRFksSUFBQyxDQUFBLEtBQUEsRUFDYixDQUFBO0FBQUEsSUFEaUIsSUFBQyxDQUFBLFNBQUEsTUFDbEIsQ0FBQTtBQUFBLElBQUEsSUFBQyxDQUFBLGVBQUQsR0FBbUIsRUFBbkIsQ0FEVztFQUFBLENBQWI7O0FBQUEsbUJBTUEsY0FBQSxHQUFnQixTQUFDLElBQUQsR0FBQTtBQUNkLFFBQUEsVUFBQTtBQUFBLElBQUEsVUFBQSxHQUFhLElBQUMsQ0FBQSxNQUFPLENBQUEsSUFBSSxDQUFDLElBQUwsQ0FBckIsQ0FBQTtBQUNBLElBQUEsSUFBRyxrQkFBSDthQUNFLFVBQUEsQ0FBVyxJQUFYLEVBREY7S0FBQSxNQUFBO0FBR0UsWUFBVSxJQUFBLEtBQUEsQ0FB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
|