{"id":31920217,"url":"https://github.com/aegisjsproject/commands","last_synced_at":"2026-01-20T17:02:24.764Z","repository":{"id":317081316,"uuid":"1065884117","full_name":"AegisJSProject/commands","owner":"AegisJSProject","description":"A lightweight command system for handling DOM interactions through `command` events and the `commandfor` attribute.","archived":false,"fork":false,"pushed_at":"2025-10-09T15:19:00.000Z","size":183,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-10-10T15:35:04.179Z","etag":null,"topics":["aegisjsproject","commands","dom","invoker","invoker-commans"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@aegisjsproject/commands","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AegisJSProject.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"shgysk8zer0","liberapay":"shgysk8zer0"}},"created_at":"2025-09-28T16:12:27.000Z","updated_at":"2025-10-08T21:49:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"510358dd-4a69-4147-8273-db87f52b3daa","html_url":"https://github.com/AegisJSProject/commands","commit_stats":null,"previous_names":["aegisjsproject/commands"],"tags_count":1,"template":false,"template_full_name":"shgysk8zer0/npm-template","purl":"pkg:github/AegisJSProject/commands","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AegisJSProject%2Fcommands","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AegisJSProject%2Fcommands/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AegisJSProject%2Fcommands/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AegisJSProject%2Fcommands/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AegisJSProject","download_url":"https://codeload.github.com/AegisJSProject/commands/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AegisJSProject%2Fcommands/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279017013,"owners_count":26085951,"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","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["aegisjsproject","commands","dom","invoker","invoker-commans"],"created_at":"2025-10-13T21:56:24.100Z","updated_at":"2025-10-13T21:56:29.248Z","avatar_url":"https://github.com/AegisJSProject.png","language":"JavaScript","funding_links":["https://github.com/sponsors/shgysk8zer0","https://liberapay.com/shgysk8zer0","https://liberapay.com/shgysk8zer0/donate"],"categories":[],"sub_categories":[],"readme":"# `@aegisjsproject/commands`\n\nA lightweight command system for handling DOM interactions through `command` events and the `commandfor` attribute.\n\n[![CodeQL](https://github.com/AegisJSProject/commands/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/AegisJSProject/commands/actions/workflows/codeql-analysis.yml)\n![Node CI](https://github.com/AegisJSProject/commands/workflows/Node%20CI/badge.svg)\n![Lint Code Base](https://github.com/AegisJSProject/commands/workflows/Lint%20Code%20Base/badge.svg)\n\n[![GitHub license](https://img.shields.io/github/license/AegisJSProject/commands.svg)](https://github.com/AegisJSProject/commands/blob/master/LICENSE)\n[![GitHub last commit](https://img.shields.io/github/last-commit/AegisJSProject/commands.svg)](https://github.com/AegisJSProject/commands/commits/master)\n[![GitHub release](https://img.shields.io/github/release/AegisJSProject/commands?logo=github)](https://github.com/AegisJSProject/commands/releases)\n[![GitHub Sponsors](https://img.shields.io/github/sponsors/shgysk8zer0?logo=github)](https://github.com/sponsors/shgysk8zer0)\n\n[![npm](https://img.shields.io/npm/v/@aegisjsproject/commands)](https://www.npmjs.com/package/@aegisjsproject/commands)\n![node-current](https://img.shields.io/node/v/@aegisjsproject/commands)\n![npm bundle size gzipped](https://img.shields.io/bundlephobia/minzip/@aegisjsproject/commands)\n[![npm](https://img.shields.io/npm/dw/@aegisjsproject/commands?logo=npm)](https://www.npmjs.com/package/@aegisjsproject/commands)\n\n[![GitHub followers](https://img.shields.io/github/followers/AegisJSProject.svg?style=social)](https://github.com/AegisJSProject)\n![GitHub forks](https://img.shields.io/github/forks/AegisJSProject/commands.svg?style=social)\n![GitHub stars](https://img.shields.io/github/stars/AegisJSProject/commands.svg?style=social)\n[![Twitter Follow](https://img.shields.io/twitter/follow/shgysk8zer0.svg?style=social)](https://twitter.com/shgysk8zer0)\n\n[![Donate using Liberapay](https://img.shields.io/liberapay/receives/shgysk8zer0.svg?logo=liberapay)](https://liberapay.com/shgysk8zer0/donate \"Donate using Liberapay\")\n- - -\n\n- [Code of Conduct](./.github/CODE_OF_CONDUCT.md)\n- [Contributing](./.github/CONTRIBUTING.md)\n\u003c!-- - [Security Policy](./.github/SECURITY.md) --\u003e\n\n## Core Concept\n\nThis library is based on the [Invoker Commands API](https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API).\nElements with a `commandfor` attribute automatically dispatch `command` events to their target elements when triggered. The\nlibrary handles these events with built-in commands or custom registered handlers.\n\n```html\n\u003c!-- Using Built-In Commands --\u003e\n\u003cbutton commandfor=\"my-element\" command=\"show-modal\"\u003eShow Modal\u003c/button\u003e\n\u003cdialog id=\"my-element\"\u003e\n  \u003cp\u003eHello, World!\u003c/p\u003e\n  \u003cbutton commandfor=\"my-element\" command=\"close\"\u003eClose\u003c/button\u003e\n\u003c/dialog\u003e\n\u003c!-- Using Custom Commands --\u003e\n\u003cbutton commandfor=\"another-el\" command=\"--aegis-command-remove\"\u003eRemove Element\u003c/button\u003e\n\u003cdiv id=\"another-el\"\u003eThis content will be removed.\u003c/div\u003e\n```\n\n## Custom, pre-registered Commands\n\n- `--aegis-command-hide`/`--aegis-command-unhide` - Controls hidden attribute\n- `--aegis-command-disable`/`--aegis-command-enable` - Controls disabled attribute\n- `--aegis-command-remove` - Removes element from DOM\n- `--aegis-command-scroll-into-view` - Scrolls element into view (respects `prefers-reduced-motion`)\n- `--aegis-command-request-fullscreen`/`--aegis-command-exit-fullscreen`/`--aegis-command-toggle-fullscreen` - Fullscreen API\n- `--aegis-command-show-picker` - Opens input picker (date, color, etc.)\n- `--aegis-command-step-up`/`--aegis-command-step-down` - Steps numeric inputs\n- `--aegis-command-open-details`/`--aegis-command-close-details`/`--aegis-command-toggle-details` - Controls \u003cdetails\u003e elements\n- `--aegis-command-play-media`/`--aegis-command-pause-media` - Media element controls\n- `--aegis-command-request-picture-in-picture` - Picture-in-picture for videos\n- `--aegis-command-copy-text` - Copies element's textContent to clipboard\n\n## API\n\n### `observeCommands(target?)`\nSets up automatic command handling. Call once during initialization.\n\n```js\nimport { observeCommands } from './commands.js';\nobserveCommands(); // Observes document.body by default\n```\n\n### `registerCommand(command, callback)`\nRegisters custom commands (must be prefixed with `--`).\n\n```js\nimport { registerCommand } from './commands.js';\n\nregisterCommand('--my-command', (event) =\u003e {\n  console.log('Custom command triggered on', event.target);\n});\n```\n\n### `createCommand(callback)`\nGenerates a unique command string and registers the callback.\n\n```js\nimport { createCommand } from './commands.js';\n\nconst cmd = createCommand((event) =\u003e {\n  event.target.style.color = 'red';\n});\n// Use `cmd` as the command attribute value\n```\n\n### `command(callback)`\nConvenience function that returns a complete attribute string.\n\n```js\nimport { command } from './commands.js';\n\nelement.innerHTML = `\u003cbutton ${command(e =\u003e alert('clicked'))}\u003eClick me\u003c/button\u003e`;\n```\n\n### `listenForCommands(target, init?)`\nManually add command listener to specific elements.\n\n```js\nimport { listenForCommands } from './commands.js';\nlistenForCommands(myElement, { once: true });\n```\n\n## Usage Patterns\n\n### Basic Setup\n```js\nimport { observeCommands } from './commands.js';\nobserveCommands();\n```\n\n### Custom Commands\n```js\nimport { observeCommands, registerCommand } from './commands.js';\n\nregisterCommand('--toggle-class', (event) =\u003e {\n  event.target.classList.toggle('active');\n});\n\nobserveCommands();\n```\n\n### Dynamic Command Generation\n```js\nimport { observeCommands, createCommand } from './commands.js';\n\nconst toggleColor = createCommand((event) =\u003e {\n  const colors = ['red', 'blue', 'green'];\n  const current = colors.indexOf(event.target.style.color);\n  event.target.style.color = colors[(current + 1) % colors.length];\n});\n\ndocument.body.innerHTML += `\u003cbutton commandfor=\"target\" command=\"${toggleColor}\"\u003eChange Color\u003c/button\u003e`;\nobserveCommands();\n```\n\n## CommandEvent Properties\n\nCommand events extend regular events with:\n- `source` - The element that triggered the command (the button/trigger)\n- `command` - The command string that was executed#\n\n# Memory Considerations\n\n\u003e [!WARNING]\n\u003e Command listeners are not automatically removed when elements are deleted. If you're frequently adding/removing elements with `commandfor` attributes in long-running applications, consider using `listenForCommands()` with `{ once: true }` for one-time interactions, or manually manage listeners for dynamic content.\n\n## Security\n\nCommand registration closes automatically after initial setup. Call `closeCommandRegistration()` explicitly if needed for additional security.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faegisjsproject%2Fcommands","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faegisjsproject%2Fcommands","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faegisjsproject%2Fcommands/lists"}