npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

kagekiri

v2.0.0

Published

Shadow DOM-piercing querySelector/querySelectorAll implementation

Downloads

21,763

Readme

kagekiri

Shadow DOM-piercing query APIs. Supports:

| API | Interface | Support | |--------------------------|-------------------|:------:| | querySelector | Element, Document | ✅ | | querySelectorAll | Element, Document | ✅ | | getElementsByClassName | Element, Document | ✅ | | getElementsByTagName | Element, Document | ✅ | | getElementsByTagNameNS | Element, Document | ✅ | | getElementById | Document | ✅ | | getElementsByName | Document | ✅ | | matches | Element | ✅ | | closest | Element | ✅ |

Usage

Install:

npm install --save kagekiri

Query the document or a specific element:

import { querySelector, querySelectorAll } from 'kagekiri'

// query the document
const elements = querySelectorAll('.container button')
const element = querySelector('.container button')

// or a specific element
const elements = querySelectorAll('button', otherElement)
const element = querySelector('button', otherElement)

Example

A custom element:

<my-component></my-component>
<script>
  class MyComponent extends HTMLElement {
    constructor() {
      super()
      const shadowRoot = this.attachShadow({mode: 'open'})
      shadowRoot.innerHTML = '<span class="hello">Hello</span>'
    }
  }
  customElements.define('my-component', MyComponent)
</script>

It renders as:

<my-component>
  <!-- shadow root (open) -->
  <span class="hello">Hello</span>
</my-component>

You can't query the .hello element:

document.querySelector('.hello')    // undefined 😞
document.querySelectorAll('.hello') // empty 😞

But with kagekiri you can!

kagekiri.querySelector('.hello')    // <span> 😃
kagekiri.querySelectorAll('.hello') // [<span>] 😃

Your can even query across the shadow boundary!

kagekiri.querySelector('my-component .hello')   // <span> 😃
kagekiri.querySelector('my-component > .hello') // <span> 😃

API

closest

closest(selector: string, element: Node): Element | null

Find the closest ancestor of an element (or the element itself) matching the given CSS selector. Analogous to Element.closest

Parameters:

Name | Type | Description | :------ | :------ | :------ | selector | string | CSS selector | element | Node | target element to match against, and whose ancestors to match against |

Returns: Element | null


getElementById

getElementById(id: string, context?: DocumentOrShadowRoot): Element | null

Query for an element matching the given ID, or null if not found. Analogous to Document.getElementById

The default context is document. Choose another DocumentOrShadowRoot to query within that context.

Parameters:

Name | Type | Description | :------ | :------ | :------ | id | string | element ID | context? | DocumentOrShadowRoot | context to query in, or document by default |

Returns: Element | null


getElementsByClassName

getElementsByClassName(names: string, context?: Node): Element[]

Query for all elements matching a given class name, or multiple if a whitespace-separated list is provided. Analogous to Document.getElementsByClassName.

Unlike the standard API, this returns a static array of Elements rather than a live HTMLCollection.

The default context is document. Choose another node to query within that context.

Parameters:

Name | Type | Description | :------ | :------ | :------ | names | string | class name or whitespace-separated class names | context? | Node | context to query in, or document by default |

Returns: Element[]


getElementsByName

getElementsByName(name: string, context?: DocumentOrShadowRoot): Element[]

Query for all elements matching a given name. Analogous to Document.getElementsByName

The default context is document. Choose another DocumentOrShadowRoot to query within that context.

Unlike the standard API, this returns a static array of Elements rather than a live NodeList.

Parameters:

Name | Type | Description | :------ | :------ | :------ | name | string | element name attribute | context? | DocumentOrShadowRoot | context to query in, or document by default |

Returns: Element[]


getElementsByTagName

getElementsByTagName(tagName: string, context?: Node): Element[]

Query for all elements matching a given tag name. Analogous to Document.getElementsByTagName. The "*" query is supported.

Unlike the standard API, this returns a static array of Elements rather than a live HTMLCollection.

The default context is document. Choose another node to query within that context.

Parameters:

Name | Type | Description | :------ | :------ | :------ | tagName | string | name of the element tag | context? | Node | context to query in, or document by default |

Returns: Element[]


getElementsByTagNameNS

getElementsByTagNameNS(namespaceURI: string, localName: string, context?: Node): Element[]

Query for all elements matching a given tag name and namespace. Analogous to Document.getElementsByTagNameNS. The "*" query is supported.

Unlike the standard API, this returns a static array of Elements rather than a live NodeList.

The default context is document. Choose another node to query within that context.

Parameters:

Name | Type | Description | :------ | :------ | :------ | namespaceURI | string | namespace URI, or "*" for all | localName | string | local name, or "*" for all | context? | Node | context to query in, or document by default |

Returns: Element[]


matches

matches(selector: string, element: Node): boolean

Return true if the given Node matches the given CSS selector, or false otherwise. Analogous to Element.closest

Parameters:

Name | Type | Description | :------ | :------ | :------ | selector | string | CSS selector | element | Node | element to match against |

Returns: boolean


querySelector

querySelector(selector: string, context?: Node): Element | null

Query for a single element matching the CSS selector, or return null if not found. Analogous to Document.querySelector

The default context is document. Choose another element or DocumentOrShadowRoot to query within that context.

Parameters:

Name | Type | Description | :------ | :------ | :------ | selector | string | CSS selector | context? | Node | context to query in, or document by default |

Returns: Element | null


querySelectorAll

querySelectorAll(selector: string, context?: Node): Element[]

Query for all elements matching a CSS selector. Analogous to Document.querySelectorAll

The default context is document. Choose another node to query within that context.

Parameters:

Name | Type | Description | :------ | :------ | :------ | selector | string | CSS selector | context? | Node | context to query in, or document by default |

Returns: Element[]

How it works

kagekiri parses the CSS selector using postcss-selector-parser. Then it queries the entire DOM tree, traverses any shadowRoots it may find, and checks the selector from children to ancestors (the same way a browser would).

Note that it only works on open shadow DOM. Closed shadow DOM cannot be traversed.

Slotted elements are considered to be children of their slots (inside the shadow DOM) rather than children of their host components. If you don't want this behavior, you can use the normal DOM APIs (e.g. document.querySelector() or document.querySelectorAll()).

See the tests for full supported CSS features.

The name

kage (shadow) + 切り kiri (cut).

Roughly, "shadow-cutter."

Build

npm run build

Build TypeScript-based API docs using kagekiri.d.ts, inject them into the README:

npm run typedoc

Test

npm test

Debug:

npm run test:debug

Test with coverage:

npm run test:coverage

Lint:

npm run lint

Fix most lint issues:

npm run lint:fix

Test bundle size:

npm run test:bundlesize