+});
+
+var TextNode = function(nativeNode, document) {
+ DocumentNode.call(this, nativeNode, document);
+};
+
+$.extend(TextNode.prototype, DocumentNode.prototype, {
+ nodeType: Node.TEXT_NODE,
+
+ getText: function() {
+ return this.nativeNode.data;
+ },
+
+ setText: function(text) {
+ this.nativeNode.data = text;
+ this.triggerTextChangeEvent();
+ },
+
+ appendText: function(text) {
+ this.nativeNode.data = this.nativeNode.data + text;
+ this.triggerTextChangeEvent();
+ },
+
+ prependText: function(text) {
+ this.nativeNode.data = text + this.nativeNode.data;
+ this.triggerTextChangeEvent();
+ },
+
+ triggerTextChangeEvent: function() {
+ var event = new events.ChangeEvent('nodeTextChange', {node: this});
+ this.document.trigger('change', event);
+ }
+});
+
+
+var parseXML = function(xml) {
+ return $(xml)[0];
+};
+
+var Document = function(xml) {
+ this.loadXML(xml);
+};
+
+$.extend(Document.prototype, Backbone.Events, {
+ ElementNodeFactory: ElementNode,
+ TextNodeFactory: TextNode,
+
+ createElementNode: function(from) {
+ if(!(from instanceof HTMLElement)) {
+ from = $('<' + from.tagName + '>')[0];
+ }
+ return new this.ElementNodeFactory(from, this);
+ },
+
+ createTextNode: function(nativeNode) {
+ return new this.TextNodeFactory(nativeNode, this);
+ },
+
+ loadXML: function(xml, options) {
+ options = options || {};
+ defineDocumentProperties(this, $(parseXML(xml)));
+ if(!options.silent) {
+ this.trigger('contentSet');
+ }
+ },
+
+ toXML: function() {
+ return this.root.toXML();
+ }
+});
+
+var defineDocumentProperties = function(doc, $document) {
+ Object.defineProperty(doc, 'root', {get: function() {
+ return doc.createElementNode($document[0]);
+ }, configurable: true});
+ Object.defineProperty(doc, 'dom', {get: function() {
+ return $document[0];
+ }, configurable: true});