<commit_before># dom-delegator

<!--
    [![build status][1]][2]
    [![NPM version][3]][4]
    [![Coverage Status][5]][6]
    [![gemnasium Dependency Status][7]][8]
    [![Davis Dependency status][9]][10]
-->

<!-- [![browser support][11]][12] -->

Decorate elements with delegated events

## Example DOM

```js
var document = require("global/document")
var Delegator = require("dom-delegator")
var addEvent = require("dom-delegator/event")
var h = require("hyperscript")
var uuid = require("uuid")

var prefix = uuid()
var delegator = Delegator(document.body, {
    prefix: prefix
})

var elem = h("div.foo", [
    h("div.bar", "bar"),
    h("span.baz", "baz")
])
var bar = elem.querySelector(".bar")
var baz = elem.querySelector(".baz")
document.body.appendChild(elem)


// either add individual elems
addEvent(bar, {
    prefix: prefix,
    type: "click",
    name: "text-clicked",
    data: { type: "bar" }
})
addEvent(baz, {
    prefix: prefix,
    type: "click",
    name: "text-clicked",
    data: { type: "baz" }
})

// or add multiple
addEvent(elem, {
    prefix: prefix
    ".bar": {
        type: "click",
        name: "text-clicked",
        data: { type: "baz" }      
    } 
    ".baz": {
        type: "click",
        name: "text-clicked",
        data: { type: "baz" }
    }
})

delegator.on("text-clicked", function (data, ev) {
    var elem = ev.currentTarget
    var value = ev.currentValue
    var type = data.type

    console.log("doSomething", elem, value, type)
})
```

## Example data- attributes

```js
var document = require("global/document")
var Delegator = require("dom-delegator")
var h = require("hyperscript")
var uuid = require("uuid")

var prefix = uuid()
var delegator = Delegator(document.body, {
    prefix: prefix
})

var elem = h("div.foo", {
    "data-event-prefix": prefix
}, [
    h("div.bar", { 
        "data-click": "text-clicked:bar"
    }, "bar"),
    h("div.baz", {
        "data-click": "text-clicked:baz"
    }, "baz")
])
document.body.appendChild(elem)

delegator.on("text-clicked", function (data, ev) {
    var elem = ev.currentTarget
    var value = ev.currentValue
    var type = data

    console.log("doSomething", elem, value, type)
})
```

## Example JSONML

```js
var document = require("global/document")
var Delegator = require("dom-delegator")
var dom = require("jsonml-dom")
var Event = require("jsonml-event")
var uuid = require("uuid")

var prefix = uuid()
var delegator = Delegator(document.body, {
    prefix: prefix
})
var event = Event(prefix)

var elem = dom(["div.foo", [
    ["div.bar", { 
        "click": event("text-clicked", { type: "bar" })
    }, "bar"],
    ["div.baz", {
        "click": event("text-clicked", { type: "baz" })
    }, "baz"]
]])
document.body.appendChild(elem)

delegator.on("text-clicked", function (data, ev) {
    var elem = ev.currentTarget
    var value = ev.currentValue
    var type = data.type

    console.log("doSomething", elem, value, type)
})
```

## Installation

`npm install dom-delegator`

## Contributors

 - Raynos

## MIT Licenced

  [1]: https://secure.travis-ci.org/Raynos/dom-delegator.png
  [2]: https://travis-ci.org/Raynos/dom-delegator<commit_msg>show concept<commit_after># dom-delegator

<!--
    [![build status][1]][2]
    [![NPM version][3]][4]
    [![Coverage Status][5]][6]
    [![gemnasium Dependency Status][7]][8]
    [![Davis Dependency status][9]][10]
-->

<!-- [![browser support][11]][12] -->

Decorate elements with delegated events

## Example DOM

```js
var document = require("global/document")
var Delegator = require("dom-delegator")
var addEvent = require("dom-delegator/event")
var h = require("hyperscript")
var uuid = require("uuid")

var prefix = uuid()
var delegator = Delegator(document.body, {
    prefix: prefix
})

var elem = h("div.foo", [
    h("div.bar", "bar"),
    h("span.baz", "baz")
])
var bar = elem.querySelector(".bar")
var baz = elem.querySelector(".baz")
document.body.appendChild(elem)


// either add individual elems
addEvent(bar, {
    prefix: prefix,
    type: "click",
    name: "text-clicked",
    data: { type: "bar" }
})
addEvent(baz, {
    prefix: prefix,
    type: "click",
    name: "text-clicked",
    data: { type: "baz" }
})

// or add multiple
addEvent(elem, {
    prefix: prefix
    ".bar": {
        type: "click",
        name: "text-clicked",
        data: { type: "baz" }      
    } 
    ".baz": {
        type: "click",
        name: "text-clicked",
        data: { type: "baz" }
    }
})

delegator.on("text-clicked", function (data, ev) {
    var elem = ev.currentTarget
    var value = ev.currentValue
    var type = data.type

    console.log("doSomething", elem, value, type)
})
```

