X-Git-Url: https://git.mdrn.pl/fnpeditor.git/blobdiff_plain/097ad6254d6b36c226072b0c7bdcaa5f945dc483..d221e72024aa5d6f90e256728fa70f622d4e57d7:/src/smartxml/core.js?ds=sidebyside diff --git a/src/smartxml/core.js b/src/smartxml/core.js index 867353d..65b7852 100644 --- a/src/smartxml/core.js +++ b/src/smartxml/core.js @@ -3,30 +3,36 @@ define(function(require) { 'use strict'; /* globals Node */ -var _ = require('libs/underscore'), - TEXT_NODE = Node.TEXT_NODE; +var _ = require('libs/underscore'); var INSERTION = function(implementation) { - var toret = function(node) { + var toret = function(node, options) { var insertion = this.getNodeInsertion(node), nodeWasContained = this.document.containsNode(insertion.ofNode), - nodeParent; + nodeParent, + returned; + options = options || {}; if(!(this.document.containsNode(this))) { nodeParent = insertion.ofNode.parent(); } - implementation.call(this, insertion.ofNode.nativeNode); - this.triggerChangeEvent(insertion.insertsNew ? 'nodeAdded' : 'nodeMoved', {node: insertion.ofNode}, nodeParent, nodeWasContained); - return insertion.ofNode; + returned = implementation.call(this, insertion.ofNode); + if(!options.silent && returned.sameNode(insertion.ofNode)) { + this.triggerChangeEvent(insertion.insertsNew ? 'nodeAdded' : 'nodeMoved', {node: insertion.ofNode}, nodeParent, nodeWasContained); + } + return returned; }; return toret; }; 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; }, @@ -40,12 +46,26 @@ var documentNodeTransformations = { return toret; }, - after: INSERTION(function(nativeNode) { - return this._$.after(nativeNode); + after: INSERTION(function(node) { + 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); + return node; }), - before: INSERTION(function(nativeNode) { - return this._$.before(nativeNode); + before: INSERTION(function(node) { + 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); + return node; }), wrapWith: function(node) { @@ -116,12 +136,28 @@ var elementNodeTransformations = { } }, - append: INSERTION(function(nativeNode) { - this._$.append(nativeNode); + append: INSERTION(function(node) { + 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); + return node; + } }), - prepend: INSERTION(function(nativeNode) { - this._$.prepend(nativeNode); + prepend: INSERTION(function(node) { + 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 node; + } }), insertAtIndex: function(nativeNode, index) { @@ -147,38 +183,23 @@ var elementNodeTransformations = { 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)] }; }, @@ -188,9 +209,50 @@ var elementNodeTransformations = { }; var textNodeTransformations = { - setText: function(text) { - this.nativeNode.data = text; - this.triggerTextChangeEvent(); + setText: { + impl: function(t, text) { + t.oldText = this.getText(); + this.nativeNode.data = text; + this.triggerTextChangeEvent(); + }, + undo: function(t) { + this.setText(t.oldText); + } + }, + + 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) {