Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions lib/api/manipulation.js
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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