diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2ce794f..ade3921 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,7 +9,7 @@ jobs: node-version: ${{matrix.node}} - run: npm install - run: npm test - - uses: codecov/codecov-action@v4 + - uses: codecov/codecov-action@v5 strategy: matrix: node: diff --git a/package.json b/package.json index 9596e1e..482d717 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "hast-util-to-string": "^3.0.0", "hast-util-whitespace": "^3.0.0", "nth-check": "^2.0.0", - "property-information": "^6.0.0", + "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" @@ -25,14 +25,14 @@ "devDependencies": { "@types/node": "^22.0.0", "c8": "^10.0.0", - "hastscript": "^8.0.0", + "hastscript": "^9.0.0", "prettier": "^3.0.0", "remark-cli": "^12.0.0", - "remark-preset-wooorm": "^10.0.0", + "remark-preset-wooorm": "^11.0.0", "type-coverage": "^2.0.0", "typescript": "^5.0.0", "unist-builder": "^4.0.0", - "xo": "^0.59.0" + "xo": "^0.60.0" }, "exports": "./index.js", "files": [ @@ -92,7 +92,7 @@ "strict": true }, "type": "module", - "version": "6.0.3", + "version": "6.0.4", "xo": { "overrides": [ { diff --git a/readme.md b/readme.md index 955db5e..e2095c5 100644 --- a/readme.md +++ b/readme.md @@ -1,15 +1,12 @@ # hast-util-select -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] -[![Sponsors][sponsors-badge]][collective] -[![Backers][backers-badge]][collective] -[![Chat][chat-badge]][chat] +[![Build][badge-build-image]][badge-build-url] +[![Coverage][badge-coverage-image]][badge-coverage-url] +[![Downloads][badge-downloads-image]][badge-downloads-url] +[![Size][badge-size-image]][badge-size-url] -[hast][] utility with equivalents for `matches`, `querySelector`, -and `querySelectorAll`. +[hast][github-hast] utility with equivalents for +`matches`, `querySelector`, and `querySelectorAll`. ## Contents @@ -33,30 +30,42 @@ and `querySelectorAll`. ## What is this? -This package lets you find nodes in a tree, similar to how `matches`, -`querySelector`, and `querySelectorAll` work with the DOM. +This package lets you find nodes in a tree, +similar to how `matches`, +`querySelector`, +and +`querySelectorAll` work with the DOM. One notable difference between DOM and hast is that DOM nodes have references -to their parents, meaning that `document.body.matches(':last-child')` can -be evaluated to check whether the body is the last child of its parent. -This information is not stored in hast, so selectors like that don’t work. +to their parents, +meaning that `document.body.matches(':last-child')` can be evaluated to check +whether the body is the last child of its parent. +This information is not stored in hast, +so selectors like that don’t work. ## When should I use this? -This is a small utility that is quite useful, but is rather slow if you use it a -lot. -For each call, it has to walk the entire tree. -In some cases, walking the tree once with [`unist-util-visit`][unist-util-visit] -is smarter, such as when you want to change certain nodes. -On the other hand, this is quite powerful and fast enough for many other cases. - -This utility is similar to [`unist-util-select`][unist-util-select], which can -find and match any unist node. +This is a small utility that is quite useful, +but is rather slow if you use it a lot. +For each call, +it has to walk the entire tree. +In some cases, +walking the tree once with +[`unist-util-visit`][github-unist-util-visit] +is smarter, +such as when you want to change certain nodes. +On the other hand, +this is quite powerful and fast enough for many other cases. + +This utility is similar to +[`unist-util-select`][github-unist-util-select], +which can find and match any unist node. ## Install -This package is [ESM only][esm]. -In Node.js (version 16+), install with [npm][]: +This package is [ESM only][github-gist-esm]. +In Node.js (version 16+), +install with [npm][npmjs-install]: ```sh npm install hast-util-select @@ -65,14 +74,14 @@ npm install hast-util-select In Deno with [`esm.sh`][esmsh]: ```js -import {matches, select, selectAll} from "https://esm.sh/hast-util-select@6" +import {matches, select, selectAll} from 'https://esm.sh/hast-util-select@6' ``` In browsers with [`esm.sh`][esmsh]: ```html ``` @@ -104,25 +113,33 @@ console.log(selectAll('h1 ~ :nth-child(even)', tree)) ## API This package exports the identifiers [`matches`][api-matches], -[`select`][api-select], and [`selectAll`][api-select-all]. +[`select`][api-select], +and [`selectAll`][api-select-all]. There is no default export. ### `matches(selector, node[, space])` Check that the given `node` matches `selector`. -This only checks the element itself, not the surrounding tree. -Thus, nesting in selectors is not supported (`p b`, `p > b`), neither are -selectors like `:first-child`, etc. +This only checks the element itself, +not the surrounding tree. +Thus, +nesting in selectors is not supported (`p b`, `p > b`), +neither are selectors like `:first-child`, +etc. This only checks that the given element matches the selector. ###### Parameters -* `selector` (`string`) - — CSS selector, such as (`h1`, `a, b`) -* `node` ([`Node`][node], optional) - — node that might match `selector`, should be an element -* `space` ([`Space`][api-space], default: `'html'`) +* `selector` + (`string`, example: `'h1'`, `'a, b'`) + — CSS selector +* `node` + ([`Node`][github-hast-nodes], optional) + — node that might match `selector`, + should be an element +* `space` + ([`Space`][api-space], default: `'html'`) — name of namespace ###### Returns @@ -147,15 +164,18 @@ matches('[lang|=en]', h('a', {lang: 'en-GB'})) // => true ### `select(selector, tree[, space])` Select the first element that matches `selector` in the given `tree`. -Searches the tree in *[preorder][]*. +Searches the tree in *[preorder][github-unist-preorder]*. ###### Parameters -* `selector` (`string`) +* `selector` + (`string`, example: `'h1'`, `'a, b'`) — CSS selector, such as (`h1`, `a, b`) -* `tree` ([`Node`][node], optional) +* `tree` + ([`Node`][github-hast-nodes], optional) — tree to search -* `space` ([`Space`][api-space], default: `'html'`) +* `space` + ([`Space`][api-space], default: `'html'`) — name of namespace ###### Returns @@ -196,15 +216,18 @@ Yields: ### `selectAll(selector, tree[, space])` Select all elements that match `selector` in the given `tree`. -Searches the tree in *[preorder][]*. +Searches the tree in *[preorder][github-unist-preorder]*. ###### Parameters -* `selector` (`string`) - — CSS selector, such as (`h1`, `a, b`) -* `tree` ([`Node`][node], optional) +* `selector` + (`string`, example: `'h1'`, `'a, b'`) + — CSS selector +* `tree` + ([`Node`][github-hast-nodes], optional) — tree to search -* `space` ([`Space`][api-space], default: `'html'`) +* `space` + ([`Space`][api-space], default: `'html'`) — name of namespace ###### Returns @@ -363,10 +386,14 @@ type Space = 'html' | 'svg' ###### Notes * \* — not supported in `matches` -* † — needs a user, browser, interactivity, scripting, or whole CSS to make - sense +* † — needs a user, + browser, + interactivity, + scripting, + or whole CSS to make sense * ‡ — not very interested in writing / including the code for this -* § — too new, the spec is still changing +* § — too new, + the spec is still changing * ‖ — pr wanted! * `:any()` and `:matches()` are renamed to `:is()` in CSS. @@ -380,19 +407,20 @@ It exports the additional type [`Space`][api-space]. Projects maintained by the unified collective are compatible with maintained versions of Node.js. -When we cut a new major release, we drop support for unmaintained versions of -Node. -This means we try to keep the current release line, `hast-util-select@^6`, +When we cut a new major release, +we drop support for unmaintained versions of Node. +This means we try to keep the current release line, +`hast-util-select@6`, compatible with Node.js 16. ## Security This package does not change the syntax tree so there are no openings for -[cross-site scripting (XSS)][xss] attacks. +[cross-site scripting (XSS)][wikipedia-xss] attacks. ## Related -* [`unist-util-select`](https://github.com/syntax-tree/unist-util-select) +* [`unist-util-select`][github-unist-util-select] — select unist nodes with CSS-like selectors * [`hast-util-find-and-replace`](https://github.com/syntax-tree/hast-util-find-and-replace) — find and replace text in a hast tree @@ -403,82 +431,75 @@ This package does not change the syntax tree so there are no openings for ## Contribute -See [`contributing.md`][contributing] in [`syntax-tree/.github`][health] for -ways to get started. -See [`support.md`][help] for ways to get help. +See [`contributing.md`][health-contributing] +in +[`syntax-tree/.github`][health] +for ways to get started. +See [`support.md`][health-support] for ways to get help. -This project has a [code of conduct][coc]. -By interacting with this repository, organization, or community you agree to -abide by its terms. +This project has a [code of conduct][health-coc]. +By interacting with this repository, +organization, +or community you agree to abide by its terms. ## License -[MIT][license] © [Titus Wormer][author] +[MIT][file-license] © [Titus Wormer][wooorm] -[build-badge]: https://github.com/syntax-tree/hast-util-select/workflows/main/badge.svg - -[build]: https://github.com/syntax-tree/hast-util-select/actions - -[coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/hast-util-select.svg - -[coverage]: https://codecov.io/github/syntax-tree/hast-util-select +[api-matches]: #matchesselector-node-space -[downloads-badge]: https://img.shields.io/npm/dm/hast-util-select.svg +[api-select]: #selectselector-tree-space -[downloads]: https://www.npmjs.com/package/hast-util-select +[api-select-all]: #selectallselector-tree-space -[size-badge]: https://img.shields.io/badge/dynamic/json?label=minzipped%20size&query=$.size.compressedSize&url=https://deno.bundlejs.com/?q=hast-util-select +[api-space]: #space -[size]: https://bundlejs.com/?q=hast-util-select +[badge-build-image]: https://github.com/syntax-tree/hast-util-select/workflows/main/badge.svg -[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg +[badge-build-url]: https://github.com/syntax-tree/hast-util-select/actions -[backers-badge]: https://opencollective.com/unified/backers/badge.svg +[badge-coverage-image]: https://img.shields.io/codecov/c/github/syntax-tree/hast-util-select.svg -[collective]: https://opencollective.com/unified +[badge-coverage-url]: https://codecov.io/github/syntax-tree/hast-util-select -[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg +[badge-downloads-image]: https://img.shields.io/npm/dm/hast-util-select.svg -[chat]: https://github.com/syntax-tree/unist/discussions +[badge-downloads-url]: https://www.npmjs.com/package/hast-util-select -[npm]: https://docs.npmjs.com/cli/install +[badge-size-image]: https://img.shields.io/bundlejs/size/hast-util-select -[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c +[badge-size-url]: https://bundlejs.com/?q=hast-util-select [esmsh]: https://esm.sh -[typescript]: https://www.typescriptlang.org - -[license]: license +[file-license]: license -[author]: https://wooorm.com +[github-gist-esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c -[health]: https://github.com/syntax-tree/.github +[github-hast]: https://github.com/syntax-tree/hast -[contributing]: https://github.com/syntax-tree/.github/blob/main/contributing.md +[github-hast-nodes]: https://github.com/syntax-tree/hast#nodes -[help]: https://github.com/syntax-tree/.github/blob/main/support.md +[github-unist-preorder]: https://github.com/syntax-tree/unist#preorder -[coc]: https://github.com/syntax-tree/.github/blob/main/code-of-conduct.md +[github-unist-util-select]: https://github.com/syntax-tree/unist-util-select -[preorder]: https://github.com/syntax-tree/unist#preorder +[github-unist-util-visit]: https://github.com/syntax-tree/unist-util-visit -[hast]: https://github.com/syntax-tree/hast - -[node]: https://github.com/syntax-tree/hast#nodes +[health]: https://github.com/syntax-tree/.github -[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting +[health-coc]: https://github.com/syntax-tree/.github/blob/main/code-of-conduct.md -[unist-util-visit]: https://github.com/syntax-tree/unist-util-visit +[health-contributing]: https://github.com/syntax-tree/.github/blob/main/contributing.md -[unist-util-select]: https://github.com/syntax-tree/unist-util-select +[health-support]: https://github.com/syntax-tree/.github/blob/main/support.md -[api-matches]: #matchesselector-node-space +[npmjs-install]: https://docs.npmjs.com/cli/install -[api-select]: #selectselector-tree-space +[typescript]: https://www.typescriptlang.org -[api-select-all]: #selectallselector-tree-space +[wikipedia-xss]: https://en.wikipedia.org/wiki/Cross-site_scripting -[api-space]: #space +[wooorm]: https://wooorm.com diff --git a/test/matches.js b/test/matches.js index ee79206..91bb7f8 100644 --- a/test/matches.js +++ b/test/matches.js @@ -1646,7 +1646,7 @@ test('select.matches()', async function (t) { }) await t.test('should match if w/o elements or texts', async function () { - assert.ok(matches(':empty', h('', u('comment', '?')))) + assert.ok(matches(':empty', h('', [u('comment', '?')]))) }) await t.test('should not match if w/ elements', async function () { @@ -1654,13 +1654,13 @@ test('select.matches()', async function (t) { }) await t.test('should not match if w/ text', async function () { - assert.ok(!matches(':empty', h('', u('text', '.')))) + assert.ok(!matches(':empty', h('', [u('text', '.')]))) }) await t.test( 'should not match if w/ white-space text', async function () { - assert.ok(!matches(':empty', h('', u('text', ' ')))) + assert.ok(!matches(':empty', h('', [u('text', ' ')]))) } ) }) @@ -1675,7 +1675,7 @@ test('select.matches()', async function (t) { }) await t.test('should match if w/ white-space text', async function () { - assert.ok(matches(':blank', h('', u('text', ' ')))) + assert.ok(matches(':blank', h('', [u('text', ' ')]))) }) await t.test('should not match if w/ elements', async function () { @@ -1683,7 +1683,7 @@ test('select.matches()', async function (t) { }) await t.test('should not match if w/ text', async function () { - assert.ok(!matches(':blank', h('', u('text', '.')))) + assert.ok(!matches(':blank', h('', [u('text', '.')]))) }) })