smartxml: Support for Node.object.describesParent property
authorAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Wed, 14 May 2014 13:34:58 +0000 (15:34 +0200)
committerAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Wed, 28 May 2014 12:45:58 +0000 (14:45 +0200)
src/smartxml/core.js
src/smartxml/smartxml.test.js

index 007468f..fdce751 100644 (file)
@@ -187,15 +187,21 @@ var elementNodeTransformations = {
             return;
         }
 
+        this.contents()
+            .filter(function(child) {
+                return child.getProperty('describesParent');
+            }.bind(this))
+            .forEach(function(child) {
+                child.detach();
+            });
+
         var myContents = this.contents(),
             myIdx = parent.indexOf(this);
 
-
         if(myContents.length === 0) {
             return this.detach();
         }
 
-
         var childrenLength = this.contents().length,
             first = true,
             shiftRange = false;
@@ -381,7 +387,9 @@ var documentTransformations = {
         }
 
         for(var i = idx1; i <= idx2; i++) {
-            wrapper.append(parentContents[i].detach());
+            if(!parentContents[i].getProperty('describesParent')) {
+                wrapper.append(parentContents[i].detach());
+            }
         }
 
         insertingTarget[insertingMethod](wrapper);
@@ -426,7 +434,9 @@ var documentTransformations = {
                 wrapperElement.append({text: prefixInside});
             }
             for(var i = idx1 + 1; i < idx2; i++) {
-                wrapperElement.append(contentsInside[i]);
+                if(!contentsInside[i].getProperty('describesParent')) {
+                    wrapperElement.append(contentsInside[i]);
+                }
             }
             if(suffixInside.length > 0) {
                 wrapperElement.append({text: suffixInside});
index 5430278..b7676e2 100644 (file)
@@ -578,6 +578,24 @@ describe('smartxml', function() {
             expect(node.contents()[2].getText()).to.equal(' a cat!');
         });
 
+        it('removes parent-describing sibling nodes of unwrapped node', function() {
+            var doc = getDocumentFromXML('<root><div><a></a><x></x><a></a></div></root>'),
+                div = doc.root.contents()[0],
+                x = div.contents()[1];
+
+            doc.registerExtension({documentNode: {methods: {
+                object: {
+                    describesParent: function() {
+                        return this.getTagName() === 'x';
+                    }
+                }
+            }}});
+
+            div.unwrapContent();
+            expect(doc.root.contents().length).to.equal(2);
+            expect(x.isInDocument()).to.be.false;
+        });
+
         it('unwrap single element node from its parent', function() {
             var doc = getDocumentFromXML('<div><a><b></b></a></div>'),
                 div = doc.root,
@@ -630,6 +648,28 @@ describe('smartxml', function() {
                 expect(wrapperContents[1].contents().length).to.equal(1);
                 expect(wrapperContents[1].contents()[0].getText()).to.equal('small');
             });
+
+            it('keeps parent-describing nodes in place', function() {
+                var doc = getDocumentFromXML('<root>Alice<x></x> has a cat</root>'),
+                    root = doc.root,
+                    x = root.contents()[1];
+
+                doc.registerExtension({documentNode: {methods: {
+                    object: {
+                        describesParent: function() {
+                            return this.getTagName() === 'x';
+                        }
+                    }
+                }}});
+
+                root.wrapText({
+                    _with: {tagName: 'span', attrs: {'attr1': 'value1'}},
+                    offsetStart: 1,
+                    offsetEnd: 4,
+                    textNodeIdx: [0,2]
+                });
+                expect(x.parent().sameNode(root)).to.be.true;
+            });
         });
 
         describe('Wrapping Nodes', function() {
@@ -678,6 +718,29 @@ describe('smartxml', function() {
                 expect(headerChildren[0].sameNode(div2)).to.equal(true, 'first node wrapped');
                 expect(headerChildren[1].sameNode(div3)).to.equal(true, 'second node wrapped');
             });
+
+            it('keeps parent-describing nodes in place', function() {
+                var section = elementNodeFromXML('<section>Alice<x></x><div>a cat</div></section>'),
+                    aliceText = section.contents()[0],
+                    x = section.contents()[1],
+                    lastDiv = section.contents()[2];
+
+                section.document.registerExtension({documentNode: {methods: {
+                    object: {
+                        describesParent: function() {
+                            return this.getTagName() === 'x';
+                        }
+                    }
+                }}});
+
+                section.document.wrapNodes({
+                        node1: aliceText,
+                        node2: lastDiv,
+                        _with: {tagName: 'header'}
+                    });
+
+                expect(x.parent().sameNode(section)).to.be.true;
+            });
         });
 
     });