X-Git-Url: https://git.mdrn.pl/fnpeditor.git/blobdiff_plain/dec5a3d8b3a4cc70a9b2bc7bc1305ba0ae11a369..8f44492501cad481f4d4ddcd58f7e9b26e2a7721:/src/smartxml/core.js?ds=sidebyside diff --git a/src/smartxml/core.js b/src/smartxml/core.js index 007468f..7326507 100644 --- a/src/smartxml/core.js +++ b/src/smartxml/core.js @@ -23,7 +23,7 @@ var INSERTION = function(implementation) { next.detach(); } returned = implementation.call(this, insertion.ofNode); - if(!options.silent && returned.sameNode(insertion.ofNode)) { + if(!options.silent && returned && returned.sameNode(insertion.ofNode)) { if(!insertion.insertsNew) { this.triggerChangeEvent('nodeDetached', {node: insertion.ofNode, parent: nodeParent, move: true}); } @@ -63,7 +63,11 @@ var documentNodeTransformations = { }, after: INSERTION(function(node) { + if(this.isRoot()) { + return; + } var next = this.next(); + if(next && next.nodeType === Node.TEXT_NODE && node.nodeType === Node.TEXT_NODE) { next.setText(node.getText() + next.getText()); node.detach(); @@ -74,6 +78,9 @@ var documentNodeTransformations = { }), before: INSERTION(function(node) { + if(this.isRoot()) { + return; + } var prev = this.prev(); if(prev && prev.nodeType === Node.TEXT_NODE && node.nodeType === Node.TEXT_NODE) { prev.setText(prev.getText() + node.getText()); @@ -113,12 +120,32 @@ var documentNodeTransformations = { var elementNodeTransformations = { - detach: function() { - var next; + detach: function(params) { + var next, prev; + + params = params || {}; + + if(!params.normalizeStrategy) { + params.normalizeStrategy = 'merge'; + } + if(this.parent() && this.isSurroundedByTextNodes()) { - next = this.next(); - this.prev().appendText(next.getText()); - next.detach(); + if(params.normalizeStrategy === 'detach-left') { + this.prev().detach(); + } else if(params.normalizeStrategy === 'detach-right') { + this.next().detach(); + } else if(params.normalizeStrategy === 'merge') { + next = this.next(); + prev = this.prev(); + params.ret = { + mergedTo: prev, + previousLen: prev.getText().length + }; + prev.appendText(next.getText()); + next.detach(); + } else { + throw new Error('unknown normalize strategy for detach'); + } } return this.__super__.detach(); }, @@ -142,7 +169,11 @@ var elementNodeTransformations = { setAttr: function(name, value, silent) { var oldVal = this.getAttr(name); - this._$.attr(name, value); + if(_.isUndefined(value)) { + this._$.removeAttr(name); + } else { + this._$.attr(name, value); + } if(!silent) { this.triggerChangeEvent('nodeAttrChange', {attr: name, oldVal: oldVal, newVal: value}); } @@ -187,15 +218,21 @@ var elementNodeTransformations = { return; } + this.contents() + .filter(function(child) { + return child.getProperty('describesParent'); + }.bind(this)) + .forEach(function(child) { + child.detach(); + }); + var myContents = this.contents(), myIdx = parent.indexOf(this); - if(myContents.length === 0) { return this.detach(); } - var childrenLength = this.contents().length, first = true, shiftRange = false; @@ -326,7 +363,7 @@ var textNodeTransformations = { newElement.prepend({text: suffix}); } - return {first: parentElement, second: newElement}; + return {first: parentElement, second: newElement, created: newElement}; }, divideWithElementNode: function(node, params) { @@ -381,7 +418,9 @@ var documentTransformations = { } for(var i = idx1; i <= idx2; i++) { - wrapper.append(parentContents[i].detach()); + if(!parentContents[i].getProperty('describesParent')) { + wrapper.append(parentContents[i].detach()); + } } insertingTarget[insertingMethod](wrapper); @@ -426,7 +465,9 @@ var documentTransformations = { wrapperElement.append({text: prefixInside}); } for(var i = idx1 + 1; i < idx2; i++) { - wrapperElement.append(contentsInside[i]); + if(!contentsInside[i].getProperty('describesParent')) { + wrapperElement.append(contentsInside[i]); + } } if(suffixInside.length > 0) { wrapperElement.append({text: suffixInside}); @@ -445,7 +486,7 @@ var documentTransformations = { return insertion.ofNode; }, deleteText: function(params) { - var ptr, next, toDetach, middle, text; + var ptr, next, nextNext, toDetach, middle, text; if(params.from.node.sameNode(params.to.node)) { ptr = params.from.node; @@ -473,7 +514,11 @@ var documentTransformations = { } else { toDetach = next; next = next.next(); - toDetach.detach(); + nextNext = next ? next.next() : null; + toDetach.detach({normalizeStrategy: (next && next.sameNode(params.to.node)) ? 'merge' : 'detach-right'}); + if(next && !next.isInDocument()) { + next = nextNext; + } } } else { ptr = ptr.parent();