
Security News
Security Community Slams MIT-linked Report Claiming AI Powers 80% of Ransomware
Experts push back on new claims about AI-driven ransomware, warning that hype and sponsored research are distorting how the threat is understood.
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 | ✅ | 
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)
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> 😃
▸ 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
| Name | Type | Description | 
|---|---|---|
| selector | string | CSS selector | 
| element | Node | target element to match against, and whose ancestors to match against | 
Returns: Element | null
▸ 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.
| Name | Type | Description | 
|---|---|---|
| id | string | element ID | 
| context? | DocumentOrShadowRoot | context to query in, or documentby default | 
Returns: Element | null
▸ 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.
| Name | Type | Description | 
|---|---|---|
| names | string | class name or whitespace-separated class names | 
| context? | Node | context to query in, or documentby default | 
Returns: Element[]
▸ 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.
| Name | Type | Description | 
|---|---|---|
| name | string | element name attribute | 
| context? | DocumentOrShadowRoot | context to query in, or documentby default | 
Returns: Element[]
▸ 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.
| Name | Type | Description | 
|---|---|---|
| tagName | string | name of the element tag | 
| context? | Node | context to query in, or documentby default | 
Returns: Element[]
▸ 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.
| Name | Type | Description | 
|---|---|---|
| namespaceURI | string | namespace URI, or "*"for all | 
| localName | string | local name, or "*"for all | 
| context? | Node | context to query in, or documentby default | 
Returns: Element[]
▸ matches(selector: string, element: Node): boolean
Return true if the given Node matches the given CSS selector, or false otherwise. Analogous to
Element.closest
| Name | Type | Description | 
|---|---|---|
| selector | string | CSS selector | 
| element | Node | element to match against | 
Returns: boolean
▸ 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.
| Name | Type | Description | 
|---|---|---|
| selector | string | CSS selector | 
| context? | Node | context to query in, or documentby default | 
Returns: Element | null
▸ 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.
| Name | Type | Description | 
|---|---|---|
| selector | string | CSS selector | 
| context? | Node | context to query in, or documentby default | 
Returns: Element[]
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.
陰 kage (shadow) + 切り kiri (cut).
Roughly, "shadow-cutter."
npm run build
Build TypeScript-based API docs using kagekiri.d.ts, inject them into the README:
npm run typedoc
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
FAQs
Shadow DOM-piercing querySelector/querySelectorAll implementation
We found that kagekiri demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Experts push back on new claims about AI-driven ransomware, warning that hype and sponsored research are distorting how the threat is understood.

Security News
Ruby's creator Matz assumes control of RubyGems and Bundler repositories while former maintainers agree to step back and transfer all rights to end the dispute.

Research
/Security News
Socket researchers found 10 typosquatted npm packages that auto-run on install, show fake CAPTCHAs, fingerprint by IP, and deploy a credential stealer.