{"id":18949979,"url":"https://github.com/salesforce/kagekiri","last_synced_at":"2025-04-12T19:49:30.793Z","repository":{"id":36113881,"uuid":"201091420","full_name":"salesforce/kagekiri","owner":"salesforce","description":"Shadow DOM-piercing query APIs for the browser.","archived":false,"fork":false,"pushed_at":"2025-02-18T02:33:46.000Z","size":939,"stargazers_count":90,"open_issues_count":4,"forks_count":9,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-09T23:04:46.117Z","etag":null,"topics":["selector","shadow-dom"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/salesforce.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-07T16:57:47.000Z","updated_at":"2025-04-04T04:39:20.000Z","dependencies_parsed_at":"2023-09-24T16:58:16.071Z","dependency_job_id":"f5754b9f-d726-4c73-9ac7-1209ee4925ad","html_url":"https://github.com/salesforce/kagekiri","commit_stats":{"total_commits":100,"total_committers":6,"mean_commits":"16.666666666666668","dds":0.47,"last_synced_commit":"978abc24d5ed4ab2b6d5a8a888373634936b7ce9"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salesforce%2Fkagekiri","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salesforce%2Fkagekiri/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salesforce%2Fkagekiri/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salesforce%2Fkagekiri/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/salesforce","download_url":"https://codeload.github.com/salesforce/kagekiri/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248125623,"owners_count":21051770,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["selector","shadow-dom"],"created_at":"2024-11-08T13:20:06.233Z","updated_at":"2025-04-12T19:49:30.774Z","avatar_url":"https://github.com/salesforce.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"kagekiri\n====\n\nShadow DOM-piercing query APIs. Supports:\n\n| API                      |     Interface     | Support |\n|--------------------------|-------------------|:------:|\n| `querySelector`          | Element, Document |    ✅    |\n| `querySelectorAll`       | Element, Document |    ✅    |\n| `getElementsByClassName` | Element, Document |    ✅    |\n| `getElementsByTagName`   | Element, Document |    ✅    |\n| `getElementsByTagNameNS` | Element, Document |    ✅    |\n| `getElementById`         |      Document     |    ✅    |\n| `getElementsByName`      |      Document     |    ✅    |\n| `matches`                |      Element      |    ✅    |\n| `closest`                |      Element      |    ✅    |\n\n\nUsage\n---\n\nInstall:\n\n```sh\nnpm install --save kagekiri\n```\n\nQuery the `document` or a specific element:\n\n```javascript\nimport { querySelector, querySelectorAll } from 'kagekiri'\n\n// query the document\nconst elements = querySelectorAll('.container button')\nconst element = querySelector('.container button')\n\n// or a specific element\nconst elements = querySelectorAll('button', otherElement)\nconst element = querySelector('button', otherElement)\n```\n\nExample\n---\n\nA custom element:\n\n```html\n\u003cmy-component\u003e\u003c/my-component\u003e\n\u003cscript\u003e\n  class MyComponent extends HTMLElement {\n    constructor() {\n      super()\n      const shadowRoot = this.attachShadow({mode: 'open'})\n      shadowRoot.innerHTML = '\u003cspan class=\"hello\"\u003eHello\u003c/span\u003e'\n    }\n  }\n  customElements.define('my-component', MyComponent)\n\u003c/script\u003e\n```\n\nIt renders as:\n\n```html\n\u003cmy-component\u003e\n  \u003c!-- shadow root (open) --\u003e\n  \u003cspan class=\"hello\"\u003eHello\u003c/span\u003e\n\u003c/my-component\u003e\n```\n\nYou can't query the `.hello` element:\n\n```js\ndocument.querySelector('.hello')    // undefined 😞\ndocument.querySelectorAll('.hello') // empty 😞\n```\n\nBut with `kagekiri` you can!\n\n```js\nkagekiri.querySelector('.hello')    // \u003cspan\u003e 😃\nkagekiri.querySelectorAll('.hello') // [\u003cspan\u003e] 😃\n```\n\nYour can even query _across_ the shadow boundary!\n\n```js\nkagekiri.querySelector('my-component .hello')   // \u003cspan\u003e 😃\nkagekiri.querySelector('my-component \u003e .hello') // \u003cspan\u003e 😃\n```\n\n## API\n\n### closest\n\n▸ **closest**(`selector`: *string*, `element`: Node): Element \\| *null*\n\nFind the closest ancestor of an element (or the element itself) matching the given CSS selector. Analogous to\n[`Element.closest`](https://developer.mozilla.org/en-US/docs/Web/API/Element/closest)\n\n#### Parameters:\n\nName | Type | Description |\n:------ | :------ | :------ |\n`selector` | *string* | CSS selector   |\n`element` | Node | target element to match against, and whose ancestors to match against    |\n\n**Returns:** Element \\| *null*\n\n___\n\n### getElementById\n\n▸ **getElementById**(`id`: *string*, `context?`: DocumentOrShadowRoot): Element \\| *null*\n\nQuery for an element matching the given ID, or null if not found. Analogous to\n[`Document.getElementById`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById)\n\nThe default `context` is `document`. Choose another DocumentOrShadowRoot to query within that context.\n\n#### Parameters:\n\nName | Type | Description |\n:------ | :------ | :------ |\n`id` | *string* | element ID   |\n`context?` | DocumentOrShadowRoot | context to query in, or `document` by default    |\n\n**Returns:** Element \\| *null*\n\n___\n\n### getElementsByClassName\n\n▸ **getElementsByClassName**(`names`: *string*, `context?`: Node): Element[]\n\nQuery for all elements matching a given class name, or multiple if a whitespace-separated list is provided.\nAnalogous to\n[`Document.getElementsByClassName`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName).\n\nUnlike the standard API, this returns a static array of Elements rather than a live HTMLCollection.\n\nThe default `context` is `document`. Choose another node to query within that context.\n\n#### Parameters:\n\nName | Type | Description |\n:------ | :------ | :------ |\n`names` | *string* | class name or whitespace-separated class names   |\n`context?` | Node | context to query in, or `document` by default    |\n\n**Returns:** Element[]\n\n___\n\n### getElementsByName\n\n▸ **getElementsByName**(`name`: *string*, `context?`: DocumentOrShadowRoot): Element[]\n\nQuery for all elements matching a given name. Analogous to\n[`Document.getElementsByName`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByName)\n\nThe default `context` is `document`. Choose another DocumentOrShadowRoot to query within that context.\n\nUnlike the standard API, this returns a static array of Elements rather than a live NodeList.\n\n#### Parameters:\n\nName | Type | Description |\n:------ | :------ | :------ |\n`name` | *string* | element name attribute   |\n`context?` | DocumentOrShadowRoot | context to query in, or `document` by default    |\n\n**Returns:** Element[]\n\n___\n\n### getElementsByTagName\n\n▸ **getElementsByTagName**(`tagName`: *string*, `context?`: Node): Element[]\n\nQuery for all elements matching a given tag name. Analogous to\n[`Document.getElementsByTagName`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByTagName).\nThe `\"*\"` query is supported.\n\nUnlike the standard API, this returns a static array of Elements rather than a live HTMLCollection.\n\nThe default `context` is `document`. Choose another node to query within that context.\n\n#### Parameters:\n\nName | Type | Description |\n:------ | :------ | :------ |\n`tagName` | *string* | name of the element tag   |\n`context?` | Node | context to query in, or `document` by default    |\n\n**Returns:** Element[]\n\n___\n\n### getElementsByTagNameNS\n\n▸ **getElementsByTagNameNS**(`namespaceURI`: *string*, `localName`: *string*, `context?`: Node): Element[]\n\nQuery for all elements matching a given tag name and namespace. Analogous to\n[`Document.getElementsByTagNameNS`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByTagNameNS).\nThe `\"*\"` query is supported.\n\nUnlike the standard API, this returns a static array of Elements rather than a live NodeList.\n\nThe default `context` is `document`. Choose another node to query within that context.\n\n#### Parameters:\n\nName | Type | Description |\n:------ | :------ | :------ |\n`namespaceURI` | *string* | namespace URI, or `\"*\"` for all   |\n`localName` | *string* | local name, or `\"*\"` for all   |\n`context?` | Node | context to query in, or `document` by default    |\n\n**Returns:** Element[]\n\n___\n\n### matches\n\n▸ **matches**(`selector`: *string*, `element`: Node): *boolean*\n\nReturn true if the given Node matches the given CSS selector, or false otherwise. Analogous to\n[`Element.closest`](https://developer.mozilla.org/en-US/docs/Web/API/Element/closest)\n\n#### Parameters:\n\nName | Type | Description |\n:------ | :------ | :------ |\n`selector` | *string* | CSS selector   |\n`element` | Node | element to match against    |\n\n**Returns:** *boolean*\n\n___\n\n### querySelector\n\n▸ **querySelector**(`selector`: *string*, `context?`: Node): Element \\| *null*\n\nQuery for a single element matching the CSS selector, or return null if not found. Analogous to\n[`Document.querySelector`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)\n\nThe default `context` is `document`. Choose another element or DocumentOrShadowRoot to query within that context.\n\n#### Parameters:\n\nName | Type | Description |\n:------ | :------ | :------ |\n`selector` | *string* | CSS selector   |\n`context?` | Node | context to query in, or `document` by default    |\n\n**Returns:** Element \\| *null*\n\n___\n\n### querySelectorAll\n\n▸ **querySelectorAll**(`selector`: *string*, `context?`: Node): Element[]\n\nQuery for all elements matching a CSS selector. Analogous to\n[`Document.querySelectorAll`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll)\n\nThe default `context` is `document`. Choose another node to query within that context.\n\n#### Parameters:\n\nName | Type | Description |\n:------ | :------ | :------ |\n`selector` | *string* | CSS selector   |\n`context?` | Node | context to query in, or `document` by default    |\n\n**Returns:** Element[]\n\nHow it works\n---\n\n`kagekiri` parses the CSS selector using [postcss-selector-parser](https://www.npmjs.com/package/postcss-selector-parser). Then it queries the entire DOM tree, traverses any `shadowRoot`s it may find, and checks the selector from children to ancestors (the same way a browser would).\n\nNote that it only works on open shadow DOM. Closed shadow DOM cannot be traversed.\n\nSlotted 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()`).\n\nSee the tests for full supported CSS features.\n\nThe name\n---\n\n陰 _kage_ (shadow) + 切り _kiri_ (cut).\n\nRoughly, \"shadow-cutter.\"\n\nBuild\n---\n\n```sh\nnpm run build\n```\n\nBuild TypeScript-based API docs using `kagekiri.d.ts`, inject them into the README:\n\n```sh\nnpm run typedoc\n```\n\nTest\n---\n\n```sh\nnpm test\n```\n\nDebug:\n\n```sh\nnpm run test:debug\n```\n\nTest with coverage:\n\n```sh\nnpm run test:coverage\n```\n\nLint:\n\n```sh\nnpm run lint\n```\n\nFix most lint issues:\n\n```sh\nnpm run lint:fix\n```\n\nTest bundle size:\n\n```sh\nnpm run test:bundlesize\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalesforce%2Fkagekiri","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsalesforce%2Fkagekiri","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalesforce%2Fkagekiri/lists"}