tests run fine. but it needs some more user testing
This commit is contained in:
parent
968e07a8ff
commit
3415d0ee5e
File diff suppressed because one or more lines are too long
@ -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
4
build/browser/Frameworks/XmlFramework.min.js
vendored
4
build/browser/Frameworks/XmlFramework.min.js
vendored
File diff suppressed because one or more lines are too long
@ -26,6 +26,7 @@
|
||||
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);
|
||||
@ -80,6 +81,10 @@
|
||||
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;
|
||||
@ -94,9 +99,12 @@
|
||||
initialized_me = true;
|
||||
_this.engine.applyOpsCheckDouble(data.HB);
|
||||
if (!data.initialized) {
|
||||
return conn.send({
|
||||
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);
|
||||
|
File diff suppressed because one or more lines are too long
@ -218,12 +218,13 @@
|
||||
Insert.prototype.type = "Insert";
|
||||
|
||||
Insert.prototype.applyDelete = function(o) {
|
||||
var garbagecollect, _ref;
|
||||
var callLater, garbagecollect, _ref;
|
||||
if (this.deleted_by == null) {
|
||||
this.deleted_by = [];
|
||||
}
|
||||
callLater = false;
|
||||
if ((this.parent != null) && !this.isDeleted()) {
|
||||
this.parent.callEvent("delete", this, o);
|
||||
callLater = true;
|
||||
}
|
||||
if (o != null) {
|
||||
this.deleted_by.push(o);
|
||||
@ -233,6 +234,9 @@
|
||||
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();
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -47,11 +47,22 @@
|
||||
};
|
||||
|
||||
TextInsert.prototype.applyDelete = function() {
|
||||
TextInsert.__super__.applyDelete.apply(this, arguments);
|
||||
if (this.content instanceof types.Operation) {
|
||||
this.content.applyDelete();
|
||||
}
|
||||
this.content = null;
|
||||
return TextInsert.__super__.applyDelete.apply(this, arguments);
|
||||
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) {
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,5 +1,5 @@
|
||||
(function() {
|
||||
var json_types_uninitialized, proxy_token,
|
||||
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; };
|
||||
|
||||
@ -7,27 +7,45 @@
|
||||
|
||||
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 = function(f_name, f) {
|
||||
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);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
Element.prototype._proxy = _proxy;
|
||||
}
|
||||
|
||||
module.exports = function(HB) {
|
||||
var XmlType, json_types, parser, types;
|
||||
var TextNodeType, XmlType, json_types, parser, types;
|
||||
json_types = json_types_uninitialized(HB);
|
||||
types = json_types.types;
|
||||
parser = json_types.parser;
|
||||
@ -35,7 +53,7 @@
|
||||
__extends(XmlType, _super);
|
||||
|
||||
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.xml = xml;
|
||||
|
||||
@ -48,12 +66,18 @@
|
||||
prev = prev.prev_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)) {
|
||||
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;
|
||||
@ -63,17 +87,16 @@
|
||||
}
|
||||
if (this.xml != null) {
|
||||
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];
|
||||
this.attributes.val(attr.name, attr.value);
|
||||
}
|
||||
_ref1 = this.xml.childNodes;
|
||||
for (_j = 0, _len = _ref1.length; _j < _len; _j++) {
|
||||
n = _ref1[_j];
|
||||
_ref2 = this.xml.childNodes;
|
||||
for (_j = 0, _len = _ref2.length; _j < _len; _j++) {
|
||||
n = _ref2[_j];
|
||||
if (n.nodeType === n.TEXT_NODE) {
|
||||
word = new types.WordType();
|
||||
word = new TextNodeType(void 0, n);
|
||||
HB.addOperation(word).execute();
|
||||
word.push(n.textContent);
|
||||
this.elements.push(word);
|
||||
} else if (n.nodeType === n.ELEMENT_NODE) {
|
||||
element = new XmlType(void 0, void 0, void 0, void 0, n);
|
||||
@ -90,10 +113,14 @@
|
||||
|
||||
XmlType.prototype.type = "XmlType";
|
||||
|
||||
XmlType.prototype.applyDelete = function() {
|
||||
this.attributes.applyDelete();
|
||||
this.elements.applyDelete();
|
||||
return XmlType.__super__.applyDelete.call(this);
|
||||
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() {
|
||||
@ -101,42 +128,156 @@
|
||||
};
|
||||
|
||||
XmlType.prototype.setXmlProxy = function() {
|
||||
var insertBefore, removeChild, that;
|
||||
var findNode, insertBefore, removeChild, renewClassList, that;
|
||||
this.xml._yatta = this;
|
||||
that = this;
|
||||
insertBefore = function(insertedNode, adjacentNode) {
|
||||
var element, next, prev;
|
||||
next = adjacentNode != null ? adjacentNode._yatta : void 0;
|
||||
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 != 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);
|
||||
}
|
||||
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('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 = that.elements.beginning.next_cl;
|
||||
while (elem.type !== 'Delimiter' && elem.content !== node._yatta) {
|
||||
elem = elem.next_cl;
|
||||
}
|
||||
if (elem.type === 'Delimiter') {
|
||||
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);
|
||||
return HB.addOperation(d).execute();
|
||||
HB.addOperation(d).execute();
|
||||
return node._yatta = null;
|
||||
};
|
||||
this.xml._proxy('removeChild', removeChild);
|
||||
return this.xml._proxy('replaceChild', function(insertedNode, replacedNode) {
|
||||
insertBefore.call(this, replacedNode, insertedNode);
|
||||
insertBefore.call(this, insertedNode, replacedNode);
|
||||
return removeChild.call(this, replacedNode);
|
||||
});
|
||||
};
|
||||
@ -161,11 +302,12 @@
|
||||
e = this.elements.beginning.next_cl;
|
||||
while (e.type !== "Delimiter") {
|
||||
n = e.content;
|
||||
if (!e.isDeleted()) {
|
||||
if (!e.isDeleted() && (e.content != null)) {
|
||||
if (n.type === "XmlType") {
|
||||
this.xml.appendChild(n.val(enforce));
|
||||
} else if (n.type === "WordType") {
|
||||
text_node = document.createTextNode(n.val());
|
||||
} else if (n.type === "TextNodeType") {
|
||||
text_node = n.val();
|
||||
text_node._yatta = this;
|
||||
this.xml.appendChild(text_node);
|
||||
} else {
|
||||
throw new Error("Internal structure cannot be transformed to dom");
|
||||
@ -180,7 +322,7 @@
|
||||
};
|
||||
|
||||
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'];
|
||||
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;
|
||||
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
@ -100,11 +100,6 @@
|
||||
XmlFramework
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlType.html'>
|
||||
XmlType
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
@ -257,21 +252,13 @@
|
||||
(lib/Frameworks)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='file/lib/Types/XmlTypes.coffee.html'>
|
||||
XmlTypes.coffee
|
||||
</a>
|
||||
<small>
|
||||
(lib/Types)
|
||||
</small>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -302,7 +302,7 @@ data from the received intent.</p>
|
||||
</div>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -335,7 +335,7 @@ JsonFramework was initialized (Depending on the HistoryBuffer implementation).</
|
||||
</div>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -466,7 +466,7 @@ if (x.type === "JsonType") {
|
||||
</div>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -139,7 +139,7 @@ console.log(w.newProperty == "Awesome") # true!</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -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.
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<span class='signature'>
|
||||
<a href='#onNewConnection-dynamic'>
|
||||
#
|
||||
(void)
|
||||
<b>onNewConnection</b><span>(f)</span>
|
||||
</a>
|
||||
</span>
|
||||
<span class='desc'>
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<span class='signature'>
|
||||
<a href='#addConnection-dynamic'>
|
||||
@ -194,6 +205,15 @@ on how to do that with urls.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class='method_details'>
|
||||
<p class='signature' id='onNewConnection-dynamic'>
|
||||
#
|
||||
(void)
|
||||
<b>onNewConnection</b><span>(f)</span>
|
||||
<br>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<div class='method_details'>
|
||||
<p class='signature' id='addConnection-dynamic'>
|
||||
@ -222,7 +242,7 @@ on how to do that with urls.</p>
|
||||
</div>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -356,7 +356,7 @@ JsonFramework was initialized (Depending on the HistoryBuffer implementation).</
|
||||
</div>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -455,7 +455,7 @@ yatta.bind(textbox);</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -44,8 +44,9 @@
|
||||
<p>Manages XML types
|
||||
Not supported:</p><ul>
|
||||
<li>Attribute nodes</li>
|
||||
<li>Real replace of child elements (to much overhead). Currently, the new element is inserted after the 'replaced' element, and then it is deleted.
|
||||
*</li>
|
||||
<li>Real replace of child elements (to much overhead). Currently, the new element is inserted after the 'replaced' element, and then it is deleted.</li>
|
||||
<li>Namespaces (*NS)</li>
|
||||
<li>Browser specific methods (webkit-* operations)</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@ -122,7 +123,6 @@ Use it in order to check whether this is an xml-type or something else.</p>
|
||||
</a>
|
||||
</span>
|
||||
<span class='desc'>
|
||||
If possible set the replace manager in the content.
|
||||
</span>
|
||||
</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>
|
||||
<br>
|
||||
</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 class='method_details'>
|
||||
<p class='signature' id='getParent-dynamic'>
|
||||
@ -258,7 +248,7 @@ This result can be send to other clients.</p>
|
||||
</div>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -99,18 +99,6 @@
|
||||
</small>
|
||||
<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>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -38,7 +38,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -70,7 +70,7 @@ But I would become really motivated if you gave me some feedback :) (<a href="ht
|
||||
<ul>
|
||||
<li>XML support</li>
|
||||
</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="mailto:kevin.jahns@rwth-aachen.de">kevin.jahns@rwth-aachen.de</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="mailto:kevin.jahns@rwth-aachen.de">kevin.jahns@rwth-aachen.de</a>
|
||||
|
||||
|
||||
|
||||
@ -79,7 +79,7 @@ But I would become really motivated if you gave me some feedback :) (<a href="ht
|
||||
</div>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -100,7 +100,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -158,7 +158,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -39,7 +39,7 @@
|
||||
</table>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -48,7 +48,7 @@
|
||||
</dl>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -60,7 +60,7 @@
|
||||
</dl>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -60,7 +60,7 @@
|
||||
</dl>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -48,7 +48,7 @@
|
||||
</dl>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -39,7 +39,7 @@
|
||||
</table>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -39,7 +39,7 @@
|
||||
</table>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -39,7 +39,7 @@
|
||||
</table>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -39,7 +39,7 @@
|
||||
</table>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -53,15 +53,34 @@ But yatta's proxy may be called only once!</p>
|
||||
<div class='tags'>
|
||||
</div>
|
||||
</dd>
|
||||
<dt id='Element.prototype._proxy-variable'>
|
||||
Element.prototype._proxy
|
||||
=
|
||||
</dt>
|
||||
<dd>
|
||||
<pre><code class='coffeescript'>_proxy</code></pre>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2>Method Summary</h2>
|
||||
<ul class='summary'>
|
||||
<li>
|
||||
<span class='signature'>
|
||||
<a href='#Element-'>
|
||||
<a href='#dont_proxy-'>
|
||||
~
|
||||
(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>
|
||||
</span>
|
||||
<span class='desc'>
|
||||
@ -71,10 +90,19 @@ But yatta's proxy may be called only once!</p>
|
||||
<h2>Method Details</h2>
|
||||
<div class='methods'>
|
||||
<div class='method_details'>
|
||||
<p class='signature' id='Element-'>
|
||||
<p class='signature' id='dont_proxy-'>
|
||||
~
|
||||
(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>
|
||||
</p>
|
||||
|
||||
@ -82,7 +110,7 @@ But yatta's proxy may be called only once!</p>
|
||||
</div>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -37,7 +37,7 @@
|
||||
</table>
|
||||
</div>
|
||||
<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'>
|
||||
Codo
|
||||
</a>
|
||||
|
@ -153,14 +153,6 @@
|
||||
lib/Types
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='file/lib/Types/XmlTypes.coffee.html' target='main'>
|
||||
XmlTypes.coffee
|
||||
</a>
|
||||
<small class='namespace'>
|
||||
lib/Types
|
||||
</small>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<li>
|
||||
|
File diff suppressed because one or more lines are too long
@ -30,19 +30,11 @@
|
||||
</div>
|
||||
<ul>
|
||||
<li>
|
||||
<a href='file/lib/Types/XmlTypes.coffee.html#Element-' target='main' title='Element'>
|
||||
~Element
|
||||
</a>
|
||||
<small>
|
||||
(lib/Types/XmlTypes.coffee)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlType.html#_encode-dynamic' target='main' title='_encode'>
|
||||
<a href='class/WordType.html#_encode-dynamic' target='main' title='_encode'>
|
||||
#_encode
|
||||
</a>
|
||||
<small>
|
||||
(XmlType)
|
||||
(WordType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
@ -53,14 +45,6 @@
|
||||
(JsonType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/WordType.html#_encode-dynamic' target='main' title='_encode'>
|
||||
#_encode
|
||||
</a>
|
||||
<small>
|
||||
(WordType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/PeerJsConnector.html#addConnection-dynamic' target='main' title='addConnection'>
|
||||
#addConnection
|
||||
@ -69,6 +53,14 @@
|
||||
(PeerJsConnector)
|
||||
</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
|
||||
@ -78,16 +70,8 @@
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlType.html#applyDelete-dynamic' target='main' title='applyDelete'>
|
||||
#applyDelete
|
||||
</a>
|
||||
<small>
|
||||
(XmlType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/WordType.html#applyDelete-dynamic' target='main' title='applyDelete'>
|
||||
#applyDelete
|
||||
<a href='class/WordType.html#bind-dynamic' target='main' title='bind'>
|
||||
#bind
|
||||
</a>
|
||||
<small>
|
||||
(WordType)
|
||||
@ -102,8 +86,8 @@
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/WordType.html#bind-dynamic' target='main' title='bind'>
|
||||
#bind
|
||||
<a href='class/WordType.html#cleanup-dynamic' target='main' title='cleanup'>
|
||||
#cleanup
|
||||
</a>
|
||||
<small>
|
||||
(WordType)
|
||||
@ -117,22 +101,6 @@
|
||||
(JsonType)
|
||||
</small>
|
||||
</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>
|
||||
<a href='class/PeerJsConnector.html#connectToPeer-dynamic' target='main' title='connectToPeer'>
|
||||
#connectToPeer
|
||||
@ -141,30 +109,6 @@
|
||||
(PeerJsConnector)
|
||||
</small>
|
||||
</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>
|
||||
<a href='class/IwcConnector.html#constructor-dynamic' target='main' title='constructor'>
|
||||
#constructor
|
||||
@ -173,6 +117,22 @@
|
||||
(IwcConnector)
|
||||
</small>
|
||||
</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>
|
||||
<a href='class/JsonType.html#constructor-dynamic' target='main' title='constructor'>
|
||||
#constructor
|
||||
@ -197,6 +157,14 @@
|
||||
(XmlFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/WordType.html#constructor-dynamic' target='main' title='constructor'>
|
||||
#constructor
|
||||
</a>
|
||||
<small>
|
||||
(WordType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/TextFramework.html#constructor-dynamic' target='main' title='constructor'>
|
||||
#constructor
|
||||
@ -205,14 +173,6 @@
|
||||
(TextFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/JsonFramework.html#constructor-dynamic' target='main' title='constructor'>
|
||||
#constructor
|
||||
</a>
|
||||
<small>
|
||||
(JsonFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='file/lib/Connectors/IwcConnector.coffee.html#createIwcConnector-' target='main' title='createIwcConnector'>
|
||||
~createIwcConnector
|
||||
@ -253,14 +213,6 @@
|
||||
(TextFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlType.html#execute-dynamic' target='main' title='execute'>
|
||||
#execute
|
||||
</a>
|
||||
<small>
|
||||
(XmlType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/PeerJsConnector.html#getAllConnectionIds-dynamic' target='main' title='getAllConnectionIds'>
|
||||
#getAllConnectionIds
|
||||
@ -269,14 +221,6 @@
|
||||
(PeerJsConnector)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/TextFramework.html#getConnector-dynamic' target='main' title='getConnector'>
|
||||
#getConnector
|
||||
</a>
|
||||
<small>
|
||||
(TextFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/JsonFramework.html#getConnector-dynamic' target='main' title='getConnector'>
|
||||
#getConnector
|
||||
@ -285,6 +229,14 @@
|
||||
(JsonFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/TextFramework.html#getConnector-dynamic' target='main' title='getConnector'>
|
||||
#getConnector
|
||||
</a>
|
||||
<small>
|
||||
(TextFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlFramework.html#getConnector-dynamic' target='main' title='getConnector'>
|
||||
#getConnector
|
||||
@ -293,6 +245,14 @@
|
||||
(XmlFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/TextFramework.html#getHistoryBuffer-dynamic' target='main' title='getHistoryBuffer'>
|
||||
#getHistoryBuffer
|
||||
</a>
|
||||
<small>
|
||||
(TextFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlFramework.html#getHistoryBuffer-dynamic' target='main' title='getHistoryBuffer'>
|
||||
#getHistoryBuffer
|
||||
@ -309,14 +269,6 @@
|
||||
(JsonFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/TextFramework.html#getHistoryBuffer-dynamic' target='main' title='getHistoryBuffer'>
|
||||
#getHistoryBuffer
|
||||
</a>
|
||||
<small>
|
||||
(TextFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/JsonType.html#getParent-dynamic' target='main' title='getParent'>
|
||||
#getParent
|
||||
@ -325,14 +277,6 @@
|
||||
(JsonType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlType.html#getParent-dynamic' target='main' title='getParent'>
|
||||
#getParent
|
||||
</a>
|
||||
<small>
|
||||
(XmlType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlFramework.html#getSharedObject-dynamic' target='main' title='getSharedObject'>
|
||||
#getSharedObject
|
||||
@ -357,14 +301,6 @@
|
||||
(JsonFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlFramework.html#getUserId-dynamic' target='main' title='getUserId'>
|
||||
#getUserId
|
||||
</a>
|
||||
<small>
|
||||
(XmlFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/TextFramework.html#getUserId-dynamic' target='main' title='getUserId'>
|
||||
#getUserId
|
||||
@ -373,6 +309,14 @@
|
||||
(TextFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlFramework.html#getUserId-dynamic' target='main' title='getUserId'>
|
||||
#getUserId
|
||||
</a>
|
||||
<small>
|
||||
(XmlFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/JsonFramework.html#getUserId-dynamic' target='main' title='getUserId'>
|
||||
#getUserId
|
||||
@ -405,14 +349,6 @@
|
||||
(WordType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlFramework.html#on-dynamic' target='main' title='on'>
|
||||
#on
|
||||
</a>
|
||||
<small>
|
||||
(XmlFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/TextFramework.html#on-dynamic' target='main' title='on'>
|
||||
#on
|
||||
@ -421,6 +357,14 @@
|
||||
(TextFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlFramework.html#on-dynamic' target='main' title='on'>
|
||||
#on
|
||||
</a>
|
||||
<small>
|
||||
(XmlFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/JsonFramework.html#on-dynamic' target='main' title='on'>
|
||||
#on
|
||||
@ -429,6 +373,14 @@
|
||||
(JsonFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/PeerJsConnector.html#onNewConnection-dynamic' target='main' title='onNewConnection'>
|
||||
#onNewConnection
|
||||
</a>
|
||||
<small>
|
||||
(PeerJsConnector)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/WordType.html#push-dynamic' target='main' title='push'>
|
||||
#push
|
||||
@ -485,14 +437,6 @@
|
||||
(IwcConnector)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlFramework.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'>
|
||||
#setMutableDefault
|
||||
</a>
|
||||
<small>
|
||||
(XmlFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/JsonFramework.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'>
|
||||
#setMutableDefault
|
||||
@ -509,6 +453,14 @@
|
||||
(JsonType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlFramework.html#setMutableDefault-dynamic' target='main' title='setMutableDefault'>
|
||||
#setMutableDefault
|
||||
</a>
|
||||
<small>
|
||||
(XmlFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/JsonType.html#setReplaceManager-dynamic' target='main' title='setReplaceManager'>
|
||||
#setReplaceManager
|
||||
@ -525,14 +477,6 @@
|
||||
(WordType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlType.html#setXmlProxy-dynamic' target='main' title='setXmlProxy'>
|
||||
#setXmlProxy
|
||||
</a>
|
||||
<small>
|
||||
(XmlType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/XmlFramework.html#toJson-dynamic' target='main' title='toJson'>
|
||||
#toJson
|
||||
@ -565,14 +509,6 @@
|
||||
(WordType)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/TextFramework.html#val-dynamic' target='main' title='val'>
|
||||
#val
|
||||
</a>
|
||||
<small>
|
||||
(TextFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='class/WordType.html#val-dynamic' target='main' title='val'>
|
||||
#val
|
||||
@ -582,19 +518,19 @@
|
||||
</small>
|
||||
</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
|
||||
</a>
|
||||
<small>
|
||||
(XmlType)
|
||||
(TextFramework)
|
||||
</small>
|
||||
</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
|
||||
</a>
|
||||
<small>
|
||||
(JsonFramework)
|
||||
(XmlFramework)
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
@ -606,11 +542,11 @@
|
||||
</small>
|
||||
</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
|
||||
</a>
|
||||
<small>
|
||||
(XmlFramework)
|
||||
(JsonFramework)
|
||||
</small>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -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.
|
||||
};
|
||||
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'!
|
||||
```
|
||||
|
||||
|
||||
|
@ -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.
|
||||
};
|
||||
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.
|
||||
|
@ -27,6 +27,41 @@ var yatta, yattaHandler;
|
||||
Y.createPeerJsConnector({key: 'h7nlefbgavh1tt9'}, function(Connector, user_id){
|
||||
|
||||
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());
|
||||
});
|
||||
```
|
||||
|
@ -9,14 +9,17 @@
|
||||
<script src="./index.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1> PeerJs + Json Tutorial</h1>
|
||||
<p> Collaborative Json editing with <a href="https://github.com/DadaMonad/Yatta/">Yatta</a>
|
||||
<body id="collaborative">
|
||||
<h1> PeerJs + XML Example</h1>
|
||||
<p> Collaborative XML editing with <a href="https://github.com/DadaMonad/Yatta/">Yatta</a>
|
||||
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.
|
||||
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>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -27,5 +27,31 @@ var yatta, yattaHandler;
|
||||
Y.createPeerJsConnector({key: 'h7nlefbgavh1tt9'}, function(Connector, user_id){
|
||||
|
||||
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());
|
||||
});
|
||||
|
@ -39,6 +39,7 @@ createPeerJsConnector = ()->
|
||||
|
||||
@peer = peer
|
||||
@connections = {}
|
||||
@new_connection_listeners = []
|
||||
|
||||
@peer.on 'connection', (conn)=>
|
||||
@addConnection conn
|
||||
@ -82,6 +83,9 @@ createPeerJsConnector = ()->
|
||||
for conn_id of @connections
|
||||
conn_id
|
||||
|
||||
onNewConnection: (f)->
|
||||
@new_connection_listeners.push f
|
||||
|
||||
#
|
||||
# Adds an existing connection to this connector.
|
||||
# @param conn {PeerJsConnection}
|
||||
@ -105,6 +109,8 @@ createPeerJsConnector = ()->
|
||||
if not data.initialized
|
||||
conn.send
|
||||
conns: @getAllConnectionIds()
|
||||
@new_connection_listeners.map (f)->
|
||||
f(conn)
|
||||
else if data.op?
|
||||
@engine.applyOp data.op
|
||||
else if data.conns?
|
||||
|
@ -271,15 +271,18 @@ module.exports = (HB)->
|
||||
#
|
||||
applyDelete: (o)->
|
||||
@deleted_by ?= []
|
||||
callLater = false
|
||||
if @parent? and not @isDeleted()
|
||||
# call iff wasn't deleted earlyer
|
||||
@parent.callEvent "delete", @, o
|
||||
callLater = true
|
||||
if o?
|
||||
@deleted_by.push o
|
||||
garbagecollect = false
|
||||
if not (@prev_cl? and @next_cl?) or @prev_cl.isDeleted()
|
||||
garbagecollect = true
|
||||
super garbagecollect
|
||||
if callLater
|
||||
@parent.callEvent "delete", @, o
|
||||
if @next_cl?.isDeleted()
|
||||
# garbage collect next_cl
|
||||
@next_cl.applyDelete()
|
||||
|
@ -43,10 +43,18 @@ module.exports = (HB)->
|
||||
@content.length
|
||||
|
||||
applyDelete: ()->
|
||||
super # no braces indeed!
|
||||
if @content instanceof types.Operation
|
||||
@content.applyDelete()
|
||||
@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
|
||||
|
@ -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
|
||||
# But yatta's proxy may be called only once!
|
||||
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)->
|
||||
old_f = @[f_name]
|
||||
if old_f?
|
||||
@[f_name] = ()->
|
||||
if not proxy_token and not @_yatta?.isDeleted()
|
||||
proxy_token = true
|
||||
old_f.apply this, arguments
|
||||
f.apply this, arguments
|
||||
proxy_token = false
|
||||
that = this
|
||||
args = arguments
|
||||
dont_proxy ()->
|
||||
f.apply that, args
|
||||
old_f.apply that, args
|
||||
else
|
||||
old_f.apply this, arguments
|
||||
#else
|
||||
@ -48,11 +58,18 @@ module.exports = (HB)->
|
||||
|
||||
super(uid)
|
||||
|
||||
|
||||
if @xml?._yatta?
|
||||
d = new types.Delete undefined, @xml._yatta
|
||||
HB.addOperation(d).execute()
|
||||
@xml._yatta = null
|
||||
|
||||
if attributes? and elements?
|
||||
@saveOperation 'attributes', attributes
|
||||
@saveOperation 'elements', elements
|
||||
else if (not attributes?) and (not elements?)
|
||||
@attributes = new types.JsonType()
|
||||
@attributes.setMutableDefault 'immutable'
|
||||
HB.addOperation(@attributes).execute()
|
||||
@elements = new types.WordType()
|
||||
@elements.parent = @
|
||||
@ -67,11 +84,9 @@ module.exports = (HB)->
|
||||
@attributes.val(attr.name, attr.value)
|
||||
for n in @xml.childNodes
|
||||
if n.nodeType is n.TEXT_NODE
|
||||
word = new types.WordType()
|
||||
word = new TextNodeType(undefined, n)
|
||||
HB.addOperation(word).execute()
|
||||
word.push n.textContent
|
||||
@elements.push word
|
||||
n._yatta = word
|
||||
else if n.nodeType is n.ELEMENT_NODE
|
||||
element = new XmlType undefined, undefined, undefined, undefined, n
|
||||
HB.addOperation(element).execute()
|
||||
@ -87,10 +102,13 @@ module.exports = (HB)->
|
||||
#
|
||||
type: "XmlType"
|
||||
|
||||
applyDelete: ()->
|
||||
@attributes.applyDelete()
|
||||
@elements.applyDelete()
|
||||
super()
|
||||
applyDelete: (op)->
|
||||
if @insert_parent? and not @insert_parent.isDeleted()
|
||||
@insert_parent.applyDelete op
|
||||
else
|
||||
@attributes.applyDelete()
|
||||
@elements.applyDelete()
|
||||
super
|
||||
|
||||
cleanup: ()->
|
||||
super()
|
||||
@ -98,11 +116,50 @@ module.exports = (HB)->
|
||||
setXmlProxy: ()->
|
||||
@xml._yatta = @
|
||||
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.
|
||||
# @param child {DomElement} Dom element.
|
||||
# @return {InsertType} This carries the XmlType that represents the DomElement (child). false if i couldn't find it.
|
||||
#
|
||||
findNode = (child)->
|
||||
if not child?
|
||||
throw new Error "you must specify a parameter!"
|
||||
child = child._yatta
|
||||
elem = that.elements.beginning.next_cl
|
||||
while elem.type isnt 'Delimiter' and elem.content isnt child
|
||||
@ -112,7 +169,7 @@ module.exports = (HB)->
|
||||
else
|
||||
elem
|
||||
|
||||
insertBefore = (insertedNode, adjacentNode)->
|
||||
insertBefore = (insertedNode_s, adjacentNode)->
|
||||
next = null
|
||||
if adjacentNode?
|
||||
next = findNode adjacentNode
|
||||
@ -121,9 +178,21 @@ module.exports = (HB)->
|
||||
prev = next.prev_cl
|
||||
else
|
||||
prev = @_yatta.elements.end.prev_cl
|
||||
element = new XmlType undefined, undefined, undefined, undefined, insertedNode
|
||||
HB.addOperation(element).execute()
|
||||
that.elements.insertAfter prev, element
|
||||
while prev.isDeleted()
|
||||
prev = prev.prev_cl
|
||||
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 'appendChild', insertBefore
|
||||
@xml._proxy 'removeAttribute', (name)->
|
||||
@ -131,8 +200,16 @@ module.exports = (HB)->
|
||||
@xml._proxy 'setAttribute', (name, value)->
|
||||
that.attributes.val name, value
|
||||
|
||||
renewClassList = ()->
|
||||
that.attributes.val('class', Array.prototype.join.call this, " ")
|
||||
renewClassList = (newclass)->
|
||||
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, 'remove', renewClassList
|
||||
@xml.__defineSetter__ 'className', (val)->
|
||||
@ -158,6 +235,7 @@ module.exports = (HB)->
|
||||
throw new Error "You are only allowed to delete existing (direct) child elements!"
|
||||
d = new types.Delete undefined, elem
|
||||
HB.addOperation(d).execute()
|
||||
node._yatta = null
|
||||
@xml._proxy 'removeChild', removeChild
|
||||
@xml._proxy 'replaceChild', (insertedNode, replacedNode)->
|
||||
insertBefore.call this, insertedNode, replacedNode
|
||||
@ -180,12 +258,11 @@ module.exports = (HB)->
|
||||
e = @elements.beginning.next_cl
|
||||
while e.type isnt "Delimiter"
|
||||
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"
|
||||
@xml.appendChild n.val(enforce)
|
||||
else if n.type is "WordType"
|
||||
text_node = document.createTextNode n.val()
|
||||
text_node._yatta = @
|
||||
else if n.type is "TextNodeType"
|
||||
text_node = n.val()
|
||||
@xml.appendChild text_node
|
||||
else
|
||||
throw new Error "Internal structure cannot be transformed to dom"
|
||||
@ -238,6 +315,51 @@ module.exports = (HB)->
|
||||
|
||||
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
|
||||
|
||||
|
@ -36,27 +36,36 @@ describe "XmlFramework", ->
|
||||
|
||||
@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_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 = @$dom[0]
|
||||
@test_user.val(@dom)
|
||||
@test_user_listen.getConnector().flushAll()
|
||||
@test_user_listen_dom = @test_user_listen.val()
|
||||
|
||||
@check = ()=>
|
||||
dom_ = @test_user.val(true)
|
||||
expect(dom_.outerHTML).to.equal(@dom.outerHTML)
|
||||
dom_ = @dom.outerHTML
|
||||
# now test if other collaborators can parse the HB and result in the same content
|
||||
hb = @test_user.HB._encode()
|
||||
@test_user2.engine.applyOps(hb)
|
||||
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()
|
||||
|
||||
it "can transform to a new real Dom element", ->
|
||||
dom_ = @test_user.val(true)
|
||||
expect(dom_ isnt @dom).to.be.true
|
||||
@check()
|
||||
|
||||
it "supports dom.insertBefore", ->
|
||||
newdom = $("<p>dtrn</p>")[0]
|
||||
@ -116,6 +125,7 @@ describe "XmlFramework", ->
|
||||
|
||||
it "supports jquery.appendTo", ->
|
||||
$("<b>appendedTo</b>").appendTo("#test_dom p")
|
||||
$("p").appendTo("#test_dom")
|
||||
@check()
|
||||
|
||||
it "supports jquery.before", ->
|
||||
|
Loading…
x
Reference in New Issue
Block a user