Skip to content
This repository has been archived by the owner on Nov 17, 2021. It is now read-only.

Commit

Permalink
feat(Utility functions): Add tag() and attrs(); return undefineds
Browse files Browse the repository at this point in the history
  • Loading branch information
nokome committed Feb 27, 2020
1 parent 56619ee commit 71820f7
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 18 deletions.
55 changes: 48 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ Several utility functions are provided in the [`util`](./src/util) module for tr
<dt><a href="#ready">ready(func)</a></dt>
<dd><p>Register a function to be executed when the DOM is fully loaded.</p>
</dd>
<dt><a href="#first">first([elem], selector)</a> ⇒ <code>Element</code> | <code>null</code></dt>
<dt><a href="#first">first([elem], selector)</a> ⇒ <code>Element</code> | <code>undefined</code></dt>
<dd><p>Select the first element matching a CSS selector.</p>
</dd>
<dt><a href="#select">select([elem], selector)</a> ⇒ <code>Array.&lt;Element&gt;</code></dt>
Expand All @@ -352,7 +352,13 @@ Several utility functions are provided in the [`util`](./src/util) module for tr
<dt><a href="#create">create([spec], ...children)</a> ⇒ <code>Element</code></dt>
<dd><p>Create a new element.</p>
</dd>
<dt><a href="#attr">attr(target, name, [value])</a> ⇒ <code>string</code> | <code>null</code> | <code>undefined</code></dt>
<dt><a href="#tag">tag(target, [value])</a> ⇒ <code>string</code> | <code>undefined</code></dt>
<dd><p>Get or set the tag name of an element.</p>
</dd>
<dt><a href="#attrs">attrs(target, [value])</a> ⇒ <code>object</code> | <code>undefined</code></dt>
<dd><p>Get or set the attributes of an element</p>
</dd>
<dt><a href="#attr">attr(target, name, [value])</a> ⇒ <code>string</code> | <code>undefined</code></dt>
<dd><p>Get or set the value of an attribute on an element.</p>
</dd>
<dt><a href="#text">text(target, [value])</a> ⇒ <code>string</code> | <code>null</code> | <code>undefined</code></dt>
Expand Down Expand Up @@ -399,11 +405,11 @@ ready(() => {
```
<a name="first"></a>

### first([elem], selector) ⇒ <code>Element</code> \| <code>null</code>
### first([elem], selector) ⇒ <code>Element</code> \| <code>undefined</code>
Select the first element matching a CSS selector.

**Kind**: global function
**Returns**: <code>Element</code> \| <code>null</code> - An `Element` or `null` if no match
**Returns**: <code>Element</code> \| <code>undefined</code> - An `Element` or `undefined` if no match
**Detail**: This function provides a short hand for `querySelector` but
also allowing for the use of semantic selectors.
You can use it for the whole document, or scoped to a particular element.
Expand Down Expand Up @@ -492,14 +498,49 @@ create(':--Person', create('span :--name', 'John Doe'))
// <span itemprop="name">John Doe</span>
// </div>
```
<a name="tag"></a>

### tag(target, [value]) ⇒ <code>string</code> \| <code>undefined</code>
Get or set the tag name of an element.

**Kind**: global function
**Returns**: <code>string</code> \| <code>undefined</code> - `undefined` when setting

| Param | Type | Description |
| --- | --- | --- |
| target | <code>Element</code> | The element to get or set the tag |
| [value] | <code>string</code> | The value of the tag (when setting) |

**Example** *(Set the tag)*
```js

tag(elem, "h3")
```
**Example** *(Get the tag)*
```js

tag(elem) // "h3"
```
<a name="attrs"></a>

### attrs(target, [value]) ⇒ <code>object</code> \| <code>undefined</code>
Get or set the attributes of an element

**Kind**: global function
**Returns**: <code>object</code> \| <code>undefined</code> - `undefined` if the attribute does not exist, or when setting

| Param | Type | Description |
| --- | --- | --- |
| target | <code>Element</code> | The element to get or set the attributes |
| [value] | <code>object</code> | The name/value pairs of the attributes |

<a name="attr"></a>

### attr(target, name, [value]) ⇒ <code>string</code> \| <code>null</code> \| <code>undefined</code>
### attr(target, name, [value]) ⇒ <code>string</code> \| <code>undefined</code>
Get or set the value of an attribute on an element.

**Kind**: global function
**Returns**: <code>string</code> \| <code>null</code> \| <code>undefined</code> - `null` if the attribute does not exist,
`undefined` when setting
**Returns**: <code>string</code> \| <code>undefined</code> - `undefined` if the attribute does not exist, or when setting

| Param | Type | Description |
| --- | --- | --- |
Expand Down
2 changes: 1 addition & 1 deletion src/util/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ describe('attr', () => {
it('gets attributes of an element', () => {
const elem = create('<img foo="bar">')
expect(attr(elem, 'foo')).toEqual('bar')
expect(attr(elem, 'baz')).toEqual(null)
expect(attr(elem, 'baz')).toEqual(undefined)
})

it('sets attributes of an element', () => {
Expand Down
67 changes: 57 additions & 10 deletions src/util/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ export function whenReady(): void {
document.removeEventListener('DOMContentLoaded', whenReady)
}

export function first(selector: string): Element | null
export function first(selector: string): Element | undefined
export function first(
elem: Document | Element,
selector: string
): Element | null
): Element | undefined
/**
* Select the first element matching a CSS selector.
*
Expand All @@ -89,15 +89,15 @@ export function first(
*
* @param {Element} [elem] The element to query (defaults to the `window.document`)
* @param {string} selector The selector to match
* @returns {Element | null} An `Element` or `null` if no match
* @returns {Element | undefined} An `Element` or `undefined` if no match
*/
export function first(
...args: (string | Document | Element)[]
): Element | null {
): Element | undefined {
const [elem, selector] = (args.length === 1
? [document, args[0]]
: args.slice(0, 2)) as [Element, string]
return elem.querySelector(translate(selector))
return elem.querySelector(translate(selector)) ?? undefined
}

export function select(selector: string): Element[]
Expand Down Expand Up @@ -238,7 +238,55 @@ export function create(
return elem
}

export function attr(target: Element, name: string): string | null
export function tag(target: Element): string
export function tag(target: Element, value: string): undefined
/**
* Get or set the tag name of an element.
*
* @example <caption>Set the tag</caption>
*
* tag(elem, "h3")
*
* @example <caption>Get the tag</caption>
*
* tag(elem) // "h3"
*
* @param {Element} target The element to get or set the tag
* @param {string} [value] The value of the tag (when setting)
* @returns {string | undefined} `undefined` when setting
*/
export function tag(target: Element, value?: string): string | undefined {
if (value === undefined) return target.tagName

const replacement = create(value, attrs(target))
replacement.innerHTML = target.innerHTML
replace(target, replacement)
}

export function attrs(target: Element): Record<string, string>
export function attrs(target: Element, value: object): undefined
/**
* Get or set the attributes of an element
*
* @param {Element} target The element to get or set the attributes
* @param {object} [value] The name/value pairs of the attributes
* @returns {object | undefined} `undefined` if the attribute does not exist, or when setting
*/
export function attrs(
target: Element,
value?: object
): Record<string, string> | undefined {
if (value === undefined)
return Object.assign(
{},
...Array.from(target.attributes, ({ name, value }) => ({ [name]: value }))
)
Object.entries(value).forEach(([name, value]) =>
target.setAttribute(name, value)
)
}

export function attr(target: Element, name: string): string
export function attr(target: Element, name: string, value: string): undefined
/**
* Get or set the value of an attribute on an element.
Expand All @@ -254,15 +302,14 @@ export function attr(target: Element, name: string, value: string): undefined
* @param {Element} target The element to get or set the attribute
* @param {string} name The name of the attribute
* @param {string} [value] The value of the attribute (when setting)
* @returns {string | null | undefined} `null` if the attribute does not exist,
* `undefined` when setting
* @returns {string | undefined} `undefined` if the attribute does not exist, or when setting
*/
export function attr(
target: Element,
name: string,
value?: string
): string | null | undefined {
if (value === undefined) return target.getAttribute(name)
): string | undefined {
if (value === undefined) return target.getAttribute(name) ?? undefined
target.setAttribute(name, value)
}

Expand Down

0 comments on commit 71820f7

Please sign in to comment.