Skip to content

Commit

Permalink
Add select.last
Browse files Browse the repository at this point in the history
  • Loading branch information
fregante committed May 24, 2019
1 parent b422b23 commit c625358
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 0 deletions.
13 changes: 13 additions & 0 deletions index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,19 @@ expectType<HTMLBaseElement | null>(select('base'));
expectType<SVGElement | null>(select('g'));
expectType<SVGGElement | null>(select('g'));

/**
* LAST
*/
expectType<Element | null>(select.last('.wow'));
expectType<HTMLElement | null>(select.last('.wow'));
expectType<HTMLAnchorElement | null>(select.last<HTMLAnchorElement>('.wow'));

expectType<HTMLElement | null>(select.last('base'));
expectType<HTMLBaseElement | null>(select.last('base'));

expectType<SVGElement | null>(select.last('g'));
expectType<SVGGElement | null>(select.last('g'));

/**
* EXISTS
*/
Expand Down
29 changes: 29 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,34 @@ function select(selectors: any, baseElement: any): any {
return (baseElement || document).querySelector(selectors);
}

/**
* @param selectors One or more CSS selectors separated by commas
* @param [baseElement] The element to look inside of
* @return The element found, if any
*/

function selectLast<T extends keyof HTMLElementTagNameMap>(
selectors: T,
baseElement?: BaseElement
): HTMLElementTagNameMap[T] | null;
function selectLast<T extends keyof SVGElementTagNameMap>(
selectors: T,
baseElement?: BaseElement
): SVGElementTagNameMap[T] | null;
function selectLast<T extends HTMLElement = HTMLElement>(
selectors: string,
baseElement?: BaseElement
): T | null;
function selectLast(selectors: any, baseElement: any): any {
// Shortcut with specified-but-null baseElement
if (arguments.length === 2 && !baseElement) {
return null;
}

const all = (baseElement || document).querySelectorAll(selectors);
return all[all.length - 1];
}

/**
* @param selectors One or more CSS selectors separated by commas
* @param [baseElement] The element to look inside of
Expand Down Expand Up @@ -94,6 +122,7 @@ function selectAll<T>(selectors: any, baseElements: any): T[] {
return arr;
}

select.last = selectLast;
select.exists = selectExists;
select.all = selectAll;

Expand Down
4 changes: 4 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ select('.foo a[href=bar]', baseElement)
// => <Element>
```

### `select.last(selector[, baseElement = document])`

Like `select()`, except that it returns the last matching item on the page instead of the first one.

### `select.exists(selector[, baseElement = document])`

Tests the existence of one or more elements matching the selector. It's like `select()`, except it returns a `boolean`.
Expand Down
14 changes: 14 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ test('selects one element within an ancestor', t => {
t.equal(select('li', select('ul')), li);
});

test('selects the last element', t => {
t.plan(1);

const li = [...document.querySelectorAll('ul li')].pop();
t.equal(select.last('ul li'), li);
});

test('selects the last element within an ancestor', t => {
t.plan(1);

const li = [...document.querySelectorAll('ul li')].pop();
t.equal(select.last('li', select.last('ul')), li);
});

test('tests existence of one element', t => {
t.plan(2);

Expand Down

0 comments on commit c625358

Please sign in to comment.