diff --git a/.gitignore b/.gitignore index 72e9b45..9df4e9f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /dist /node_modules /npm-debug.log +package-lock.json .DS_Store diff --git a/src/undom.js b/src/undom.js index 74d4a88..5528c34 100644 --- a/src/undom.js +++ b/src/undom.js @@ -140,16 +140,19 @@ export default function undom() { splice(this.__handlers[toLower(type)], handler, 0, true); } dispatchEvent(event) { - let t = event.currentTarget = this, + let t = event.target = this, c = event.cancelable, l, i; do { + event.currentTarget = t; l = t.__handlers && t.__handlers[toLower(event.type)]; if (l) for (i=l.length; i--; ) { - if ((l[i].call(t, event)===false || event._end) && c) break; + if ((l[i].call(t, event) === false || event._end) && c) { + event.defaultPrevented = true; + } } - } while (event.bubbles && !(c && event._stop) && (event.target=t=t.parentNode)); - return !event.defaultPrevented; + } while (event.bubbles && !(c && event._stop) && (t=t.parentNode)); + return l!=null; } } @@ -164,8 +167,8 @@ export default function undom() { class Event { constructor(type, opts) { this.type = type; - this.bubbles = !!opts.bubbles; - this.cancelable = !!opts.cancelable; + this.bubbles = !!(opts && opts.bubbles); + this.cancelable = !!(opts && opts.cancelable); } stopPropagation() { this._stop = true; diff --git a/test/undom.js b/test/undom.js index a198bf7..877e25b 100644 --- a/test/undom.js +++ b/test/undom.js @@ -240,7 +240,7 @@ describe('undom', () => { }); it('should bubble if enabled', () => { - let event = { type:'foo', cancelable:true, bubbles:true }; + let event = new document.defaultView.Event('foo', { cancelable:true, bubbles:true }); let child = document.createElement('div'); let parent = document.createElement('div'); parent.appendChild(child); @@ -264,6 +264,32 @@ describe('undom', () => { child.dispatchEvent(event); expect(parent.fn).not.to.have.been.called; }); + + it('should return `found`', () => { + let el = document.createElement('div'); + let el2 = document.createElement('div'); + el.addEventListener('foo', () => {}); + + expect(el.dispatchEvent(new document.defaultView.Event('foo'))).to.equal(true); + expect(el2.dispatchEvent(new document.defaultView.Event('foo'))).to.equal(false); + }); + + it('preventDefault() should set defaultPrevented', () => { + let event = new document.defaultView.Event('foo', { cancelable: true, bubbles: true }); + let el = document.createElement('div'); + let parent = document.createElement('div'); + parent.appendChild(el); + let fn = spy(e => { e.preventDefault(); }); + let parentFn = spy(e => { e.preventDefault(); }); + el.addEventListener('foo', fn); + parent.addEventListener('foo', parentFn); + + el.dispatchEvent(event); + + expect(fn).to.have.been.calledOnce; + expect(parentFn).to.have.been.calledOnce; + expect(parentFn.firstCall.args[0]).to.have.property('defaultPrevented', true); + }); }); }); });