Skip to content

Commit

Permalink
feat(manipulation): Add unwrap function (#1651)
Browse files Browse the repository at this point in the history
Co-authored-by: 5saviahv <5saviahv@users.noreply.github.com>
Co-authored-by: Felix Böhm <me@feedic.com>
  • Loading branch information
3 people committed Jan 5, 2021
1 parent bb6cb38 commit 2037d83
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 0 deletions.
41 changes: 41 additions & 0 deletions lib/api/manipulation.js
Expand Up @@ -364,6 +364,47 @@ exports.wrapInner = _wrap(function (el, elInsertLocation, wrapperDom) {
updateDOM(wrapperDom, el);
});

/**
* The .unwrap() function, removes the parents of the set of matched elements
* from the DOM, leaving the matched elements in their place.
*
* @example <caption>without selector</caption>
* const $ = cheerio.load(
* '<div id=test>\n <div><p>Hello</p></div>\n <div><p>World</p></div>\n</div>'
* );
* $('#test p').unwrap();
*
* //=> <div id=test>
* // <p>Hello</p>
* // <p>World</p>
* // </div>
*
* @example <caption>with selector</caption>
* const $ = cheerio.load(
* '<div id=test>\n <p>Hello</p>\n <b><p>World</p></b>\n</div>'
* );
* $('#test p').unwrap('b');
*
* //=> <div id=test>
* // <p>Hello</p>
* // <p>World</p>
* // </div>
*
* @param {string} [selector] - A selector to check the parent element against. If
* an element's parent does not match the selector, the element won't be unwrapped.
* @see {@link https://api.jquery.com/unwrap/}
* @returns {Cheerio} The instance itself, for chaining.
*/
exports.unwrap = function (selector) {
var self = this;
this.parent(selector)
.not('body')
.each(function (i, el) {
self._make(el).replaceWith(el.children);
});
return this;
};

/**
* The .wrapAll() function can take any string or object that could be passed to
* the $() function to specify a DOM structure. This structure may be nested
Expand Down
83 changes: 83 additions & 0 deletions test/api/manipulation.js
Expand Up @@ -324,6 +324,89 @@ describe('$(...)', function () {
});
});

describe('.unwrap', function () {
var $elem;
var unwrapspans = [
'<div id=unwrap style="display: none;">',
'<div id=unwrap1><span class=unwrap>a</span><span class=unwrap>b</span></div>',
'<div id=unwrap2><span class=unwrap>c</span><span class=unwrap>d</span></div>',
'<div id=unwrap3><b><span class="unwrap unwrap3">e</span></b><b><span class="unwrap unwrap3">f</span></b></div>',
'</div>',
].join('');

beforeEach(function () {
$elem = cheerio.load(unwrapspans);
});

it('() : should be unwrap span elements', function () {
var abcd = $elem('#unwrap1 > span, #unwrap2 > span').get();
var abcdef = $elem('#unwrap span').get();

// make #unwrap1 and #unwrap2 go away
expect(
$elem('#unwrap1 span').add('#unwrap2 span:first-child').unwrap()
).toHaveLength(3);

//.toEqual
// all four spans should still exist
expect($elem('#unwrap > span').get()).toEqual(abcd);

// make all b elements in #unwrap3 go away
expect($elem('#unwrap3 span').unwrap().get()).toEqual(
$elem('#unwrap3 > span').get()
);

// make #unwrap3 go away
expect($elem('#unwrap3 span').unwrap().get()).toEqual(
$elem('#unwrap > span.unwrap3').get()
);

// #unwrap only contains 6 child spans
expect($elem('#unwrap').children().get()).toEqual(abcdef);

// make the 6 spans become children of body
expect($elem('#unwrap > span').unwrap().get()).toEqual(
$elem('body > span.unwrap').get()
);

// can't unwrap children of body
expect($elem('body > span.unwrap').unwrap().get()).toEqual(
$elem('body > span.unwrap').get()
);

// can't unwrap children of body
expect($elem('body > span.unwrap').unwrap().get()).toEqual(abcdef);

// can't unwrap children of body
expect($elem('body > span.unwrap').get()).toEqual(abcdef);
});

it('(selector) : should only unwrap element parent what specified', function () {
var abcd = $elem('#unwrap1 > span, #unwrap2 > span').get();
// var abcdef = $elem('#unwrap span').get();

// Shouldn't unwrap, no match
$elem('#unwrap1 span').unwrap('#unwrap2');
expect($elem('#unwrap1')).toHaveLength(1);

// Shouldn't unwrap, no match
$elem('#unwrap1 span').unwrap('span');
expect($elem('#unwrap1')).toHaveLength(1);

// Unwraps
$elem('#unwrap1 span').unwrap('#unwrap1');
expect($elem('#unwrap1')).toHaveLength(0);

// Should not unwrap - unmatched unwrap
$elem('#unwrap2 span').unwrap('quote');
expect($elem('#unwrap > span')).toHaveLength(2);

// Check return values - matched unwrap
$elem('#unwrap2 span').unwrap('#unwrap2');
expect($elem('#unwrap > span').get()).toEqual(abcd);
});
});

describe('.wrapAll', function () {
var doc;
var $inner;
Expand Down

0 comments on commit 2037d83

Please sign in to comment.