smartxml: sending nodeDetached events when existing node added to out of document...
authorAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Mon, 2 Dec 2013 21:55:50 +0000 (22:55 +0100)
committerAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Mon, 2 Dec 2013 21:55:50 +0000 (22:55 +0100)
src/smartxml/smartxml.js
src/smartxml/smartxml.test.js

index e3c831d..021a116 100644 (file)
@@ -13,9 +13,13 @@ var TEXT_NODE = Node.TEXT_NODE;
 
 var INSERTION = function(implementation) {
     var toret = function(node) {
 
 var INSERTION = function(implementation) {
     var toret = function(node) {
-        var insertion = this.getNodeInsertion(node);
+        var insertion = this.getNodeInsertion(node),
+            nodeParent;
+        if(!(this.document.containsNode(this))) {
+            nodeParent = insertion.ofNode.parent();
+        }
         implementation.call(this, insertion.ofNode.nativeNode);
         implementation.call(this, insertion.ofNode.nativeNode);
-        this.triggerChangeEvent(insertion.insertsNew ? 'nodeAdded' : 'nodeMoved', {node: insertion.ofNode});
+        this.triggerChangeEvent(insertion.insertsNew ? 'nodeAdded' : 'nodeMoved', {node: insertion.ofNode}, nodeParent);
         return insertion.ofNode;
     };
     return toret;
         return insertion.ofNode;
     };
     return toret;
@@ -155,11 +159,16 @@ $.extend(DocumentNode.prototype, {
         }
     },
 
         }
     },
 
-    triggerChangeEvent: function(type, metaData) {
-        var event = new events.ChangeEvent(type, $.extend({node: this}, metaData || {}));
+    triggerChangeEvent: function(type, metaData, origParent) {
+        var node = (metaData && metaData.node) ? metaData.node : this,
+            event = new events.ChangeEvent(type, $.extend({node: node}, metaData || {}));
         if(type === 'nodeDetached' || this.document.containsNode(event.meta.node)) {
             this.document.trigger('change', event);
         }
         if(type === 'nodeDetached' || this.document.containsNode(event.meta.node)) {
             this.document.trigger('change', event);
         }
+        if((type === 'nodeAdded' || type === 'nodeMoved') && !(this.document.containsNode(this))) {
+             event = new events.ChangeEvent('nodeDetached', {node: node, parent: origParent});
+             this.document.trigger('change', event);
+        }
     },
     
     getNodeInsertion: function(node) {
     },
     
     getNodeInsertion: function(node) {
index e045788..0b85383 100644 (file)
@@ -715,6 +715,28 @@ describe('smartxml', function() {
             expect(event2.type).to.equal('nodeAdded');
             expect(event2.meta.node.sameNode(doc.root)).to.equal(true, 'new root node in nodelAdded event meta');
         });
             expect(event2.type).to.equal('nodeAdded');
             expect(event2.meta.node.sameNode(doc.root)).to.equal(true, 'new root node in nodelAdded event meta');
         });
+
+
+        ['append', 'prepend', 'before', 'after'].forEach(function(insertionMethod) {
+            it('emits nodeDetached for node moved from a document tree to out of document node ' + insertionMethod, function() {
+                var doc = getDocumentFromXML('<div><a></a></div>'),
+                    a = doc.root.contents()[0],
+                    spy = sinon.spy();
+
+                doc.on('change', spy);
+
+                var newNode = doc.createDocumentNode({tagName: 'b'}),
+                    newNodeInner = newNode.append({tagName:'c'});
+
+                newNodeInner[insertionMethod](a);
+
+                var event = spy.args[0][0];
+                expect(event.type).to.equal('nodeDetached');
+                expect(event.meta.node.sameNode(a));
+            });
+        });
+
+
     });
 
     describe('Traversing', function() {
     });
 
     describe('Traversing', function() {