## Example data- attributes

```js
var document = require("global/document")
var Delegator = require("dom-delegator")
var h = require("hyperscript")
var uuid = require("uuid")

var prefix = uuid()
var delegator = Delegator(document.body, {
    prefix: prefix
})

var elem = h("div.foo", {
    "data-event-prefix": prefix
}, [
    h("div.bar", { 
        "data-click": "text-clicked:bar"
    }, "bar"),
    h("div.baz", {
        "data-click": "text-clicked:baz"
    }, "baz")
])
document.body.appendChild(elem)

delegator.on("text-clicked", function (data, ev) {
    var elem = ev.currentTarget
    var value = ev.currentValue
    var type = data

    console.log("doSomething", elem, value, type)
})
```

## Example JSONML

```js
var document = require("global/document")
var Delegator = require("dom-delegator")
var dom = require("jsonml-dom")
var Event = require("jsonml-event")
var uuid = require("uuid")

var prefix = uuid()
var delegator = Delegator(document.body, {
    prefix: prefix
})
var event = Event(prefix)

var elem = dom(["div.foo", [
    ["div.bar", { 
        "click": event("text-clicked", { type: "bar" })
    }, "bar"],
    ["div.baz", {
        "click": event("text-clicked", { type: "baz" })
    }, "baz"]
]])
document.body.appendChild(elem)

delegator.on("text-clicked", function (data, ev) {
    var elem = ev.currentTarget
    var value = ev.currentValue
    var type = data.type

    console.log("doSomething", elem, value, type)
})
```

## Concept.

The concept behind `dom-delegator` is to seperate declaring
  which UI elements trigger well named user input events from 
  the event handling.

For example you might have an `input.js` where you handle user
  input, based on well named, non-DOM specific events.

```js
// input.js
module.exports = Input

function Input(state, delegator) {
    // when the input event todo addition occurs
    // create a fresh item and add it
    delegator.on("todoAdded", function (data, ev) {
        var value = ev.currentValue
        var todo = { title: value, completed: false }
        state.todos.push(todo)
    })

    // when the input event todo removal occurs
    // find the item and delete it from the list
    delegator.on("todoRemoved", function (data, ev) {
        var id = data
        var index = -1
        state.todos.some(function (todo, itemIndex) {
            if (todo.id() === id) {
                index = itemIndex
                return true
            }
        })

        state.todos.splice(index, 1)
    })
}
```

One thing to notice here is that the input handling is coupled
  to keypress or click events. Those are implementation details
  of the declarative UI. The input handling has been described 
  in a loosely coupled way.

The only coupling is that addition is based on the current value
  of the UI element that triggered the `todoAdded` event.

Since we have defined our input handling, we now need to add
  the declarative event hooks to our UI.

We will use `HTML` and the `data- attributes` style interface
  for the delegator

```html
// ui.html
<ul>
    <li data-id="4">
        <span class="todo-title">Some todo</span>
        <button data-click="todoRemoved:4">Remove</button>
    </li>
</ul>
<input class="add-todo" data-submit="todoAdded" />
```

Here we have decorated the todo item UI with a click event.
  whenever it is clicked it will emit the `todoRemoved` event
  and data will be set to the value after the `:` in this case
  `4`.

We also decorated the input with the `todoAdded` event.

The contract between the input handler and the UI is fairly
  loosely defined and it should be possible to refactor the UI
  without breaking the input handler. You can make the
  `todoAdded` event more generic like:

```html
// ui.html

<div class="todo-addition" data-submit="todoAdded">
    <input class="add-todo" name="title" />
</div>
```

Then update the input handler

```js
// when the input event todo addition occurs
// create a fresh item and add it
delegator.on("todoAdded", function (data, ev) {
    var title = ev.currentValue.title
    var todo = { title: title, completed: false }
    state.todos.push(todo)
})
```

We have now bound the `todoAdded` event less tightly to 
  `currentValue` and as long as there is some kind of `input`
  or `textarea` or `custom element` with a name called `'title'`
  the input handling code will still work.

## Installation

`npm install dom-delegator`

## Contributors

 - Raynos

## MIT Licenced

  [1]: https://secure.travis-ci.org/Raynos/dom-delegator.png
  [2]: https://travis-ci.org/Raynos/dom-delegator
{'fraction_non_alphanumeric': 0.15598013816925735, 'fraction_numerical': 0.0042098445595854924, 'mean_word_length': 3.134315037929496, 'pattern_counts': {'":': 14, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5841562', 'n_tokens_mistral': 3118, 'n_tokens_neox': 3065, 'n_words': 886}