Repository: cheeriojs/cheerio
Pull request #797 (2016-01-04 00:43:08)

Fix PR #726 adding `appendTo()` and `prependTo()`
Some improvements was asked by @jugglinmike for the pull request #726 started by @digihaven,  which was intended to fix issue #641 by adding the two functions `.appendTo()` and `.prependTo()`.

This PR is a continuation of #726 and try to fix it.

---

##### This is a combination of 5 commits:

- Fix incorrect indentation
- Fix the two test description provided
- Extend arguments for `.appendTo()` and `.prependTo()`

 - Based on jQuery documentation, these two functions accept also Node and Array as argument.
 - As `a.appendTo(b)` is actually just `b.append(a)`, the function has to convert the target to a Cheerio object as long as it is not one already.

- Add unit tests to `.appendTo()` and `.prependTo()`

 - These test case are intended to verify the correct behavior of functions for different arguments accepted according to the jQuery documentation (htmlString, Cheerio object, Node element, selector or Array of elements).

- Update API documentation with `.appendTo()` and `.prependTo()`

-

##### Moreover, there is two more changes which are not directly related:

- Fix one incorrect unit test of `.before()` with Node object

- Rename argument `content` to `target` in `.insertAfter()` and `.insertBefore()` API documentation

---

I hope this is what you expected, @jugglinmike.

Let me know if you see some mistake or needed improvements.


Patch:
diff --git a/Readme.md b/Readme.md
index 29dba03c..13271d06 100644
--- a/Readme.md
+++ b/Readme.md
@@ -586,6 +586,20 @@ $.html()
 //    </ul>
 ```
 
+#### .appendTo( target )
+Insert every element in the set of matched elements to the end of the target.
+
+```js
+$('<li class="plum">Plum</li>').appendTo('#fruits')
+$.html()
+//=>  <ul id="fruits">
+//      <li class="apple">Apple</li>
+//      <li class="orange">Orange</li>
+//      <li class="pear">Pear</li>
+//      <li class="plum">Plum</li>
+//    </ul>
+```
+
 #### .prepend( content, [content, ...] )
 Inserts content as the *first* child of each of the selected elements.
 
@@ -600,6 +614,20 @@ $.html()
 //    </ul>
 ```
 
+#### .prependTo( target )
+Insert every element in the set of matched elements to the beginning of the target.
+
+```js
+$('<li class="plum">Plum</li>').prependTo('#fruits')
+$.html()
+//=>  <ul id="fruits">
+//      <li class="plum">Plum</li>
+//      <li class="apple">Apple</li>
+//      <li class="orange">Orange</li>
+//      <li class="pear">Pear</li>
+//    </ul>
+```
+
 #### .after( content, [content, ...] )
 Insert content next to each element in the set of matched elements.
 
@@ -614,7 +642,7 @@ $.html()
 //    </ul>
 ```
 
-#### .insertAfter( content )
+#### .insertAfter( target )
 Insert every element in the set of matched elements after the target.
 
 ```js
@@ -642,7 +670,7 @@ $.html()
 //    </ul>
 ```
 
-#### .insertBefore( content )
+#### .insertBefore( target )
 Insert every element in the set of matched elements before the target.
 
 ```js
diff --git a/lib/api/manipulation.js b/lib/api/manipulation.js
index 7e7670a1..670837d3 100644
--- a/lib/api/manipulation.js
+++ b/lib/api/manipulation.js
@@ -102,6 +102,26 @@ var uniqueSplice = function(array, spliceIdx, spliceCount, newElems, parent) {
   return array.splice.apply(array, spliceArgs);
 };
 
+exports.appendTo = function(target) {
+  if (!target.cheerio) {
+    target = this.constructor.call(this.constructor, target, null, this._originalRoot);
+  }
+
+  target.append(this);
+
+  return this;
+};
+
+exports.prependTo = function(target) {
+  if (!target.cheerio) {
+    target = this.constructor.call(this.constructor, target, null, this._originalRoot);
+  }
+
+  target.prepend(this);
+
+  return this;
+};
+
 exports.append = _insert(function(dom, children, parent) {
   uniqueSplice(children, children.length, 0, dom, parent);
 });


Test patch:
diff --git a/test/api/manipulation.js b/test/api/manipulation.js
index f5c82375..0d4ba2a6 100644
--- a/test/api/manipulation.js
+++ b/test/api/manipulation.js
@@ -496,6 +496,66 @@ describe('$(...)', function() {
     });
   });
 
+  describe('.appendTo', function() {
+
+    it('(html) : should add element as last child', function() {
+      var $plum = $('<li class="plum">Plum</li>').appendTo(fruits);
+      expect($plum.parent().children().eq(3).hasClass('plum')).to.be.ok();
+    });
+
+    it('($(...)) : should add element as last child', function() {
+      $('<li class="plum">Plum</li>').appendTo($fruits);
+      expect($fruits.children().eq(3).hasClass('plum')).to.be.ok();
+    });
+
+    it('(Node) : should add element as last child', function() {
+      $('<li class="plum">Plum</li>').appendTo($fruits[0]);
+      expect($fruits.children().eq(3).hasClass('plum')).to.be.ok();
+    });
+
+    it('(selector) : should add element as last child', function() {
+      $('<li class="plum">Plum</li>').appendTo('#fruits');
+      expect($fruits.children().eq(3).hasClass('plum')).to.be.ok();
+    });
+
+    it('(Array) : should add element as last child of all elements in the array', function() {
+      var $multiple = $('<ul><li>Apple</li></ul><ul><li>Orange</li></ul>');
+      $('<li class="plum">Plum</li>').appendTo($multiple.get());
+      expect($multiple.first().children().eq(1).hasClass('plum')).to.be.ok();
+      expect($multiple.last().children().eq(1).hasClass('plum')).to.be.ok();
+    });
+  });
+
+  describe('.prependTo', function() {
+
+    it('(html) : should add element as first child', function() {
+      var $plum = $('<li class="plum">Plum</li>').prependTo(fruits);
+      expect($plum.parent().children().eq(0).hasClass('plum')).to.be.ok();
+    });
+
+    it('($(...)) : should add element as first child', function() {
+      $('<li class="plum">Plum</li>').prependTo($fruits);
+      expect($fruits.children().eq(0).hasClass('plum')).to.be.ok();
+    });
+
+    it('(Node) : should add node as first child', function() {
+      $('<li class="plum">Plum</li>').prependTo($fruits[0]);
+      expect($fruits.children().eq(0).hasClass('plum')).to.be.ok();
+    });
+
+    it('(selector) : should add element as first child', function() {
+      $('<li class="plum">Plum</li>').prependTo('#fruits');
+      expect($fruits.children().eq(0).hasClass('plum')).to.be.ok();
+    });
+
+    it('(Array) : should add element as first child of all elements in the array', function() {
+      var $multiple = $('<ul><li>Apple</li></ul><ul><li>Orange</li></ul>');
+      $('<li class="plum">Plum</li>').prependTo($multiple.get());
+      expect($multiple.first().children().eq(0).hasClass('plum')).to.be.ok();
+      expect($multiple.last().children().eq(0).hasClass('plum')).to.be.ok();
+    });
+  });
+
   describe('.after', function() {
 
     it('() : should do nothing', function() {
@@ -790,7 +850,7 @@ describe('$(...)', function() {
     });
 
     it('(Node) : should add element as previous sibling', function() {
-      var plum = $('<li class="plum">Plum</li>');
+      var plum = $('<li class="plum">Plum</li>')[0];
       $('.apple').before(plum);
       expect($('.apple').prev().hasClass('plum')).to.be.ok();
     });