Created
March 4, 2013 09:55
-
-
Save johanlunds/5081176 to your computer and use it in GitHub Desktop.
Discussed in https://github.com/spine/spine/issues/418, patch-format
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 863f316336dae0af7b418d30b40959b5fdd9dcba Mon Sep 17 00:00:00 2001 | |
From: aeischeid <[email protected]> | |
Date: Wed, 20 Feb 2013 11:42:46 -0600 | |
Subject: [PATCH 01/10] wild stab at a test for instance individual events | |
unbinding | |
--- | |
test/specs/model.js | 12 +++++++++++- | |
1 file changed, 11 insertions(+), 1 deletion(-) | |
diff --git a/test/specs/model.js b/test/specs/model.js | |
index 608e792..d1d9477 100644 | |
--- a/test/specs/model.js | |
+++ b/test/specs/model.js | |
@@ -453,7 +453,7 @@ describe("Model", function(){ | |
asset.updateAttributes({name: "lonely heart.png"}); | |
}); | |
- it("should be able to unbind instance events", function(){ | |
+ it("should be able to unbind all instance events", function(){ | |
var asset = Asset.create({name: "cartoon world.png"}); | |
asset.bind("save", spy); | |
@@ -462,6 +462,16 @@ describe("Model", function(){ | |
expect(spy).not.toHaveBeenCalled(); | |
}); | |
+ | |
+ it("should be able to unbind individual instance events", function(){ | |
+ var asset = Asset.create({name: "cartoon world.png"}); | |
+ | |
+ asset.bind("save, refresh, change", spy); | |
+ asset.unbind('save'); | |
+ asset.save(); | |
+ | |
+ expect(spy).not.toHaveBeenCalled(); | |
+ }); | |
it("should unbind events on instance destroy", function(){ | |
var asset = Asset.create({name: "cartoon world.png"}); | |
-- | |
1.7.10 | |
From 28053c4d1d1fe9b78ad9c17b00e12a060e582e72 Mon Sep 17 00:00:00 2001 | |
From: aeischeid <[email protected]> | |
Date: Wed, 20 Feb 2013 11:59:20 -0600 | |
Subject: [PATCH 02/10] more better tests that fail for the model instance | |
unbinder | |
--- | |
test/specs/model.js | 15 +++++++++++++-- | |
1 file changed, 13 insertions(+), 2 deletions(-) | |
diff --git a/test/specs/model.js b/test/specs/model.js | |
index d1d9477..a4e57fb 100644 | |
--- a/test/specs/model.js | |
+++ b/test/specs/model.js | |
@@ -466,11 +466,22 @@ describe("Model", function(){ | |
it("should be able to unbind individual instance events", function(){ | |
var asset = Asset.create({name: "cartoon world.png"}); | |
- asset.bind("save, refresh, change", spy); | |
+ asset.bind("save, customEvent", spy); | |
asset.unbind('save'); | |
asset.save(); | |
- | |
expect(spy).not.toHaveBeenCalled(); | |
+ asset.trigger('customEvent'); | |
+ expect(spy).toHaveBeenCalled(); | |
+ }); | |
+ | |
+ it("should be able to unbind individual callbacks to individual instance events", function(){ | |
+ var asset = Asset.create({name: "cartoon world.png"}); | |
+ asset.bind("customEvent", spy); | |
+ asset.bind("customEvent", spy2); | |
+ asset.unbind("customEvent", spy2); | |
+ asset.trigger('customEvent'); | |
+ expect(spy).toHaveBeenCalled(); | |
+ expect(spy2).not.toHaveBeenCalled(); | |
}); | |
it("should unbind events on instance destroy", function(){ | |
-- | |
1.7.10 | |
From 7af20a9099b39d5f7cad2530eaa6e9709613eb77 Mon Sep 17 00:00:00 2001 | |
From: aeischeid <[email protected]> | |
Date: Wed, 20 Feb 2013 12:18:07 -0600 | |
Subject: [PATCH 03/10] forgot to define spy2 for test | |
--- | |
test/specs/model.js | 3 +++ | |
1 file changed, 3 insertions(+) | |
diff --git a/test/specs/model.js b/test/specs/model.js | |
index a4e57fb..f5f1583 100644 | |
--- a/test/specs/model.js | |
+++ b/test/specs/model.js | |
@@ -476,6 +476,9 @@ describe("Model", function(){ | |
it("should be able to unbind individual callbacks to individual instance events", function(){ | |
var asset = Asset.create({name: "cartoon world.png"}); | |
+ var noop2 = {spy2: function(){}}; | |
+ spyOn(noop2, "spy2"); | |
+ var spy2 = noop2.spy2; | |
asset.bind("customEvent", spy); | |
asset.bind("customEvent", spy2); | |
asset.unbind("customEvent", spy2); | |
-- | |
1.7.10 | |
From 0968b36c3332b250a95138aadd23ed5f83fa552b Mon Sep 17 00:00:00 2001 | |
From: aeischeid <[email protected]> | |
Date: Wed, 20 Feb 2013 11:42:46 -0600 | |
Subject: [PATCH 04/10] wild stab at a test for instance individual events | |
unbinding | |
--- | |
test/specs/model.js | 12 +++++++++++- | |
1 file changed, 11 insertions(+), 1 deletion(-) | |
diff --git a/test/specs/model.js b/test/specs/model.js | |
index 608e792..d1d9477 100644 | |
--- a/test/specs/model.js | |
+++ b/test/specs/model.js | |
@@ -453,7 +453,7 @@ describe("Model", function(){ | |
asset.updateAttributes({name: "lonely heart.png"}); | |
}); | |
- it("should be able to unbind instance events", function(){ | |
+ it("should be able to unbind all instance events", function(){ | |
var asset = Asset.create({name: "cartoon world.png"}); | |
asset.bind("save", spy); | |
@@ -462,6 +462,16 @@ describe("Model", function(){ | |
expect(spy).not.toHaveBeenCalled(); | |
}); | |
+ | |
+ it("should be able to unbind individual instance events", function(){ | |
+ var asset = Asset.create({name: "cartoon world.png"}); | |
+ | |
+ asset.bind("save, refresh, change", spy); | |
+ asset.unbind('save'); | |
+ asset.save(); | |
+ | |
+ expect(spy).not.toHaveBeenCalled(); | |
+ }); | |
it("should unbind events on instance destroy", function(){ | |
var asset = Asset.create({name: "cartoon world.png"}); | |
-- | |
1.7.10 | |
From 72ba480d0d0e8570044d3d1710e6ee7c5f486895 Mon Sep 17 00:00:00 2001 | |
From: aeischeid <[email protected]> | |
Date: Wed, 20 Feb 2013 11:59:20 -0600 | |
Subject: [PATCH 05/10] more better tests that fail for the model instance | |
unbinder | |
--- | |
test/specs/model.js | 15 +++++++++++++-- | |
1 file changed, 13 insertions(+), 2 deletions(-) | |
diff --git a/test/specs/model.js b/test/specs/model.js | |
index d1d9477..a4e57fb 100644 | |
--- a/test/specs/model.js | |
+++ b/test/specs/model.js | |
@@ -466,11 +466,22 @@ describe("Model", function(){ | |
it("should be able to unbind individual instance events", function(){ | |
var asset = Asset.create({name: "cartoon world.png"}); | |
- asset.bind("save, refresh, change", spy); | |
+ asset.bind("save, customEvent", spy); | |
asset.unbind('save'); | |
asset.save(); | |
- | |
expect(spy).not.toHaveBeenCalled(); | |
+ asset.trigger('customEvent'); | |
+ expect(spy).toHaveBeenCalled(); | |
+ }); | |
+ | |
+ it("should be able to unbind individual callbacks to individual instance events", function(){ | |
+ var asset = Asset.create({name: "cartoon world.png"}); | |
+ asset.bind("customEvent", spy); | |
+ asset.bind("customEvent", spy2); | |
+ asset.unbind("customEvent", spy2); | |
+ asset.trigger('customEvent'); | |
+ expect(spy).toHaveBeenCalled(); | |
+ expect(spy2).not.toHaveBeenCalled(); | |
}); | |
it("should unbind events on instance destroy", function(){ | |
-- | |
1.7.10 | |
From fe96cb4ebd41e49e9e050f58d3f58602d72de5be Mon Sep 17 00:00:00 2001 | |
From: aeischeid <[email protected]> | |
Date: Wed, 20 Feb 2013 12:18:07 -0600 | |
Subject: [PATCH 06/10] forgot to define spy2 for test | |
--- | |
test/specs/model.js | 3 +++ | |
1 file changed, 3 insertions(+) | |
diff --git a/test/specs/model.js b/test/specs/model.js | |
index a4e57fb..f5f1583 100644 | |
--- a/test/specs/model.js | |
+++ b/test/specs/model.js | |
@@ -476,6 +476,9 @@ describe("Model", function(){ | |
it("should be able to unbind individual callbacks to individual instance events", function(){ | |
var asset = Asset.create({name: "cartoon world.png"}); | |
+ var noop2 = {spy2: function(){}}; | |
+ spyOn(noop2, "spy2"); | |
+ var spy2 = noop2.spy2; | |
asset.bind("customEvent", spy); | |
asset.bind("customEvent", spy2); | |
asset.unbind("customEvent", spy2); | |
-- | |
1.7.10 | |
From d8e5d360a4439bd5d9f6365e249a199fa2410aa3 Mon Sep 17 00:00:00 2001 | |
From: Chris Engebretson <[email protected]> | |
Date: Wed, 20 Feb 2013 14:31:16 -0600 | |
Subject: [PATCH 07/10] first stab at getting unbind to work at the instance | |
level, man that was a pain! | |
--- | |
lib/spine.js | 14 ++++++++------ | |
src/spine.coffee | 15 ++++++++------- | |
test/specs/model.js | 3 ++- | |
3 files changed, 18 insertions(+), 14 deletions(-) | |
diff --git a/lib/spine.js b/lib/spine.js | |
index c0aa6dc..0127f33 100644 | |
--- a/lib/spine.js | |
+++ b/lib/spine.js | |
@@ -632,10 +632,12 @@ | |
return callback.apply(_this, arguments); | |
} | |
}); | |
- this.constructor.bind('unbind', unbinder = function(record) { | |
- if (record && _this.eql(record)) { | |
- _this.constructor.unbind(events, binder); | |
- return _this.constructor.unbind('unbind', unbinder); | |
+ this.constructor.bind("unbind", unbinder = function(record, event, cb) { | |
+ if (record && _this.eql(record) && (!event || events === event)) { | |
+ if (!cb || cb === callback) { | |
+ _this.constructor.unbind(events, binder); | |
+ return _this.constructor.unbind("unbind", unbinder); | |
+ } | |
} | |
}); | |
return binder; | |
@@ -657,8 +659,8 @@ | |
return (_ref = this.constructor).trigger.apply(_ref, args); | |
}; | |
- Model.prototype.unbind = function() { | |
- return this.trigger('unbind'); | |
+ Model.prototype.unbind = function(events, callback) { | |
+ return this.trigger('unbind', events, callback); | |
}; | |
return Model; | |
diff --git a/src/spine.coffee b/src/spine.coffee | |
index 650a945..5ed952a 100644 | |
--- a/src/spine.coffee | |
+++ b/src/spine.coffee | |
@@ -38,7 +38,7 @@ Events = | |
delete @_callbacks[name] | |
continue | |
- for cb, i in list when cb is callback | |
+ for cb, i in list when (cb is callback) | |
list = list.slice() | |
list.splice(i, 1) | |
@_callbacks[name] = list | |
@@ -376,10 +376,11 @@ class Model extends Module | |
@constructor.bind events, binder = (record) => | |
if record && @eql(record) | |
callback.apply(this, arguments) | |
- @constructor.bind 'unbind', unbinder = (record) => | |
- if record && @eql(record) | |
- @constructor.unbind(events, binder) | |
- @constructor.unbind('unbind', unbinder) | |
+ @constructor.bind "unbind", unbinder = (record, event, cb) => | |
+ if record && @eql(record) and (not event or events is event) | |
+ if not cb or cb is callback | |
+ @constructor.unbind(events, binder) | |
+ @constructor.unbind("unbind", unbinder) | |
binder | |
one: (events, callback) -> | |
@@ -391,8 +392,8 @@ class Model extends Module | |
args.splice(1, 0, this) | |
@constructor.trigger(args...) | |
- unbind: -> | |
- @trigger('unbind') | |
+ unbind: (events, callback) -> | |
+ @trigger('unbind', events, callback) | |
class Controller extends Module | |
@include Events | |
diff --git a/test/specs/model.js b/test/specs/model.js | |
index f5f1583..20e9fe5 100644 | |
--- a/test/specs/model.js | |
+++ b/test/specs/model.js | |
@@ -466,7 +466,8 @@ describe("Model", function(){ | |
it("should be able to unbind individual instance events", function(){ | |
var asset = Asset.create({name: "cartoon world.png"}); | |
- asset.bind("save, customEvent", spy); | |
+ asset.bind("save", spy); | |
+ asset.bind("customEvent", spy); | |
asset.unbind('save'); | |
asset.save(); | |
expect(spy).not.toHaveBeenCalled(); | |
-- | |
1.7.10 | |
From b1fe152d21816c7296bf0b242a71666624696bed Mon Sep 17 00:00:00 2001 | |
From: Chris Engebretson <[email protected]> | |
Date: Wed, 20 Feb 2013 18:31:35 -0600 | |
Subject: [PATCH 08/10] should be able to use bind and unbind with multiple | |
events. Also bind/one should return the this object. | |
--- | |
lib/spine.js | 48 +++++++++++++++++++++++++++++++++++------------- | |
src/spine.coffee | 25 ++++++++++++++++--------- | |
test/specs/model.js | 31 +++++++++++++++++++++++++++++++ | |
3 files changed, 82 insertions(+), 22 deletions(-) | |
diff --git a/lib/spine.js b/lib/spine.js | |
index 0127f33..c5d3f77 100644 | |
--- a/lib/spine.js | |
+++ b/lib/spine.js | |
@@ -625,29 +625,40 @@ | |
}; | |
Model.prototype.bind = function(events, callback) { | |
- var binder, unbinder, | |
+ var binder, evs, _fn, _i, _len, _ref, | |
_this = this; | |
this.constructor.bind(events, binder = function(record) { | |
if (record && _this.eql(record)) { | |
return callback.apply(_this, arguments); | |
} | |
}); | |
- this.constructor.bind("unbind", unbinder = function(record, event, cb) { | |
- if (record && _this.eql(record) && (!event || events === event)) { | |
- if (!cb || cb === callback) { | |
- _this.constructor.unbind(events, binder); | |
+ _ref = events.split(' '); | |
+ _fn = function(evs) { | |
+ var unbinder; | |
+ return _this.constructor.bind("unbind", unbinder = function(record, event, cb) { | |
+ if (record && _this.eql(record)) { | |
+ if (event && event !== evs) { | |
+ return; | |
+ } | |
+ if (cb && cb !== callback) { | |
+ return; | |
+ } | |
+ _this.constructor.unbind(event, binder); | |
return _this.constructor.unbind("unbind", unbinder); | |
} | |
- } | |
- }); | |
- return binder; | |
+ }); | |
+ }; | |
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
+ evs = _ref[_i]; | |
+ _fn(evs); | |
+ } | |
+ return this; | |
}; | |
Model.prototype.one = function(events, callback) { | |
- var binder, | |
- _this = this; | |
- return binder = this.bind(events, function() { | |
- _this.constructor.unbind(events, binder); | |
+ var _this = this; | |
+ return this.bind(events, function() { | |
+ _this.unbind(events, arguments.callee); | |
return callback.apply(_this, arguments); | |
}); | |
}; | |
@@ -660,7 +671,18 @@ | |
}; | |
Model.prototype.unbind = function(events, callback) { | |
- return this.trigger('unbind', events, callback); | |
+ var event, _i, _len, _ref, _results; | |
+ if (events) { | |
+ _ref = events.split(' '); | |
+ _results = []; | |
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
+ event = _ref[_i]; | |
+ _results.push(this.trigger('unbind', event, callback)); | |
+ } | |
+ return _results; | |
+ } else { | |
+ return this.trigger('unbind'); | |
+ } | |
}; | |
return Model; | |
diff --git a/src/spine.coffee b/src/spine.coffee | |
index 5ed952a..2311694 100644 | |
--- a/src/spine.coffee | |
+++ b/src/spine.coffee | |
@@ -376,16 +376,19 @@ class Model extends Module | |
@constructor.bind events, binder = (record) => | |
if record && @eql(record) | |
callback.apply(this, arguments) | |
- @constructor.bind "unbind", unbinder = (record, event, cb) => | |
- if record && @eql(record) and (not event or events is event) | |
- if not cb or cb is callback | |
- @constructor.unbind(events, binder) | |
- @constructor.unbind("unbind", unbinder) | |
- binder | |
+ for evs in events.split(' ') | |
+ do (evs) => | |
+ @constructor.bind "unbind", unbinder = (record, event, cb) => | |
+ if record && @eql(record) | |
+ return if event and event isnt evs | |
+ return if cb and cb isnt callback | |
+ @constructor.unbind(event, binder) | |
+ @constructor.unbind("unbind", unbinder) | |
+ this | |
one: (events, callback) -> | |
- binder = @bind events, => | |
- @constructor.unbind(events, binder) | |
+ @bind events, => | |
+ @unbind(events, arguments.callee) | |
callback.apply(this, arguments) | |
trigger: (args...) -> | |
@@ -393,7 +396,11 @@ class Model extends Module | |
@constructor.trigger(args...) | |
unbind: (events, callback) -> | |
- @trigger('unbind', events, callback) | |
+ if events | |
+ for event in events.split(' ') | |
+ @trigger('unbind', event, callback) | |
+ else | |
+ @trigger('unbind') | |
class Controller extends Module | |
@include Events | |
diff --git a/test/specs/model.js b/test/specs/model.js | |
index 20e9fe5..423b458 100644 | |
--- a/test/specs/model.js | |
+++ b/test/specs/model.js | |
@@ -482,12 +482,43 @@ describe("Model", function(){ | |
var spy2 = noop2.spy2; | |
asset.bind("customEvent", spy); | |
asset.bind("customEvent", spy2); | |
+ asset.trigger("customEvent"); | |
+ expect(spy).toHaveBeenCalled(); | |
+ expect(spy2).toHaveBeenCalled(); | |
+ spy.reset(); | |
+ spy2.reset(); | |
asset.unbind("customEvent", spy2); | |
asset.trigger('customEvent'); | |
expect(spy).toHaveBeenCalled(); | |
expect(spy2).not.toHaveBeenCalled(); | |
}); | |
+ it("should be able to unbind a single event that uses a callback another event is bind to.", function(){ | |
+ var asset = Asset.create({name: "cartoon world.png"}); | |
+ asset.bind("customEvent1 customEvent2", spy); | |
+ asset.trigger("customEvent1"); | |
+ asset.trigger("customEvent2"); | |
+ expect(spy.calls.length).toEqual(2); | |
+ spy.reset(); | |
+ asset.unbind("customEvent1"); | |
+ asset.trigger("customEvent1"); | |
+ asset.trigger("customEvent2"); | |
+ expect(spy.calls.length).toEqual(1); | |
+ }); | |
+ | |
+ it("should be able to bind and unbind multiple events with a single call.", function(){ | |
+ var asset = Asset.create({name: "cartoon world.png"}); | |
+ asset.bind("customEvent1 customEvent2", spy) | |
+ asset.trigger("customEvent1"); | |
+ asset.trigger("customEvent2"); | |
+ expect(spy.calls.length).toEqual(2); | |
+ spy.reset(); | |
+ asset.unbind("customEvent1 customEvent2") | |
+ asset.trigger("customEvent1"); | |
+ asset.trigger("customEvent2"); | |
+ expect(spy.calls.length).toEqual(0); | |
+ }); | |
+ | |
it("should unbind events on instance destroy", function(){ | |
var asset = Asset.create({name: "cartoon world.png"}); | |
-- | |
1.7.10 | |
From 80e7a3fc26a462b6909befa46ab1196f412751db Mon Sep 17 00:00:00 2001 | |
From: Chris Engebretson <[email protected]> | |
Date: Thu, 21 Feb 2013 18:30:56 -0600 | |
Subject: [PATCH 09/10] better variable name | |
--- | |
src/spine.coffee | 7 ++++--- | |
1 file changed, 4 insertions(+), 3 deletions(-) | |
diff --git a/src/spine.coffee b/src/spine.coffee | |
index 2311694..e0e0cbf 100644 | |
--- a/src/spine.coffee | |
+++ b/src/spine.coffee | |
@@ -376,11 +376,12 @@ class Model extends Module | |
@constructor.bind events, binder = (record) => | |
if record && @eql(record) | |
callback.apply(this, arguments) | |
- for evs in events.split(' ') | |
- do (evs) => | |
+ # create a wrapper function to be called with 'unbind' for each event | |
+ for singleEvent in events.split(' ') | |
+ do (singleEvent) => | |
@constructor.bind "unbind", unbinder = (record, event, cb) => | |
if record && @eql(record) | |
- return if event and event isnt evs | |
+ return if event and event isnt singleEvent | |
return if cb and cb isnt callback | |
@constructor.unbind(event, binder) | |
@constructor.unbind("unbind", unbinder) | |
-- | |
1.7.10 | |
From 6efd7bbf31e0256c465bc0bf0f020838ee0316a3 Mon Sep 17 00:00:00 2001 | |
From: Chris Engebretson <[email protected]> | |
Date: Thu, 21 Feb 2013 18:31:09 -0600 | |
Subject: [PATCH 10/10] new spine.js build | |
--- | |
lib/spine.js | 10 +++++----- | |
1 file changed, 5 insertions(+), 5 deletions(-) | |
diff --git a/lib/spine.js b/lib/spine.js | |
index c5d3f77..69821b0 100644 | |
--- a/lib/spine.js | |
+++ b/lib/spine.js | |
@@ -625,7 +625,7 @@ | |
}; | |
Model.prototype.bind = function(events, callback) { | |
- var binder, evs, _fn, _i, _len, _ref, | |
+ var binder, singleEvent, _fn, _i, _len, _ref, | |
_this = this; | |
this.constructor.bind(events, binder = function(record) { | |
if (record && _this.eql(record)) { | |
@@ -633,11 +633,11 @@ | |
} | |
}); | |
_ref = events.split(' '); | |
- _fn = function(evs) { | |
+ _fn = function(singleEvent) { | |
var unbinder; | |
return _this.constructor.bind("unbind", unbinder = function(record, event, cb) { | |
if (record && _this.eql(record)) { | |
- if (event && event !== evs) { | |
+ if (event && event !== singleEvent) { | |
return; | |
} | |
if (cb && cb !== callback) { | |
@@ -649,8 +649,8 @@ | |
}); | |
}; | |
for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
- evs = _ref[_i]; | |
- _fn(evs); | |
+ singleEvent = _ref[_i]; | |
+ _fn(singleEvent); | |
} | |
return this; | |
}; | |
-- | |
1.7.10 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment