Skip to content

Commit 1c6fa3e

Browse files
authored
refactor: Move is to traversing, optimize (#1908)
Moved so it can use `getFilterFn`.
1 parent c81a512 commit 1c6fa3e

File tree

4 files changed

+82
-78
lines changed

4 files changed

+82
-78
lines changed

src/api/attributes.spec.ts

-52
Original file line numberDiff line numberDiff line change
@@ -1028,56 +1028,4 @@ describe('$(...)', () => {
10281028
);
10291029
});
10301030
});
1031-
1032-
describe('.is', () => {
1033-
it('() : should return false', () => {
1034-
expect($('li.apple').is()).toBe(false);
1035-
});
1036-
1037-
it('(true selector) : should return true', () => {
1038-
expect(cheerio('#vegetables', vegetables).is('ul')).toBe(true);
1039-
});
1040-
1041-
it('(false selector) : should return false', () => {
1042-
expect(cheerio('#vegetables', vegetables).is('div')).toBe(false);
1043-
});
1044-
1045-
it('(true selection) : should return true', () => {
1046-
const $vegetables = cheerio('li', vegetables);
1047-
expect($vegetables.is($vegetables.eq(1))).toBe(true);
1048-
});
1049-
1050-
it('(false selection) : should return false', () => {
1051-
const $vegetableList = cheerio(vegetables);
1052-
const $vegetables = $vegetableList.find('li');
1053-
expect($vegetables.is($vegetableList)).toBe(false);
1054-
});
1055-
1056-
it('(true element) : should return true', () => {
1057-
const $vegetables = cheerio('li', vegetables);
1058-
expect($vegetables.is($vegetables[0])).toBe(true);
1059-
});
1060-
1061-
it('(false element) : should return false', () => {
1062-
const $vegetableList = cheerio(vegetables);
1063-
const $vegetables = $vegetableList.find('li');
1064-
expect($vegetables.is($vegetableList[0])).toBe(false);
1065-
});
1066-
1067-
it('(true predicate) : should return true', () => {
1068-
const result = $('li').is(function () {
1069-
return this.tagName === 'li' && $(this).hasClass('pear');
1070-
});
1071-
expect(result).toBe(true);
1072-
});
1073-
1074-
it('(false predicate) : should return false', () => {
1075-
const result = $('li')
1076-
.last()
1077-
.is(function () {
1078-
return this.tagName === 'ul';
1079-
});
1080-
expect(result).toBe(false);
1081-
});
1082-
});
10831031
});

src/api/attributes.ts

-23
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { text } from '../static';
88
import { isTag, domEach, camelCase, cssCase } from '../utils';
99
import type { Node, Element } from 'domhandler';
1010
import type { Cheerio } from '../cheerio';
11-
import { AcceptedFilters } from '../types';
1211
const hasOwn = Object.prototype.hasOwnProperty;
1312
const rspace = /\s+/;
1413
const dataAttrPrefix = 'data-';
@@ -1000,25 +999,3 @@ export function toggleClass<T extends Node, R extends ArrayLike<T>>(
1000999

10011000
return this;
10021001
}
1003-
1004-
/**
1005-
* Checks the current list of elements and returns `true` if *any* of the
1006-
* elements match the selector. If using an element or Cheerio selection,
1007-
* returns `true` if *any* of the elements match. If using a predicate function,
1008-
* the function is executed in the context of the selected element, so `this`
1009-
* refers to the current element.
1010-
*
1011-
* @category Attributes
1012-
* @param selector - Selector for the selection.
1013-
* @returns Whether or not the selector matches an element of the instance.
1014-
* @see {@link https://api.jquery.com/is/}
1015-
*/
1016-
export function is<T>(
1017-
this: Cheerio<T>,
1018-
selector?: AcceptedFilters<T>
1019-
): boolean {
1020-
if (selector) {
1021-
return this.filter(selector).length > 0;
1022-
}
1023-
return false;
1024-
}

src/api/traversing.spec.ts

+53
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
text,
1010
forms,
1111
mixedText,
12+
vegetables,
1213
} from '../__fixtures__/fixtures';
1314

