'use strict';
/* globals Node */
-var _ = require('libs/underscore'),
- TEXT_NODE = Node.TEXT_NODE;
+var _ = require('libs/underscore');
var INSERTION = function(implementation) {
var documentNodeTransformations = {
detach: function() {
- var parent = this.parent();
+ var parent = this.parent(),
+ existed = this.document.containsNode(this);
this._$.detach();
- this.triggerChangeEvent('nodeDetached', {parent: parent});
+ if(existed) {
+ this.triggerChangeEvent('nodeDetached', {parent: parent});
+ }
return this;
},
var next = this.next();
if(next && next.nodeType === Node.TEXT_NODE && node.nodeType === Node.TEXT_NODE) {
next.setText(node.getText() + next.getText());
+ node.detach();
return next;
}
this._$.after(node.nativeNode);
var prev = this.prev();
if(prev && prev.nodeType === Node.TEXT_NODE && node.nodeType === Node.TEXT_NODE) {
prev.setText(prev.getText() + node.getText());
+ node.detach();
return prev;
}
this._$.before(node.nativeNode);
var last = _.last(this.contents());
if(last && last.nodeType === Node.TEXT_NODE && node.nodeType === Node.TEXT_NODE) {
last.setText(last.getText() + node.getText());
+ node.detach();
return last;
} else {
this._$.append(node.nativeNode);
var first = this.contents()[0];
if(first && first.nodeType === Node.TEXT_NODE && node.nodeType === Node.TEXT_NODE) {
first.setText(node.getText() + first.getText());
+ node.detach();
return first;
} else {
this._$.prepend(node.nativeNode);
return this.detach();
}
- var prev = this.prev(),
- next = this.next(),
- moveLeftRange, moveRightRange, leftMerged;
-
- if(prev && (prev.nodeType === TEXT_NODE) && (myContents[0].nodeType === TEXT_NODE)) {
- prev.appendText(myContents[0].getText());
- myContents[0].detach();
- moveLeftRange = true;
- leftMerged = true;
- } else {
- leftMerged = false;
- }
-
- if(!(leftMerged && myContents.length === 1)) {
- var lastContents = _.last(myContents);
- if(next && (next.nodeType === TEXT_NODE) && (lastContents.nodeType === TEXT_NODE)) {
- next.prependText(lastContents.getText());
- lastContents.detach();
- moveRightRange = true;
- }
- }
- var childrenLength = this.contents().length;
+ var childrenLength = this.contents().length,
+ first = true,
+ shiftRange = false;
this.contents().forEach(function(child) {
- this.before(child);
+ var returned = this.before(child);
+ if(first && !(returned.sameNode(child))) {
+ shiftRange = true;
+ first = false;
+ }
}.bind(this));
this.detach();
return {
- element1: parent.contents()[myIdx + (moveLeftRange ? -1 : 0)],
- element2: parent.contents()[myIdx + childrenLength-1 + (moveRightRange ? 1 : 0)]
+ element1: parent.contents()[myIdx + (shiftRange ? -1 : 0)],
+ element2: parent.contents()[myIdx + childrenLength-1 + (shiftRange ? -1 : 0)]
};
},
before: INSERTION(function(node) {
if(node.nodeType === Node.TEXT_NODE) {
this.prependText(node.getText());
+ node.detach();
return this;
} else {
return this.__super__.before(node, {silent:true});
after: INSERTION(function(node) {
if(node.nodeType === Node.TEXT_NODE) {
this.appendText(node.getText());
+ node.detach();
return this;
} else {
return this.__super__.after(node, {silent:true});
}
}),
+ append: function(node) {
+ if(node.nodeType === Node.TEXT_NODE) {
+ this.appendText(node.getText());
+ node.detach();
+ return this;
+ }
+ },
+ prepend: function(node) {
+ if(node.nodeType === Node.TEXT_NODE) {
+ this.prependText(node.getText());
+ node.detach();
+ return this;
+ }
+ },
+
appendText: function(text) {
this.nativeNode.data = this.nativeNode.data + text;
this.triggerTextChangeEvent();
this._defineDocumentProperties(insertion.ofNode._$);
insertion.ofNode.triggerChangeEvent('nodeAdded');
return insertion.ofNode;
+ },
+ deleteText: function(params) {
+ var ptr, prev, next, toDetach, middle, text;
+
+ if(params.from.node.sameNode(params.to.node)) {
+ ptr = params.from.node;
+ text = ptr.getText();
+ ptr.setText(text.substr(0, params.from.offset) + text.substr(params.to.offset));
+ return;
+ }
+
+ ptr = params.from.node;
+ ptr.setText(ptr.getText().substr(0, params.from.offset));
+ next = ptr.next();
+ while(next || ptr.parent()) {
+ if(next) {
+ if(next.sameNode(params.to.node) || (next.nodeType === Node.ELEMENT_NODE && next.containsNode(params.to.node))) {
+ middle = next;
+ break;
+ } else {
+ toDetach = next;
+ next = next.next();
+ toDetach.detach();
+ }
+ } else {
+ ptr = ptr.parent();
+ next = ptr.next();
+ }
+ }
+
+ ptr = params.to.node;
+ ptr.setText(ptr.getText().substr(params.to.offset));
+ prev = ptr.prev();
+ while(prev || ptr.parent()) {
+ if(ptr.sameNode(middle)) {
+ break;
+ }
+ if(prev) {
+ toDetach = prev;
+ prev = prev.prev();
+ toDetach.detach();
+ } else {
+ ptr = ptr.parent();
+ prev = ptr.prev();
+ }
+ }
}
};