8 var TEXT_NODE = Node.TEXT_NODE, ELEMENT_NODE = Node.ELEMENT_NODE;
10 var parseXML = function(xml) {
14 var Document = function(nativeNode) {
15 var $document = $(nativeNode);
18 Object.defineProperty(this, 'root', {get: function() { return new ElementNode($document[0])}});
22 var ElementNode = function(nativeNode) {
23 this.nativeNode = nativeNode;
24 this._$ = $(nativeNode);
27 $.extend(ElementNode.prototype, {
28 nodeType: Node.ELEMENT_NODE,
30 getTagName: function() {
31 return this.nativeNode.tagName.toLowerCase();
34 append: function(documentNode) {
35 this._$.append(documentNode.nativeNode);
38 before: function(node) {
39 this._$.before(node.nativeNode);
42 contents: function() {
44 this._$.contents().each(function() {
45 if(this.nodeType === Node.ELEMENT_NODE)
46 toret.push(new ElementNode(this));
47 else if(this.nodeType === Node.TEXT_NODE)
48 toret.push(new TextNode(this));
54 sameNode: function(otherNode) {
55 return this.nativeNode === otherNode.nativeNode;
58 indexOf: function(node) {
59 return this._$.contents().index(node._$);
67 return new ElementNode(this._$.parent());
70 unwrapContent: function() {
71 var parent = this.parent();
75 var parentContents = parent.contents(),
76 myContents = this.contents(),
77 myIdx = parent.indexOf(this);
79 if(myContents.length === 0)
82 var moveLeftRange, moveRightRange, leftMerged;
84 if(myIdx > 0 && (parentContents[myIdx-1].nodeType === TEXT_NODE) && (myContents[0].nodeType === TEXT_NODE)) {
85 parentContents[myIdx-1].appendText(myContents[0].getText());
86 myContents[0].detach();
93 if(!(leftMerged && myContents.length === 1)) {
94 if(myIdx < parentContents.length - 1 && (parentContents[myIdx+1].nodeType === TEXT_NODE) && (myContents[myContents.length-1].nodeType === TEXT_NODE)) {
95 parentContents[myIdx+1].prependText(myContents[myContents.length-1].getText());
96 myContents[myContents.length-1].detach();
97 moveRightRange = true;
101 var childrenLength = this.contents().length;
102 this.contents().forEach(function(child) {
109 element1: parent.contents()[myIdx + (moveLeftRange ? -1 : 0)],
110 element2: parent.contents()[myIdx + childrenLength-1 + (moveRightRange ? 1 : 0)]
116 var TextNode = function(nativeNode) {
117 this.nativeNode = nativeNode;
118 this._$ = $(nativeNode);
121 $.extend(TextNode.prototype, {
122 nodeType: Node.TEXT_NODE,
128 getText: function() {
129 return this.nativeNode.data;
132 appendText: function(text) {
133 this.nativeNode.data = this.nativeNode.data + text;
136 prependText: function(text) {
137 this.nativeNode.data = text + this.nativeNode.data;
143 documentFromXML: function(xml) {
144 return new Document(parseXML(xml));
147 elementNodeFromXML: function(xml) {
148 return new ElementNode(parseXML(xml));