tests run fine. but it needs some more user testing

This commit is contained in:
Kevin Jahns 2014-10-02 21:14:37 +02:00
parent 968e07a8ff
commit 3415d0ee5e
56 changed files with 1329 additions and 457 deletions

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
!function n(e,t,r){function o(u,s){if(!t[u]){if(!e[u]){var c="function"==typeof require&&require;if(!s&&c)return c(u,!0);if(i)return i(u,!0);throw new Error("Cannot find module '"+u+"'")}var a=t[u]={exports:{}};e[u][0].call(a.exports,function(n){var t=e[u][1][n];return o(t?t:n)},a,a.exports,n,e,t,r)}return t[u].exports}for(var i="function"==typeof require&&require,u=0;u<r.length;u++)o(r[u]);return o}({1:[function(n,e){var t;t=function(){var n,e,t;return t=null,2===arguments.length?(t=new Peer(arguments[0]),e=arguments[1]):(t=new Peer(arguments[0],arguments[1]),t.on("error",function(n){throw new Error("Peerjs connector: "+n)}),t.on("disconnected",function(){throw new Error("Peerjs connector disconnected from signalling server. Cannot accept new connections. Not fatal, but not so good either..")}),e=arguments[2]),n=function(){function n(n,e,r,o){var i,u;this.engine=n,this.HB=e,this.execution_listener=r,this.yatta=o,this.peer=t,this.connections={},this.peer.on("connection",function(n){return function(e){return n.addConnection(e)}}(this)),u=function(n){return function(){var e,t,r,o;r=n.connections,o=[];for(t in r)e=r[t],o.push(e.send({sync_state_vector:n.HB.getOperationCounter()}));return o}}(this),setInterval(u,4e3),i=function(n){return function(e){var t,r,o,i;if(e.uid.creator===n.HB.getUserId()&&"string"!=typeof e.uid.op_number){o=n.connections,i=[];for(r in o)t=o[r],i.push(t.send({op:e}));return i}}}(this),this.execution_listener.push(i)}return n.prototype.connectToPeer=function(n){return null==this.connections[n]&&n!==this.yatta.getUserId()?this.addConnection(t.connect(n)):void 0},n.prototype.getAllConnectionIds=function(){var n,e;e=[];for(n in this.connections)e.push(n);return e},n.prototype.addConnection=function(n){var e,t,r;return this.connections[n.peer]=n,t=!1,e=!1,n.on("data",function(r){return function(o){var i,u,s,c,a;if("empty_message"===o);else if(null!=o.HB){if(t=!0,r.engine.applyOpsCheckDouble(o.HB),!o.initialized)return n.send({conns:r.getAllConnectionIds()})}else{if(null!=o.op)return r.engine.applyOp(o.op);if(null!=o.conns){for(c=o.conns,a=[],u=0,s=c.length;s>u;u++)i=c[u],a.push(r.connectToPeer(i));return a}if(null!=o.sync_state_vector)return n.send({HB:r.yatta.getHistoryBuffer()._encode(o.sync_state_vector),initialized:!0});if(null==o.state_vector)throw new Error("Can't parse this operation: "+o);if(!e)return n.send({HB:r.yatta.getHistoryBuffer()._encode(o.state_vector),initialized:!1}),e=!0}}}(this)),r=function(e){return function(){return n.send({state_vector:e.HB.getOperationCounter()}),t?void 0:setTimeout(r,100)}}(this),r()},n}(),t.on("open",function(t){return e(n,t)})},e.exports=t,"undefined"!=typeof window&&null!==window&&(null==window.Y&&(window.Y={}),window.Y.createPeerJsConnector=t)},{}]},{},[1]); !function n(e,t,r){function o(s,u){if(!t[s]){if(!e[s]){var c="function"==typeof require&&require;if(!u&&c)return c(s,!0);if(i)return i(s,!0);throw new Error("Cannot find module '"+s+"'")}var a=t[s]={exports:{}};e[s][0].call(a.exports,function(n){var t=e[s][1][n];return o(t?t:n)},a,a.exports,n,e,t,r)}return t[s].exports}for(var i="function"==typeof require&&require,s=0;s<r.length;s++)o(r[s]);return o}({1:[function(n,e){var t;t=function(){var n,e,t;return t=null,2===arguments.length?(t=new Peer(arguments[0]),e=arguments[1]):(t=new Peer(arguments[0],arguments[1]),t.on("error",function(n){throw new Error("Peerjs connector: "+n)}),t.on("disconnected",function(){throw new Error("Peerjs connector disconnected from signalling server. Cannot accept new connections. Not fatal, but not so good either..")}),e=arguments[2]),n=function(){function n(n,e,r,o){var i,s;this.engine=n,this.HB=e,this.execution_listener=r,this.yatta=o,this.peer=t,this.connections={},this.new_connection_listeners=[],this.peer.on("connection",function(n){return function(e){return n.addConnection(e)}}(this)),s=function(n){return function(){var e,t,r,o;r=n.connections,o=[];for(t in r)e=r[t],o.push(e.send({sync_state_vector:n.HB.getOperationCounter()}));return o}}(this),setInterval(s,4e3),i=function(n){return function(e){var t,r,o,i;if(e.uid.creator===n.HB.getUserId()&&"string"!=typeof e.uid.op_number){o=n.connections,i=[];for(r in o)t=o[r],i.push(t.send({op:e}));return i}}}(this),this.execution_listener.push(i)}return n.prototype.connectToPeer=function(n){return null==this.connections[n]&&n!==this.yatta.getUserId()?this.addConnection(t.connect(n)):void 0},n.prototype.getAllConnectionIds=function(){var n,e;e=[];for(n in this.connections)e.push(n);return e},n.prototype.onNewConnection=function(n){return this.new_connection_listeners.push(n)},n.prototype.addConnection=function(n){var e,t,r;return this.connections[n.peer]=n,t=!1,e=!1,n.on("data",function(r){return function(o){var i,s,u,c,a;if("empty_message"===o);else if(null!=o.HB){if(t=!0,r.engine.applyOpsCheckDouble(o.HB),!o.initialized)return n.send({conns:r.getAllConnectionIds()}),r.new_connection_listeners.map(function(e){return e(n)})}else{if(null!=o.op)return r.engine.applyOp(o.op);if(null!=o.conns){for(c=o.conns,a=[],s=0,u=c.length;u>s;s++)i=c[s],a.push(r.connectToPeer(i));return a}if(null!=o.sync_state_vector)return n.send({HB:r.yatta.getHistoryBuffer()._encode(o.sync_state_vector),initialized:!0});if(null==o.state_vector)throw new Error("Can't parse this operation: "+o);if(!e)return n.send({HB:r.yatta.getHistoryBuffer()._encode(o.state_vector),initialized:!1}),e=!0}}}(this)),r=function(e){return function(){return n.send({state_vector:e.HB.getOperationCounter()}),t?void 0:setTimeout(r,100)}}(this),r()},n}(),t.on("open",function(t){return e(n,t)})},e.exports=t,"undefined"!=typeof window&&null!==window&&(null==window.Y&&(window.Y={}),window.Y.createPeerJsConnector=t)},{}]},{},[1]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -26,6 +26,7 @@
this.yatta = yatta; this.yatta = yatta;
this.peer = peer; this.peer = peer;
this.connections = {}; this.connections = {};
this.new_connection_listeners = [];
this.peer.on('connection', (function(_this) { this.peer.on('connection', (function(_this) {
return function(conn) { return function(conn) {
return _this.addConnection(conn); return _this.addConnection(conn);
@ -80,6 +81,10 @@
return _results; return _results;
}; };
PeerJsConnector.prototype.onNewConnection = function(f) {
return this.new_connection_listeners.push(f);
};
PeerJsConnector.prototype.addConnection = function(conn) { PeerJsConnector.prototype.addConnection = function(conn) {
var initialized_him, initialized_me, sendStateVector; var initialized_him, initialized_me, sendStateVector;
this.connections[conn.peer] = conn; this.connections[conn.peer] = conn;
@ -94,9 +99,12 @@
initialized_me = true; initialized_me = true;
_this.engine.applyOpsCheckDouble(data.HB); _this.engine.applyOpsCheckDouble(data.HB);
if (!data.initialized) { if (!data.initialized) {
return conn.send({ conn.send({
conns: _this.getAllConnectionIds() conns: _this.getAllConnectionIds()
}); });
return _this.new_connection_listeners.map(function(f) {
return f(conn);
});
} }
} else if (data.op != null) { } else if (data.op != null) {
return _this.engine.applyOp(data.op); return _this.engine.applyOp(data.op);

File diff suppressed because one or more lines are too long

View File

@ -218,12 +218,13 @@
Insert.prototype.type = "Insert"; Insert.prototype.type = "Insert";
Insert.prototype.applyDelete = function(o) { Insert.prototype.applyDelete = function(o) {
var garbagecollect, _ref; var callLater, garbagecollect, _ref;
if (this.deleted_by == null) { if (this.deleted_by == null) {
this.deleted_by = []; this.deleted_by = [];
} }
callLater = false;
if ((this.parent != null) && !this.isDeleted()) { if ((this.parent != null) && !this.isDeleted()) {
this.parent.callEvent("delete", this, o); callLater = true;
} }
if (o != null) { if (o != null) {
this.deleted_by.push(o); this.deleted_by.push(o);
@ -233,6 +234,9 @@
garbagecollect = true; garbagecollect = true;
} }
Insert.__super__.applyDelete.call(this, garbagecollect); Insert.__super__.applyDelete.call(this, garbagecollect);
if (callLater) {
this.parent.callEvent("delete", this, o);
}
if ((_ref = this.next_cl) != null ? _ref.isDeleted() : void 0) { if ((_ref = this.next_cl) != null ? _ref.isDeleted() : void 0) {
return this.next_cl.applyDelete(); return this.next_cl.applyDelete();
} }

File diff suppressed because one or more lines are too long

View File

@ -47,11 +47,22 @@
}; };
TextInsert.prototype.applyDelete = function() { TextInsert.prototype.applyDelete = function() {
TextInsert.__super__.applyDelete.apply(this, arguments);
if (this.content instanceof types.Operation) { if (this.content instanceof types.Operation) {
this.content.applyDelete(); this.content.applyDelete();
} }
this.content = null; return this.content = null;
return TextInsert.__super__.applyDelete.apply(this, arguments); };
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) { TextInsert.prototype.val = function(current_position) {

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
(function() { (function() {
var json_types_uninitialized, proxy_token, var dont_proxy, json_types_uninitialized, proxy_token, _proxy,
__hasProp = {}.hasOwnProperty, __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; }; __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; };
@ -7,27 +7,45 @@
proxy_token = false; 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) { if (typeof Element !== "undefined" && Element !== null) {
Element.prototype._proxy = function(f_name, f) { Element.prototype._proxy = _proxy;
var old_f;
old_f = this[f_name];
if (old_f != null) {
return this[f_name] = function() {
if (!proxy_token) {
proxy_token = true;
old_f.apply(this, arguments);
f.apply(this, arguments);
return proxy_token = false;
} else {
return old_f.apply(this, arguments);
}
};
}
};
} }
module.exports = function(HB) { module.exports = function(HB) {
var XmlType, json_types, parser, types; var TextNodeType, XmlType, json_types, parser, types;
json_types = json_types_uninitialized(HB); json_types = json_types_uninitialized(HB);
types = json_types.types; types = json_types.types;
parser = json_types.parser; parser = json_types.parser;
@ -35,7 +53,7 @@
__extends(XmlType, _super); __extends(XmlType, _super);
function XmlType(uid, tagname, attributes, elements, xml) { function XmlType(uid, tagname, attributes, elements, xml) {
var attr, element, i, n, word, _i, _j, _len, _ref, _ref1; var attr, d, element, i, n, word, _i, _j, _len, _ref, _ref1, _ref2;
this.tagname = tagname; this.tagname = tagname;
this.xml = xml; this.xml = xml;
@ -48,12 +66,18 @@
prev = prev.prev_cl prev = prev.prev_cl
next = prev.next_cl next = prev.next_cl
*/ */
XmlType.__super__.constructor.call(this); 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)) { if ((attributes != null) && (elements != null)) {
this.saveOperation('attributes', attributes); this.saveOperation('attributes', attributes);
this.saveOperation('elements', elements); this.saveOperation('elements', elements);
} else if ((attributes == null) && (elements == null)) { } else if ((attributes == null) && (elements == null)) {
this.attributes = new types.JsonType(); this.attributes = new types.JsonType();
this.attributes.setMutableDefault('immutable');
HB.addOperation(this.attributes).execute(); HB.addOperation(this.attributes).execute();
this.elements = new types.WordType(); this.elements = new types.WordType();
this.elements.parent = this; this.elements.parent = this;
@ -63,17 +87,16 @@
} }
if (this.xml != null) { if (this.xml != null) {
this.tagname = this.xml.tagName; this.tagname = this.xml.tagName;
for (i = _i = 0, _ref = this.xml.attributes.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { for (i = _i = 0, _ref1 = this.xml.attributes.length; 0 <= _ref1 ? _i < _ref1 : _i > _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
attr = xml.attributes[i]; attr = xml.attributes[i];
this.attributes.val(attr.name, attr.value); this.attributes.val(attr.name, attr.value);
} }
_ref1 = this.xml.childNodes; _ref2 = this.xml.childNodes;
for (_j = 0, _len = _ref1.length; _j < _len; _j++) { for (_j = 0, _len = _ref2.length; _j < _len; _j++) {
n = _ref1[_j]; n = _ref2[_j];
if (n.nodeType === n.TEXT_NODE) { if (n.nodeType === n.TEXT_NODE) {
word = new types.WordType(); word = new TextNodeType(void 0, n);
HB.addOperation(word).execute(); HB.addOperation(word).execute();
word.push(n.textContent);
this.elements.push(word); this.elements.push(word);
} else if (n.nodeType === n.ELEMENT_NODE) { } else if (n.nodeType === n.ELEMENT_NODE) {
element = new XmlType(void 0, void 0, void 0, void 0, n); element = new XmlType(void 0, void 0, void 0, void 0, n);
@ -90,10 +113,14 @@
XmlType.prototype.type = "XmlType"; XmlType.prototype.type = "XmlType";
XmlType.prototype.applyDelete = function() { XmlType.prototype.applyDelete = function(op) {
this.attributes.applyDelete(); if ((this.insert_parent != null) && !this.insert_parent.isDeleted()) {
this.elements.applyDelete(); return this.insert_parent.applyDelete(op);
return XmlType.__super__.applyDelete.call(this); } else {
this.attributes.applyDelete();
this.elements.applyDelete();
return XmlType.__super__.applyDelete.apply(this, arguments);
}
}; };
XmlType.prototype.cleanup = function() { XmlType.prototype.cleanup = function() {
@ -101,42 +128,156 @@
}; };
XmlType.prototype.setXmlProxy = function() { XmlType.prototype.setXmlProxy = function() {
var insertBefore, removeChild, that; var findNode, insertBefore, removeChild, renewClassList, that;
this.xml._yatta = this; this.xml._yatta = this;
that = this; that = this;
insertBefore = function(insertedNode, adjacentNode) { this.elements.on('insert', function(event, op) {
var element, next, prev; var newNode, right, rightNode;
next = adjacentNode != null ? adjacentNode._yatta : void 0; 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; prev = null;
if (next != null) { if (next) {
prev = next.prev_cl; prev = next.prev_cl;
} else { } else {
prev = this._yatta.elements.end.prev_cl; 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);
} }
element = new XmlType(void 0, void 0, void 0, void 0, insertedNode);
HB.addOperation(element).execute();
return that.elements.insertAfter(prev, element);
}; };
this.xml._proxy('insertBefore', insertBefore); this.xml._proxy('insertBefore', insertBefore);
this.xml._proxy('appendChild', insertBefore); this.xml._proxy('appendChild', insertBefore);
this.xml._proxy('removeAttribute', function(name) { this.xml._proxy('removeAttribute', function(name) {
return that.attributes.val(name, void 0); 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) { removeChild = function(node) {
var d, elem; var d, elem;
elem = that.elements.beginning.next_cl; elem = findNode(node);
while (elem.type !== 'Delimiter' && elem.content !== node._yatta) { if (!elem) {
elem = elem.next_cl;
}
if (elem.type === 'Delimiter') {
throw new Error("You are only allowed to delete existing (direct) child elements!"); throw new Error("You are only allowed to delete existing (direct) child elements!");
} }
d = new types.Delete(void 0, elem); d = new types.Delete(void 0, elem);
return HB.addOperation(d).execute(); HB.addOperation(d).execute();
return node._yatta = null;
}; };
this.xml._proxy('removeChild', removeChild); this.xml._proxy('removeChild', removeChild);
return this.xml._proxy('replaceChild', function(insertedNode, replacedNode) { return this.xml._proxy('replaceChild', function(insertedNode, replacedNode) {
insertBefore.call(this, replacedNode, insertedNode); insertBefore.call(this, insertedNode, replacedNode);
return removeChild.call(this, replacedNode); return removeChild.call(this, replacedNode);
}); });
}; };
@ -161,11 +302,12 @@
e = this.elements.beginning.next_cl; e = this.elements.beginning.next_cl;
while (e.type !== "Delimiter") { while (e.type !== "Delimiter") {
n = e.content; n = e.content;
if (!e.isDeleted()) { if (!e.isDeleted() && (e.content != null)) {
if (n.type === "XmlType") { if (n.type === "XmlType") {
this.xml.appendChild(n.val(enforce)); this.xml.appendChild(n.val(enforce));
} else if (n.type === "WordType") { } else if (n.type === "TextNodeType") {
text_node = document.createTextNode(n.val()); text_node = n.val();
text_node._yatta = this;
this.xml.appendChild(text_node); this.xml.appendChild(text_node);
} else { } else {
throw new Error("Internal structure cannot be transformed to dom"); throw new Error("Internal structure cannot be transformed to dom");
@ -180,7 +322,7 @@
}; };
XmlType.prototype.execute = function() { XmlType.prototype.execute = function() {
return XmlType.__super__.execute.apply(this, arguments); return XmlType.__super__.execute.call(this);
}; };
@ -216,6 +358,49 @@
uid = json['uid'], attributes = json['attributes'], elements = json['elements'], tagname = json['tagname']; uid = json['uid'], attributes = json['attributes'], elements = json['elements'], tagname = json['tagname'];
return new XmlType(uid, tagname, attributes, elements, void 0); 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;
}
this._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; types['XmlType'] = XmlType;
return json_types; return json_types;
}; };

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -100,11 +100,6 @@
XmlFramework XmlFramework
</a> </a>
</li> </li>
<li>
<a href='class/XmlType.html'>
XmlType
</a>
</li>
</ul> </ul>
</ul> </ul>
</div> </div>
@ -257,21 +252,13 @@
(lib&#47;Frameworks) (lib&#47;Frameworks)
</small> </small>
</li> </li>
<li>
<a href='file/lib/Types/XmlTypes.coffee.html'>
XmlTypes.coffee
</a>
<small>
(lib&#47;Types)
</small>
</li>
</ul> </ul>
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -302,7 +302,7 @@ data from the received intent.</p>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -335,7 +335,7 @@ JsonFramework was initialized (Depending on the HistoryBuffer implementation).</
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -466,7 +466,7 @@ if (x.type === &quot;JsonType&quot;) {
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -139,7 +139,7 @@ console.log(w.newProperty == &quot;Awesome&quot;) # true!</code></pre>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -72,6 +72,17 @@ user-id of the peer (browser/client). And then you can connect to it.</p>
Receive the id of every connected peer. Receive the id of every connected peer.
</span> </span>
</li> </li>
<li>
<span class='signature'>
<a href='#onNewConnection-dynamic'>
#
(void)
<b>onNewConnection</b><span>(f)</span>
</a>
</span>
<span class='desc'>
</span>
</li>
<li> <li>
<span class='signature'> <span class='signature'>
<a href='#addConnection-dynamic'> <a href='#addConnection-dynamic'>
@ -194,6 +205,15 @@ on how to do that with urls.</p>
</li> </li>
</ul> </ul>
</div> </div>
</div>
<div class='method_details'>
<p class='signature' id='onNewConnection-dynamic'>
#
(void)
<b>onNewConnection</b><span>(f)</span>
<br>
</p>
</div> </div>
<div class='method_details'> <div class='method_details'>
<p class='signature' id='addConnection-dynamic'> <p class='signature' id='addConnection-dynamic'>
@ -222,7 +242,7 @@ on how to do that with urls.</p>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -356,7 +356,7 @@ JsonFramework was initialized (Depending on the HistoryBuffer implementation).</
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -455,7 +455,7 @@ yatta.bind(textbox);</code></pre>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -44,8 +44,9 @@
<p>Manages XML types <p>Manages XML types
Not supported:</p><ul> Not supported:</p><ul>
<li>Attribute nodes</li> <li>Attribute nodes</li>
<li>Real replace of child elements (to much overhead). Currently, the new element is inserted after the &#39;replaced&#39; element, and then it is deleted. <li>Real replace of child elements (to much overhead). Currently, the new element is inserted after the &#39;replaced&#39; element, and then it is deleted.</li>
*</li> <li>Namespaces (*NS)</li>
<li>Browser specific methods (webkit-* operations)</li>
</ul> </ul>
</div> </div>
@ -122,7 +123,6 @@ Use it in order to check whether this is an xml-type or something else.</p>
</a> </a>
</span> </span>
<span class='desc'> <span class='desc'>
If possible set the replace manager in the content.
</span> </span>
</li> </li>
<li> <li>
@ -208,17 +208,7 @@ Use it in order to check whether this is an xml-type or something else.</p>
<b>execute</b><span>()</span> <b>execute</b><span>()</span>
<br> <br>
</p> </p>
<div class='docstring'>
<p>If possible set the replace manager in the content.</p>
</div>
<div class='tags'>
<h3>See also:</h3>
<ul class='see'>
<li>
<a href='WordType.setReplaceManager'>WordType.setReplaceManager</a>
</li>
</ul>
</div>
</div> </div>
<div class='method_details'> <div class='method_details'>
<p class='signature' id='getParent-dynamic'> <p class='signature' id='getParent-dynamic'>
@ -258,7 +248,7 @@ This result can be send to other clients.</p>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 15:16:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -99,18 +99,6 @@
</small> </small>
<small class='namespace'> <small class='namespace'>
</small>
</li>
<li>
<a href='class/XmlType.html' target='main'>
XmlType
</a>
<small class='parent'>
<
types.Insert
</small>
<small class='namespace'>
</small> </small>
</li> </li>
</ul> </ul>

View File

@ -38,7 +38,7 @@
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -70,7 +70,7 @@ But I would become really motivated if you gave me some feedback :) (<a href="ht
<ul> <ul>
<li>XML support</li> <li>XML support</li>
</ul> </ul>
<h2 id="support">Support</h2><p>Please report any issues to the <a href="https://github.com/DadaMonad/Yatta/issues">Github issue page</a>!</p><h2 id="license">License</h2><p>Yatta! is licensed under the <a href="./LICENSE.txt">MIT License</a>.</p><a href="&#x6d;&#97;&#x69;&#x6c;&#x74;&#111;&#58;&#x6b;&#101;&#x76;&#x69;&#110;&#46;&#x6a;&#x61;&#104;&#x6e;&#x73;&#64;&#x72;&#119;&#x74;&#104;&#45;&#97;&#97;&#x63;&#104;&#x65;&#x6e;&#x2e;&#100;&#x65;">&#x6b;&#101;&#x76;&#x69;&#110;&#46;&#x6a;&#x61;&#104;&#x6e;&#x73;&#64;&#x72;&#119;&#x74;&#104;&#45;&#97;&#97;&#x63;&#104;&#x65;&#x6e;&#x2e;&#100;&#x65;</a> <h2 id="support">Support</h2><p>Please report any issues to the <a href="https://github.com/DadaMonad/Yatta/issues">Github issue page</a>!</p><h2 id="license">License</h2><p>Yatta! is licensed under the <a href="./LICENSE.txt">MIT License</a>.</p><a href="&#x6d;&#97;&#105;&#108;&#116;&#111;&#58;&#x6b;&#x65;&#118;&#105;&#x6e;&#x2e;&#106;&#x61;&#104;&#x6e;&#115;&#x40;&#114;&#x77;&#x74;&#x68;&#45;&#97;&#97;&#99;&#x68;&#x65;&#110;&#x2e;&#100;&#x65;">&#x6b;&#x65;&#118;&#105;&#x6e;&#x2e;&#106;&#x61;&#104;&#x6e;&#115;&#x40;&#114;&#x77;&#x74;&#x68;&#45;&#97;&#97;&#99;&#x68;&#x65;&#110;&#x2e;&#100;&#x65;</a>
@ -79,7 +79,7 @@ But I would become really motivated if you gave me some feedback :) (<a href="ht
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -100,7 +100,7 @@
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -158,7 +158,7 @@
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -39,7 +39,7 @@
</table> </table>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -48,7 +48,7 @@
</dl> </dl>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -60,7 +60,7 @@
</dl> </dl>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -60,7 +60,7 @@
</dl> </dl>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -48,7 +48,7 @@
</dl> </dl>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -39,7 +39,7 @@
</table> </table>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -39,7 +39,7 @@
</table> </table>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -39,7 +39,7 @@
</table> </table>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -39,7 +39,7 @@
</table> </table>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -53,15 +53,34 @@ But yatta&#39;s proxy may be called only once!</p>
<div class='tags'> <div class='tags'>
</div> </div>
</dd> </dd>
<dt id='Element.prototype._proxy-variable'>
Element.prototype._proxy
=
</dt>
<dd>
<pre><code class='coffeescript'>_proxy</code></pre>
</dd>
</dl> </dl>
<h2>Method Summary</h2> <h2>Method Summary</h2>
<ul class='summary'> <ul class='summary'>
<li> <li>
<span class='signature'> <span class='signature'>
<a href='#Element-'> <a href='#dont_proxy-'>
~ ~
(void) (void)
<b>Element</b><span>(f_name, f)</span> <b>dont_proxy</b><span>(f)</span>
</a>
</span>
<span class='desc'>
</span>
</li>
<li>
<span class='signature'>
<a href='#_proxy-'>
~
(void)
<b>_proxy</b><span>(f_name, f)</span>
</a> </a>
</span> </span>
<span class='desc'> <span class='desc'>
@ -71,10 +90,19 @@ But yatta&#39;s proxy may be called only once!</p>
<h2>Method Details</h2> <h2>Method Details</h2>
<div class='methods'> <div class='methods'>
<div class='method_details'> <div class='method_details'>
<p class='signature' id='Element-'> <p class='signature' id='dont_proxy-'>
~ ~
(void) (void)
<b>Element</b><span>(f_name, f)</span> <b>dont_proxy</b><span>(f)</span>
<br>
</p>
</div>
<div class='method_details'>
<p class='signature' id='_proxy-'>
~
(void)
<b>_proxy</b><span>(f_name, f)</span>
<br> <br>
</p> </p>
@ -82,7 +110,7 @@ But yatta&#39;s proxy may be called only once!</p>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 15:16:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -37,7 +37,7 @@
</table> </table>
</div> </div>
<div id='footer'> <div id='footer'>
September 29, 14 16:10:05 by October 02, 14 21:00:56 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -153,14 +153,6 @@
lib&#47;Types lib&#47;Types
</small> </small>
</li> </li>
<li>
<a href='file/lib/Types/XmlTypes.coffee.html' target='main'>
XmlTypes.coffee
</a>
<small class='namespace'>
lib&#47;Types
</small>
</li>
</ul> </ul>
<li> <li>

File diff suppressed because one or more lines are too long

View File

@ -30,19 +30,11 @@
</div> </div>
<ul> <ul>
<li> <li>
<a href='file/lib/Types/XmlTypes.coffee.html#Element-' target='main' title='Element'> <a href='class/WordType.html#_encode-dynamic' target='main' title='_encode'>
~Element
</a>
<small>
(lib&#47;Types&#47;XmlTypes.coffee)
</small>
</li>
<li>
<a href='class/XmlType.html#_encode-dynamic' target='main' title='_encode'>
#_encode #_encode
</a> </a>
<small> <small>
(XmlType) (WordType)
</small> </small>
</li> </li>
<li> <li>
@ -53,14 +45,6 @@
(JsonType) (JsonType)
</small> </small>
</li> </li>
<li>
<a href='class/WordType.html#_encode-dynamic' target='main' title='_encode'>
#_encode
</a>
<small>
(WordType)
</small>
</li>
<li> <li>
<a href='class/PeerJsConnector.html#addConnection-dynamic' target='main' title='addConnection'> <a href='class/PeerJsConnector.html#addConnection-dynamic' target='main' title='addConnection'>
#addConnection #addConnection
@ -69,6 +53,14 @@
(PeerJsConnector) (PeerJsConnector)
</small> </small>
</li> </li>
<li>
<a href='class/WordType.html#applyDelete-dynamic' target='main' title='applyDelete'>
#applyDelete
</a>
<small>
(WordType)
</small>
</li>
<li> <li>
<a href='class/JsonType.html#applyDelete-dynamic' target='main' title='applyDelete'> <a href='class/JsonType.html#applyDelete-dynamic' target='main' title='applyDelete'>
#applyDelete #applyDelete
@ -78,16 +70,8 @@
</small> </small>
</li> </li>
<li> <li>
<a href='class/XmlType.html#applyDelete-dynamic' target='main' title='applyDelete'> <a href='class/WordType.html#bind-dynamic' target='main' title='bind'>
#applyDelete #bind
</a>
<small>
(XmlType)
</small>
</li>
<li>
<a href='class/WordType.html#applyDelete-dynamic' target='main' title='applyDelete'>
#applyDelete
</a> </a>
<small> <small>
(WordType) (WordType)
@ -102,8 +86,8 @@
</small> </small>
</li> </li>
<li> <li>
<a href='class/WordType.html#bind-dynamic' target='main' title='bind'> <a href='class/WordType.html#cleanup-dynamic' target='main' title='cleanup'>
#bind #cleanup
</a> </a>
<small> <small>
(WordType) (WordType)
@ -117,22 +101,6 @@
(JsonType) (JsonType)
</small> </small>
</li> </li>
<li>
<a href='class/WordType.html#cleanup-dynamic' target='main' title='cleanup'>
#cleanup
</a>
<small>
(WordType)
</small>
</li>
<li>
<a href='class/XmlType.html#cleanup-dynamic' target='main' title='cleanup'>
#cleanup
</a>
<small>
(XmlType)
</small>
</li>
<li> <li>
<a href='class/PeerJsConnector.html#connectToPeer-dynamic' target='main' title='connectToPeer'> <a href='class/PeerJsConnector.html#connectToPeer-dynamic' target='main' title='connectToPeer'>
#connectToPeer #connectToPeer
@ -141,30 +109,6 @@
(PeerJsConnector) (PeerJsConnector)
</small> </small>
</li> </li>
<li>
<a href='class/WordType.html#constructor-dynamic' target='main' title='constructor'>
#constructor
</a>
<small>
(WordType)
</small>
</li>
<li>
<a href='class/XmlType.html#constructor-dynamic' target='main' title='constructor'>
#constructor
</a>
<small>
(XmlType)
</small>
</li>
<li>
<a href='class/PeerJsConnector.html#constructor-dynamic' target='main' title='constructor'>
#constructor
</a>
<small>
(PeerJsConnector)
</small>
</li>
<li> <li>
<a href='class/IwcConnector.html#constructor-dynamic' target='main' title='constructor'> <a href='class/IwcConnector.html#constructor-dynamic' target='main' title='constructor'>
#constructor #constructor
@ -173,6 +117,22 @@
(IwcConnector) (IwcConnector)
</small> </small>
</li> </li>
<li>
<a href='class/JsonFramework.html#constructor-dynamic' target='main' title='constructor'>
#constructor
</a>
<small>
(JsonFramework)
</small>
</li>
<li>
<a href='class/PeerJsConnector.html#constructor-dynamic' target='main' title='constructor'>
#constructor
</a>
<small>
(PeerJsConnector)
</small>
</li>
<li> <li>
<a href='class/JsonType.html#constructor-dynamic' target='main' title='constructor'> <a href='class/JsonType.html#constructor-dynamic' target='main' title='constructor'>
#constructor #constructor
@ -197,6 +157,14 @@
(XmlFramework) (XmlFramework)
</small> </small>
</li> </li>
<li>
<a href='class/WordType.html#constructor-dynamic' target='main' title='constructor'>
#constructor
</a>
<small>
(WordType)
</small>
</li>
<li> <li>
<a href='class/TextFramework.html#constructor-dynamic' target='main' title='constructor'> <a href='class/TextFramework.html#constructor-dynamic' target='main' title='constructor'>
#constructor #constructor
@ -205,14 +173,6 @@
(TextFramework) (TextFramework)
</small> </small>
</li> </li>
<li>
<a href='class/JsonFramework.html#constructor-dynamic' target='main' title='constructor'>
#constructor
</a>
<small>
(JsonFramework)
</small>
</li>
<li> <li>
<a href='file/lib/Connectors/IwcConnector.coffee.html#createIwcConnector-' target='main' title='createIwcConnector'> <a href='file/lib/Connectors/IwcConnector.coffee.html#createIwcConnector-' target='main' title='createIwcConnector'>
~createIwcConnector ~createIwcConnector
@ -253,14 +213,6 @@
(TextFramework) (TextFramework)
</small> </small>
</li> </li>
<li>
<a href='class/XmlType.html#execute-dynamic' target='main' title='execute'>
#execute
</a>
<small>
(XmlType)
</small>
</li>
<li> <li>
<a href='class/PeerJsConnector.html#getAllConnectionIds-dynamic' target='main' title='getAllConnectionIds'> <a href='class/PeerJsConnector.html#getAllConnectionIds-dynamic' target='main' title='getAllConnectionIds'>
#getAllConnectionIds #getAllConnectionIds
@ -269,14 +221,6 @@
(PeerJsConnector) (PeerJsConnector)
</small> </small>
</li> </li>
<li>
<a href='class/TextFramework.html#getConnector-dynamic' target='main' title='getConnector'>
#getConnector
</a>
<small>
(TextFramework)
</small>
</li>
<li> <li>
<a href='class/JsonFramework.html#getConnector-dynamic' target='main' title='getConnector'> <a href='class/JsonFramework.html#getConnector-dynamic' target='main' title='getConnector'>
#getConnector #getConnector
@ -285,6 +229,14 @@
(JsonFramework) (JsonFramework)
</small> </small>
</li> </li>
<li>
<a href='class/TextFramework.html#getConnector-dynamic' target='main' title='getConnector'>
#getConnector
</a>
<small>
(TextFramework)
</small>
</li>
<li> <li>
<a href='class/XmlFramework.html#getConnector-dynamic' target='main' title='getConnector'> <a href='class/XmlFramework.html#getConnector-dynamic' target='main' title='getConnector'>
#getConnector #getConnector
@ -293,6 +245,14 @@
(XmlFramework) (XmlFramework)
</small> </small>
</li> </li>
<li>
<a href='class/TextFramework.html#getHistoryBuffer-dynamic' target='main' title='getHistoryBuffer'>
#getHistoryBuffer
</a>
<small>
(TextFramework)
</small>
</li>
<li> <li>
<a href='class/XmlFramework.html#getHistoryBuffer-dynamic' target='main' title='getHistoryBuffer'> <a href='class/XmlFramework.html#getHistoryBuffer-dynamic' target='main' title='getHistoryBuffer'>
#getHistoryBuffer #getHistoryBuffer
@ -309,14 +269,6 @@
(JsonFramework) (JsonFramework)
</small> </small>
</li> </li>
<li>
<a href='class/TextFramework.html#getHistoryBuffer-dynamic' target='main' title='getHistoryBuffer'>
#getHistoryBuffer
</a>
<small>
(TextFramework)
</small>
</li>
<li> <li>
<a href='class/JsonType.html#getParent-dynamic' target='main' title='getParent'> <a href='class/JsonType.html#getParent-dynamic' target='main' title='getParent'>
#getParent #getParent
@ -325,14 +277,6 @@
(JsonType) (JsonType)
</small> </small>
</li> </li>
<li>
<a href='class/XmlType.html#getParent-dynamic' target='main' title='getParent'>
#getParent
</a>
<small>
(XmlType)
</small>
</li>
<li> <li>
<a href='class/XmlFramework.html#getSharedObject-dynamic' target='main' title='getSharedObject'> <a href='class/XmlFramework.html#getSharedObject-dynamic' target='main' title='getSharedObject'>
#getSharedObject #getSharedObject
@ -357,14 +301,6 @@
(JsonFramework) (JsonFramework)
</small> </small>
</li> </li>
<li>
<a href='class/XmlFramework.html#getUserId-dynamic' target='main' title='getUserId'>
#getUserId
</a>
<small>
(XmlFramework)
</small>
</li>
<li> <li>
<a href='class/TextFramework.html#getUserId-dynamic' target='main' title='getUserId'> <a href='class/TextFramework.html#getUserId-dynamic' target='main' title='getUserId'>
#getUserId #getUserId
@ -373,6 +309,14 @@
(TextFramework) (TextFramework)
</small> </small>
</li> </li>
<li>
<a href='class/XmlFramework.html#getUserId-dynamic' target='main' title='getUserId'>
#getUserId
</a>
<small>
(XmlFramework)
</small>
</li>
<li> <li>
<a href='class/JsonFramework.html#getUserId-dynamic' target='main' title='getUserId'> <a href='class/JsonFramework.html#getUserId-dynamic' target='main' title='getUserId'>
#getUserId #getUserId
@ -405,14 +349,6 @@
(WordType) (WordType)
</small> </small>
</li> </li>
<li>
<a href='class/XmlFramework.html#on-dynamic' target='main' title='on'>
#on
</a>
<small>
(XmlFramework)
</small>
</li>
<li> <li>
<a href='class/TextFramework.html#on-dynamic' target='main' title='on'> <a href='class/TextFramework.html#on-dynamic' target='main' title='on'>
#on #on
@ -421,6 +357,14 @@
(TextFramework) (TextFramework)
</small> </small>
</li> </li>
<li>
<a href='class/XmlFramework.html#on-dynamic' target='main' title='on'>
#on
</a>
<small>
(XmlFramework)
</small>
</li>
<li> <li>
<a href='class/JsonFramework.html#on-dynamic' target='main' title='on'> <a href='class/JsonFramework.html#on-dynamic' target='main' title='on'>
#on #on
@ -429,6 +373,14 @@
(JsonFramework) (JsonFramework)
</small> </small>
</li> </li>
<li>
<a href='class/PeerJsConnector.html#onNewConnection-dynamic' target='main' title='onNewConnection'>
#onNewConnection
</a>
<small>
(PeerJsConnector)
</small>
</li>
<li> <li>
<a href='class/WordType.html#push-dynamic' target='main' title='push'> <a href='class/WordType.html#push-dynamic' target='main' title='push'>
#push #push
@ -485,14 +437,6 @@
(IwcConnector) (IwcConnector)
</small> </small>
</li> </li>
<li>
<a href='class/XmlFramework.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'>
#setMutableDefault
</a>
<small>
(XmlFramework)
</small>
</li>
<li> <li>
<a href='class/JsonFramework.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'> <a href='class/JsonFramework.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'>
#setMutableDefault #setMutableDefault
@ -509,6 +453,14 @@
(JsonType) (JsonType)
</small> </small>
</li> </li>
<li>
<a href='class/XmlFramework.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'>
#setMutableDefault
</a>
<small>
(XmlFramework)
</small>
</li>
<li> <li>
<a href='class/JsonType.html#setReplaceManager-dynamic' target='main' title='setReplaceManager'> <a href='class/JsonType.html#setReplaceManager-dynamic' target='main' title='setReplaceManager'>
#setReplaceManager #setReplaceManager
@ -525,14 +477,6 @@
(WordType) (WordType)
</small> </small>
</li> </li>
<li>
<a href='class/XmlType.html#setXmlProxy-dynamic' target='main' title='setXmlProxy'>
#setXmlProxy
</a>
<small>
(XmlType)
</small>
</li>
<li> <li>
<a href='class/XmlFramework.html#toJson-dynamic' target='main' title='toJson'> <a href='class/XmlFramework.html#toJson-dynamic' target='main' title='toJson'>
#toJson #toJson
@ -565,14 +509,6 @@
(WordType) (WordType)
</small> </small>
</li> </li>
<li>
<a href='class/TextFramework.html#val-dynamic' target='main' title='val'>
#val
</a>
<small>
(TextFramework)
</small>
</li>
<li> <li>
<a href='class/WordType.html#val-dynamic' target='main' title='val'> <a href='class/WordType.html#val-dynamic' target='main' title='val'>
#val #val
@ -582,19 +518,19 @@
</small> </small>
</li> </li>
<li> <li>
<a href='class/XmlType.html#val-dynamic' target='main' title='val'> <a href='class/TextFramework.html#val-dynamic' target='main' title='val'>
#val #val
</a> </a>
<small> <small>
(XmlType) (TextFramework)
</small> </small>
</li> </li>
<li> <li>
<a href='class/JsonFramework.html#val-dynamic' target='main' title='val'> <a href='class/XmlFramework.html#val-dynamic' target='main' title='val'>
#val #val
</a> </a>
<small> <small>
(JsonFramework) (XmlFramework)
</small> </small>
</li> </li>
<li> <li>
@ -606,11 +542,11 @@
</small> </small>
</li> </li>
<li> <li>
<a href='class/XmlFramework.html#val-dynamic' target='main' title='val'> <a href='class/JsonFramework.html#val-dynamic' target='main' title='val'>
#val #val
</a> </a>
<small> <small>
(XmlFramework) (JsonFramework)
</small> </small>
</li> </li>
</ul> </ul>

View File

@ -194,7 +194,7 @@ Apply a 'change' - listener to a JsonType.
console.log("New value: " + show(this.val(property_name)) + ""); // 'this' is the object on which the property changed. console.log("New value: " + show(this.val(property_name)) + ""); // 'this' is the object on which the property changed.
}; };
yatta.on('change', change); yatta.on('change', change);
yatta.val('mutable_string', "text", 'mutable'); // Property 'mutable_string' was replaced or changed! yatta.val('mutable_string', "text", 'mutable'); // You changed the value of property 'mutable_string'!
``` ```

View File

@ -156,7 +156,7 @@ Y.createPeerJsConnector("unique_id", {key: 'h7nlefbgavh1tt9'}, function(Connecto
console.log("New value: " + show(this.val(property_name)) + ""); // 'this' is the object on which the property changed. console.log("New value: " + show(this.val(property_name)) + ""); // 'this' is the object on which the property changed.
}; };
yatta.on('change', change); yatta.on('change', change);
yatta.val('mutable_string', "text", 'mutable'); // Property 'mutable_string' was replaced or changed! yatta.val('mutable_string', "text", 'mutable'); // You changed the value of property 'mutable_string'!
/** /**
'change' and 'addProperty' do also fire for nested properties. 'change' and 'addProperty' do also fire for nested properties.

View File

@ -27,6 +27,41 @@ var yatta, yattaHandler;
Y.createPeerJsConnector({key: 'h7nlefbgavh1tt9'}, function(Connector, user_id){ Y.createPeerJsConnector({key: 'h7nlefbgavh1tt9'}, function(Connector, user_id){
yatta = new Y.XmlFramework(user_id, Connector); yatta = new Y.XmlFramework(user_id, Connector);
console.log(yatta.getUserId()); ```
Get the url of this frame. If it has a url-encoded parameter
we will connect to the foreign peer.
```js
var url = window.location.href;
var peer_id = location.search
var url = url.substring(0,-peer_id.length);
peer_id = peer_id.substring(1);
```
Set the shareable link.
```js
document.getElementById("peer_link").setAttribute("href",url+"?"+user_id);
```
Connect to other peer.
```js
if (peer_id.length > 0){
yatta.connector.connectToPeer(peer_id);
}
yatta.connector.onNewConnection(function(){
$("#collaborative").replaceWith(yatta.val())
});
yatta.val($("#collaborative")[0])
console.log(yatta.getUserId());
}); });
``` ```

View File

@ -9,14 +9,17 @@
<script src="./index.js"></script> <script src="./index.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head> </head>
<body> <body id="collaborative">
<h1> PeerJs + Json Tutorial</h1> <h1> PeerJs + XML Example</h1>
<p> Collaborative Json editing with <a href="https://github.com/DadaMonad/Yatta/">Yatta</a> <p> Collaborative XML editing with <a href="https://github.com/DadaMonad/Yatta/">Yatta</a>
and <a href="http://peerjs.com/">PeerJs</a> (WebRTC). </p> and <a href="http://peerjs.com/">PeerJs</a> (WebRTC). </p>
<p> <a href="https://github.com/DadaMonad/Yatta/">Yatta</a> is a Framework for Real-Time collaboration on arbitrary data structures. <p> <a href="https://github.com/DadaMonad/Yatta/">Yatta</a> is a Framework for Real-Time collaboration on arbitrary data structures.
You can find the code for this example <a href="https://github.com/DadaMonad/Yatta/tree/master/examples/PeerJs-Json">here</a>. You can find the code for this example <a href="https://github.com/DadaMonad/Yatta/tree/master/examples/PeerJs-Json">here</a>.
<a id="peer_link" target="_blank">Drop me </a>
</p> </p>
</body> </body>
</html> </html>

View File

@ -27,5 +27,31 @@ var yatta, yattaHandler;
Y.createPeerJsConnector({key: 'h7nlefbgavh1tt9'}, function(Connector, user_id){ Y.createPeerJsConnector({key: 'h7nlefbgavh1tt9'}, function(Connector, user_id){
yatta = new Y.XmlFramework(user_id, Connector); yatta = new Y.XmlFramework(user_id, Connector);
console.log(yatta.getUserId());
/**
Get the url of this frame. If it has a url-encoded parameter
we will connect to the foreign peer.
*/
var url = window.location.href;
var peer_id = location.search
var url = url.substring(0,-peer_id.length);
peer_id = peer_id.substring(1);
/**
Set the shareable link.
*/
document.getElementById("peer_link").setAttribute("href",url+"?"+user_id);
/**
Connect to other peer.
*/
if (peer_id.length > 0){
yatta.connector.connectToPeer(peer_id);
}
yatta.connector.onNewConnection(function(){
$("#collaborative").replaceWith(yatta.val())
});
yatta.val($("#collaborative")[0])
console.log(yatta.getUserId());
}); });

View File

@ -39,6 +39,7 @@ createPeerJsConnector = ()->
@peer = peer @peer = peer
@connections = {} @connections = {}
@new_connection_listeners = []
@peer.on 'connection', (conn)=> @peer.on 'connection', (conn)=>
@addConnection conn @addConnection conn
@ -82,6 +83,9 @@ createPeerJsConnector = ()->
for conn_id of @connections for conn_id of @connections
conn_id conn_id
onNewConnection: (f)->
@new_connection_listeners.push f
# #
# Adds an existing connection to this connector. # Adds an existing connection to this connector.
# @param conn {PeerJsConnection} # @param conn {PeerJsConnection}
@ -105,6 +109,8 @@ createPeerJsConnector = ()->
if not data.initialized if not data.initialized
conn.send conn.send
conns: @getAllConnectionIds() conns: @getAllConnectionIds()
@new_connection_listeners.map (f)->
f(conn)
else if data.op? else if data.op?
@engine.applyOp data.op @engine.applyOp data.op
else if data.conns? else if data.conns?

View File

@ -271,15 +271,18 @@ module.exports = (HB)->
# #
applyDelete: (o)-> applyDelete: (o)->
@deleted_by ?= [] @deleted_by ?= []
callLater = false
if @parent? and not @isDeleted() if @parent? and not @isDeleted()
# call iff wasn't deleted earlyer # call iff wasn't deleted earlyer
@parent.callEvent "delete", @, o callLater = true
if o? if o?
@deleted_by.push o @deleted_by.push o
garbagecollect = false garbagecollect = false
if not (@prev_cl? and @next_cl?) or @prev_cl.isDeleted() if not (@prev_cl? and @next_cl?) or @prev_cl.isDeleted()
garbagecollect = true garbagecollect = true
super garbagecollect super garbagecollect
if callLater
@parent.callEvent "delete", @, o
if @next_cl?.isDeleted() if @next_cl?.isDeleted()
# garbage collect next_cl # garbage collect next_cl
@next_cl.applyDelete() @next_cl.applyDelete()

View File

@ -43,10 +43,18 @@ module.exports = (HB)->
@content.length @content.length
applyDelete: ()-> applyDelete: ()->
super # no braces indeed!
if @content instanceof types.Operation if @content instanceof types.Operation
@content.applyDelete() @content.applyDelete()
@content = null @content = null
super
execute: ()->
if not @validateSavedOperations()
return false
else
if @content instanceof types.Operation
@content.insert_parent = @
super()
# #
# The result will be concatenated with the results from the other insert operations # The result will be concatenated with the results from the other insert operations

View File

@ -5,15 +5,25 @@ json_types_uninitialized = require "./JsonTypes"
# For example xml.insertChild(dom) , wich inserts an element at the end, and xml.insertAfter(dom,null) wich does the same # For example xml.insertChild(dom) , wich inserts an element at the end, and xml.insertAfter(dom,null) wich does the same
# But yatta's proxy may be called only once! # But yatta's proxy may be called only once!
proxy_token = false proxy_token = false
dont_proxy = (f)->
proxy_token = true
try
f()
catch e
proxy_token = false
throw new Error e
proxy_token = false
_proxy = (f_name, f)-> _proxy = (f_name, f)->
old_f = @[f_name] old_f = @[f_name]
if old_f? if old_f?
@[f_name] = ()-> @[f_name] = ()->
if not proxy_token and not @_yatta?.isDeleted() if not proxy_token and not @_yatta?.isDeleted()
proxy_token = true that = this
old_f.apply this, arguments args = arguments
f.apply this, arguments dont_proxy ()->
proxy_token = false f.apply that, args
old_f.apply that, args
else else
old_f.apply this, arguments old_f.apply this, arguments
#else #else
@ -48,11 +58,18 @@ module.exports = (HB)->
super(uid) super(uid)
if @xml?._yatta?
d = new types.Delete undefined, @xml._yatta
HB.addOperation(d).execute()
@xml._yatta = null
if attributes? and elements? if attributes? and elements?
@saveOperation 'attributes', attributes @saveOperation 'attributes', attributes
@saveOperation 'elements', elements @saveOperation 'elements', elements
else if (not attributes?) and (not elements?) else if (not attributes?) and (not elements?)
@attributes = new types.JsonType() @attributes = new types.JsonType()
@attributes.setMutableDefault 'immutable'
HB.addOperation(@attributes).execute() HB.addOperation(@attributes).execute()
@elements = new types.WordType() @elements = new types.WordType()
@elements.parent = @ @elements.parent = @
@ -67,11 +84,9 @@ module.exports = (HB)->
@attributes.val(attr.name, attr.value) @attributes.val(attr.name, attr.value)
for n in @xml.childNodes for n in @xml.childNodes
if n.nodeType is n.TEXT_NODE if n.nodeType is n.TEXT_NODE
word = new types.WordType() word = new TextNodeType(undefined, n)
HB.addOperation(word).execute() HB.addOperation(word).execute()
word.push n.textContent
@elements.push word @elements.push word
n._yatta = word
else if n.nodeType is n.ELEMENT_NODE else if n.nodeType is n.ELEMENT_NODE
element = new XmlType undefined, undefined, undefined, undefined, n element = new XmlType undefined, undefined, undefined, undefined, n
HB.addOperation(element).execute() HB.addOperation(element).execute()
@ -87,10 +102,13 @@ module.exports = (HB)->
# #
type: "XmlType" type: "XmlType"
applyDelete: ()-> applyDelete: (op)->
@attributes.applyDelete() if @insert_parent? and not @insert_parent.isDeleted()
@elements.applyDelete() @insert_parent.applyDelete op
super() else
@attributes.applyDelete()
@elements.applyDelete()
super
cleanup: ()-> cleanup: ()->
super() super()
@ -98,11 +116,50 @@ module.exports = (HB)->
setXmlProxy: ()-> setXmlProxy: ()->
@xml._yatta = @ @xml._yatta = @
that = @ that = @
@elements.on 'insert', (event, op)->
if op.creator isnt HB.getUserId() and this is that.elements
newNode = op.content.val()
right = op.next_cl
while right? and right.isDeleted()
right = right.next_cl
rightNode = null
if right.type isnt 'Delimiter'
rightNode = right.val().val()
dont_proxy ()->
that.xml.insertBefore newNode, rightNode
@elements.on 'delete', (event, op)->
del_op = op.deleted_by[0]
if del_op? and del_op.creator isnt HB.getUserId() and this is that.elements
deleted = op.content.val()
dont_proxy ()->
that.xml.removeChild deleted
@attributes.on ['addProperty', 'change'], (event, property_name, op)->
if op.creator isnt HB.getUserId() and this is that.attributes
dont_proxy ()->
newval = op.val().val()
if newval?
that.xml.setAttribute(property_name, op.val().val())
else
that.xml.removeAttribute(property_name)
## Here are all methods that proxy the behavior of the xml
# you want to find a specific child element. Since they are carried by an Insert-Type, you want to find that Insert-Operation. # you want to find a specific child element. Since they are carried by an Insert-Type, you want to find that Insert-Operation.
# @param child {DomElement} Dom element. # @param child {DomElement} Dom element.
# @return {InsertType} This carries the XmlType that represents the DomElement (child). false if i couldn't find it. # @return {InsertType} This carries the XmlType that represents the DomElement (child). false if i couldn't find it.
# #
findNode = (child)-> findNode = (child)->
if not child?
throw new Error "you must specify a parameter!"
child = child._yatta child = child._yatta
elem = that.elements.beginning.next_cl elem = that.elements.beginning.next_cl
while elem.type isnt 'Delimiter' and elem.content isnt child while elem.type isnt 'Delimiter' and elem.content isnt child
@ -112,7 +169,7 @@ module.exports = (HB)->
else else
elem elem
insertBefore = (insertedNode, adjacentNode)-> insertBefore = (insertedNode_s, adjacentNode)->
next = null next = null
if adjacentNode? if adjacentNode?
next = findNode adjacentNode next = findNode adjacentNode
@ -121,9 +178,21 @@ module.exports = (HB)->
prev = next.prev_cl prev = next.prev_cl
else else
prev = @_yatta.elements.end.prev_cl prev = @_yatta.elements.end.prev_cl
element = new XmlType undefined, undefined, undefined, undefined, insertedNode while prev.isDeleted()
HB.addOperation(element).execute() prev = prev.prev_cl
that.elements.insertAfter prev, element inserted_nodes = null
if insertedNode_s.nodeType is insertedNode_s.DOCUMENT_FRAGMENT_NODE
child = insertedNode_s.lastChild
while child?
element = new XmlType undefined, undefined, undefined, undefined, child
HB.addOperation(element).execute()
that.elements.insertAfter prev, element
child = child.previousSibling
else
element = new XmlType undefined, undefined, undefined, undefined, insertedNode_s
HB.addOperation(element).execute()
that.elements.insertAfter prev, element
@xml._proxy 'insertBefore', insertBefore @xml._proxy 'insertBefore', insertBefore
@xml._proxy 'appendChild', insertBefore @xml._proxy 'appendChild', insertBefore
@xml._proxy 'removeAttribute', (name)-> @xml._proxy 'removeAttribute', (name)->
@ -131,8 +200,16 @@ module.exports = (HB)->
@xml._proxy 'setAttribute', (name, value)-> @xml._proxy 'setAttribute', (name, value)->
that.attributes.val name, value that.attributes.val name, value
renewClassList = ()-> renewClassList = (newclass)->
that.attributes.val('class', Array.prototype.join.call this, " ") dont_do_it = false
if newclass?
for elem in this
if newclass is elem
dont_do_it = true
value = Array.prototype.join.call this, " "
if newclass? and not dont_do_it
value += " "+newclass
that.attributes.val('class', value )
_proxy.call @xml.classList, 'add', renewClassList _proxy.call @xml.classList, 'add', renewClassList
_proxy.call @xml.classList, 'remove', renewClassList _proxy.call @xml.classList, 'remove', renewClassList
@xml.__defineSetter__ 'className', (val)-> @xml.__defineSetter__ 'className', (val)->
@ -158,6 +235,7 @@ module.exports = (HB)->
throw new Error "You are only allowed to delete existing (direct) child elements!" throw new Error "You are only allowed to delete existing (direct) child elements!"
d = new types.Delete undefined, elem d = new types.Delete undefined, elem
HB.addOperation(d).execute() HB.addOperation(d).execute()
node._yatta = null
@xml._proxy 'removeChild', removeChild @xml._proxy 'removeChild', removeChild
@xml._proxy 'replaceChild', (insertedNode, replacedNode)-> @xml._proxy 'replaceChild', (insertedNode, replacedNode)->
insertBefore.call this, insertedNode, replacedNode insertBefore.call this, insertedNode, replacedNode
@ -180,12 +258,11 @@ module.exports = (HB)->
e = @elements.beginning.next_cl e = @elements.beginning.next_cl
while e.type isnt "Delimiter" while e.type isnt "Delimiter"
n = e.content n = e.content
if not e.isDeleted() if not e.isDeleted() and e.content? # TODO: how can this happen? Probably because listeners
if n.type is "XmlType" if n.type is "XmlType"
@xml.appendChild n.val(enforce) @xml.appendChild n.val(enforce)
else if n.type is "WordType" else if n.type is "TextNodeType"
text_node = document.createTextNode n.val() text_node = n.val()
text_node._yatta = @
@xml.appendChild text_node @xml.appendChild text_node
else else
throw new Error "Internal structure cannot be transformed to dom" throw new Error "Internal structure cannot be transformed to dom"
@ -238,6 +315,51 @@ module.exports = (HB)->
new XmlType uid, tagname, attributes, elements, undefined new XmlType uid, tagname, attributes, elements, undefined
#
# @nodoc
# Defines an object that is cannot be changed. You can use this to set an immutable string, or a number.
#
class TextNodeType extends types.ImmutableObject
#
# @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.
# @param {Object} content
#
constructor: (uid, content)->
if content._yatta?
d = new types.Delete undefined, content._yatta
HB.addOperation(d).execute()
content._yatta = null
content._yatta = @
super uid, content
applyDelete: (op)->
if @insert_parent? and not @insert_parent.isDeleted()
@insert_parent.applyDelete op
else
super
type: "TextNodeType"
#
# Encode this operation in such a way that it can be parsed by remote peers.
#
_encode: ()->
json = {
'type': @type
'uid' : @getUid()
'content' : @content.textContent
}
json
parser['TextNodeType'] = (json)->
{
'uid' : uid
'content' : content
} = json
textnode = document.createTextNode content
new TextNodeType uid, textnode
types['XmlType'] = XmlType types['XmlType'] = XmlType

View File

@ -36,27 +36,36 @@ describe "XmlFramework", ->
@users = @yTest.users @users = @yTest.users
### ###
@test_user = @yTest.makeNewUser 0, (Connector_uninitialized []) test_users = []
connector = (Connector_uninitialized test_users)
@test_user = @yTest.makeNewUser 0, connector
test_users.push @test_user
# test_user_listen listens to the actions of test_user. He will update his dom when he receives from test_user.
@test_user_listen = @yTest.makeNewUser 2, connector
test_users.push @test_user_listen
@test_user2 = @yTest.makeNewUser 1, (Connector_uninitialized []) @test_user2 = @yTest.makeNewUser 1, (Connector_uninitialized [])
$("#test_dom").replaceWith('<div id="test_dom" test_attribute="the test" class="stuffy" style="color: blue"><p id="replaceme">replace me</p><p id="removeme">remove me</p><p>This is a test object for <b>XmlFramework</b></p><span class="span_element"><p>span</p></span></div>')
@$dom = $("#test_dom") @$dom = $("#test_dom")
@dom = @$dom[0] @dom = @$dom[0]
@test_user.val(@dom) @test_user.val(@dom)
@test_user_listen.getConnector().flushAll()
@test_user_listen_dom = @test_user_listen.val()
@check = ()=> @check = ()=>
dom_ = @test_user.val(true) dom_ = @dom.outerHTML
expect(dom_.outerHTML).to.equal(@dom.outerHTML)
# now test if other collaborators can parse the HB and result in the same content # now test if other collaborators can parse the HB and result in the same content
hb = @test_user.HB._encode() hb = @test_user.HB._encode()
@test_user2.engine.applyOps(hb) @test_user2.engine.applyOps(hb)
dom2 = @test_user2.val() dom2 = @test_user2.val()
expect(dom_.outerHTML).to.equal(dom2.outerHTML) expect(dom_).to.equal(dom2.outerHTML)
@test_user_listen.getConnector().flushAll()
expect(dom_).to.equal(@test_user_listen_dom.outerHTML)
done() done()
it "can transform to a new real Dom element", -> it "can transform to a new real Dom element", ->
dom_ = @test_user.val(true) dom_ = @test_user.val(true)
expect(dom_ isnt @dom).to.be.true expect(dom_ isnt @dom).to.be.true
@check()
it "supports dom.insertBefore", -> it "supports dom.insertBefore", ->
newdom = $("<p>dtrn</p>")[0] newdom = $("<p>dtrn</p>")[0]
@ -116,6 +125,7 @@ describe "XmlFramework", ->
it "supports jquery.appendTo", -> it "supports jquery.appendTo", ->
$("<b>appendedTo</b>").appendTo("#test_dom p") $("<b>appendedTo</b>").appendTo("#test_dom p")
$("p").appendTo("#test_dom")
@check() @check()
it "supports jquery.before", -> it "supports jquery.before", ->