diff options
Diffstat (limited to 'src/modules/core/event.js')
-rw-r--r-- | src/modules/core/event.js | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/src/modules/core/event.js b/src/modules/core/event.js new file mode 100644 index 0000000..2fcaf58 --- /dev/null +++ b/src/modules/core/event.js @@ -0,0 +1,119 @@ +import { delimiter } from './regex.js' +import { makeInstance } from '../../utils/adopter.js' + +let listenerId = 0 + +function getEvents (node) { + const n = makeInstance(node).getEventHolder() + if (!n.events) n.events = {} + return n.events +} + +function getEventTarget (node) { + return makeInstance(node).getEventTarget() +} + +function clearEvents (node) { + const n = makeInstance(node).getEventHolder() + if (n.events) n.events = {} +} + +// Add event binder in the SVG namespace +export function on (node, events, listener, binding, options) { + var l = listener.bind(binding || node) + var bag = getEvents(node) + var n = getEventTarget(node) + + // events can be an array of events or a string of events + events = Array.isArray(events) ? events : events.split(delimiter) + + // 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 bag = getEvents(node) + var n = getEventTarget(node) + + // listener can be a function or a number + if (typeof listener === 'function') { + listener = listener._svgjsListenerId + if (!listener) return + } + + // 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) } + + clearEvents(node) + } + }) +} + +export function dispatch (node, event, data) { + var n = 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 +} |