throw new Error('undefined document for a node');
}
this.document = document;
+ this.object = {};
this._setNativeNode(nativeNode);
};
$.extend(DocumentNode.prototype, {
+ getProperty: function(propName) {
+ var toret = this.object[propName];
+ if(toret && _.isFunction(toret)) {
+ toret = toret.call(this);
+ }
+ return toret;
+ },
+
transform: function(Transformation, args) {
var transformation = new Transformation(this.document, this, args);
return this.document.transform(transformation);
return myIdx < parentContents.length - 1 ? parentContents[myIdx+1] : null;
},
- isSurroundedByTextElements: function() {
- var prev = this.prev(),
- next = this.next();
- return prev && (prev.nodeType === Node.TEXT_NODE) && next && (next.nodeType === Node.TEXT_NODE);
+ isSurroundedByTextNodes: function() {
+ return this.isPrecededByTextNode() && this.isFollowedByTextNode();
+ },
+
+ isPrecededByTextNode: function() {
+ var prev = this.prev();
+ return prev && prev.nodeType === Node.TEXT_NODE;
+ },
+
+ isFollowedByTextNode: function() {
+ var next = this.next();
+ return next && next.nodeType === Node.TEXT_NODE;
},
triggerChangeEvent: function(type, metaData, origParent, nodeWasContained) {
var node = (metaData && metaData.node) ? metaData.node : this,
event = new events.ChangeEvent(type, $.extend({node: node}, metaData || {}));
if(type === 'nodeDetached' || this.document.containsNode(event.meta.node)) {
- if(type === 'nodeMoved') {
- event.meta.parent = origParent;
- }
this.document.trigger('change', event);
}
- if((type === 'nodeAdded' || type === 'nodeMoved') && !this.document.containsNode(this) && nodeWasContained) {
+ if(type === 'nodeAdded' && !this.document.containsNode(this) && nodeWasContained) {
event = new events.ChangeEvent('nodeDetached', {node: node, parent: origParent});
this.document.trigger('change', event);
}
},
getIndex: function() {
+ var parent;
+
if(this.isRoot()) {
return 0;
}
- return this.parent().indexOf(this);
+
+ parent = this.parent();
+ return parent ? parent.indexOf(this) : undefined;
},
getNearestElementNode: function() {
$.extend(ElementNode.prototype, {
nodeType: Node.ELEMENT_NODE,
- setData: function(key, value) {
- if(value !== undefined) {
- this._$.data(key, value);
+ setData: function(arg1, arg2) {
+ if(arguments.length === 2) {
+ if(_.isUndefined(arg2)) {
+ this._$.removeData(arg1);
+ } else {
+ this._$.data(arg1, arg2);
+ }
} else {
this._$.removeData(_.keys(this._$.data()));
- this._$.data(key);
+ this._$.data(arg1);
}
},
return node && (node.nativeNode === this.nativeNode || node._$.parents().index(this._$) !== -1);
},
+ getLastTextNode: function() {
+ var contents = this.contents(),
+ toret;
+
+ contents.reverse().some(function(node) {
+ if(node.nodeType === Node.TEXT_NODE) {
+ toret = node;
+ return true;
+ }
+ toret = node.getLastTextNode();
+ return !!toret;
+ });
+
+ return toret;
+ },
+
toXML: function() {
var wrapper = $('<div>');
wrapper.append(this._getXMLDOMToDump());
var parseXML = function(xml) {
var toret = $($.trim(xml));
- if(!toret.length) {
+ if(toret.length !== 1) {
throw new Error('Unable to parse XML: ' + xml);
}
return toret[0];
if(transformations.length > 1) {
// In case of real transactions we don't want to run undo on all of transformations if we don't have to.
- stopAt = undefined;
transformations.some(function(t, idx) {
if(!t.undo && t.getChangeRoot().sameNode(doc.root)) {
stopAt = idx;
getNodeByPath: function(path) {
var toret = this.root;
- path.forEach(function(idx) {
+ path.some(function(idx) {
toret = toret.contents()[idx];
+ if(!toret) {
+ return true;
+ }
});
return toret;
},