Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

add stopImmediatePropagation() implementation

  • Loading branch information...
commit 3c863122d221e52c871118b0fd79795b8d5126c6 1 parent 45da23b
@rvagg rvagg authored
Showing with 72 additions and 3 deletions.
  1. +8 −3 src/bean.js
  2. +64 −0 tests/event-object-test.js
View
11 src/bean.js
@@ -195,6 +195,10 @@
}
Event.prototype.stopImmediatePropagation = function () {
if (this.originalEvent.stopImmediatePropagation) this.originalEvent.stopImmediatePropagation()
+ this.isImmediatePropagationStopped = function () { return true }
+ }
+ Event.prototype.isImmediatePropagationStopped = function () {
+ return this.originalEvent.isImmediatePropagationStopped && this.originalEvent.isImmediatePropagationStopped()
}
Event.prototype.stop = function () {
this.preventDefault()
@@ -202,8 +206,9 @@
this.stopped = true
}
Event.prototype.clone = function (currentTarget) {
- var ne = new Event(), p
- for (p in this) ne[p] = this[p]
+ //TODO: this is ripe for optimisation, new events are *expensive*
+ // improving this will speed up delegated events
+ var ne = new Event(this, this.element, this.isNative)
ne.currentTarget = currentTarget
return ne
}
@@ -390,7 +395,7 @@
event = new Event(event, this, true)
if (type) event.type = type
- for (; i < l; i++) {
+ for (; i < l && !event.isImmediatePropagationStopped(); i++) {
if (!listeners[i].removed) listeners[i].handler.call(this, event)
}
}
View
64 tests/event-object-test.js
@@ -58,6 +58,12 @@ buster.testCase('event object', {
})
}
+ , 'should have stopImmediatePropagation method': function (done) {
+ this.runTest(false, done, function (event) {
+ assert.isFunction(event.stopImmediatePropagation, 'event object has stopImmediatePropagation method')
+ })
+ }
+
, 'should have stopPropagation method on custom event': function (done) {
this.runTest(true, done, function (event) {
assert.isFunction(event.stopPropagation, 'event object has stopPropagation method')
@@ -69,6 +75,12 @@ buster.testCase('event object', {
assert.isFunction(event.preventDefault, 'event object has preventDefault method')
})
}
+
+ , 'should have stopImmediatePropagation method on custom event': function (done) {
+ this.runTest(true, done, function (event) {
+ assert.isFunction(event.stopImmediatePropagation, 'event object has stopImmediatePropagation method')
+ })
+ }
}
, 'stop()': {
@@ -118,6 +130,58 @@ buster.testCase('event object', {
}
}
+ , 'stopImmediatePropagation()': {
+ 'setUp': function () {
+ var self = this
+
+ this.runTest = function (delegate, done) {
+ // we should be able to prevent a keypress and event propagation with stop()
+ // on the keypress event, checking the parent doesn't receive the keypress
+ // and then checking the input contents on a keyup, it should be empty.
+ var stopper = self.byId('stopper')
+ , txt = self.byId('txt')
+ , trigger = self.trigger()
+ , spy1 = self.spy()
+ , spy2 = self.spy()
+ , spy3 = self.spy()
+ , stopHandler = function (event) {
+ event.stopImmediatePropagation()
+ }
+
+ trigger.after(function () {
+ assert.equals(spy1.callCount, 1, 'first spy should be called')
+ assert.equals(spy2.callCount, 0, 'second spy should not be called')
+ assert.equals(spy3.callCount, 0, 'third spy should not be called')
+ done()
+ })
+
+ bean.setSelectorEngine(qwery)
+
+ if (delegate) {
+ bean.on(stopper , 'click', '[type=text]', trigger.wrap(spy1))
+ bean.on(stopper , 'click', '[type=text]', trigger.wrap(stopHandler))
+ bean.on(stopper , 'click', '[type=text]', trigger.wrap(spy2))
+ bean.on(stopper , 'click', '[type=text]', trigger.wrap(spy3))
+ Syn.click(txt)
+ } else {
+ bean.on(stopper , 'click', trigger.wrap(spy1))
+ bean.on(stopper , 'click', trigger.wrap(stopHandler))
+ bean.on(stopper , 'click', trigger.wrap(spy2))
+ bean.on(stopper , 'click', trigger.wrap(spy3))
+ Syn.click(stopper)
+ }
+ }
+ }
+
+ , 'should stop immediate propagation': function(done) {
+ this.runTest(false, done)
+ }
+
+ , 'should stop immediate propagation on delegated events': function (done) {
+ this.runTest(true, done)
+ }
+ }
+
, 'should have keyCode': function (done) {
var el = this.byId('input')
, trigger = this.trigger()
Please sign in to comment.
Something went wrong with that request. Please try again.