Positional Selectors: :gt and :lt
Relevant source files
The following files were used as context for generating this wiki page:
cheerio-select is a CSS selector engine built upon css-select that extends standard CSS functionality to support jQuery-style positional pseudo-selectors. The :gt(index) (Greater Than) and :lt(index) (Less Than) selectors allow developers to filter a set of matched elements based on their zero-indexed position within that set.
These selectors are particularly useful for DOM manipulation tasks where the structure is known but standard CSS selectors like :nth-child are insufficient because they operate relative to siblings rather than the entire matched result set. cheerio-select handles these by identifying them as "filters" and processing them through a specialized positional logic layer.
Sources: README.md:1-15, src/index.ts:1-15
Functional Definitions
The :gt and :lt selectors are part of the jQuery positional pseudo-selector suite supported by the library.
| Selector | Description | Logic Implementation |
|---|---|---|
:gt(index) | Selects elements with a higher index than the specified value. | elements.slice(position + 1) |
:lt(index) | Selects elements with a lower index than the specified value. | Returns the set restricted by getLimit. |
Sources: README.md:11-12, src/index.ts:98-106, src/positionals.ts:59-65
Architecture and Data Flow
The processing of positional selectors involves identifying them within the parsed selector array and executing them against a candidate list of elements.
Selector Grouping
When a selector string is parsed, cheerio-select splits the resulting Selector[][] into two categories: "plain" selectors (standard CSS) and "filtered" selectors (positional jQuery selectors). This ensures that standard CSS engines can handle the bulk of the work before positional logic is applied.
Sources: src/helpers.ts:24-38, src/index.ts:58-65
Positional Processing Logic
The filterByPosition function executes the actual slicing of the element array based on the pseudo-class name.
- For
:lt(index): The engine utilizesgetLimitto optimize the query. If a selector ends in:lt(5), the engine knows it only needs to find at most 5 elements from the underlying DOM traversal. - For
:gt(index): The engine retrieves the full set of matching elements (up to the total limit) and then appliesArray.prototype.slice(position + 1).
Implementation Details
The filterByPosition Function
This function acts as the execution core for positional filters. It converts the string data (the index provided in the selector) into an integer and applies the corresponding JavaScript array method.
function filterByPosition(
filter: Filter,
elements: Element[],
data: Selector[][] | string | null,
options: Options,
): Element[] {
const position =
typeof data === "string" ? Number.parseInt(data, 10) : Number.NaN;
switch (filter) {
case "lt": {
// Already done in `getLimit`
return elements;
}
case "gt": {
return Number.isFinite(position)
? elements.slice(position + 1)
: [];
}
// ... other filters
}
}
Sources: src/index.ts:77-118
Index Handling and Edge Cases
- Non-numeric data: If the data passed to
:gt()or:lt()is not a valid number (e.g.,:gt(foo)), thepositionevaluates toNaN. The implementation checksNumber.isFinite(position)and returns an empty array if invalid. - Negative Indices: While
slicehandles negative indices in standard JavaScript, thefilterByPositionimplementation for:gtspecifically checks for finiteness before slicing. Testing indicates that:lt(-1)is supported and behaves like a slice from the end.
Sources: src/index.ts:83-84, src/index.spec.ts:39-44, test/sizzle.spec.ts:1016-1025
Query Optimization with getLimit
To prevent unnecessary DOM traversals, the engine calculates a limit for the findElements call.
| Selector | Limit Calculation | Logic |
|---|---|---|
:lt(n) | Math.min(totalLimit, n) | Only search for n elements since higher indices are discarded. |
:gt(n) | totalLimit | Must search for all elements to determine which ones are "after" index n. |
Sources: src/positionals.ts:59-65
Conclusion
The :gt and :lt selectors in cheerio-select provide a bridge between standard CSS and jQuery's procedural selection style. By integrating these as "filters" within the css-select pipeline, the library maintains performance through early limit application (for :lt) while providing the expected results for index-based filtering across broad result sets.
Sources: src/index.ts:245-265, README.md:38-45