unwrapping nodes
authorAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Wed, 3 Jul 2013 12:19:46 +0000 (14:19 +0200)
committerAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Wed, 3 Jul 2013 12:19:46 +0000 (14:19 +0200)
modules/documentCanvas/canvas.js
modules/documentCanvas/canvasManager.js
modules/documentCanvas/tests/canvas.test.js
modules/documentToolbar/template.html

index a1f516d..ab8a578 100644 (file)
@@ -97,6 +97,61 @@ Canvas.prototype.nodeWrap = function(options) {
     options._with.dom.after(suffixOutside);
 };
 
     options._with.dom.after(suffixOutside);
 };
 
+Canvas.prototype.nodeUnwrap = function(options) {
+
+    var removeWithJoin = function(node) {
+        var contents = node.parent().contents(),
+            idx = contents.index(node),
+            prev = idx > 0 ? contents[idx-1] : null,
+            next = idx + 1 < contents.length ? contents[idx+1] : null;
+
+        if(prev && prev.nodeType === 3 && next && next.nodeType === 3) {
+            prev.data = prev.data + next.data;
+            $(next).remove();
+        }
+        node.remove();
+    };
+
+    var toUnwrap = $(this.content.find('#' + options.node.getId()).get(0));
+
+
+    var parent = toUnwrap.parent();
+    var parentContents = parent.contents();
+
+    if(toUnwrap.contents().length !== 1 || toUnwrap.contents()[0].nodeType !== 3)
+        return false;
+
+    var idx = parentContents.index(toUnwrap);
+
+    var combineWith,
+        action;
+
+    if(idx > 0 && parentContents[idx-1].nodeType === 3) {
+        combineWith = parentContents[idx-1];
+        action = 'append';
+    } else if(idx + 1 < parentContents.length && parentContents[idx+1].nodeType === 3) {
+        combineWith = parentContents[idx+1];
+        action = 'prepend';
+    }
+
+    if(combineWith) {
+        var text = 
+                (action === 'prepend' ? toUnwrap.text() : '') +
+                combineWith.data +
+                (action === 'append' ? toUnwrap.text() : '')
+        ;
+        combineWith.data = text;
+        removeWithJoin(toUnwrap);
+    } else {
+        if(parentContents.length === 1 || idx === 0) {
+            parent.append(toUnwrap.text());
+        } else {
+            toUnwrap.prev().after(toUnwrap.text());
+        }
+        toUnwrap.remove();
+    }
+};
+
 Canvas.prototype.nodeSplit = function(options) {
     options = _.extend({textNodeIdx: 0}, options);
     
 Canvas.prototype.nodeSplit = function(options) {
     options = _.extend({textNodeIdx: 0}, options);
     
index 3b7f72d..edb599c 100644 (file)
@@ -245,6 +245,9 @@ Manager.prototype.command = function(command, meta) {
                 this.sandbox.publish('contentChanged');
             //}
         }
                 this.sandbox.publish('contentChanged');
             //}
         }
+    } else if(command === 'unwrap-node') {
+        this.canvas.nodeUnwrap({node: canvasNode.create(pos.parentNode)});
+        this.sandbox.publish('contentChanged');
     }
 
 };
     }
 
 };
index 53f4aee..5dc017b 100644 (file)
@@ -76,6 +76,35 @@ define([
             c.nodeWrap({inside: header, _with: wrapper, offsetStart: 6, offsetEnd: 4, textNodeIdx: [0,2]});
             assertDomEqual(c.getContent(), '<div wlxml-tag="header">Alice <span wlxml-tag="aside">has a <span wlxml-tag="span">small</span> cat</span></div>');            
         });
             c.nodeWrap({inside: header, _with: wrapper, offsetStart: 6, offsetEnd: 4, textNodeIdx: [0,2]});
             assertDomEqual(c.getContent(), '<div wlxml-tag="header">Alice <span wlxml-tag="aside">has a <span wlxml-tag="span">small</span> cat</span></div>');            
         });
+
+        test('unwrap text', function() {
+            var c = canvas.create('<div wlxml-tag="div">Alice <span wlxml-tag="span">has</span> a cat</div>');
+            var span = c.findNodes({tag:'span'})[0];
+            c.nodeUnwrap({node: span});
+            assertDomEqual(c.getContent(), '<div wlxml-tag="div">Alice has a cat</div>');
+        });
+
+        test('unwrap text - first text node', function() {
+            var c = canvas.create('<div wlxml-tag="div"><span wlxml-tag="span">Alice</span> has a cat</div>');
+            var span = c.findNodes({tag:'span'})[0];
+            c.nodeUnwrap({node: span});
+            assertDomEqual(c.getContent(), '<div wlxml-tag="div">Alice has a cat</div>'); 
+        });
+
+        test('unwrap text - only text node', function() {
+            var c = canvas.create('<div wlxml-tag="div"><span wlxml-tag="span">Alice</span></div>');
+            var span = c.findNodes({tag:'span'})[0];
+            c.nodeUnwrap({node: span});
+            assertDomEqual(c.getContent(), '<div wlxml-tag="div">Alice</div>'); 
+        });
+
+
+        test('unwrap text - non text neighbours', function() {
+            var c = canvas.create('<div wlxml-tag="div"><div wlxml-tag"div">a</div><span wlxml-tag="span">Alice</span><div wlxml-tag"div">b</div></div>');
+            var span = c.findNodes({tag:'span'})[0];
+            c.nodeUnwrap({node: span});
+            assertDomEqual(c.getContent(), '<div wlxml-tag="div"><div wlxml-tag"div">a</div>Alice<div wlxml-tag"div">b</div></div>'); 
+        });
         
         test('split node', function() {
             var c = canvas.create('<div wlxml-tag="section"><div wlxml-tag="header">Header 1</div></div>');
         
         test('split node', function() {
             var c = canvas.create('<div wlxml-tag="section"><div wlxml-tag="header">Header 1</div></div>');
index 31ecbf6..62f4070 100644 (file)
@@ -18,6 +18,9 @@
         </select>
         <button data-btn="new-node" data-btn-type="cmd" class="btn btn-mini"><i class="icon-plus"></i></button>
     </div>
         </select>
         <button data-btn="new-node" data-btn-type="cmd" class="btn btn-mini"><i class="icon-plus"></i></button>
     </div>
+    <div class="rng-module-documentToolbar-toolbarGroup">
+        <button data-btn="unwrap-node" data-btn-type="cmd" class="btn btn-mini"><i class="icon-arrow-up"></i></button>
+    </div>    
     <div class="rng-module-documentToolbar-toolbarGroup">
         <button data-btn="grid" data-btn-type="toggle" class="btn btn-mini"><i class="icon-th-large"></i></button>
         <button data-btn="tags" data-btn-type="toggle" class="btn btn-mini"><i class="icon-tag"></i></button>
     <div class="rng-module-documentToolbar-toolbarGroup">
         <button data-btn="grid" data-btn-type="toggle" class="btn btn-mini"><i class="icon-th-large"></i></button>
         <button data-btn="tags" data-btn-type="toggle" class="btn btn-mini"><i class="icon-tag"></i></button>