(dispatch)
| 571 | }; |
| 572 | |
| 573 | function d3_dispatch_event(dispatch) { |
| 574 | var listeners = [], |
| 575 | listenerByName = new d3_Map; |
| 576 | |
| 577 | function event() { |
| 578 | var z = listeners, // defensive reference |
| 579 | i = -1, |
| 580 | n = z.length, |
| 581 | l; |
| 582 | while (++i < n) if (l = z[i].on) l.apply(this, arguments); |
| 583 | return dispatch; |
| 584 | } |
| 585 | |
| 586 | event.on = function(name, listener) { |
| 587 | var l = listenerByName.get(name), |
| 588 | i; |
| 589 | |
| 590 | // return the current listener, if any |
| 591 | if (arguments.length < 2) return l && l.on; |
| 592 | |
| 593 | // remove the old listener, if any (with copy-on-write) |
| 594 | if (l) { |
| 595 | l.on = null; |
| 596 | listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); |
| 597 | listenerByName.remove(name); |
| 598 | } |
| 599 | |
| 600 | // add the new listener, if any |
| 601 | if (listener) listeners.push(listenerByName.set(name, {on: listener})); |
| 602 | |
| 603 | return dispatch; |
| 604 | }; |
| 605 | |
| 606 | return event; |
| 607 | } |
| 608 | // TODO align |
| 609 | d3.format = function(specifier) { |
| 610 | var match = d3_format_re.exec(specifier), |
no test coverage detected