insertBefore (xml), and prevent bug for addProperty-listener
This commit is contained in:
@@ -12,12 +12,13 @@
|
||||
this.is_deleted = false;
|
||||
this.doSync = true;
|
||||
this.garbage_collected = false;
|
||||
if (uid != null) {
|
||||
this.doSync = !isNaN(parseInt(uid.op_number));
|
||||
} else {
|
||||
if (uid == null) {
|
||||
uid = HB.getNextOperationIdentifier();
|
||||
}
|
||||
this.creator = uid['creator'], this.op_number = uid['op_number'];
|
||||
if (uid.doSync == null) {
|
||||
uid.doSync = !isNaN(parseInt(uid.op_number));
|
||||
}
|
||||
this.creator = uid['creator'], this.op_number = uid['op_number'], this.doSync = uid['doSync'];
|
||||
}
|
||||
|
||||
Operation.prototype.type = "Insert";
|
||||
@@ -217,34 +218,32 @@
|
||||
Insert.prototype.type = "Insert";
|
||||
|
||||
Insert.prototype.applyDelete = function(o) {
|
||||
var garbagecollect;
|
||||
var garbagecollect, _ref;
|
||||
if (this.deleted_by == null) {
|
||||
this.deleted_by = [];
|
||||
}
|
||||
if ((this.parent != null) && !this.isDeleted()) {
|
||||
if (o != null) {
|
||||
this.parent.callEvent("delete", this, o);
|
||||
}
|
||||
this.parent.callEvent("delete", this, o);
|
||||
}
|
||||
if (o != null) {
|
||||
this.deleted_by.push(o);
|
||||
}
|
||||
garbagecollect = false;
|
||||
if (this.prev_cl.isDeleted()) {
|
||||
if (!((this.prev_cl != null) && (this.next_cl != null)) || this.prev_cl.isDeleted()) {
|
||||
garbagecollect = true;
|
||||
}
|
||||
Insert.__super__.applyDelete.call(this, garbagecollect);
|
||||
if (this.next_cl.isDeleted()) {
|
||||
if ((_ref = this.next_cl) != null ? _ref.isDeleted() : void 0) {
|
||||
return this.next_cl.applyDelete();
|
||||
}
|
||||
};
|
||||
|
||||
Insert.prototype.cleanup = function() {
|
||||
var d, o, _i, _len, _ref;
|
||||
if (this.prev_cl.isDeleted()) {
|
||||
_ref = this.deleted_by;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
d = _ref[_i];
|
||||
var d, o, _i, _len, _ref, _ref1;
|
||||
if ((_ref = this.prev_cl) != null ? _ref.isDeleted() : void 0) {
|
||||
_ref1 = this.deleted_by;
|
||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||||
d = _ref1[_i];
|
||||
d.cleanup();
|
||||
}
|
||||
o = this.next_cl;
|
||||
@@ -274,8 +273,11 @@
|
||||
return d;
|
||||
};
|
||||
|
||||
Insert.prototype.execute = function() {
|
||||
Insert.prototype.execute = function(fire_event) {
|
||||
var distance_to_origin, i, o, parent, _ref;
|
||||
if (fire_event == null) {
|
||||
fire_event = true;
|
||||
}
|
||||
if (!this.validateSavedOperations()) {
|
||||
return false;
|
||||
} else {
|
||||
@@ -313,7 +315,7 @@
|
||||
this.next_cl.prev_cl = this;
|
||||
}
|
||||
parent = (_ref = this.prev_cl) != null ? _ref.getParent() : void 0;
|
||||
if (parent != null) {
|
||||
if ((parent != null) && fire_event) {
|
||||
this.setParent(parent);
|
||||
this.parent.callEvent("insert", this);
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -255,9 +255,7 @@
|
||||
}
|
||||
});
|
||||
addPropertyListener = function(event, op) {
|
||||
if (op.next_cl instanceof types.Delimiter && op.prev_cl instanceof types.Delimiter) {
|
||||
repl_manager.parent.callEvent('addProperty', property_name, op);
|
||||
}
|
||||
repl_manager.parent.callEvent('addProperty', property_name, op);
|
||||
return repl_manager.deleteListener('addProperty', addPropertyListener);
|
||||
};
|
||||
this.on('insert', addPropertyListener);
|
||||
@@ -323,7 +321,6 @@
|
||||
this.content.applyDelete();
|
||||
this.content.dontSync();
|
||||
}
|
||||
this.beforeDelete = this.content;
|
||||
this.content = null;
|
||||
return Replaceable.__super__.applyDelete.apply(this, arguments);
|
||||
};
|
||||
@@ -342,7 +339,7 @@
|
||||
_ref.setReplaceManager(this.parent);
|
||||
}
|
||||
}
|
||||
ins_result = Replaceable.__super__.execute.call(this);
|
||||
ins_result = Replaceable.__super__.execute.call(this, this.content != null);
|
||||
if (ins_result) {
|
||||
if (this.next_cl.type === "Delimiter" && this.prev_cl.type !== "Delimiter") {
|
||||
this.prev_cl.applyDelete();
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -101,23 +101,37 @@
|
||||
return WordType.__super__.cleanup.call(this);
|
||||
};
|
||||
|
||||
WordType.prototype.insertText = function(position, content) {
|
||||
var c, ith, left, op, right, _i, _len;
|
||||
ith = this.getOperationByPosition(position);
|
||||
left = ith.prev_cl;
|
||||
WordType.prototype.push = function(content) {
|
||||
return this.insertAfter(this.end.prev_cl, content);
|
||||
};
|
||||
|
||||
WordType.prototype.insertAfter = function(left, content) {
|
||||
var c, op, right, _i, _len;
|
||||
while (left.isDeleted()) {
|
||||
left = left.prev_cl;
|
||||
}
|
||||
right = left.next_cl;
|
||||
for (_i = 0, _len = content.length; _i < _len; _i++) {
|
||||
c = content[_i];
|
||||
op = new TextInsert(c, void 0, left, right);
|
||||
if (content.type != null) {
|
||||
op = new TextInsert(content, void 0, left, right);
|
||||
HB.addOperation(op).execute();
|
||||
left = op;
|
||||
} else {
|
||||
for (_i = 0, _len = content.length; _i < _len; _i++) {
|
||||
c = content[_i];
|
||||
op = new TextInsert(c, void 0, left, right);
|
||||
HB.addOperation(op).execute();
|
||||
left = op;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
WordType.prototype.insertText = function(position, content) {
|
||||
var ith, left;
|
||||
ith = this.getOperationByPosition(position);
|
||||
left = ith.prev_cl;
|
||||
return this.insertAfter(left, content);
|
||||
};
|
||||
|
||||
WordType.prototype.deleteText = function(position, length) {
|
||||
var d, delete_ops, i, o, _i;
|
||||
o = this.getOperationByPosition(position);
|
||||
@@ -174,12 +188,16 @@
|
||||
WordType.prototype.setReplaceManager = function(op) {
|
||||
this.saveOperation('replace_manager', op);
|
||||
this.validateSavedOperations();
|
||||
this.on('insert', function(event, ins) {
|
||||
return op.forwardEvent(this, 'change', ins);
|
||||
});
|
||||
this.on('insert', (function(_this) {
|
||||
return function(event, ins) {
|
||||
var _ref;
|
||||
return (_ref = _this.replace_manager) != null ? _ref.forwardEvent(_this, 'change', ins) : void 0;
|
||||
};
|
||||
})(this));
|
||||
return this.on('delete', (function(_this) {
|
||||
return function(event, ins, del) {
|
||||
return op.forwardEvent(_this, 'change', del);
|
||||
var _ref;
|
||||
return (_ref = _this.replace_manager) != null ? _ref.forwardEvent(_this, 'change', del) : void 0;
|
||||
};
|
||||
})(this));
|
||||
};
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,193 @@
|
||||
(function() {
|
||||
var json_types_uninitialized,
|
||||
__hasProp = {}.hasOwnProperty,
|
||||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
||||
|
||||
json_types_uninitialized = require("./JsonTypes");
|
||||
|
||||
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() {
|
||||
f.apply(this, arguments);
|
||||
return old_f.apply(this, arguments);
|
||||
};
|
||||
} else {
|
||||
return this[f_name] = f;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = function(HB) {
|
||||
var XmlType, json_types, parser, types;
|
||||
json_types = json_types_uninitialized(HB);
|
||||
types = json_types.types;
|
||||
parser = json_types.parser;
|
||||
XmlType = (function(_super) {
|
||||
__extends(XmlType, _super);
|
||||
|
||||
function XmlType(uid, tagname, attributes, elements, xml, prev, next, origin) {
|
||||
var attr, element, i, last, n, word, _i, _j, _len, _ref, _ref1;
|
||||
this.tagname = tagname;
|
||||
this.xml = xml;
|
||||
if ((prev != null) && (next == null) && (prev.type != null)) {
|
||||
while (prev.isDeleted()) {
|
||||
prev = prev.prev_cl;
|
||||
}
|
||||
next = prev.next_cl;
|
||||
}
|
||||
XmlType.__super__.constructor.call(this, uid, prev, next, origin);
|
||||
if ((attributes != null) && (elements != null)) {
|
||||
this.saveOperation('attributes', attributes);
|
||||
this.saveOperation('elements', elements);
|
||||
} else if ((attributes == null) && (elements == null)) {
|
||||
this.attributes = new types.JsonType();
|
||||
HB.addOperation(this.attributes).execute();
|
||||
this.elements = new types.WordType();
|
||||
this.elements.parent = this;
|
||||
HB.addOperation(this.elements).execute();
|
||||
} else {
|
||||
throw new Error("Either define attribute and elements both, or none of them");
|
||||
}
|
||||
if (this.xml != null) {
|
||||
this.tagname = this.xml.tagName;
|
||||
for (i = _i = 0, _ref = this.xml.attributes.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_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];
|
||||
if (n.nodeType === n.TEXT_NODE) {
|
||||
word = new types.WordType();
|
||||
HB.addOperation(word).execute();
|
||||
word.push(n.textContent);
|
||||
this.elements.push(word);
|
||||
} else if (n.nodeType === n.ELEMENT_NODE) {
|
||||
last = this.elements.end;
|
||||
element = new XmlType(void 0, void 0, void 0, void 0, n, last.prev_cl, last);
|
||||
HB.addOperation(element).execute();
|
||||
this.elements.push(element);
|
||||
} else {
|
||||
throw new Error("I don't know Node-type " + n.nodeType + "!!");
|
||||
}
|
||||
}
|
||||
this.setXmlProxy();
|
||||
}
|
||||
void 0;
|
||||
}
|
||||
|
||||
XmlType.prototype.type = "XmlType";
|
||||
|
||||
XmlType.prototype.applyDelete = function() {
|
||||
this.attributes.applyDelete();
|
||||
this.elements.applyDelete();
|
||||
return XmlType.__super__.applyDelete.call(this);
|
||||
};
|
||||
|
||||
XmlType.prototype.cleanup = function() {
|
||||
return XmlType.__super__.cleanup.call(this);
|
||||
};
|
||||
|
||||
XmlType.prototype.setXmlProxy = function() {
|
||||
this.xml._yatta = this;
|
||||
return this.xml._proxy('insertBefore', function(insertedNode, adjacentNode) {
|
||||
var element, next, prev;
|
||||
next = adjacentNode != null ? adjacentNode._yatta : void 0;
|
||||
prev = null;
|
||||
if (next != null) {
|
||||
prev = next.prev_cl;
|
||||
} else {
|
||||
prev = this._yatta.elements.end.prev_cl;
|
||||
}
|
||||
element = new XmlType(void 0, void 0, void 0, void 0, insertedNode, prev);
|
||||
return HB.addOperation(element).execute();
|
||||
});
|
||||
};
|
||||
|
||||
XmlType.prototype.val = function(enforce) {
|
||||
var a, attr, attr_name, e, n, text_node, value;
|
||||
if (enforce == null) {
|
||||
enforce = false;
|
||||
}
|
||||
if (typeof document !== "undefined" && document !== null) {
|
||||
if ((this.xml == null) || enforce) {
|
||||
this.xml = document.createElement(this.tagname);
|
||||
attr = this.attributes.val();
|
||||
for (attr_name in attr) {
|
||||
value = attr[attr_name];
|
||||
a = document.createAttribute(attr_name);
|
||||
a.value = value;
|
||||
this.xml.setAttributeNode(a);
|
||||
}
|
||||
e = this.elements.beginning.next_cl;
|
||||
while (e.type !== "Delimiter") {
|
||||
n = e.content;
|
||||
if (!n.isDeleted()) {
|
||||
if (n.type === "XmlType") {
|
||||
this.xml.appendChild(n.val(enforce));
|
||||
} else if (n.type === "WordType") {
|
||||
text_node = document.createTextNode(n.val());
|
||||
this.xml.appendChild(text_node);
|
||||
} else {
|
||||
throw new Error("Internal structure cannot be transformed to dom");
|
||||
}
|
||||
}
|
||||
e = e.next_cl;
|
||||
}
|
||||
}
|
||||
this.setXmlProxy();
|
||||
return this.xml;
|
||||
}
|
||||
};
|
||||
|
||||
XmlType.prototype.execute = function() {
|
||||
return XmlType.__super__.execute.apply(this, arguments);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
if not @validateSavedOperations()
|
||||
return false
|
||||
else
|
||||
|
||||
return true
|
||||
*/
|
||||
|
||||
XmlType.prototype.getParent = function() {
|
||||
return this.parent;
|
||||
};
|
||||
|
||||
XmlType.prototype._encode = function() {
|
||||
var json, _ref, _ref1, _ref2;
|
||||
json = {
|
||||
'type': this.type,
|
||||
'attributes': this.attributes.getUid(),
|
||||
'elements': this.elements.getUid(),
|
||||
'tagname': this.tagname,
|
||||
'uid': this.getUid(),
|
||||
'prev': (_ref = this.prev_cl) != null ? _ref.getUid() : void 0,
|
||||
'next': (_ref1 = this.next_cl) != null ? _ref1.getUid() : void 0
|
||||
};
|
||||
if (this.origin !== this.prev_cl) {
|
||||
json["origin"] = (_ref2 = this.origin) != null ? _ref2.getUid() : void 0;
|
||||
}
|
||||
return json;
|
||||
};
|
||||
|
||||
return XmlType;
|
||||
|
||||
})(types.Insert);
|
||||
parser['XmlType'] = function(json) {
|
||||
var attributes, elements, next, origin, prev, tagname, uid;
|
||||
uid = json['uid'], attributes = json['attributes'], elements = json['elements'], tagname = json['tagname'], prev = json['prev'], next = json['next'], origin = json['origin'];
|
||||
return new XmlType(uid, tagname, attributes, elements, void 0, prev, next, origin);
|
||||
};
|
||||
types['XmlType'] = XmlType;
|
||||
return json_types;
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user