Skip to content
Shadow DOM-piercing querySelector()/querySelectorAll() implementation.
JavaScript
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci
src
test
.gitignore
CODE_OF_CONDUCT.md
LICENSE
README.md
karma.conf.js
package-lock.json
package.json
rollup.config.js

README.md

kagekiri build status

Shadow DOM-piercing querySelector() / querySelectorAll() implementation.

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> 😃

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 querySelector()/querySelectorAll() API.

See the tests for full supported CSS features.

The name

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

Roughly, "shadow-cutter."

Build

npm run build

Test

npm test

Debug:

npm run test:debug

Lint:

npm run lint

Fix most lint issues:

npm run lint:fix
You can’t perform that action at this time.