1415
function getText(el: Cheerio<Element>) {
@@ -1528,4 +1529,56 @@ describe('$(...)', () => {
15281529
expect($div.addBack()).toBe($div);
15291530
});
15301531
});
1532+
1533+
describe('.is', () => {
1534+
it('() : should return false', () => {
1535+
expect($('li.apple').is()).toBe(false);
1536+
});
1537+
1538+
it('(true selector) : should return true', () => {
1539+
expect(cheerio('#vegetables', vegetables).is('ul')).toBe(true);
1540+
});
1541+
1542+
it('(false selector) : should return false', () => {
1543+
expect(cheerio('#vegetables', vegetables).is('div')).toBe(false);
1544+
});
1545+
1546+
it('(true selection) : should return true', () => {
1547+
const $vegetables = cheerio('li', vegetables);
1548+
expect($vegetables.is($vegetables.eq(1))).toBe(true);
1549+
});
1550+
1551+
it('(false selection) : should return false', () => {
1552+
const $vegetableList = cheerio(vegetables);
1553+
const $vegetables = $vegetableList.find('li');
1554+
expect($vegetables.is($vegetableList)).toBe(false);
1555+
});
1556+
1557+
it('(true element) : should return true', () => {
1558+
const $vegetables = cheerio('li', vegetables);
1559+
expect($vegetables.is($vegetables[0])).toBe(true);
1560+
});
1561+
1562+
it('(false element) : should return false', () => {
1563+
const $vegetableList = cheerio(vegetables);
1564+
const $vegetables = $vegetableList.find('li');
1565+
expect($vegetables.is($vegetableList[0])).toBe(false);
1566+
});
1567+
1568+
it('(true predicate) : should return true', () => {
1569+
const result = $('li').is(function () {
1570+
return this.tagName === 'li' && $(this).hasClass('pear');
1571+
});
1572+
expect(result).toBe(true);
1573+
});
1574+
1575+
it('(false predicate) : should return false', () => {
1576+
const result = $('li')
1577+
.last()
1578+
.is(function () {
1579+
return this.tagName === 'ul';
1580+
});
1581+
expect(result).toBe(false);
1582+
});
1583+
});
15311584
});

src/api/traversing.ts

+29-3
Original file line numberDiff line numberDiff line change
@@ -683,9 +683,7 @@ function getFilterFn<T>(
683683
match: FilterFunction<T> | Cheerio<T> | T
684684
): (el: T, i: number) => boolean {
685685
if (typeof match === 'function') {
686-
return function (el, i) {
687-
return (match as FilterFunction<T>).call(el, i, el);
688-
};
686+
return (el, i) => (match as FilterFunction<T>).call(el, i, el);
689687
}
690688
if (isCheerio<T>(match)) {
691689
return (el) => match.is(el);
@@ -799,6 +797,34 @@ export function filter<T>(
799797
return container._make<unknown>(result);
800798
}
801799

800+
/**
801+
* Checks the current list of elements and returns `true` if *any* of the
802+
* elements match the selector. If using an element or Cheerio selection,
803+
* returns `true` if *any* of the elements match. If using a predicate function,
804+
* the function is executed in the context of the selected element, so `this`
805+
* refers to the current element.
806+
*
807+
* @category Attributes
808+
* @param selector - Selector for the selection.
809+
* @returns Whether or not the selector matches an element of the instance.
810+
* @see {@link https://api.jquery.com/is/}
811+
*/
812+
export function is<T>(
813+
this: Cheerio<T>,
814+
selector?: AcceptedFilters<T>
815+
): boolean {
816+
const nodes = this.toArray();
817+
return typeof selector === 'string'
818+
? select.some(
819+
(nodes as unknown as Node[]).filter(isTag),
820+
selector,
821+
this.options
822+
)
823+
: selector
824+
? nodes.some(getFilterFn<T>(selector))
825+
: false;
826+
}
827+
802828
/**
803829
* Remove elements from the set of matched elements. Given a Cheerio object that
804830
* represents a set of DOM elements, the `.not()` method constructs a new

0 commit comments

Comments
 (0)