aboutsummaryrefslogtreecommitdiffstats
path: root/src/event.js
blob: 8d54782f6f77f421f480bdfa556fd2e0cc94b6c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import EventTarget from './EventTarget.js'
import Element from './Element.js'
import {delimiter} from './regex.js'

// // Add events to elements
// ;[ 'click',
//   'dblclick',
//   'mousedown',
//   'mouseup',
//   'mouseover',
//   'mouseout',
//   'mousemove',
//   'mouseenter',
//   'mouseleave',
//   'touchstart',
//   'touchmove',
//   'touchleave',
//   'touchend',
//   'touchcancel' ].forEach(function (event) {
//     // add event to Element
//     Element.prototype[event] = function (f) {
//       if (f === null) {
//         off(this, event)
//       } else {
//         on(this, event, f)
//       }
//       return this
//     }
//   })

let listenerId = 0

// Add event binder in the SVG namespace
export function on (node, events, listener, binding, options) {
  var l = listener.bind(binding || node)
  var n = node instanceof EventTarget ? node.getEventTarget() : node

  // events can be an array of events or a string of events
  events = Array.isArray(events) ? events : events.split(delimiter)

  // ensure instance object for nodes which are not adopted
  n.instance = n.instance || {events: {}}

  // pull event handlers from the element
  var bag = n.instance.events

  // add id to listener
  if (!listener._svgjsListenerId) {
    listener._svgjsListenerId = ++listenerId
  }

  events.forEach(function (event) {
    var ev = event.split('.')[0]
    var ns = event.split('.')[1] || '*'

    // ensure valid object
    bag[ev] = bag[ev] || {}
    bag[ev][ns] = bag[ev][ns] || {}

    // reference listener
    bag[ev][ns][listener._svgjsListenerId] = l

    // add listener
    n.addEventListener(ev, l, options || false)
  })
}

// Add event unbinder in the SVG namespace
export function off (node, events, listener, options) {
  var n = node instanceof EventTarget ? node.getEventTarget() : node
  if (!n.instance) return

  // listener can be a function or a number
  if (typeof listener === 'function') {
    listener = listener._svgjsListenerId
    if (!listener) return
  }

  // pull event handlers from the element
  var bag = n.instance.events

  // events can be an array of events or a string or undefined
  events = Array.isArray(events) ? events : (events || '').split(delimiter)

  events.forEach(function (event) {
    var ev = event && event.split('.')[0]
    var ns = event && event.split('.')[1]
    var namespace, l

    if (listener) {
      // remove listener reference
      if (bag[ev] && bag[ev][ns || '*']) {
        // removeListener
        n.removeEventListener(ev, bag[ev][ns || '*'][listener], options || false)

        delete bag[ev][ns || '*'][listener]
      }
    } else if (ev && ns) {
      // remove all listeners for a namespaced event
      if (bag[ev] && bag[ev][ns]) {
        for (l in bag[ev][ns]) { off(n, [ev, ns].join('.'), l) }

        delete bag[ev][ns]
      }
    } else if (ns) {
      // remove all listeners for a specific namespace
      for (event in bag) {
        for (namespace in bag[event]) {
          if (ns === namespace) { off(n, [event, ns].join('.')) }
        }
      }
    } else if (ev) {
      // remove all listeners for the event
      if (bag[ev]) {
        for (namespace in bag[ev]) { off(n, [ev, namespace].join('.')) }

        delete bag[ev]
      }
    } else {
      // remove all listeners on a given node
      for (event in bag) { off(n, event) }

      n.instance.events = {}
    }
  })
}

export function dispatch (node, event, data) {
  var n = node instanceof EventTarget ? node.getEventTarget() : node

  // Dispatch event
  if (event instanceof window.Event) {
    n.dispatchEvent(event)
  } else {
    event = new window.CustomEvent(event, {detail: data, cancelable: true})
    n.dispatchEvent(event)
  }
  return event
}