# Command Registry

Source: https://developers.inkdrop.app/modules/command-registry

Associates listener functions with commands in a context-sensitive way using DOM node.
Available as `env.commands` on the [Environment](https://developers.inkdrop.app/modules/environment) passed to `activate(env)`.

The global command registry facilitates a style of event handling known as event delegation. Inkdrop commands are expressed as custom DOM events that can be invoked on the currently focused element via a key binding.
Rather than binding listeners for command events directly to DOM nodes, you instead register command event listeners globally on `inkdrop.commands` and constrain them to specific kinds of elements with DOM nodes.

Command names must follow the `namespace:action` pattern, where `namespace` will typically be the name of your package, and `action` describes the behavior of your command.
If either part consists of multiple words, these must be separated by hyphens. E.g. `awesome-package:turn-it-up-to-eleven`.
All words should be lowercased.

As the event bubbles upward through the DOM, all registered event listeners with matching selectors are invoked in order of specificity.
In the event of a specificity tie, the most recently registered listener is invoked first.
This mirrors the "cascade" semantics of CSS.
Event listeners are invoked in the context of the current DOM node, meaning `this` always points at `event.currentTarget`.
As is normally the case with DOM events, `stopPropagation` and `stopImmediatePropagation` can be used to terminate the bubbling process and prevent invocation of additional listeners.

---

## Register a command `add(target, commandName, callback)`

Add a command listener associated with a DOM node.

### Parameters

- **target** (DOM node, required)

  A DOM node.
- **commandName** (string, required)

  A string indicating the command's name, e.g., `user:insert-date`.
- **callback(event)** (function, required)

  A function called when the command is invoked on an element matching the selector. It references the matching DOM node.

Here is a command that inserts the current date in an editor:

```js
env.commands.add(
  document.body,
  'custom:insert-date',
  (event) => {
    const { editingNote } = env.store.getState()
    const body = editingNote.body + '\n' + new Date().toLocaleString()
    env.store.dispatch(actions.editingNote.update({ body }))
    env.store.dispatch(actions.editor.change(true))
  }
)
```

---

## Add multiple commands `add(target, commands)`

Add multiple command listeners associated with a DOM node.

### Parameters

- **target** (DOM node, required)

  A DOM node.
- **commands** (object, required)

  An object mapping command names like `user:insert-date` to listener functions.

```js
env.commands.add(document.body, {
  'custom:insert-date': () => {
    const { editingNote } = env.store.getState()
    const body = editingNote.body + '\n' + new Date().toLocaleString()
    env.store.dispatch(actions.editingNote.update({ body }))
    env.store.dispatch(actions.editor.change(true))
  }
})
```

---

## Dispatch the given command `dispatch(target, commandName, detail)`

Simulate the dispatch of a command on a DOM node.

This is useful for testing, especially when simulating a command's invocation on a detached DOM node. Otherwise, the DOM node must be attached to the document so the event can bubble up to the root node.

### Parameters

- **target** (DOM node, required)

  The DOM node to start the command event bubbling.
- **commandName** (string, required)

  A string indicating the command's name.
- **detail** (object)

  Parameters to be passed.

```js
env.commands.dispatch(document.body, 'core:save-note')
```
