X-Git-Url: https://git.mdrn.pl/fnpeditor.git/blobdiff_plain/bc95fc1358ca35ecbd410d50b3c8c40e1afe0fa9..7a3c737d962ff2b2e2653fd8ed0108e92c7fe0d5:/src/smartxml/smartxml.js diff --git a/src/smartxml/smartxml.js b/src/smartxml/smartxml.js index 6f4677b..e3c831d 100644 --- a/src/smartxml/smartxml.js +++ b/src/smartxml/smartxml.js @@ -6,7 +6,7 @@ define([ ], function($, _, Backbone, events) { 'use strict'; - +/* globals Node */ var TEXT_NODE = Node.TEXT_NODE; @@ -36,6 +36,30 @@ $.extend(DocumentNode.prototype, { this._$ = $(nativeNode); }, + clone: function() { + return this.document.createDocumentNode(this._$.clone(true, true)[0]); + }, + + getPath: function(ancestor) { + var nodePath = [this].concat(this.parents()), + toret, idx; + ancestor = ancestor || this.document.root; + + nodePath.some(function(node, i) { + if(node.sameNode(ancestor)) { + idx = i; + return true; + } + }); + + if(idx !== 'undefined') { + nodePath = nodePath.slice(0, idx); + } + toret = nodePath.map(function(node) {return node.getIndex(); }); + toret.reverse(); + return toret; + }, + isRoot: function() { return this.document.root.sameNode(this); }, @@ -47,8 +71,18 @@ $.extend(DocumentNode.prototype, { return this; }, + replaceWith: function(node) { + var toret; + if(this.isRoot()) { + return this.document.replaceRoot(node); + } + toret = this.after(node); + this.detach(); + return toret; + }, + sameNode: function(otherNode) { - return otherNode && this.nativeNode === otherNode.nativeNode; + return !!(otherNode) && this.nativeNode === otherNode.nativeNode; }, parent: function() { @@ -129,15 +163,7 @@ $.extend(DocumentNode.prototype, { }, getNodeInsertion: function(node) { - var insertion = {}; - if(node instanceof DocumentNode) { - insertion.ofNode = node; - insertion.insertsNew = !this.document.containsNode(node); - } else { - insertion.ofNode = this.document.createDocumentNode(node); - insertion.insertsNew = true; - } - return insertion; + return this.document.getNodeInsertion(node); }, getIndex: function() { @@ -158,7 +184,7 @@ $.extend(ElementNode.prototype, { detach: function() { var next; - if(parent && this.isSurroundedByTextElements()) { + if(this.parent() && this.isSurroundedByTextElements()) { next = this.next(); this.prev().appendText(next.getText()); next.detach(); @@ -246,6 +272,15 @@ $.extend(ElementNode.prototype, { this._$.prepend(nativeNode); }), + insertAtIndex: function(nativeNode, index) { + var contents = this.contents(); + if(index < contents.length) { + return contents[index].before(nativeNode); + } else if(index === contents.length) { + return this.append(nativeNode); + } + }, + unwrapContent: function() { var parent = this.parent(); if(!parent) { @@ -411,6 +446,7 @@ $.extend(Document.prototype, Backbone.Events, { createDocumentNode: function(from) { if(!(from instanceof Node)) { if(from.text !== undefined) { + /* globals document */ from = document.createTextNode(from.text); } else { var node = $('<' + from.tagName + '>'); @@ -448,17 +484,17 @@ $.extend(Document.prototype, Backbone.Events, { }, wrapNodes: function(params) { - if(!(params.element1.parent().sameNode(params.element2.parent()))) { + if(!(params.node1.parent().sameNode(params.node2.parent()))) { throw new Error('Wrapping non-sibling nodes not supported.'); } - var parent = params.element1.parent(), + var parent = params.node1.parent(), parentContents = parent.contents(), wrapper = this.createDocumentNode({ tagName: params._with.tagName, attrs: params._with.attrs}), - idx1 = parent.indexOf(params.element1), - idx2 = parent.indexOf(params.element2); + idx1 = parent.indexOf(params.node1), + idx2 = parent.indexOf(params.node2); if(idx1 > idx2) { var tmp = idx1; @@ -555,6 +591,26 @@ $.extend(Document.prototype, Backbone.Events, { trigger: function() { //console.log('trigger: ' + arguments[0] + (arguments[1] ? ', ' + arguments[1].type : '')); Backbone.Events.trigger.apply(this, arguments); + }, + + getNodeInsertion: function(node) { + var insertion = {}; + if(node instanceof DocumentNode) { + insertion.ofNode = node; + insertion.insertsNew = !this.containsNode(node); + } else { + insertion.ofNode = this.createDocumentNode(node); + insertion.insertsNew = true; + } + return insertion; + }, + + replaceRoot: function(node) { + var insertion = this.getNodeInsertion(node); + this.root.detach(); + defineDocumentProperties(this, insertion.ofNode._$); + insertion.ofNode.triggerChangeEvent('nodeAdded'); + return insertion.ofNode; } });