aboutsummaryrefslogtreecommitdiff
path: root/js/src/dom/eventHandler.js
diff options
context:
space:
mode:
authorAlessandro Chitolina <[email protected]>2017-09-15 16:07:24 +0200
committerXhmikosR <[email protected]>2019-02-20 22:05:45 +0200
commit33211eefdfb27eff7ba21886e16f2efdc0efa3e6 (patch)
treef8f3f3342a6c2c2363448346debf52beb4954b21 /js/src/dom/eventHandler.js
parent9f9712b98c92678c709b2ad0adfa954e3c120911 (diff)
downloadbootstrap-33211eefdfb27eff7ba21886e16f2efdc0efa3e6.tar.xz
bootstrap-33211eefdfb27eff7ba21886e16f2efdc0efa3e6.zip
Rewritten modal without jquery (#23955)
* Trigger jquery events if available in event handler * Rewritten modal without jquery
Diffstat (limited to 'js/src/dom/eventHandler.js')
-rw-r--r--js/src/dom/eventHandler.js105
1 files changed, 81 insertions, 24 deletions
diff --git a/js/src/dom/eventHandler.js b/js/src/dom/eventHandler.js
index 746f84bcb..a69ab6136 100644
--- a/js/src/dom/eventHandler.js
+++ b/js/src/dom/eventHandler.js
@@ -63,6 +63,7 @@ if (!window.Event || typeof window.Event !== 'function') {
const namespaceRegex = /[^.]*(?=\..*)\.|.*/
const stripNameRegex = /\..*/
const keyEventRegex = /^key/
+const stripUidRegex = /::\d+$/
// Events storage
const eventRegistry = {}
@@ -110,10 +111,10 @@ function bootstrapHandler(element, fn) {
}
}
-function bootstrapDelegationHandler(selector, fn) {
+function bootstrapDelegationHandler(element, selector, fn) {
return function (event) {
event = fixEvent(event)
- const domElements = document.querySelectorAll(selector)
+ const domElements = element.querySelectorAll(selector)
for (let target = event.target; target && target !== this; target = target.parentNode) {
for (let i = domElements.length; i--;) {
if (domElements[i] === target) {
@@ -126,6 +127,26 @@ function bootstrapDelegationHandler(selector, fn) {
}
}
+function removeHandler(element, events, typeEvent, handler) {
+ const uidEvent = handler.uidEvent
+ const fn = events[typeEvent][uidEvent]
+ element.removeEventListener(typeEvent, fn, fn.delegation)
+ delete events[typeEvent][uidEvent]
+}
+
+function removeNamespacedHandlers(element, events, typeEvent, namespace) {
+ const storeElementEvent = events[typeEvent] || {}
+ for (const handlerKey in storeElementEvent) {
+ if (!Object.prototype.hasOwnProperty.call(storeElementEvent, handlerKey)) {
+ continue
+ }
+
+ if (handlerKey.indexOf(namespace) > -1) {
+ removeHandler(element, events, typeEvent, storeElementEvent[handlerKey].originalHandler)
+ }
+ }
+}
+
const EventHandler = {
on(element, originalTypeEvent, handler, delegationFn) {
if (typeof originalTypeEvent !== 'string' ||
@@ -155,7 +176,7 @@ const EventHandler = {
return
}
- const fn = !delegation ? bootstrapHandler(element, handler) : bootstrapDelegationHandler(handler, delegationFn)
+ const fn = !delegation ? bootstrapHandler(element, handler) : bootstrapDelegationHandler(element, handler, delegationFn)
fn.isDelegation = delegation
handlers[uid] = fn
originalHandler.uidEvent = uid
@@ -179,43 +200,49 @@ const EventHandler = {
const events = getEvent(element)
let typeEvent = originalTypeEvent.replace(stripNameRegex, '')
+
const inNamespace = typeEvent !== originalTypeEvent
const custom = customEvents[typeEvent]
if (custom) {
typeEvent = custom
}
+
const isNative = nativeEvents.indexOf(typeEvent) > -1
if (!isNative) {
typeEvent = originalTypeEvent
}
- if (typeof handler === 'undefined') {
+ if (typeof handler !== 'undefined') {
+ // Simplest case: handler is passed, remove that listener ONLY.
+ if (!events || !events[typeEvent]) {
+ return
+ }
+
+ removeHandler(element, events, typeEvent, handler)
+ return
+ }
+
+ const isNamespace = originalTypeEvent.charAt(0) === '.'
+ if (isNamespace) {
for (const elementEvent in events) {
if (!Object.prototype.hasOwnProperty.call(events, elementEvent)) {
continue
}
- const storeElementEvent = events[elementEvent]
- for (const keyHandlers in storeElementEvent) {
- if (!Object.prototype.hasOwnProperty.call(storeElementEvent, keyHandlers)) {
- continue
- }
- // delete all the namespaced listeners
- if (inNamespace && keyHandlers.indexOf(originalTypeEvent) > -1) {
- const handlerFn = events[elementEvent][keyHandlers]
- EventHandler.off(element, elementEvent, handlerFn.originalHandler)
- }
- }
+ removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.substr(1))
}
- } else {
- if (!events || !events[typeEvent]) {
- return
+ }
+
+ const storeElementEvent = events[typeEvent] || {}
+ for (const keyHandlers in storeElementEvent) {
+ if (!Object.prototype.hasOwnProperty.call(storeElementEvent, keyHandlers)) {
+ continue
}
- const uidEvent = handler.uidEvent
- const fn = events[typeEvent][uidEvent]
- element.removeEventListener(typeEvent, fn, fn.delegation)
- delete events[typeEvent][uidEvent]
+ const handlerKey = keyHandlers.replace(stripUidRegex, '')
+ if (!inNamespace || originalTypeEvent.indexOf(handlerKey) > -1) {
+ removeHandler(element, events, typeEvent, storeElementEvent[keyHandlers].originalHandler)
+ }
}
},
@@ -226,7 +253,25 @@ const EventHandler = {
}
const typeEvent = event.replace(stripNameRegex, '')
+ const inNamespace = event !== typeEvent
const isNative = nativeEvents.indexOf(typeEvent) > -1
+
+ const $ = Util.jQuery
+ let jQueryEvent
+
+ let bubbles = true
+ let nativeDispatch = true
+ let defaultPrevented = false
+
+ if (inNamespace && typeof $ !== 'undefined') {
+ jQueryEvent = new $.Event(event, args)
+
+ $(element).trigger(jQueryEvent)
+ bubbles = !jQueryEvent.isPropagationStopped()
+ nativeDispatch = !jQueryEvent.isImmediatePropagationStopped()
+ defaultPrevented = jQueryEvent.isDefaultPrevented()
+ }
+
let evt = null
if (isNative) {
@@ -234,7 +279,7 @@ const EventHandler = {
evt.initEvent(typeEvent, true, true)
} else {
evt = new CustomEvent(event, {
- bubbles: true,
+ bubbles,
cancelable: true
})
}
@@ -243,7 +288,19 @@ const EventHandler = {
if (typeof args !== 'undefined') {
evt = Util.extend(evt, args)
}
- element.dispatchEvent(evt)
+
+ if (defaultPrevented) {
+ evt.preventDefault()
+ }
+
+ if (nativeDispatch) {
+ element.dispatchEvent(evt)
+ }
+
+ if (evt.defaultPrevented && typeof jQueryEvent !== 'undefined') {
+ jQueryEvent.preventDefault()
+ }
+
return evt
}
}