Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/bootstrap.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorJohann-S <johann.servoire@gmail.com>2017-08-22 19:47:54 +0300
committerXhmikosR <xhmikosr@gmail.com>2019-02-20 23:05:45 +0300
commit00ca7811718ee7259090be3edaf33a8ea4632876 (patch)
tree7be080c16ba2355d0f882cfcfc154e4fd69f2fe5 /js
parent744071040eeaa6785d558f7a11c469d1a7674b32 (diff)
Add namespaced events
Diffstat (limited to 'js')
-rw-r--r--js/src/dom/eventHandler.js120
1 files changed, 102 insertions, 18 deletions
diff --git a/js/src/dom/eventHandler.js b/js/src/dom/eventHandler.js
index 9b9d369028..cc792adab5 100644
--- a/js/src/dom/eventHandler.js
+++ b/js/src/dom/eventHandler.js
@@ -57,38 +57,122 @@ if (!window.Event || typeof window.Event !== 'function') {
window.Event.prototype = origEvent.prototype
}
+const namespaceRegex = /[^.]*(?=\..*)\.|.*/
+const stripNameRegex = /\..*/
+
+// Events storage
+const eventRegistry = {}
+let uidEvent = 1
+
+function getUidEvent(element, uid) {
+ return element.uidEvent = uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++
+}
+
+function getEvent(element) {
+ const uid = getUidEvent(element)
+ return eventRegistry[uid] = eventRegistry[uid] || {}
+}
+
+const nativeEvents =
+`click,dblclick,mouseup,mousedown,contextmenu,
+'mousewheel,DOMMouseScroll,
+'mouseover,mouseout,mousemove,selectstart,selectend,
+'keydown,keypress,keyup,
+'orientationchange,
+'touchstart,touchmove,touchend,touchcancel,
+'gesturestart,gesturechange,gestureend,
+'focus,blur,change,reset,select,submit,
+'load,unload,beforeunload,resize,move,DOMContentLoaded,readystatechange,
+'error,abort,scroll`.split(',')
+
+function bootstrapHandler(element, fn) {
+ return function (event) {
+ return fn.apply(element, [event])
+ }
+}
+
const EventHandler = {
- on(element, event, handler) {
- if (typeof event !== 'string' || typeof element === 'undefined') {
+ on(element, originalTypeEvent, handler) {
+ if (typeof originalTypeEvent !== 'string' ||
+ (typeof element === 'undefined' || element === null)) {
+ return
+ }
+
+ // allow to get the native events from namespaced events ('click.bs.button' --> 'click')
+ let typeEvent = originalTypeEvent.replace(stripNameRegex, '')
+ const isNative = nativeEvents.indexOf(typeEvent) > -1
+ if (!isNative) {
+ typeEvent = originalTypeEvent
+ }
+ const events = getEvent(element)
+ const handlers = events[typeEvent] || (events[typeEvent] = {})
+ const uid = getUidEvent(handler, originalTypeEvent.replace(namespaceRegex, ''))
+ // TODO : Handle multi events on one element
+ if (handlers[uid]) {
return
}
- element.addEventListener(event, handler, false)
+
+ const fn = bootstrapHandler(element, handler)
+ handlers[uid] = fn
+ handler.uidEvent = uid
+ element.addEventListener(typeEvent, fn, false)
},
one(element, event, handler) {
- const complete = () => {
- /* eslint func-style: off */
- handler()
- element.removeEventListener(event, complete, false)
+ function complete(e) {
+ const typeEvent = event.replace(stripNameRegex, '')
+ const events = getEvent(element)
+ if (!events || !events[typeEvent]) {
+ return
+ }
+ const uidEvent = handler.uidEvent
+ const fn = events[typeEvent][uidEvent]
+ fn.apply(element, [e])
+ EventHandler.off(element, event, handler)
}
EventHandler.on(element, event, complete)
},
- trigger(element, event) {
- if (typeof event !== 'string' || typeof element === 'undefined') {
- return null
+ off(element, originalTypeEvent, handler) {
+ if (typeof originalTypeEvent !== 'string' ||
+ (typeof element === 'undefined' || element === null)) {
+ return
}
- const eventToDispatch = new CustomEvent(event, {
- bubbles: true,
- cancelable: true
- })
+ const typeEvent = originalTypeEvent.replace(stripNameRegex, '')
+ const events = getEvent(element)
+ if (!events || !events[typeEvent]) {
+ return
+ }
- // Add a function 'isDefaultPrevented'
- eventToDispatch.isDefaultPrevented = () => eventToDispatch.defaultPrevented
- element.dispatchEvent(eventToDispatch)
+ const uidEvent = handler.uidEvent
+ const fn = events[typeEvent][uidEvent]
+ element.removeEventListener(typeEvent, fn, false)
+ delete events[typeEvent][uidEvent]
+ },
- return eventToDispatch
+ trigger(element, event) {
+ if (typeof event !== 'string' ||
+ (typeof element === 'undefined' || element === null)) {
+ return null
+ }
+ const typeEvent = event.replace(stripNameRegex, '')
+ const isNative = nativeEvents.indexOf(typeEvent) > -1
+ let returnedEvent = null
+ if (isNative) {
+ const evt = document.createEvent('HTMLEvents')
+ evt.initEvent(typeEvent, true, true)
+ element.dispatchEvent(evt)
+ returnedEvent = evt
+ } else {
+ const eventToDispatch = new CustomEvent(event, {
+ bubbles: true,
+ cancelable: true
+ })
+ element.dispatchEvent(eventToDispatch)
+ returnedEvent = eventToDispatch
+ }
+ return returnedEvent
}
}