mirror of
https://github.com/twbs/bootstrap.git
synced 2025-02-26 23:54:23 +01:00
Fix interoperability issue regarding Event properties (#36386)
* Fix interoperability issue regarding Event properties - make possible to re-set read-only event properties - use hydrateObj() to set delegateTarget property Fixes #36207 Co-authored-by: GeoSot <geo.sotis@gmail.com> Co-authored-by: Julien Déramond <julien.deramond@orange.com>
This commit is contained in:
parent
4082a3b52d
commit
505e0235b9
@ -89,7 +89,7 @@ function getElementEvents(element) {
|
|||||||
|
|
||||||
function bootstrapHandler(element, fn) {
|
function bootstrapHandler(element, fn) {
|
||||||
return function handler(event) {
|
return function handler(event) {
|
||||||
event.delegateTarget = element
|
hydrateObj(event, { delegateTarget: element })
|
||||||
|
|
||||||
if (handler.oneOff) {
|
if (handler.oneOff) {
|
||||||
EventHandler.off(element, event.type, fn)
|
EventHandler.off(element, event.type, fn)
|
||||||
@ -109,7 +109,7 @@ function bootstrapDelegationHandler(element, selector, fn) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
event.delegateTarget = target
|
hydrateObj(event, { delegateTarget: target })
|
||||||
|
|
||||||
if (handler.oneOff) {
|
if (handler.oneOff) {
|
||||||
EventHandler.off(element, event.type, selector, fn)
|
EventHandler.off(element, event.type, selector, fn)
|
||||||
@ -302,11 +302,16 @@ const EventHandler = {
|
|||||||
|
|
||||||
function hydrateObj(obj, meta) {
|
function hydrateObj(obj, meta) {
|
||||||
for (const [key, value] of Object.entries(meta || {})) {
|
for (const [key, value] of Object.entries(meta || {})) {
|
||||||
Object.defineProperty(obj, key, {
|
try {
|
||||||
get() {
|
obj[key] = value
|
||||||
return value
|
} catch {
|
||||||
}
|
Object.defineProperty(obj, key, {
|
||||||
})
|
configurable: true,
|
||||||
|
get() {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
@ -441,4 +441,41 @@ describe('EventHandler', () => {
|
|||||||
expect(i).toEqual(5)
|
expect(i).toEqual(5)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('general functionality', () => {
|
||||||
|
it('should hydrate properties, and make them configurable', () => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
fixtureEl.innerHTML = [
|
||||||
|
'<div id="div1">',
|
||||||
|
' <div id="div2"></div>',
|
||||||
|
' <div id="div3"></div>',
|
||||||
|
'</div>'
|
||||||
|
].join('')
|
||||||
|
|
||||||
|
const div1 = fixtureEl.querySelector('#div1')
|
||||||
|
const div2 = fixtureEl.querySelector('#div2')
|
||||||
|
const div3 = fixtureEl.querySelector('#div3')
|
||||||
|
|
||||||
|
EventHandler.on(div1, 'click', event => {
|
||||||
|
event.originalTarget = div3
|
||||||
|
|
||||||
|
expect(event.currentTarget).toBe(div2)
|
||||||
|
|
||||||
|
Object.defineProperty(event, 'currentTarget', {
|
||||||
|
configurable: true,
|
||||||
|
get() {
|
||||||
|
return div1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(event.currentTarget).toBe(div1)
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
EventHandler.trigger(div1, 'click', { delegateTarget: div2, originalTarget: null, currentTarget: div2 })
|
||||||
|
}).not.toThrowError(TypeError)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user