Skip to content
This repository was archived by the owner on Oct 21, 2021. It is now read-only.

Commit fb48e56

Browse files
committed
Expand motivation and examples
1 parent ad93333 commit fb48e56

File tree

2 files changed

+77
-7
lines changed

2 files changed

+77
-7
lines changed

README.md

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
# A typed querySelector function for Flow
1+
# A typed querySelector function
2+
3+
Query the document tree by selector, filtering by element type.
24

35
## Installation
46

@@ -8,27 +10,95 @@ $ npm install @github/query-selector
810

911
## Usage
1012

13+
This library provides a set of functions to query the document tree with a
14+
standard selector paired with an additional type filter applied to the result.
15+
16+
An element must match the selector as well as the type for it to be returned.
17+
18+
- `query(context, selector, klass)`
19+
- `querySelectorAll(context, selector, klass)`
20+
- `closest(element, selector, klass)`
21+
- `namedItem(element, name, klass)`
22+
- `getAttribute(element, name)`
23+
1124
```js
1225
import {closest, getAttribute, query, querySelectorAll} from '@github/query-selector'
1326

14-
// Find an element by selector and type or throw if not found.
27+
// Find an element by selector and type, or throw if not found.
1528
const image: HTMLImageElement = query(document, '.avatar', HTMLImageElement)
1629
image.src = '/hubot.png'
1730

18-
// Find the parent by selector and type or throw if not found.
31+
// Find the parent by selector and type, or throw if not found.
1932
const parent: HTMLDetailsElement = closest(image, '.container', HTMLDetailsElement)
2033
parent.open = true
2134

22-
// Retrieve the attribute's value or throw.
23-
const url: string = getAttribute(image, 'data-url')
24-
2535
// Filter all children by selector and type.
2636
const inputs: Array<HTMLInputElement> = querySelectorAll(document, 'input', HTMLInputElement)
2737
for (const input of inputs) {
2838
input.value = ''
2939
}
40+
41+
// Retrieve the attribute's value or throw.
42+
const url: string = getAttribute(image, 'data-url')
43+
```
44+
45+
## Motivation
46+
47+
Finding an individual element in the document tree and operating on it can
48+
lead to null pointer exceptions.
49+
50+
```js
51+
const el = document.querySelector('.expected-element')
52+
// el may be null!
53+
el.classList.add('selected')
54+
el.setAttribute('title', 'hello')
55+
```
56+
57+
A safer alternative is to guard against null values with a conditional statement.
58+
59+
```js
60+
const el = document.querySelector('.expected-element')
61+
if (el) {
62+
el.classList.add('selected')
63+
el.setAttribute('title', 'hello')
64+
}
3065
```
3166

67+
Even if found, the element may be of the wrong type.
68+
69+
```js
70+
const el = document.querySelector('.expected-element')
71+
if (el) {
72+
// Element might not have a value property!
73+
el.value = 'hello'
74+
}
75+
```
76+
77+
Adding an `instanceof` test would verify the element has the properties and
78+
methods we expect.
79+
80+
```js
81+
const el = document.querySelector('.expected-element')
82+
if (el instanceof HTMLInputElement) {
83+
el.value = 'hello'
84+
}
85+
```
86+
87+
Because `document.querySelector` is so frequently used in web applications,
88+
and it's tedious to guard every element query with null checks, these tests
89+
are most often omitted.
90+
91+
When using [Flow][], however, these tests become required to pass the
92+
type checker.
93+
94+
The combination of null tests and subclass type refinements feels like we're
95+
working against the type system, rather than with it, which is the motivation
96+
for this library.
97+
98+
These typed query functions consider a missing element, or an element of the
99+
wrong type, to be failed assertions and throw an exception to fail as early
100+
as possible.
101+
32102
## Development
33103

34104
```

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@github/query-selector",
33
"version": "0.0.1",
4-
"description": "A querySelector function for Flow.",
4+
"description": "Query the document tree by selector, filtering by element type.",
55
"repository": "github/query-selector",
66
"main": "dist/index.umd.js",
77
"module": "dist/index.esm.js",

0 commit comments

Comments
 (0)