X-Git-Url: https://git.mdrn.pl/fnpeditor.git/blobdiff_plain/180cd85dd5dcdcb29eb1a4626e3c6412558caddb..65c64d3696e38bda0e2259d48c8d02978da7a3d8:/src/smartxml/smartxml.js diff --git a/src/smartxml/smartxml.js b/src/smartxml/smartxml.js index 6b02779..ffbe4c2 100644 --- a/src/smartxml/smartxml.js +++ b/src/smartxml/smartxml.js @@ -27,7 +27,9 @@ $.extend(DocumentNode.prototype, { }, detach: function() { + var parent = this.parent(); this._$.detach(); + this.triggerChangeEvent('nodeDetached', {parent: parent}); return this; }, @@ -36,24 +38,33 @@ $.extend(DocumentNode.prototype, { }, parent: function() { - return this.nativeNode.parentNode ? this.document.createElementNode(this.nativeNode.parentNode) : null; + var parentNode = this.nativeNode.parentNode; + if(parentNode && parentNode.nodeType === Node.ELEMENT_NODE) { + return this.document.createElementNode(parentNode); + } + return null; + }, + + parents: function() { + var parent = this.parent(), + parents = parent ? parent.parents() : []; + if(parent) { + parents.unshift(parent); + } + return parents; }, after: function(node) { var insertion = this.getNodeInsertion(node); this._$.after(insertion.ofNode.nativeNode); - if(insertion.insertsNew) { - this.triggerChangeEvent('nodeAdded', {node: insertion.ofNode}); - } + this.triggerChangeEvent(insertion.insertsNew ? 'nodeAdded' : 'nodeMoved', {node: insertion.ofNode}); return insertion.ofNode; }, before: function(node) { var insertion = this.getNodeInsertion(node); this._$.before(insertion.ofNode.nativeNode); - if(insertion.insertsNew) { - this.triggerChangeEvent('nodeAdded', {node: insertion.ofNode}); - } + this.triggerChangeEvent(insertion.insertsNew ? 'nodeAdded' : 'nodeMoved', {node: insertion.ofNode}); return insertion.ofNode; }, @@ -82,6 +93,10 @@ $.extend(DocumentNode.prototype, { insertion.insertsNew = true; } return insertion; + }, + + getIndex: function() { + return this.parent().indexOf(this); } }); @@ -173,18 +188,14 @@ $.extend(ElementNode.prototype, { append: function(node) { var insertion = this.getNodeInsertion(node); this._$.append(insertion.ofNode.nativeNode); - if(insertion.insertsNew) { - this.triggerChangeEvent('nodeAdded', {node: insertion.ofNode}); - } + this.triggerChangeEvent(insertion.insertsNew ? 'nodeAdded' : 'nodeMoved', {node: insertion.ofNode}); return insertion.ofNode; }, prepend: function(node) { var insertion = this.getNodeInsertion(node); this._$.prepend(insertion.ofNode.nativeNode); - if(insertion.insertsNew) { - this.triggerChangeEvent('nodeAdded', {node: insertion.ofNode}); - } + this.triggerChangeEvent(insertion.insertsNew ? 'nodeAdded' : 'nodeMoved', {node: insertion.ofNode}); return insertion.ofNode; }, @@ -283,7 +294,7 @@ $.extend(TextNode.prototype, { textNodeIdx: this.parent().indexOf(this), offsetStart: Math.min(desc.start, desc.end), offsetEnd: Math.max(desc.start, desc.end), - _with: {tag: desc.tagName, attrs: desc.attrs} + _with: {tagName: desc.tagName, attrs: desc.attrs} }); } else { return DocumentNode.prototype.wrapWith.call(this, desc); @@ -323,7 +334,13 @@ $.extend(Document.prototype, Backbone.Events, { from = node[0]; } } - return new this.ElementNodeFactory(from, this); + var Factory; + if(from.nodeType === Node.TEXT_NODE) { + Factory = this.TextNodeFactory; + } else if(from.nodeType === Node.ELEMENT_NODE) { + Factory = this.ElementNodeFactory; + } + return new Factory(from, this); }, createTextNode: function(nativeNode) { @@ -382,6 +399,25 @@ $.extend(Document.prototype, Backbone.Events, { return wrapper; }, + getSiblingParents: function(params) { + var parents1 = [params.node1].concat(params.node1.parents()).reverse(), + parents2 = [params.node2].concat(params.node2.parents()).reverse(), + noSiblingParents = null; + + if(parents1.length === 0 || parents2.length === 0 || !(parents1[0].sameNode(parents2[0]))) { + return noSiblingParents; + } + + var i; + for(i = 0; i < Math.min(parents1.length, parents2.length); i++) { + if(parents1[i].sameNode(parents2[i])) { + continue; + } + break; + } + return {node1: parents1[i], node2: parents2[i]}; + }, + _wrapText: function(params) { params = _.extend({textNodeIdx: 0}, params); if(typeof params.textNodeIdx === 'number') { @@ -404,7 +440,7 @@ $.extend(Document.prototype, Backbone.Events, { throw new Error('Wrapping text in non-sibling text nodes not supported.'); } - var wrapperElement = this.createElementNode({tagName: params._with.tag, attrs: params._with.attrs}); + var wrapperElement = this.createElementNode({tagName: params._with.tagName, attrs: params._with.attrs}); textNode1.after(wrapperElement); textNode1.detach(); @@ -430,6 +466,11 @@ $.extend(Document.prototype, Backbone.Events, { wrapperElement.after({text: suffixOutside}); } return wrapperElement; + }, + + trigger: function() { + //console.log('trigger: ' + arguments[0] + (arguments[1] ? ', ' + arguments[1].type : '')); + Backbone.Events.trigger.apply(this, arguments); } });