Everything is working smoothly again. Execution speed increased by 10x. Cleaned up the code and unused stuff.
This commit is contained in:
parent
2cf899418a
commit
584964153c
File diff suppressed because one or more lines are too long
@ -1,142 +0,0 @@
|
||||
(function() {
|
||||
var createIwcConnector;
|
||||
|
||||
createIwcConnector = function(callback, options) {
|
||||
var IwcConnector, duiClient, init, iwcHandler, received_HB, userIwcHandler;
|
||||
userIwcHandler = null;
|
||||
if (options != null) {
|
||||
userIwcHandler = options.iwcHandler;
|
||||
}
|
||||
iwcHandler = {};
|
||||
duiClient = new DUIClient();
|
||||
duiClient.connect(function(intent) {
|
||||
var _ref;
|
||||
if ((_ref = iwcHandler[intent.action]) != null) {
|
||||
_ref.map(function(f) {
|
||||
return setTimeout(function() {
|
||||
return f(intent);
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
if (userIwcHandler != null) {
|
||||
return userIwcHandler(intent);
|
||||
}
|
||||
});
|
||||
duiClient.initOK();
|
||||
received_HB = null;
|
||||
IwcConnector = (function() {
|
||||
function IwcConnector(engine, HB, execution_listener, yatta) {
|
||||
var receiveHB, receive_, sendHistoryBuffer, send_;
|
||||
this.engine = engine;
|
||||
this.HB = HB;
|
||||
this.execution_listener = execution_listener;
|
||||
this.yatta = yatta;
|
||||
this.duiClient = duiClient;
|
||||
this.iwcHandler = iwcHandler;
|
||||
send_ = (function(_this) {
|
||||
return function(o) {
|
||||
if (Object.getOwnPropertyNames(_this.initialized).length !== 0) {
|
||||
return _this.send(o);
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
this.execution_listener.push(send_);
|
||||
this.initialized = {};
|
||||
receiveHB = (function(_this) {
|
||||
return function(json) {
|
||||
var him;
|
||||
HB = json.extras.HB;
|
||||
him = json.extras.user;
|
||||
_this.engine.applyOpsCheckDouble(HB);
|
||||
return _this.initialized[him] = true;
|
||||
};
|
||||
})(this);
|
||||
iwcHandler["Yatta_push_HB_element"] = [receiveHB];
|
||||
this.sendIwcIntent("Yatta_get_HB_element", this.HB.getOperationCounter());
|
||||
receive_ = (function(_this) {
|
||||
return function(intent) {
|
||||
var o;
|
||||
o = intent.extras;
|
||||
if (_this.initialized[o.uid.creator] != null) {
|
||||
return _this.receive(o);
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
this.iwcHandler["Yatta_new_operation"] = [receive_];
|
||||
if (received_HB != null) {
|
||||
this.engine.applyOpsCheckDouble(received_HB);
|
||||
}
|
||||
sendHistoryBuffer = (function(_this) {
|
||||
return function(intent) {
|
||||
var json, state_vector;
|
||||
state_vector = intent.extras;
|
||||
console.log(state_vector);
|
||||
json = {
|
||||
HB: _this.yatta.getHistoryBuffer()._encode(state_vector),
|
||||
user: _this.yatta.getUserId()
|
||||
};
|
||||
return _this.sendIwcIntent("Yatta_push_HB_element", json);
|
||||
};
|
||||
})(this);
|
||||
this.iwcHandler["Yatta_get_HB_element"] = [sendHistoryBuffer];
|
||||
}
|
||||
|
||||
IwcConnector.prototype.setIwcHandler = function(f) {
|
||||
return userIwcHandler = f;
|
||||
};
|
||||
|
||||
IwcConnector.prototype.sendIwcIntent = function(action_name, content) {
|
||||
var intent;
|
||||
intent = null;
|
||||
if (arguments.length >= 2) {
|
||||
action_name = arguments[0], content = arguments[1];
|
||||
intent = {
|
||||
action: action_name,
|
||||
component: "",
|
||||
data: "",
|
||||
dataType: "",
|
||||
flags: ["PUBLISH_GLOBAL"],
|
||||
extras: content
|
||||
};
|
||||
} else {
|
||||
intent = arguments[0];
|
||||
}
|
||||
return this.duiClient.sendIntent(intent);
|
||||
};
|
||||
|
||||
IwcConnector.prototype.send = function(o) {
|
||||
if (o.uid.creator === this.HB.getUserId() && (typeof o.uid.op_number !== "string")) {
|
||||
return this.sendIwcIntent("Yatta_new_operation", o);
|
||||
}
|
||||
};
|
||||
|
||||
IwcConnector.prototype.receive = function(o) {
|
||||
if (o.uid.creator !== this.HB.getUserId()) {
|
||||
return this.engine.applyOp(o);
|
||||
}
|
||||
};
|
||||
|
||||
return IwcConnector;
|
||||
|
||||
})();
|
||||
init = function() {
|
||||
var proposed_user_id;
|
||||
proposed_user_id = Math.floor(Math.random() * 1000000);
|
||||
return callback(IwcConnector, proposed_user_id);
|
||||
};
|
||||
setTimeout(init, 5000);
|
||||
return void 0;
|
||||
};
|
||||
|
||||
module.exports = createIwcConnector;
|
||||
|
||||
if (typeof window !== "undefined" && window !== null) {
|
||||
if (window.Y == null) {
|
||||
window.Y = {};
|
||||
}
|
||||
window.Y.createIwcConnector = createIwcConnector;
|
||||
}
|
||||
|
||||
}).call(this);
|
||||
|
||||
//# sourceMappingURL=../Connectors/IwcConnector.js.map
|
File diff suppressed because one or more lines are too long
@ -1,169 +0,0 @@
|
||||
(function() {
|
||||
var createPeerJsConnector;
|
||||
|
||||
createPeerJsConnector = function() {
|
||||
var PeerJsConnector, callback, peer;
|
||||
peer = null;
|
||||
if (arguments.length === 2) {
|
||||
peer = new Peer(arguments[0]);
|
||||
callback = arguments[1];
|
||||
} else {
|
||||
peer = new Peer(arguments[0], arguments[1]);
|
||||
peer.on('error', function(err) {
|
||||
throw new Error("Peerjs connector: " + err);
|
||||
});
|
||||
peer.on('disconnected', function() {
|
||||
throw new Error("Peerjs connector disconnected from signalling server. Cannot accept new connections. Not fatal, but not so good either..");
|
||||
});
|
||||
callback = arguments[2];
|
||||
}
|
||||
PeerJsConnector = (function() {
|
||||
function PeerJsConnector(engine, HB, execution_listener, yatta) {
|
||||
var send_, sync_every_collaborator;
|
||||
this.engine = engine;
|
||||
this.HB = HB;
|
||||
this.execution_listener = execution_listener;
|
||||
this.yatta = yatta;
|
||||
this.peer = peer;
|
||||
this.connections = {};
|
||||
this.new_connection_listeners = [];
|
||||
this.peer.on('connection', (function(_this) {
|
||||
return function(conn) {
|
||||
return _this.addConnection(conn);
|
||||
};
|
||||
})(this));
|
||||
sync_every_collaborator = (function(_this) {
|
||||
return function() {
|
||||
var conn, conn_id, _ref, _results;
|
||||
_ref = _this.connections;
|
||||
_results = [];
|
||||
for (conn_id in _ref) {
|
||||
conn = _ref[conn_id];
|
||||
_results.push(conn.send({
|
||||
sync_state_vector: _this.HB.getOperationCounter()
|
||||
}));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
})(this);
|
||||
setInterval(sync_every_collaborator, 4000);
|
||||
send_ = (function(_this) {
|
||||
return function(o) {
|
||||
var conn, conn_id, _ref, _results;
|
||||
if (o.uid.creator === _this.HB.getUserId() && (typeof o.uid.op_number !== "string")) {
|
||||
_ref = _this.connections;
|
||||
_results = [];
|
||||
for (conn_id in _ref) {
|
||||
conn = _ref[conn_id];
|
||||
_results.push(conn.send({
|
||||
op: o
|
||||
}));
|
||||
}
|
||||
return _results;
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
this.execution_listener.push(send_);
|
||||
}
|
||||
|
||||
PeerJsConnector.prototype.connectToPeer = function(id) {
|
||||
if ((this.connections[id] == null) && id !== this.yatta.getUserId()) {
|
||||
return this.addConnection(peer.connect(id));
|
||||
}
|
||||
};
|
||||
|
||||
PeerJsConnector.prototype.getAllConnectionIds = function() {
|
||||
var conn_id, _results;
|
||||
_results = [];
|
||||
for (conn_id in this.connections) {
|
||||
_results.push(conn_id);
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
|
||||
PeerJsConnector.prototype.onNewConnection = function(f) {
|
||||
return this.new_connection_listeners.push(f);
|
||||
};
|
||||
|
||||
PeerJsConnector.prototype.addConnection = function(conn) {
|
||||
var initialized_him, initialized_me, sendStateVector;
|
||||
this.connections[conn.peer] = conn;
|
||||
initialized_me = false;
|
||||
initialized_him = false;
|
||||
conn.on('data', (function(_this) {
|
||||
return function(data) {
|
||||
var conn_id, _i, _len, _ref, _results;
|
||||
if (data === "empty_message") {
|
||||
|
||||
} else if (data.HB != null) {
|
||||
initialized_me = true;
|
||||
_this.engine.applyOpsCheckDouble(data.HB);
|
||||
if (!data.initialized) {
|
||||
conn.send({
|
||||
conns: _this.getAllConnectionIds()
|
||||
});
|
||||
return _this.new_connection_listeners.map(function(f) {
|
||||
return f(conn);
|
||||
});
|
||||
}
|
||||
} else if (data.op != null) {
|
||||
return _this.engine.applyOp(data.op);
|
||||
} else if (data.conns != null) {
|
||||
_ref = data.conns;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
conn_id = _ref[_i];
|
||||
_results.push(_this.connectToPeer(conn_id));
|
||||
}
|
||||
return _results;
|
||||
} else if (data.sync_state_vector != null) {
|
||||
return conn.send({
|
||||
HB: _this.yatta.getHistoryBuffer()._encode(data.sync_state_vector),
|
||||
initialized: true
|
||||
});
|
||||
} else if (data.state_vector != null) {
|
||||
if (!initialized_him) {
|
||||
conn.send({
|
||||
HB: _this.yatta.getHistoryBuffer()._encode(data.state_vector),
|
||||
initialized: false
|
||||
});
|
||||
return initialized_him = true;
|
||||
}
|
||||
} else {
|
||||
throw new Error("Can't parse this operation: " + data);
|
||||
}
|
||||
};
|
||||
})(this));
|
||||
sendStateVector = (function(_this) {
|
||||
return function() {
|
||||
conn.send({
|
||||
state_vector: _this.HB.getOperationCounter()
|
||||
});
|
||||
if (!initialized_me) {
|
||||
return setTimeout(sendStateVector, 100);
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
return sendStateVector();
|
||||
};
|
||||
|
||||
return PeerJsConnector;
|
||||
|
||||
})();
|
||||
return peer.on('open', function(id) {
|
||||
return callback(PeerJsConnector, id);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = createPeerJsConnector;
|
||||
|
||||
if (typeof window !== "undefined" && window !== null) {
|
||||
if (window.Y == null) {
|
||||
window.Y = {};
|
||||
}
|
||||
window.Y.createPeerJsConnector = createPeerJsConnector;
|
||||
}
|
||||
|
||||
}).call(this);
|
||||
|
||||
//# sourceMappingURL=../Connectors/PeerJsConnector.js.map
|
File diff suppressed because one or more lines are too long
@ -1,90 +0,0 @@
|
||||
(function() {
|
||||
var _;
|
||||
|
||||
_ = require("underscore");
|
||||
|
||||
module.exports = function(user_list) {
|
||||
var TestConnector;
|
||||
return TestConnector = (function() {
|
||||
function TestConnector(engine, HB, execution_listener) {
|
||||
var appliedOperationsListener, send_;
|
||||
this.engine = engine;
|
||||
this.HB = HB;
|
||||
this.execution_listener = execution_listener;
|
||||
send_ = (function(_this) {
|
||||
return function(o) {
|
||||
return _this.send(o);
|
||||
};
|
||||
})(this);
|
||||
this.execution_listener.push(send_);
|
||||
this.applied_operations = [];
|
||||
appliedOperationsListener = (function(_this) {
|
||||
return function(o) {
|
||||
return _this.applied_operations.push(o);
|
||||
};
|
||||
})(this);
|
||||
this.execution_listener.push(appliedOperationsListener);
|
||||
if (!((user_list != null ? user_list.length : void 0) === 0)) {
|
||||
this.engine.applyOps(user_list[0].getHistoryBuffer()._encode());
|
||||
}
|
||||
this.HB.setManualGarbageCollect();
|
||||
this.unexecuted = {};
|
||||
}
|
||||
|
||||
TestConnector.prototype.getOpsInExecutionOrder = function() {
|
||||
return this.applied_operations;
|
||||
};
|
||||
|
||||
TestConnector.prototype.send = function(o) {
|
||||
var user, _i, _len, _results;
|
||||
if ((o.uid.creator === this.HB.getUserId()) && (typeof o.uid.op_number !== "string")) {
|
||||
_results = [];
|
||||
for (_i = 0, _len = user_list.length; _i < _len; _i++) {
|
||||
user = user_list[_i];
|
||||
if (user.getUserId() !== this.HB.getUserId()) {
|
||||
_results.push(user.getConnector().receive(o));
|
||||
} else {
|
||||
_results.push(void 0);
|
||||
}
|
||||
}
|
||||
return _results;
|
||||
}
|
||||
};
|
||||
|
||||
TestConnector.prototype.receive = function(o) {
|
||||
var _base, _name;
|
||||
if ((_base = this.unexecuted)[_name = o.uid.creator] == null) {
|
||||
_base[_name] = [];
|
||||
}
|
||||
return this.unexecuted[o.uid.creator].push(o);
|
||||
};
|
||||
|
||||
TestConnector.prototype.flushOne = function(user) {
|
||||
var _ref;
|
||||
if (((_ref = this.unexecuted[user]) != null ? _ref.length : void 0) > 0) {
|
||||
return this.engine.applyOp(this.unexecuted[user].shift());
|
||||
}
|
||||
};
|
||||
|
||||
TestConnector.prototype.flushOneRandom = function() {
|
||||
return this.flushOne(_.random(0, user_list.length - 1));
|
||||
};
|
||||
|
||||
TestConnector.prototype.flushAll = function() {
|
||||
var n, ops, _ref;
|
||||
_ref = this.unexecuted;
|
||||
for (n in _ref) {
|
||||
ops = _ref[n];
|
||||
this.engine.applyOps(ops);
|
||||
}
|
||||
return this.unexecuted = {};
|
||||
};
|
||||
|
||||
return TestConnector;
|
||||
|
||||
})();
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
|
||||
//# sourceMappingURL=../Connectors/TestConnector.js.map
|
@ -1 +0,0 @@
|
||||
{"version":3,"sources":["Connectors/TestConnector.coffee"],"names":[],"mappings":"AACA;AAAA,MAAA,CAAA;;AAAA,EAAA,CAAA,GAAI,OAAA,CAAQ,YAAR,CAAJ,CAAA;;AAAA,EAEA,MAAM,CAAC,OAAP,GAAiB,SAAC,SAAD,GAAA;AAMf,QAAA,aAAA;WAAM;AAQS,MAAA,uBAAE,MAAF,EAAW,EAAX,EAAgB,kBAAhB,GAAA;AACX,YAAA,gCAAA;AAAA,QADY,IAAC,CAAA,SAAA,MACb,CAAA;AAAA,QADqB,IAAC,CAAA,KAAA,EACtB,CAAA;AAAA,QAD0B,IAAC,CAAA,qBAAA,kBAC3B,CAAA;AAAA,QAAA,KAAA,GAAQ,CAAA,SAAA,KAAA,GAAA;iBAAA,SAAC,CAAD,GAAA;mBACN,KAAC,CAAA,IAAD,CAAM,CAAN,EADM;UAAA,EAAA;QAAA,CAAA,CAAA,CAAA,IAAA,CAAR,CAAA;AAAA,QAEA,IAAC,CAAA,kBAAkB,CAAC,IAApB,CAAyB,KAAzB,CAFA,CAAA;AAAA,QAIA,IAAC,CAAA,kBAAD,GAAsB,EAJtB,CAAA;AAAA,QAKA,yBAAA,GAA4B,CAAA,SAAA,KAAA,GAAA;iBAAA,SAAC,CAAD,GAAA;mBAC1B,KAAC,CAAA,kBAAkB,CAAC,IAApB,CAAyB,CAAzB,EAD0B;UAAA,EAAA;QAAA,CAAA,CAAA,CAAA,IAAA,CAL5B,CAAA;AAAA,QAOA,IAAC,CAAA,kBAAkB,CAAC,IAApB,CAAyB,yBAAzB,CAPA,CAAA;AAQA,QAAA,IAAG,CAAA,sBAAK,SAAS,CAAE,gBAAX,KAAqB,CAAtB,CAAP;AACE,UAAA,IAAC,CAAA,MAAM,CAAC,QAAR,CAAiB,SAAU,CAAA,CAAA,CAAE,CAAC,gBAAb,CAAA,CAA+B,CAAC,OAAhC,CAAA,CAAjB,CAAA,CADF;SARA;AAAA,QAWA,IAAC,CAAA,EAAE,CAAC,uBAAJ,CAAA,CAXA,CAAA;AAAA,QAYA,IAAC,CAAA,UAAD,GAAc,EAZd,CADW;MAAA,CAAb;;AAAA,8BAmBA,sBAAA,GAAwB,SAAA,GAAA;eACtB,IAAC,CAAA,mBADqB;MAAA,CAnBxB,CAAA;;AAAA,8BA0BA,IAAA,GAAM,SAAC,CAAD,GAAA;AACJ,YAAA,wBAAA;AAAA,QAAA,IAAG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAN,KAAiB,IAAC,CAAA,EAAE,CAAC,SAAJ,CAAA,CAAlB,CAAA,IAAuC,CAAC,MAAA,CAAA,CAAQ,CAAC,GAAG,CAAC,SAAb,KAA4B,QAA7B,CAA1C;AACE;eAAA,gDAAA;iCAAA;AACE,YAAA,IAAG,IAAI,CAAC,SAAL,CAAA,CAAA,KAAsB,IAAC,CAAA,EAAE,CAAC,SAAJ,CAAA,CAAzB;4BACE,IAAI,CAAC,YAAL,CAAA,CAAmB,CAAC,OAApB,CAA4B,CAA5B,GADF;aAAA,MAAA;oCAAA;aADF;AAAA;0BADF;SADI;MAAA,CA1BN,CAAA;;AAAA,8BAoCA,OAAA,GAAS,SAAC,CAAD,GAAA;AACP,YAAA,YAAA;;yBAA8B;SAA9B;eACA,IAAC,CAAA,UAAW,CAAA,CAAC,CAAC,GAAG,CAAC,OAAN,CAAc,CAAC,IAA3B,CAAgC,CAAhC,EAFO;MAAA,CApCT,CAAA;;AAAA,8BA2CA,QAAA,GAAU,SAAC,IAAD,GAAA;AACR,YAAA,IAAA;AAAA,QAAA,kDAAoB,CAAE,gBAAnB,GAA4B,CAA/B;iBACE,IAAC,CAAA,MAAM,CAAC,OAAR,CAAgB,IAAC,CAAA,UAAW,CAAA,IAAA,CAAK,CAAC,KAAlB,CAAA,CAAhB,EADF;SADQ;MAAA,CA3CV,CAAA;;AAAA,8BAkDA,cAAA,GAAgB,SAAA,GAAA;eACd,IAAC,CAAA,QAAD,CAAW,CAAC,CAAC,MAAF,CAAS,CAAT,EAAa,SAAS,CAAC,MAAV,GAAiB,CAA9B,CAAX,EADc;MAAA,CAlDhB,CAAA;;AAAA,8BAwDA,QAAA,GAAU,SAAA,GAAA;AACR,YAAA,YAAA;AAAA;AAAA,aAAA,SAAA;wBAAA;AACE,UAAA,IAAC,CAAA,MAAM,CAAC,QAAR,CAAiB,GAAjB,CAAA,CADF;AAAA,SAAA;eAEA,IAAC,CAAA,UAAD,GAAc,GAHN;MAAA,CAxDV,CAAA;;2BAAA;;SAda;EAAA,CAFjB,CAAA;AAAA","file":"Connectors/TestConnector.js","sourceRoot":"/source/","sourcesContent":["\n_ = require \"underscore\"\n\nmodule.exports = (user_list)->\n\n #\n # @nodoc\n # A trivial Connector that simulates network delay.\n #\n class TestConnector\n\n #\n # @param {Engine} engine The transformation engine\n # @param {HistoryBuffer} HB\n # @param {Array<Function>} execution_listener You must ensure that whenever an operation is executed, every function in this Array is called.\n # @param {Yatta} yatta The Yatta framework.\n #\n constructor: (@engine, @HB, @execution_listener)->\n send_ = (o)=>\n @send o\n @execution_listener.push send_\n\n @applied_operations = []\n appliedOperationsListener = (o)=>\n @applied_operations.push o\n @execution_listener.push appliedOperationsListener\n if not (user_list?.length is 0)\n @engine.applyOps user_list[0].getHistoryBuffer()._encode()\n\n @HB.setManualGarbageCollect()\n @unexecuted = {}\n\n #\n # This engine applied operations in a specific order.\n # Get the ops in the right order.\n #\n getOpsInExecutionOrder: ()->\n @applied_operations\n\n #\n # This function is called whenever an operation was executed.\n # @param {Operation} o The operation that was executed.\n #\n send: (o)->\n if (o.uid.creator is @HB.getUserId()) and (typeof o.uid.op_number isnt \"string\")\n for user in user_list\n if user.getUserId() isnt @HB.getUserId()\n user.getConnector().receive(o)\n\n #\n # This function is called whenever an operation was received from another peer.\n # @param {Operation} o The operation that was received.\n #\n receive: (o)->\n @unexecuted[o.uid.creator] ?= []\n @unexecuted[o.uid.creator].push o\n\n #\n # Flush one operation from the line of a specific user.\n #\n flushOne: (user)->\n if @unexecuted[user]?.length > 0\n @engine.applyOp @unexecuted[user].shift()\n\n #\n # Flush one operation on a random line.\n #\n flushOneRandom: ()->\n @flushOne (_.random 0, (user_list.length-1))\n\n #\n # Flush all operations on every line.\n #\n flushAll: ()->\n for n,ops of @unexecuted\n @engine.applyOps ops\n @unexecuted = {}\n\n"]}
|
@ -1,142 +0,0 @@
|
||||
(function() {
|
||||
var createIwcConnector;
|
||||
|
||||
createIwcConnector = function(callback, options) {
|
||||
var IwcConnector, duiClient, init, iwcHandler, received_HB, userIwcHandler;
|
||||
userIwcHandler = null;
|
||||
if (options != null) {
|
||||
userIwcHandler = options.iwcHandler;
|
||||
}
|
||||
iwcHandler = {};
|
||||
duiClient = new DUIClient();
|
||||
duiClient.connect(function(intent) {
|
||||
var _ref;
|
||||
if ((_ref = iwcHandler[intent.action]) != null) {
|
||||
_ref.map(function(f) {
|
||||
return setTimeout(function() {
|
||||
return f(intent);
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
if (userIwcHandler != null) {
|
||||
return userIwcHandler(intent);
|
||||
}
|
||||
});
|
||||
duiClient.initOK();
|
||||
received_HB = null;
|
||||
IwcConnector = (function() {
|
||||
function IwcConnector(engine, HB, execution_listener, yatta) {
|
||||
var receiveHB, receive_, sendHistoryBuffer, send_;
|
||||
this.engine = engine;
|
||||
this.HB = HB;
|
||||
this.execution_listener = execution_listener;
|
||||
this.yatta = yatta;
|
||||
this.duiClient = duiClient;
|
||||
this.iwcHandler = iwcHandler;
|
||||
send_ = (function(_this) {
|
||||
return function(o) {
|
||||
if (Object.getOwnPropertyNames(_this.initialized).length !== 0) {
|
||||
return _this.send(o);
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
this.execution_listener.push(send_);
|
||||
this.initialized = {};
|
||||
receiveHB = (function(_this) {
|
||||
return function(json) {
|
||||
var him;
|
||||
HB = json.extras.HB;
|
||||
him = json.extras.user;
|
||||
_this.engine.applyOpsCheckDouble(HB);
|
||||
return _this.initialized[him] = true;
|
||||
};
|
||||
})(this);
|
||||
iwcHandler["Yatta_push_HB_element"] = [receiveHB];
|
||||
this.sendIwcIntent("Yatta_get_HB_element", this.HB.getOperationCounter());
|
||||
receive_ = (function(_this) {
|
||||
return function(intent) {
|
||||
var o;
|
||||
o = intent.extras;
|
||||
if (_this.initialized[o.uid.creator] != null) {
|
||||
return _this.receive(o);
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
this.iwcHandler["Yatta_new_operation"] = [receive_];
|
||||
if (received_HB != null) {
|
||||
this.engine.applyOpsCheckDouble(received_HB);
|
||||
}
|
||||
sendHistoryBuffer = (function(_this) {
|
||||
return function(intent) {
|
||||
var json, state_vector;
|
||||
state_vector = intent.extras;
|
||||
console.log(state_vector);
|
||||
json = {
|
||||
HB: _this.yatta.getHistoryBuffer()._encode(state_vector),
|
||||
user: _this.yatta.getUserId()
|
||||
};
|
||||
return _this.sendIwcIntent("Yatta_push_HB_element", json);
|
||||
};
|
||||
})(this);
|
||||
this.iwcHandler["Yatta_get_HB_element"] = [sendHistoryBuffer];
|
||||
}
|
||||
|
||||
IwcConnector.prototype.setIwcHandler = function(f) {
|
||||
return userIwcHandler = f;
|
||||
};
|
||||
|
||||
IwcConnector.prototype.sendIwcIntent = function(action_name, content) {
|
||||
var intent;
|
||||
intent = null;
|
||||
if (arguments.length >= 2) {
|
||||
action_name = arguments[0], content = arguments[1];
|
||||
intent = {
|
||||
action: action_name,
|
||||
component: "",
|
||||
data: "",
|
||||
dataType: "",
|
||||
flags: ["PUBLISH_GLOBAL"],
|
||||
extras: content
|
||||
};
|
||||
} else {
|
||||
intent = arguments[0];
|
||||
}
|
||||
return this.duiClient.sendIntent(intent);
|
||||
};
|
||||
|
||||
IwcConnector.prototype.send = function(o) {
|
||||
if (o.uid.creator === this.HB.getUserId() && (typeof o.uid.op_number !== "string")) {
|
||||
return this.sendIwcIntent("Yatta_new_operation", o);
|
||||
}
|
||||
};
|
||||
|
||||
IwcConnector.prototype.receive = function(o) {
|
||||
if (o.uid.creator !== this.HB.getUserId()) {
|
||||
return this.engine.applyOp(o);
|
||||
}
|
||||
};
|
||||
|
||||
return IwcConnector;
|
||||
|
||||
})();
|
||||
init = function() {
|
||||
var proposed_user_id;
|
||||
proposed_user_id = Math.floor(Math.random() * 1000000);
|
||||
return callback(IwcConnector, proposed_user_id);
|
||||
};
|
||||
setTimeout(init, 5000);
|
||||
return void 0;
|
||||
};
|
||||
|
||||
module.exports = createIwcConnector;
|
||||
|
||||
if (typeof window !== "undefined" && window !== null) {
|
||||
if (window.Y == null) {
|
||||
window.Y = {};
|
||||
}
|
||||
window.Y.createIwcConnector = createIwcConnector;
|
||||
}
|
||||
|
||||
}).call(this);
|
||||
|
||||
//# sourceMappingURL=../ConnectorsDeprecated/IwcConnector.js.map
|
File diff suppressed because one or more lines are too long
@ -1,169 +0,0 @@
|
||||
(function() {
|
||||
var createPeerJsConnector;
|
||||
|
||||
createPeerJsConnector = function() {
|
||||
var PeerJsConnector, callback, peer;
|
||||
peer = null;
|
||||
if (arguments.length === 2) {
|
||||
peer = new Peer(arguments[0]);
|
||||
callback = arguments[1];
|
||||
} else {
|
||||
peer = new Peer(arguments[0], arguments[1]);
|
||||
peer.on('error', function(err) {
|
||||
throw new Error("Peerjs connector: " + err);
|
||||
});
|
||||
peer.on('disconnected', function() {
|
||||
throw new Error("Peerjs connector disconnected from signalling server. Cannot accept new connections. Not fatal, but not so good either..");
|
||||
});
|
||||
callback = arguments[2];
|
||||
}
|
||||
PeerJsConnector = (function() {
|
||||
function PeerJsConnector(engine, HB, execution_listener, yatta) {
|
||||
var send_, sync_every_collaborator;
|
||||
this.engine = engine;
|
||||
this.HB = HB;
|
||||
this.execution_listener = execution_listener;
|
||||
this.yatta = yatta;
|
||||
this.peer = peer;
|
||||
this.connections = {};
|
||||
this.new_connection_listeners = [];
|
||||
this.peer.on('connection', (function(_this) {
|
||||
return function(conn) {
|
||||
return _this.addConnection(conn);
|
||||
};
|
||||
})(this));
|
||||
sync_every_collaborator = (function(_this) {
|
||||
return function() {
|
||||
var conn, conn_id, _ref, _results;
|
||||
_ref = _this.connections;
|
||||
_results = [];
|
||||
for (conn_id in _ref) {
|
||||
conn = _ref[conn_id];
|
||||
_results.push(conn.send({
|
||||
sync_state_vector: _this.HB.getOperationCounter()
|
||||
}));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
})(this);
|
||||
setInterval(sync_every_collaborator, 4000);
|
||||
send_ = (function(_this) {
|
||||
return function(o) {
|
||||
var conn, conn_id, _ref, _results;
|
||||
if (o.uid.creator === _this.HB.getUserId() && (typeof o.uid.op_number !== "string")) {
|
||||
_ref = _this.connections;
|
||||
_results = [];
|
||||
for (conn_id in _ref) {
|
||||
conn = _ref[conn_id];
|
||||
_results.push(conn.send({
|
||||
op: o
|
||||
}));
|
||||
}
|
||||
return _results;
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
this.execution_listener.push(send_);
|
||||
}
|
||||
|
||||
PeerJsConnector.prototype.connectToPeer = function(id) {
|
||||
if ((this.connections[id] == null) && id !== this.yatta.getUserId()) {
|
||||
return this.addConnection(peer.connect(id));
|
||||
}
|
||||
};
|
||||
|
||||
PeerJsConnector.prototype.getAllConnectionIds = function() {
|
||||
var conn_id, _results;
|
||||
_results = [];
|
||||
for (conn_id in this.connections) {
|
||||
_results.push(conn_id);
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
|
||||
PeerJsConnector.prototype.onNewConnection = function(f) {
|
||||
return this.new_connection_listeners.push(f);
|
||||
};
|
||||
|
||||
PeerJsConnector.prototype.addConnection = function(conn) {
|
||||
var initialized_him, initialized_me, sendStateVector;
|
||||
this.connections[conn.peer] = conn;
|
||||
initialized_me = false;
|
||||
initialized_him = false;
|
||||
conn.on('data', (function(_this) {
|
||||
return function(data) {
|
||||
var conn_id, _i, _len, _ref, _results;
|
||||
if (data === "empty_message") {
|
||||
|
||||
} else if (data.HB != null) {
|
||||
initialized_me = true;
|
||||
_this.engine.applyOpsCheckDouble(data.HB);
|
||||
if (!data.initialized) {
|
||||
conn.send({
|
||||
conns: _this.getAllConnectionIds()
|
||||
});
|
||||
return _this.new_connection_listeners.map(function(f) {
|
||||
return f(conn);
|
||||
});
|
||||
}
|
||||
} else if (data.op != null) {
|
||||
return _this.engine.applyOp(data.op);
|
||||
} else if (data.conns != null) {
|
||||
_ref = data.conns;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
conn_id = _ref[_i];
|
||||
_results.push(_this.connectToPeer(conn_id));
|
||||
}
|
||||
return _results;
|
||||
} else if (data.sync_state_vector != null) {
|
||||
return conn.send({
|
||||
HB: _this.yatta.getHistoryBuffer()._encode(data.sync_state_vector),
|
||||
initialized: true
|
||||
});
|
||||
} else if (data.state_vector != null) {
|
||||
if (!initialized_him) {
|
||||
conn.send({
|
||||
HB: _this.yatta.getHistoryBuffer()._encode(data.state_vector),
|
||||
initialized: false
|
||||
});
|
||||
return initialized_him = true;
|
||||
}
|
||||
} else {
|
||||
throw new Error("Can't parse this operation: " + data);
|
||||
}
|
||||
};
|
||||
})(this));
|
||||
sendStateVector = (function(_this) {
|
||||
return function() {
|
||||
conn.send({
|
||||
state_vector: _this.HB.getOperationCounter()
|
||||
});
|
||||
if (!initialized_me) {
|
||||
return setTimeout(sendStateVector, 100);
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
return sendStateVector();
|
||||
};
|
||||
|
||||
return PeerJsConnector;
|
||||
|
||||
})();
|
||||
return peer.on('open', function(id) {
|
||||
return callback(PeerJsConnector, id);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = createPeerJsConnector;
|
||||
|
||||
if (typeof window !== "undefined" && window !== null) {
|
||||
if (window.Y == null) {
|
||||
window.Y = {};
|
||||
}
|
||||
window.Y.createPeerJsConnector = createPeerJsConnector;
|
||||
}
|
||||
|
||||
}).call(this);
|
||||
|
||||
//# sourceMappingURL=../ConnectorsDeprecated/PeerJsConnector.js.map
|
File diff suppressed because one or more lines are too long
@ -1,90 +0,0 @@
|
||||
(function() {
|
||||
var _;
|
||||
|
||||
_ = require("underscore");
|
||||
|
||||
module.exports = function(user_list) {
|
||||
var TestConnector;
|
||||
return TestConnector = (function() {
|
||||
function TestConnector(engine, HB, execution_listener) {
|
||||
var appliedOperationsListener, send_;
|
||||
this.engine = engine;
|
||||
this.HB = HB;
|
||||
this.execution_listener = execution_listener;
|
||||
send_ = (function(_this) {
|
||||
return function(o) {
|
||||
return _this.send(o);
|
||||
};
|
||||
})(this);
|
||||
this.execution_listener.push(send_);
|
||||
this.applied_operations = [];
|
||||
appliedOperationsListener = (function(_this) {
|
||||
return function(o) {
|
||||
return _this.applied_operations.push(o);
|
||||
};
|
||||
})(this);
|
||||
this.execution_listener.push(appliedOperationsListener);
|
||||
if (!((user_list != null ? user_list.length : void 0) === 0)) {
|
||||
this.engine.applyOps(user_list[0].getHistoryBuffer()._encode());
|
||||
}
|
||||
this.HB.setManualGarbageCollect();
|
||||
this.unexecuted = {};
|
||||
}
|
||||
|
||||
TestConnector.prototype.getOpsInExecutionOrder = function() {
|
||||
return this.applied_operations;
|
||||
};
|
||||
|
||||
TestConnector.prototype.send = function(o) {
|
||||
var user, _i, _len, _results;
|
||||
if ((o.uid.creator === this.HB.getUserId()) && (typeof o.uid.op_number !== "string")) {
|
||||
_results = [];
|
||||
for (_i = 0, _len = user_list.length; _i < _len; _i++) {
|
||||
user = user_list[_i];
|
||||
if (user.getUserId() !== this.HB.getUserId()) {
|
||||
_results.push(user.getConnector().receive(o));
|
||||
} else {
|
||||
_results.push(void 0);
|
||||
}
|
||||
}
|
||||
return _results;
|
||||
}
|
||||
};
|
||||
|
||||
TestConnector.prototype.receive = function(o) {
|
||||
var _base, _name;
|
||||
if ((_base = this.unexecuted)[_name = o.uid.creator] == null) {
|
||||
_base[_name] = [];
|
||||
}
|
||||
return this.unexecuted[o.uid.creator].push(o);
|
||||
};
|
||||
|
||||
TestConnector.prototype.flushOne = function(user) {
|
||||
var _ref;
|
||||
if (((_ref = this.unexecuted[user]) != null ? _ref.length : void 0) > 0) {
|
||||
return this.engine.applyOp(this.unexecuted[user].shift());
|
||||
}
|
||||
};
|
||||
|
||||
TestConnector.prototype.flushOneRandom = function() {
|
||||
return this.flushOne(_.random(0, user_list.length - 1));
|
||||
};
|
||||
|
||||
TestConnector.prototype.flushAll = function() {
|
||||
var n, ops, _ref;
|
||||
_ref = this.unexecuted;
|
||||
for (n in _ref) {
|
||||
ops = _ref[n];
|
||||
this.engine.applyOps(ops);
|
||||
}
|
||||
return this.unexecuted = {};
|
||||
};
|
||||
|
||||
return TestConnector;
|
||||
|
||||
})();
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
|
||||
//# sourceMappingURL=../ConnectorsDeprecated/TestConnector.js.map
|
@ -1 +0,0 @@
|
||||
{"version":3,"sources":["ConnectorsDeprecated/TestConnector.coffee"],"names":[],"mappings":"AACA;AAAA,MAAA,CAAA;;AAAA,EAAA,CAAA,GAAI,OAAA,CAAQ,YAAR,CAAJ,CAAA;;AAAA,EAEA,MAAM,CAAC,OAAP,GAAiB,SAAC,SAAD,GAAA;AAMf,QAAA,aAAA;WAAM;AAQS,MAAA,uBAAE,MAAF,EAAW,EAAX,EAAgB,kBAAhB,GAAA;AACX,YAAA,gCAAA;AAAA,QADY,IAAC,CAAA,SAAA,MACb,CAAA;AAAA,QADqB,IAAC,CAAA,KAAA,EACtB,CAAA;AAAA,QAD0B,IAAC,CAAA,qBAAA,kBAC3B,CAAA;AAAA,QAAA,KAAA,GAAQ,CAAA,SAAA,KAAA,GAAA;iBAAA,SAAC,CAAD,GAAA;mBACN,KAAC,CAAA,IAAD,CAAM,CAAN,EADM;UAAA,EAAA;QAAA,CAAA,CAAA,CAAA,IAAA,CAAR,CAAA;AAAA,QAEA,IAAC,CAAA,kBAAkB,CAAC,IAApB,CAAyB,KAAzB,CAFA,CAAA;AAAA,QAIA,IAAC,CAAA,kBAAD,GAAsB,EAJtB,CAAA;AAAA,QAKA,yBAAA,GAA4B,CAAA,SAAA,KAAA,GAAA;iBAAA,SAAC,CAAD,GAAA;mBAC1B,KAAC,CAAA,kBAAkB,CAAC,IAApB,CAAyB,CAAzB,EAD0B;UAAA,EAAA;QAAA,CAAA,CAAA,CAAA,IAAA,CAL5B,CAAA;AAAA,QAOA,IAAC,CAAA,kBAAkB,CAAC,IAApB,CAAyB,yBAAzB,CAPA,CAAA;AAQA,QAAA,IAAG,CAAA,sBAAK,SAAS,CAAE,gBAAX,KAAqB,CAAtB,CAAP;AACE,UAAA,IAAC,CAAA,MAAM,CAAC,QAAR,CAAiB,SAAU,CAAA,CAAA,CAAE,CAAC,gBAAb,CAAA,CAA+B,CAAC,OAAhC,CAAA,CAAjB,CAAA,CADF;SARA;AAAA,QAWA,IAAC,CAAA,EAAE,CAAC,uBAAJ,CAAA,CAXA,CAAA;AAAA,QAYA,IAAC,CAAA,UAAD,GAAc,EAZd,CADW;MAAA,CAAb;;AAAA,8BAmBA,sBAAA,GAAwB,SAAA,GAAA;eACtB,IAAC,CAAA,mBADqB;MAAA,CAnBxB,CAAA;;AAAA,8BA0BA,IAAA,GAAM,SAAC,CAAD,GAAA;AACJ,YAAA,wBAAA;AAAA,QAAA,IAAG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAN,KAAiB,IAAC,CAAA,EAAE,CAAC,SAAJ,CAAA,CAAlB,CAAA,IAAuC,CAAC,MAAA,CAAA,CAAQ,CAAC,GAAG,CAAC,SAAb,KAA4B,QAA7B,CAA1C;AACE;eAAA,gDAAA;iCAAA;AACE,YAAA,IAAG,IAAI,CAAC,SAAL,CAAA,CAAA,KAAsB,IAAC,CAAA,EAAE,CAAC,SAAJ,CAAA,CAAzB;4BACE,IAAI,CAAC,YAAL,CAAA,CAAmB,CAAC,OAApB,CAA4B,CAA5B,GADF;aAAA,MAAA;oCAAA;aADF;AAAA;0BADF;SADI;MAAA,CA1BN,CAAA;;AAAA,8BAoCA,OAAA,GAAS,SAAC,CAAD,GAAA;AACP,YAAA,YAAA;;yBAA8B;SAA9B;eACA,IAAC,CAAA,UAAW,CAAA,CAAC,CAAC,GAAG,CAAC,OAAN,CAAc,CAAC,IAA3B,CAAgC,CAAhC,EAFO;MAAA,CApCT,CAAA;;AAAA,8BA2CA,QAAA,GAAU,SAAC,IAAD,GAAA;AACR,YAAA,IAAA;AAAA,QAAA,kDAAoB,CAAE,gBAAnB,GAA4B,CAA/B;iBACE,IAAC,CAAA,MAAM,CAAC,OAAR,CAAgB,IAAC,CAAA,UAAW,CAAA,IAAA,CAAK,CAAC,KAAlB,CAAA,CAAhB,EADF;SADQ;MAAA,CA3CV,CAAA;;AAAA,8BAkDA,cAAA,GAAgB,SAAA,GAAA;eACd,IAAC,CAAA,QAAD,CAAW,CAAC,CAAC,MAAF,CAAS,CAAT,EAAa,SAAS,CAAC,MAAV,GAAiB,CAA9B,CAAX,EADc;MAAA,CAlDhB,CAAA;;AAAA,8BAwDA,QAAA,GAAU,SAAA,GAAA;AACR,YAAA,YAAA;AAAA;AAAA,aAAA,SAAA;wBAAA;AACE,UAAA,IAAC,CAAA,MAAM,CAAC,QAAR,CAAiB,GAAjB,CAAA,CADF;AAAA,SAAA;eAEA,IAAC,CAAA,UAAD,GAAc,GAHN;MAAA,CAxDV,CAAA;;2BAAA;;SAda;EAAA,CAFjB,CAAA;AAAA","file":"ConnectorsDeprecated/TestConnector.js","sourceRoot":"/source/","sourcesContent":["\n_ = require \"underscore\"\n\nmodule.exports = (user_list)->\n\n #\n # @nodoc\n # A trivial Connector that simulates network delay.\n #\n class TestConnector\n\n #\n # @param {Engine} engine The transformation engine\n # @param {HistoryBuffer} HB\n # @param {Array<Function>} execution_listener You must ensure that whenever an operation is executed, every function in this Array is called.\n # @param {Yatta} yatta The Yatta framework.\n #\n constructor: (@engine, @HB, @execution_listener)->\n send_ = (o)=>\n @send o\n @execution_listener.push send_\n\n @applied_operations = []\n appliedOperationsListener = (o)=>\n @applied_operations.push o\n @execution_listener.push appliedOperationsListener\n if not (user_list?.length is 0)\n @engine.applyOps user_list[0].getHistoryBuffer()._encode()\n\n @HB.setManualGarbageCollect()\n @unexecuted = {}\n\n #\n # This engine applied operations in a specific order.\n # Get the ops in the right order.\n #\n getOpsInExecutionOrder: ()->\n @applied_operations\n\n #\n # This function is called whenever an operation was executed.\n # @param {Operation} o The operation that was executed.\n #\n send: (o)->\n if (o.uid.creator is @HB.getUserId()) and (typeof o.uid.op_number isnt \"string\")\n for user in user_list\n if user.getUserId() isnt @HB.getUserId()\n user.getConnector().receive(o)\n\n #\n # This function is called whenever an operation was received from another peer.\n # @param {Operation} o The operation that was received.\n #\n receive: (o)->\n @unexecuted[o.uid.creator] ?= []\n @unexecuted[o.uid.creator].push o\n\n #\n # Flush one operation from the line of a specific user.\n #\n flushOne: (user)->\n if @unexecuted[user]?.length > 0\n @engine.applyOp @unexecuted[user].shift()\n\n #\n # Flush one operation on a random line.\n #\n flushOneRandom: ()->\n @flushOne (_.random 0, (user_list.length-1))\n\n #\n # Flush all operations on every line.\n #\n flushAll: ()->\n for n,ops of @unexecuted\n @engine.applyOps ops\n @unexecuted = {}\n\n"]}
|
@ -19,7 +19,7 @@
|
||||
};
|
||||
|
||||
Engine.prototype.applyOpsBundle = function(ops_json) {
|
||||
var o, ops, _i, _j, _k, _len, _len1, _len2;
|
||||
var o, ops, _i, _j, _len, _len1;
|
||||
ops = [];
|
||||
for (_i = 0, _len = ops_json.length; _i < _len; _i++) {
|
||||
o = ops_json[_i];
|
||||
@ -27,10 +27,6 @@
|
||||
}
|
||||
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);
|
||||
}
|
||||
@ -70,8 +66,6 @@
|
||||
|
||||
} else if (!o.execute()) {
|
||||
this.unprocessed_ops.push(o);
|
||||
} else {
|
||||
this.HB.addOperation(o);
|
||||
}
|
||||
return this.tryUnprocessed();
|
||||
};
|
||||
@ -89,8 +83,6 @@
|
||||
|
||||
} else if (!op.execute()) {
|
||||
unprocessed.push(op);
|
||||
} else {
|
||||
this.HB.addOperation(op);
|
||||
}
|
||||
}
|
||||
this.unprocessed_ops = unprocessed;
|
||||
|
2
build/node/Engine.js.map
Executable file → Normal file
2
build/node/Engine.js.map
Executable file → Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,114 +0,0 @@
|
||||
(function() {
|
||||
var Engine, HistoryBuffer, TextFramework, adaptConnector, text_types_uninitialized;
|
||||
|
||||
text_types_uninitialized = require("../Types/TextTypes");
|
||||
|
||||
HistoryBuffer = require("../HistoryBuffer");
|
||||
|
||||
Engine = require("../Engine");
|
||||
|
||||
adaptConnector = require("../ConnectorAdapter");
|
||||
|
||||
TextFramework = (function() {
|
||||
function TextFramework(user_id, connector) {
|
||||
var beg, beginning, end, first_word, text_types, uid_beg, uid_end, uid_r;
|
||||
this.connector = connector;
|
||||
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);
|
||||
adaptConnector(this.connector, this.engine, this.HB, text_types.execution_listener);
|
||||
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;
|
||||
}
|
||||
|
||||
}).call(this);
|
||||
|
||||
//# sourceMappingURL=../Frameworks/TextFramework.js.map
|
File diff suppressed because one or more lines are too long
@ -1,88 +0,0 @@
|
||||
(function() {
|
||||
var Engine, HistoryBuffer, XmlFramework, adaptConnector, json_types_uninitialized;
|
||||
|
||||
json_types_uninitialized = require("../Types/XmlTypes");
|
||||
|
||||
HistoryBuffer = require("../HistoryBuffer");
|
||||
|
||||
Engine = require("../Engine");
|
||||
|
||||
adaptConnector = require("../ConnectorAdapter");
|
||||
|
||||
XmlFramework = (function() {
|
||||
function XmlFramework(user_id, connector) {
|
||||
var beg, end, type_manager, uid_beg, uid_end;
|
||||
this.connector = connector;
|
||||
this.HB = new HistoryBuffer(user_id);
|
||||
type_manager = json_types_uninitialized(this.HB);
|
||||
this.types = type_manager.types;
|
||||
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);
|
||||
uid_beg = this.HB.getReservedUniqueIdentifier();
|
||||
uid_end = this.HB.getReservedUniqueIdentifier();
|
||||
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 = new this.types.ReplaceManager(void 0, this.HB.getReservedUniqueIdentifier(), beg, end);
|
||||
this.HB.addOperation(this.root_element).execute();
|
||||
}
|
||||
|
||||
XmlFramework.prototype.getSharedObject = function() {
|
||||
return this.root_element.val();
|
||||
};
|
||||
|
||||
XmlFramework.prototype.getConnector = function() {
|
||||
return this.connector;
|
||||
};
|
||||
|
||||
XmlFramework.prototype.getHistoryBuffer = function() {
|
||||
return this.HB;
|
||||
};
|
||||
|
||||
XmlFramework.prototype.setMutableDefault = function(mutable) {
|
||||
return this.getSharedObject().setMutableDefault(mutable);
|
||||
};
|
||||
|
||||
XmlFramework.prototype.getUserId = function() {
|
||||
return this.HB.getUserId();
|
||||
};
|
||||
|
||||
XmlFramework.prototype.toJson = function() {
|
||||
return this.getSharedObject().toJson();
|
||||
};
|
||||
|
||||
XmlFramework.prototype.val = function() {
|
||||
var newXml;
|
||||
if ((arguments.length === 0) || (typeof arguments[0] === "boolean")) {
|
||||
return this.getSharedObject().val(arguments[0]);
|
||||
} else if (arguments.length === 1) {
|
||||
newXml = new this.types.XmlType(void 0, void 0, void 0, void 0, arguments[0]);
|
||||
this.HB.addOperation(newXml).execute();
|
||||
this.root_element.replace(newXml);
|
||||
return newXml;
|
||||
} else {
|
||||
throw new Error("can only parse 0, or 1 parameter!");
|
||||
}
|
||||
};
|
||||
|
||||
XmlFramework.prototype.on = function() {
|
||||
var _ref;
|
||||
return (_ref = this.getSharedObject()).on.apply(_ref, arguments);
|
||||
};
|
||||
|
||||
return XmlFramework;
|
||||
|
||||
})();
|
||||
|
||||
module.exports = XmlFramework;
|
||||
|
||||
if (typeof window !== "undefined" && window !== null) {
|
||||
if (window.Y == null) {
|
||||
window.Y = {};
|
||||
}
|
||||
window.Y.XmlFramework = XmlFramework;
|
||||
}
|
||||
|
||||
}).call(this);
|
||||
|
||||
//# sourceMappingURL=../Frameworks/XmlFramework.js.map
|
File diff suppressed because one or more lines are too long
@ -1,211 +0,0 @@
|
||||
(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.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.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;
|
||||
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.creator]) != null ? delete _ref[o.op_number] : void 0;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
}).call(this);
|
||||
|
||||
//# sourceMappingURL=HistoryBuffer.js.map
|
1
build/node/HistoryBuffer.js.map
Executable file → Normal file
1
build/node/HistoryBuffer.js.map
Executable file → Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,480 +0,0 @@
|
||||
(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.doSync = true;
|
||||
this.garbage_collected = false;
|
||||
if (uid == null) {
|
||||
uid = HB.getNextOperationIdentifier();
|
||||
}
|
||||
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'];
|
||||
}
|
||||
|
||||
Operation.prototype.type = "Insert";
|
||||
|
||||
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.deleteAllListeners = 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, 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;
|
||||
}
|
||||
};
|
||||
|
||||
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.deleteAllListeners();
|
||||
};
|
||||
|
||||
Operation.prototype.setParent = function(parent) {
|
||||
this.parent = parent;
|
||||
};
|
||||
|
||||
Operation.prototype.getParent = function() {
|
||||
return this.parent;
|
||||
};
|
||||
|
||||
Operation.prototype.getUid = function() {
|
||||
return {
|
||||
'creator': this.creator,
|
||||
'op_number': this.op_number,
|
||||
'sync': this.doSync
|
||||
};
|
||||
};
|
||||
|
||||
Operation.prototype.dontSync = function() {
|
||||
return this.doSync = false;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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()) {
|
||||
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("delete", this, o);
|
||||
}
|
||||
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(fire_event) {
|
||||
var distance_to_origin, i, o, parent, _ref;
|
||||
if (fire_event == null) {
|
||||
fire_event = true;
|
||||
}
|
||||
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.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;
|
||||
}
|
||||
parent = (_ref = this.prev_cl) != null ? _ref.getParent() : void 0;
|
||||
if ((parent != null) && fire_event) {
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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
|
||||
};
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
|
||||
//# sourceMappingURL=../Types/BasicTypes.js.map
|
File diff suppressed because one or more lines are too long
@ -1,266 +0,0 @@
|
||||
(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; },
|
||||
__slice = [].slice;
|
||||
|
||||
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(uid, initial_value, mutable) {
|
||||
var name, o;
|
||||
JsonType.__super__.constructor.call(this, uid);
|
||||
if (initial_value != null) {
|
||||
if (typeof initial_value !== "object") {
|
||||
throw new Error("The initial value of JsonTypes must be of type Object! (current type: " + (typeof initial_value) + ")");
|
||||
}
|
||||
for (name in initial_value) {
|
||||
o = initial_value[name];
|
||||
this.val(name, o, mutable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) && false) {
|
||||
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.type === "add" || (event.type = "update")) {
|
||||
_results.push(that.val(event.name, event.object[event.name]));
|
||||
} else {
|
||||
_results.push(void 0);
|
||||
}
|
||||
}
|
||||
return _results;
|
||||
});
|
||||
that.on('change', function(event_name, property_name, op) {
|
||||
var notifier, oldVal;
|
||||
if (this === that) {
|
||||
notifier = Object.getNotifier(that.bound_json);
|
||||
oldVal = that.bound_json[property_name];
|
||||
if (oldVal != null) {
|
||||
notifier.performChange('update', function() {
|
||||
return that.bound_json[property_name] = that.val(property_name);
|
||||
}, that.bound_json);
|
||||
return notifier.notify({
|
||||
object: that.bound_json,
|
||||
type: 'update',
|
||||
name: property_name,
|
||||
oldValue: oldVal,
|
||||
changed_by: op.creator
|
||||
});
|
||||
} else {
|
||||
notifier.performChange('add', function() {
|
||||
return that.bound_json[property_name] = that.val(property_name);
|
||||
}, that.bound_json);
|
||||
return notifier.notify({
|
||||
object: that.bound_json,
|
||||
type: 'add',
|
||||
name: property_name,
|
||||
oldValue: oldVal,
|
||||
changed_by: op.creator
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return this.bound_json;
|
||||
};
|
||||
|
||||
JsonType.prototype.setReplaceManager = function(replace_manager) {
|
||||
this.replace_manager = replace_manager;
|
||||
return this.on(['change', 'addProperty'], function() {
|
||||
var _ref;
|
||||
if (replace_manager.parent != null) {
|
||||
return (_ref = replace_manager.parent).forwardEvent.apply(_ref, [this].concat(__slice.call(arguments)));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
JsonType.prototype.getParent = function() {
|
||||
return this.replace_manager.parent;
|
||||
};
|
||||
|
||||
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, obj, word;
|
||||
if (typeof name === 'object') {
|
||||
json = new JsonType(void 0, name, content);
|
||||
HB.addOperation(json).execute();
|
||||
this.replace_manager.replace(json);
|
||||
return this;
|
||||
} else 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)) {
|
||||
obj = HB.addOperation(new types.ImmutableObject(void 0, content)).execute();
|
||||
return JsonType.__super__.val.call(this, name, obj);
|
||||
} else {
|
||||
if (typeof content === 'string') {
|
||||
word = HB.addOperation(new types.WordType(void 0)).execute();
|
||||
word.insertText(0, content);
|
||||
return JsonType.__super__.val.call(this, name, word);
|
||||
} else if (content.constructor === Object) {
|
||||
json = HB.addOperation(new JsonType(void 0, content, mutable)).execute();
|
||||
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
@ -1,390 +0,0 @@
|
||||
(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, 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);
|
||||
}
|
||||
|
||||
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, end, uid_beg, uid_end, uid_r, _base;
|
||||
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);
|
||||
((_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 = 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);
|
||||
}
|
||||
|
||||
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(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);
|
||||
}
|
||||
}
|
||||
|
||||
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.replace = function(content, replaceable_uid) {
|
||||
var o, op;
|
||||
o = this.getLastOperation();
|
||||
op = new Replaceable(content, this, replaceable_uid, o, o.next_cl);
|
||||
HB.addOperation(op).execute();
|
||||
return void 0;
|
||||
};
|
||||
|
||||
ReplaceManager.prototype.setParent = function(parent, property_name) {
|
||||
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) {
|
||||
repl_manager.deleteListener('insert', addPropertyListener);
|
||||
return repl_manager.parent.callEvent('addProperty', property_name, op);
|
||||
};
|
||||
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();
|
||||
}
|
||||
if (this.origin != null) {
|
||||
json["origin"] = this.origin().getUid();
|
||||
}
|
||||
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);
|
||||
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.replace = function(content) {
|
||||
return this.parent.replace(content);
|
||||
};
|
||||
|
||||
Replaceable.prototype.applyDelete = function() {
|
||||
if (this.content != null) {
|
||||
if (this.next_cl.type !== "Delimiter") {
|
||||
this.content.deleteAllListeners();
|
||||
}
|
||||
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.execute = function() {
|
||||
var ins_result, _ref;
|
||||
if (!this.validateSavedOperations()) {
|
||||
return false;
|
||||
} else {
|
||||
if ((_ref = this.content) != null) {
|
||||
if (typeof _ref.setReplaceManager === "function") {
|
||||
_ref.setReplaceManager(this.parent);
|
||||
}
|
||||
}
|
||||
ins_result = Replaceable.__super__.execute.call(this, this.content != null);
|
||||
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();
|
||||
}
|
||||
}
|
||||
return ins_result;
|
||||
}
|
||||
};
|
||||
|
||||
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
@ -1,372 +0,0 @@
|
||||
(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) {
|
||||
if ((content != null ? content.creator : void 0) != null) {
|
||||
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, op, right, _i, _len;
|
||||
while (left.isDeleted()) {
|
||||
left = left.prev_cl;
|
||||
}
|
||||
right = left.next_cl;
|
||||
if (content.type != null) {
|
||||
op = new TextInsert(content, void 0, left, right);
|
||||
HB.addOperation(op).execute();
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
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 = 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();
|
||||
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) {
|
||||
var _ref;
|
||||
return (_ref = _this.replace_manager) != null ? _ref.forwardEvent(_this, 'change', del) : void 0;
|
||||
};
|
||||
})(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();
|
||||
}
|
||||
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
@ -1,409 +0,0 @@
|
||||
(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(['addProperty', 'change'], 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
@ -1,75 +1,74 @@
|
||||
(function() {
|
||||
var Engine, HistoryBuffer, JsonFramework, adaptConnector, json_types_uninitialized;
|
||||
var Engine, HistoryBuffer, Yatta, adaptConnector, json_types_uninitialized;
|
||||
|
||||
json_types_uninitialized = require("../Types/JsonTypes");
|
||||
json_types_uninitialized = require("./Types/JsonTypes");
|
||||
|
||||
HistoryBuffer = require("../HistoryBuffer");
|
||||
HistoryBuffer = require("./HistoryBuffer");
|
||||
|
||||
Engine = require("../Engine");
|
||||
Engine = require("./Engine");
|
||||
|
||||
adaptConnector = require("../ConnectorAdapter");
|
||||
adaptConnector = require("./ConnectorAdapter");
|
||||
|
||||
JsonFramework = (function() {
|
||||
function JsonFramework(user_id, connector) {
|
||||
var beg, end, first_word, type_manager, uid_beg, uid_end;
|
||||
Yatta = (function() {
|
||||
function Yatta(connector) {
|
||||
var beg, end, first_word, type_manager, uid_beg, uid_end, user_id;
|
||||
this.connector = connector;
|
||||
user_id = this.connector.id;
|
||||
this.HB = new HistoryBuffer(user_id);
|
||||
type_manager = json_types_uninitialized(this.HB);
|
||||
this.types = type_manager.types;
|
||||
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());
|
||||
this.HB.addOperation(first_word).execute();
|
||||
first_word = new this.types.JsonType(this.HB.getReservedUniqueIdentifier()).execute();
|
||||
uid_beg = this.HB.getReservedUniqueIdentifier();
|
||||
uid_end = this.HB.getReservedUniqueIdentifier();
|
||||
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 = new this.types.ReplaceManager(void 0, this.HB.getReservedUniqueIdentifier(), beg, end);
|
||||
this.HB.addOperation(this.root_element).execute();
|
||||
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());
|
||||
}
|
||||
|
||||
JsonFramework.prototype.getSharedObject = function() {
|
||||
Yatta.prototype.getSharedObject = function() {
|
||||
return this.root_element.val();
|
||||
};
|
||||
|
||||
JsonFramework.prototype.getConnector = function() {
|
||||
Yatta.prototype.getConnector = function() {
|
||||
return this.connector;
|
||||
};
|
||||
|
||||
JsonFramework.prototype.getHistoryBuffer = function() {
|
||||
Yatta.prototype.getHistoryBuffer = function() {
|
||||
return this.HB;
|
||||
};
|
||||
|
||||
JsonFramework.prototype.setMutableDefault = function(mutable) {
|
||||
Yatta.prototype.setMutableDefault = function(mutable) {
|
||||
return this.getSharedObject().setMutableDefault(mutable);
|
||||
};
|
||||
|
||||
JsonFramework.prototype.getUserId = function() {
|
||||
Yatta.prototype.getUserId = function() {
|
||||
return this.HB.getUserId();
|
||||
};
|
||||
|
||||
JsonFramework.prototype.toJson = function() {
|
||||
Yatta.prototype.toJson = function() {
|
||||
return this.getSharedObject().toJson();
|
||||
};
|
||||
|
||||
JsonFramework.prototype.val = function() {
|
||||
Yatta.prototype.val = function() {
|
||||
var _ref;
|
||||
return (_ref = this.getSharedObject()).val.apply(_ref, arguments);
|
||||
};
|
||||
|
||||
JsonFramework.prototype.on = function() {
|
||||
Yatta.prototype.on = function() {
|
||||
var _ref;
|
||||
return (_ref = this.getSharedObject()).on.apply(_ref, arguments);
|
||||
};
|
||||
|
||||
JsonFramework.prototype.deleteListener = function() {
|
||||
Yatta.prototype.deleteListener = function() {
|
||||
var _ref;
|
||||
return (_ref = this.getSharedObject()).deleteListener.apply(_ref, arguments);
|
||||
};
|
||||
|
||||
Object.defineProperty(JsonFramework.prototype, 'value', {
|
||||
Object.defineProperty(Yatta.prototype, 'value', {
|
||||
get: function() {
|
||||
return this.getSharedObject().value;
|
||||
},
|
||||
@ -88,19 +87,16 @@
|
||||
}
|
||||
});
|
||||
|
||||
return JsonFramework;
|
||||
return Yatta;
|
||||
|
||||
})();
|
||||
|
||||
module.exports = JsonFramework;
|
||||
module.exports = Yatta;
|
||||
|
||||
if (typeof window !== "undefined" && window !== null) {
|
||||
if (window.Y == null) {
|
||||
window.Y = {};
|
||||
}
|
||||
window.Y.JsonFramework = JsonFramework;
|
||||
if ((typeof window !== "undefined" && window !== null) && (window.Yatta == null)) {
|
||||
window.Yatta = Yatta;
|
||||
}
|
||||
|
||||
}).call(this);
|
||||
|
||||
//# sourceMappingURL=../Frameworks/JsonFramework.js.map
|
||||
//# sourceMappingURL=Yatta.js.map
|
1
build/node/Yatta.js.map
Normal file
1
build/node/Yatta.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -1,10 +0,0 @@
|
||||
(function() {
|
||||
exports['JsonFramework'] = require('./Frameworks/JsonFramework');
|
||||
|
||||
exports['TextFramework'] = require('./Frameworks/TextFramework');
|
||||
|
||||
exports['XmlFramework'] = require('./Frameworks/XmlFramework');
|
||||
|
||||
}).call(this);
|
||||
|
||||
//# sourceMappingURL=index.js.map
|
@ -1 +0,0 @@
|
||||
{"version":3,"sources":["index.coffee"],"names":[],"mappings":"AACA;AAAA,EAAA,OAAQ,CAAA,eAAA,CAAR,GACE,OAAA,CAAQ,4BAAR,CADF,CAAA;;AAAA,EAEA,OAAQ,CAAA,eAAA,CAAR,GACE,OAAA,CAAQ,4BAAR,CAHF,CAAA;;AAAA,EAIA,OAAQ,CAAA,cAAA,CAAR,GACE,OAAA,CAAQ,2BAAR,CALF,CAAA;AAAA","file":"index.js","sourceRoot":"/source/","sourcesContent":["\nexports['JsonFramework'] =\n require './Frameworks/JsonFramework'\nexports['TextFramework'] =\n require './Frameworks/TextFramework'\nexports['XmlFramework'] =\n require './Frameworks/XmlFramework'\n\n"]}
|
File diff suppressed because one or more lines are too long
@ -178,7 +178,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
December 16, 14 09:44:06 by
|
||||
December 16, 14 17:57:44 by
|
||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -179,52 +179,6 @@ if (x.type === "JsonType") {
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Constructor Details</h2>
|
||||
<div class='methods'>
|
||||
<div class='method_details'>
|
||||
<p class='signature' id='constructor-dynamic'>
|
||||
#
|
||||
(void)
|
||||
<b>constructor</b><span>(uid, initial_value, mutable)</span>
|
||||
<br>
|
||||
</p>
|
||||
<div class='tags'>
|
||||
<h3>Parameters:</h3>
|
||||
<ul class='param'>
|
||||
<li>
|
||||
<span class='name'>uid</span>
|
||||
<span class='type'>
|
||||
(
|
||||
<tt>Object</tt>
|
||||
)
|
||||
</span>
|
||||
—
|
||||
<span class='desc'>A unique identifier. If uid is undefined, a new uid will be created. </span>
|
||||
</li>
|
||||
<li>
|
||||
<span class='name'>initial_value</span>
|
||||
<span class='type'>
|
||||
(
|
||||
<tt>Object</tt>
|
||||
)
|
||||
</span>
|
||||
—
|
||||
<span class='desc'>Create this operation with an initial value. </span>
|
||||
</li>
|
||||
<li>
|
||||
<span class='name'>Whether</span>
|
||||
<span class='type'>
|
||||
(
|
||||
<tt>String|Boolean</tt>
|
||||
)
|
||||
</span>
|
||||
—
|
||||
<span class='desc'>the initial_value should be created as mutable. (Optional - see setMutableDefault) </span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2>Instance Method Details</h2>
|
||||
<div class='methods'>
|
||||
<div class='method_details'>
|
||||
@ -467,7 +421,7 @@ Otherwise you will loose all the sharing-abilities (the new object will be a dee
|
||||
</div>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
December 16, 14 09:44:06 by
|
||||
December 16, 14 17:57:44 by
|
||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -139,7 +139,7 @@ console.log(w.newProperty == "Awesome") # true!</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
December 16, 14 09:44:06 by
|
||||
December 16, 14 17:57:44 by
|
||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -455,7 +455,7 @@ yatta.bind(textbox);</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
December 16, 14 09:44:06 by
|
||||
December 16, 14 17:57:44 by
|
||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -335,7 +335,7 @@ Yatta was initialized (Depending on the HistoryBuffer implementation).</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
December 16, 14 09:44:06 by
|
||||
December 16, 14 17:57:44 by
|
||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -38,7 +38,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
December 16, 14 09:44:06 by
|
||||
December 16, 14 17:57:44 by
|
||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -76,7 +76,7 @@ But I would become really motivated if you gave me some feedback :) (<a href="ht
|
||||
</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>!
|
||||
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 id='footer'>
|
||||
December 16, 14 09:44:06 by
|
||||
December 16, 14 17:57:44 by
|
||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -106,7 +106,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
December 16, 14 09:44:06 by
|
||||
December 16, 14 17:57:44 by
|
||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -48,7 +48,7 @@
|
||||
</dl>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
December 16, 14 09:44:06 by
|
||||
December 16, 14 17:57:44 by
|
||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -48,7 +48,7 @@
|
||||
</dl>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
December 16, 14 09:44:06 by
|
||||
December 16, 14 17:57:44 by
|
||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -39,7 +39,7 @@
|
||||
</table>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
December 16, 14 09:44:06 by
|
||||
December 16, 14 17:57:44 by
|
||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -39,7 +39,7 @@
|
||||
</table>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
December 16, 14 09:44:06 by
|
||||
December 16, 14 17:57:44 by
|
||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -39,7 +39,7 @@
|
||||
</table>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
December 16, 14 09:44:06 by
|
||||
December 16, 14 17:57:44 by
|
||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -39,7 +39,7 @@
|
||||
</table>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
December 16, 14 09:44:06 by
|
||||
December 16, 14 17:57:44 by
|
||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -58,7 +58,7 @@
|
||||
</dl>
|
||||
</div>
|
||||
<div id='footer'>
|
||||
December 16, 14 09:44:06 by
|
||||
December 16, 14 17:57:44 by
|
||||
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
|
||||
Codo
|
||||
</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":"WordType#cleanup","p":"class/WordType.html#cleanup-dynamic"},{"t":"JsonType#cleanup","p":"class/JsonType.html#cleanup-dynamic"},{"t":"Yatta#constructor","p":"class/Yatta.html#constructor-dynamic"},{"t":"JsonType#constructor","p":"class/JsonType.html#constructor-dynamic"},{"t":"JsonTypeWrapper#constructor","p":"class/JsonTypeWrapper.html#constructor-dynamic"},{"t":"WordType#constructor","p":"class/WordType.html#constructor-dynamic"},{"t":"Yatta#deleteListener","p":"class/Yatta.html#deleteListener-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":"JsonType#getParent","p":"class/JsonType.html#getParent-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#on","p":"class/Yatta.html#on-dynamic"},{"t":"WordType#push","p":"class/WordType.html#push-dynamic"},{"t":"WordType#replaceText","p":"class/WordType.html#replaceText-dynamic"},{"t":"JsonType#setMutableDefault","p":"class/JsonType.html#setMutableDefault-dynamic"},{"t":"Yatta#setMutableDefault","p":"class/Yatta.html#setMutableDefault-dynamic"},{"t":"JsonType#setReplaceManager","p":"class/JsonType.html#setReplaceManager-dynamic"},{"t":"WordType#setReplaceManager","p":"class/WordType.html#setReplaceManager-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#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":"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":"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":"WordType#cleanup","p":"class/WordType.html#cleanup-dynamic"},{"t":"JsonType#cleanup","p":"class/JsonType.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":"Yatta#deleteListener","p":"class/Yatta.html#deleteListener-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":"JsonType#getParent","p":"class/JsonType.html#getParent-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#on","p":"class/Yatta.html#on-dynamic"},{"t":"WordType#push","p":"class/WordType.html#push-dynamic"},{"t":"WordType#replaceText","p":"class/WordType.html#replaceText-dynamic"},{"t":"JsonType#setMutableDefault","p":"class/JsonType.html#setMutableDefault-dynamic"},{"t":"Yatta#setMutableDefault","p":"class/Yatta.html#setMutableDefault-dynamic"},{"t":"JsonType#setReplaceManager","p":"class/JsonType.html#setReplaceManager-dynamic"},{"t":"WordType#setReplaceManager","p":"class/WordType.html#setReplaceManager-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#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"}]
|
@ -53,14 +53,6 @@
|
||||
(lib/ConnectorAdapter.coffee)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/WordType.html#applyDelete-dynamic' target='main' title='applyDelete'>
|
||||
#applyDelete
|
||||
</a>
|
||||
<small>
|
||||
(WordType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/JsonType.html#applyDelete-dynamic' target='main' title='applyDelete'>
|
||||
#applyDelete
|
||||
@ -69,6 +61,14 @@
|
||||
(JsonType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/WordType.html#applyDelete-dynamic' target='main' title='applyDelete'>
|
||||
#applyDelete
|
||||
</a>
|
||||
<small>
|
||||
(WordType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/WordType.html#bind-dynamic' target='main' title='bind'>
|
||||
#bind
|
||||
@ -101,14 +101,6 @@
|
||||
(Yatta)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/JsonType.html#constructor-dynamic' target='main' title='constructor'>
|
||||
#constructor
|
||||
</a>
|
||||
<small>
|
||||
(JsonType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/JsonTypeWrapper.html#constructor-dynamic' target='main' title='constructor'>
|
||||
#constructor
|
||||
|
@ -1,31 +0,0 @@
|
||||
## IWC + JSON Example
|
||||
Here, I will give a short overview on how to use the IwcJson Framework in Role-SDK widgets.
|
||||
First you have to include the following libraries in your widget file:
|
||||
```
|
||||
<script src="http://open-app.googlecode.com/files/openapp.js"></script>
|
||||
<script src="http://dbis.rwth-aachen.de/gadgets/iwc/lib/iwc.js"></script>
|
||||
<script src="http://dbis.rwth-aachen.de/~jahns/role-widgets/widgetbundles/libraries/DUIClient.js"></script>
|
||||
<script src="../../build/browser/Frameworks/JsonFramework.min.js"></script>
|
||||
<script src="../../build/browser/Connectors/IwcConnector.min.js"></script>
|
||||
<script src="./index.js"></script>
|
||||
```
|
||||
A working widget implementation is [IwcJson.xml](./IwcJson.xml) and the js-file is [index.js](./index.js)
|
||||
|
||||
|
||||
```js
|
||||
function init(){
|
||||
Y.createIwcConnector(function(Connector, user_id){
|
||||
```
|
||||
|
||||
|
||||
You don't have to use the proposed user_id.
|
||||
|
||||
|
||||
```js
|
||||
console.log("me is number 2")
|
||||
yatta = new Y.JsonYatta(2, Connector);
|
||||
|
||||
})
|
||||
}
|
||||
window.onload = init
|
||||
```
|
@ -14,6 +14,7 @@ coffeelint = require 'gulp-coffeelint'
|
||||
mocha = require 'gulp-mocha'
|
||||
run = require 'gulp-run'
|
||||
ljs = require 'gulp-ljs'
|
||||
plumber = require 'gulp-plumber'
|
||||
mochaPhantomJS = require 'gulp-mocha-phantomjs'
|
||||
|
||||
|
||||
@ -29,11 +30,12 @@ files =
|
||||
test : ['./test/JsonYatta_test.coffee']
|
||||
gulp : ['./gulpfile.coffee']
|
||||
examples : ['./examples/**/*.js']
|
||||
|
||||
other: ['./lib/**/*']
|
||||
|
||||
files.all = []
|
||||
for name,file_list of files
|
||||
files.all = files.all.concat file_list
|
||||
if name isnt 'build'
|
||||
files.all = files.all.concat file_list
|
||||
|
||||
gulp.task 'lib', ->
|
||||
gulp.src files.lib
|
||||
@ -45,6 +47,7 @@ gulp.task 'lib', ->
|
||||
|
||||
gulp.task 'browser', ->
|
||||
gulp.src files.browser, { read: false }
|
||||
.pipe plumber()
|
||||
.pipe browserify
|
||||
transform: ['coffeeify']
|
||||
extensions: ['.coffee']
|
||||
@ -57,6 +60,7 @@ gulp.task 'browser', ->
|
||||
.pipe gulp.dest '.'
|
||||
|
||||
gulp.src files.test, {read: false}
|
||||
.pipe plumber()
|
||||
.pipe browserify
|
||||
transform: ['coffeeify']
|
||||
extensions: ['.coffee']
|
||||
@ -65,6 +69,10 @@ gulp.task 'browser', ->
|
||||
extname: ".js"
|
||||
.pipe gulp.dest './build/test'
|
||||
|
||||
gulp.task 'browser_test_watch', ['browser'], ->
|
||||
gulp.watch files.all, ['browser']
|
||||
|
||||
|
||||
gulp.task 'test', ->
|
||||
gulp.src files.test, { read: false }
|
||||
.pipe mocha {reporter : 'list'}
|
||||
|
@ -77,8 +77,6 @@ class Engine
|
||||
if @HB.getOperation(op)?
|
||||
else if not op.execute()
|
||||
unprocessed.push op
|
||||
else
|
||||
@HB.addOperation op
|
||||
@unprocessed_ops = unprocessed
|
||||
if @unprocessed_ops.length is old_length
|
||||
break
|
||||
|
@ -7,8 +7,6 @@
|
||||
#
|
||||
class HistoryBuffer
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Creates an empty HB.
|
||||
# @param {Object} user_id Creator of the HB.
|
||||
@ -84,7 +82,6 @@ class HistoryBuffer
|
||||
else
|
||||
@operation_counter[user_id]
|
||||
|
||||
|
||||
#
|
||||
# Encode this operation in such a way that it can be parsed by remote peers.
|
||||
# TODO: Make this more efficient!
|
||||
@ -98,7 +95,7 @@ class HistoryBuffer
|
||||
for u_name,user of @buffer
|
||||
# TODO next, if @state_vector[user] <= state_vector[user]
|
||||
for o_number,o of user
|
||||
if o.doSync and unknown(u_name, o_number)
|
||||
if o.uid.doSync and unknown(u_name, o_number)
|
||||
# its necessary to send it, and not known in state_vector
|
||||
o_json = o._encode()
|
||||
if o.next_cl? # applies for all ops but the most right delimiter!
|
||||
@ -137,12 +134,11 @@ class HistoryBuffer
|
||||
#
|
||||
# Retrieve an operation from a unique id.
|
||||
#
|
||||
getOperation: (uid)->
|
||||
if uid instanceof Object
|
||||
@buffer[uid.creator]?[uid.op_number]
|
||||
else if not uid?
|
||||
else
|
||||
throw new Error "This type of uid is not defined!"
|
||||
getOperation: (uid)->
|
||||
if uid.uid?
|
||||
uid = uid.uid
|
||||
@buffer[uid.creator]?[uid.op_number]
|
||||
|
||||
#
|
||||
# Add an operation to the HB. Note that this will not link it against
|
||||
# other operations (it wont executed)
|
||||
|
@ -118,7 +118,7 @@ module.exports = (HB)->
|
||||
@uid
|
||||
|
||||
dontSync: ()->
|
||||
@doSync = false
|
||||
@uid.doSync = false
|
||||
|
||||
#
|
||||
# @private
|
||||
@ -279,7 +279,7 @@ module.exports = (HB)->
|
||||
applyDelete: (o)->
|
||||
@deleted_by ?= []
|
||||
callLater = false
|
||||
if @parent? and not @isDeleted()
|
||||
if @parent? and not @isDeleted() and o? # o? : if not o?, then the delimiter deleted this Insertion. Furthermore, it would be wrong to call it. TODO: make this more expressive and save
|
||||
# call iff wasn't deleted earlyer
|
||||
callLater = true
|
||||
if o?
|
||||
@ -384,10 +384,11 @@ module.exports = (HB)->
|
||||
@next_cl.prev_cl = @
|
||||
|
||||
parent = @prev_cl?.getParent()
|
||||
super # notify the execution_listeners
|
||||
if parent? and fire_event
|
||||
@setParent parent
|
||||
@parent.callEvent "insert", @
|
||||
super # notify the execution_listeners
|
||||
@
|
||||
|
||||
#
|
||||
# Compute the position of this operation.
|
||||
@ -493,13 +494,13 @@ module.exports = (HB)->
|
||||
if @prev_cl.next_cl?
|
||||
throw new Error "Probably duplicated operations"
|
||||
@prev_cl.next_cl = @
|
||||
delete @prev_cl.unchecked.next_cl
|
||||
super
|
||||
else
|
||||
false
|
||||
else if @prev_cl? and not @prev_cl.next_cl?
|
||||
delete @prev_cl.unchecked.next_cl
|
||||
@prev_cl.next_cl = @
|
||||
super
|
||||
else if @prev_cl? or @next_cl? or true # TODO: are you sure? This can happen right?
|
||||
super
|
||||
#else
|
||||
|
@ -122,11 +122,11 @@ module.exports = (HB)->
|
||||
# @return {Json}
|
||||
#
|
||||
toJson: ()->
|
||||
if not @bound_json? or not Object.observe?
|
||||
if not @bound_json? or not Object.observe? or true # TODO: currently, you are not watching mutable strings for changes, and, therefore, the @bound_json is not updated. TODO TODO wuawuawua easy
|
||||
val = @val()
|
||||
json = {}
|
||||
for name, o of val
|
||||
if o is null
|
||||
if not o?
|
||||
json[name] = o
|
||||
else if o.constructor is {}.constructor
|
||||
json[name] = @val(name).toJson()
|
||||
|
@ -91,7 +91,7 @@ module.exports = (HB)->
|
||||
# always have the same result (ReplaceManager, and its beginning and end are the same)
|
||||
#
|
||||
execute: ()->
|
||||
if not @validateSavedOperations()
|
||||
if not @validateSavedOperations()
|
||||
return false
|
||||
else
|
||||
# helper for cloning an object
|
||||
@ -105,9 +105,9 @@ module.exports = (HB)->
|
||||
uid_r.op_number = "_#{uid_r.op_number}_RM_#{@name}"
|
||||
if not HB.getOperation(uid_r)?
|
||||
uid_beg = clone(uid_r)
|
||||
uid_beg.op_number = "_#{uid_beg.op_number}_RM_#{@name}_beginning"
|
||||
uid_beg.op_number = "#{uid_r.op_number}_beginning"
|
||||
uid_end = clone(uid_r)
|
||||
uid_end.op_number = "_#{uid_end.op_number}_RM_#{@name}_end"
|
||||
uid_end.op_number = "#{uid_r.op_number}_end"
|
||||
beg = (new types.Delimiter uid_beg, undefined, uid_end).execute()
|
||||
end = (new types.Delimiter uid_end, beg, undefined).execute()
|
||||
@map_manager.map[@name] = new ReplaceManager undefined, uid_r, beg, end
|
||||
|
@ -143,7 +143,8 @@ module.exports = (HB)->
|
||||
(new TextInsert content, undefined, left, right).execute()
|
||||
else
|
||||
for c in content
|
||||
left = (new TextInsert c, undefined, left, right).execute()
|
||||
tmp = (new TextInsert c, undefined, left, right).execute()
|
||||
left = tmp
|
||||
@
|
||||
#
|
||||
# Inserts a string into the word.
|
||||
|
@ -4,17 +4,16 @@ HistoryBuffer = require "./HistoryBuffer"
|
||||
Engine = require "./Engine"
|
||||
adaptConnector = require "./ConnectorAdapter"
|
||||
|
||||
|
||||
#
|
||||
# Framework for Json data-structures.
|
||||
# Known values that are supported:
|
||||
# * String
|
||||
# * Integer
|
||||
# * Array
|
||||
# * Array
|
||||
#
|
||||
class Yatta
|
||||
|
||||
#
|
||||
#
|
||||
# @param {String} user_id Unique id of the peer.
|
||||
# @param {Connector} Connector the connector class.
|
||||
#
|
||||
@ -35,7 +34,7 @@ class Yatta
|
||||
|
||||
@root_element = (new @types.ReplaceManager undefined, @HB.getReservedUniqueIdentifier(), beg, end).execute()
|
||||
@root_element.replace first_word, @HB.getReservedUniqueIdentifier()
|
||||
|
||||
|
||||
#
|
||||
# @return JsonType
|
||||
#
|
||||
|
@ -35,6 +35,7 @@
|
||||
"devDependencies": {
|
||||
"chai": "^1.9.1",
|
||||
"codo": "^2.0.9",
|
||||
"coffee-errors": "~0.8.6",
|
||||
"coffee-script": "^1.7.1",
|
||||
"coffeeify": "^0.6.0",
|
||||
"gulp": "^3.8.7",
|
||||
@ -42,6 +43,7 @@
|
||||
"gulp-coffee": "^2.1.1",
|
||||
"gulp-coffeelint": "^0.3.3",
|
||||
"gulp-concat": "^2.3.4",
|
||||
"gulp-copy": "0.0.2",
|
||||
"gulp-debug": "^1.0.0",
|
||||
"gulp-git": "^0.5.0",
|
||||
"gulp-if": "^1.2.4",
|
||||
@ -49,6 +51,7 @@
|
||||
"gulp-ljs": "^0.1.1",
|
||||
"gulp-mocha": "^0.5.2",
|
||||
"gulp-mocha-phantomjs": "^0.5.0",
|
||||
"gulp-plumber": "^0.6.6",
|
||||
"gulp-rename": "^1.2.0",
|
||||
"gulp-rimraf": "^0.1.0",
|
||||
"gulp-run": "^1.6.3",
|
||||
@ -57,8 +60,6 @@
|
||||
"jquery": "^2.1.1",
|
||||
"mocha": "^1.21.4",
|
||||
"sinon": "^1.10.2",
|
||||
"sinon-chai": "^2.5.0",
|
||||
"coffee-errors": "~0.8.6",
|
||||
"gulp-copy": "0.0.2"
|
||||
"sinon-chai": "^2.5.0"
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,8 @@ Yatta = require "../lib/Yatta.coffee"
|
||||
Test = require "./TestSuite"
|
||||
|
||||
class JsonTest extends Test
|
||||
makeNewUser: (user, conn)->
|
||||
makeNewUser: (userId)->
|
||||
conn = new Connector userId
|
||||
super new Yatta conn
|
||||
|
||||
type: "JsonTest"
|
||||
@ -59,15 +60,13 @@ class JsonTest extends Test
|
||||
types: [types.JsonType]
|
||||
]
|
||||
|
||||
|
||||
|
||||
describe "JsonFramework", ->
|
||||
beforeEach (done)->
|
||||
@timeout 50000
|
||||
@yTest = new JsonTest()
|
||||
@users = @yTest.users
|
||||
|
||||
@test_user = @yTest.makeNewUser 0, (new Connector 0, [])
|
||||
@test_user = @yTest.makeNewUser "test_user"
|
||||
done()
|
||||
|
||||
it "can handle many engines, many operations, concurrently (random)", ->
|
||||
@ -96,7 +95,6 @@ describe "JsonFramework", ->
|
||||
expect(change).to.be.ok
|
||||
expect(change2).to.equal 8
|
||||
|
||||
|
||||
it "has a JsonTypeWrapper", ->
|
||||
y = this.yTest.getSomeUser().getSharedObject()
|
||||
y.val('x',"dtrn", 'immutable')
|
||||
@ -112,7 +110,10 @@ describe "JsonFramework", ->
|
||||
y.value.x = {q:4}
|
||||
expect(y.value.x.q).to.equal(4)
|
||||
|
||||
### TODO: Handle this test
|
||||
|
||||
it "has a working test suite", ->
|
||||
@yTest.compareAll()
|
||||
|
||||
it "handles double-late-join", ->
|
||||
test = new JsonTest("double")
|
||||
test.run()
|
||||
@ -123,14 +124,18 @@ describe "JsonFramework", ->
|
||||
ops2 = u2.HB._encode()
|
||||
u1.engine.applyOps ops2
|
||||
u2.engine.applyOps ops1
|
||||
expect(u2.value.name.val()).to.equal(u2.value.name.val())
|
||||
###
|
||||
|
||||
it "has a working test suite", ->
|
||||
expect(test.getContent(0)).to.equal(@yTest.getContent(1))
|
||||
|
||||
it "can handle creaton of complex json (1)", ->
|
||||
@yTest.users[0].val('a', 'q')
|
||||
@yTest.users[2].val('a', 't')
|
||||
@yTest.compareAll()
|
||||
q = @yTest.users[1].val('a')
|
||||
q.insertText(0,'A')
|
||||
@yTest.compareAll()
|
||||
expect(@yTest.getSomeUser().value.a.val()).to.equal("At")
|
||||
|
||||
|
||||
it "can handle creaton of complex json", ->
|
||||
it "can handle creaton of complex json (2)", ->
|
||||
@yTest.getSomeUser().val('x', {'a':'b'})
|
||||
@yTest.getSomeUser().val('a', {'a':{q:"dtrndtrtdrntdrnrtdnrtdnrtdnrtdnrdnrdt"}})
|
||||
@yTest.getSomeUser().val('b', {'a':{}})
|
||||
@ -154,4 +159,3 @@ describe "JsonFramework", ->
|
||||
expect(@yTest.getSomeUser().val('null') is null).to.be.ok
|
||||
|
||||
|
||||
|
||||
|
@ -13,9 +13,9 @@ module.exports = class Test
|
||||
constructor: (@name_suffix = "")->
|
||||
@number_of_test_cases_multiplier = 1
|
||||
@repeat_this = 1 * @number_of_test_cases_multiplier
|
||||
@doSomething_amount = 400 + @number_of_test_cases_multiplier
|
||||
@doSomething_amount = 50 + @number_of_test_cases_multiplier
|
||||
@number_of_engines = 5 + @number_of_test_cases_multiplier - 1
|
||||
|
||||
|
||||
@time = 0
|
||||
@ops = 0
|
||||
@time_now = 0
|
||||
@ -27,14 +27,13 @@ module.exports = class Test
|
||||
reinitialize: ()->
|
||||
@users = []
|
||||
for i in [0...@number_of_engines]
|
||||
connector = new Connector i
|
||||
if @users.length > 0
|
||||
connector.join @users[0].connector
|
||||
u = @makeNewUser (i+@name_suffix), connector
|
||||
u = @makeNewUser (i+@name_suffix)
|
||||
for user in @users
|
||||
u.getConnector().join(user.getConnector()) # TODO: change the test-connector to make this more convenient
|
||||
@users.push u
|
||||
#@users[0].val('name',"i")
|
||||
@flushAll()
|
||||
|
||||
# is called by implementing class
|
||||
makeNewUser: (user)->
|
||||
user.HB.setManualGarbageCollect()
|
||||
user
|
||||
@ -199,7 +198,7 @@ module.exports = class Test
|
||||
|
||||
testHBencoding: ()->
|
||||
# in case of JsonFramework, every user will create its JSON first! therefore, the testusers id must be small than all the others (see InsertType)
|
||||
@users[@users.length] = @makeNewUser (-1), (new Connector (-1), [])
|
||||
@users[@users.length] = @makeNewUser (-1) # this does not want to join with anymody
|
||||
@users[@users.length-1].engine.applyOps @users[0].HB._encode()
|
||||
|
||||
#if @getContent(@users.length-1) isnt @getContent(0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user