backbone-support 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -0
- data/lib/assets/javascripts/backbone-support.js +1 -0
- data/lib/assets/javascripts/backbone-support/composite_view.js +4 -16
- data/lib/assets/javascripts/backbone-support/observer.js +16 -0
- data/lib/backbone-support/version.rb +1 -1
- data/spec/javascripts/composite_view_spec.js +80 -4
- data/spec/javascripts/observer_spec.js +99 -0
- data/spec/javascripts/support/jasmine.yml +1 -0
- metadata +6 -3
data/CHANGELOG
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
Support.CompositeView = function(options) {
|
2
2
|
this.children = _([]);
|
3
|
-
this.bindings = _([]);
|
4
3
|
Backbone.View.apply(this, [options]);
|
5
4
|
};
|
6
5
|
|
7
|
-
_.extend(Support.CompositeView.prototype, Backbone.View.prototype, {
|
6
|
+
_.extend(Support.CompositeView.prototype, Backbone.View.prototype, Support.Observer.prototype, {
|
8
7
|
leave: function() {
|
8
|
+
this.trigger('leave');
|
9
9
|
this.unbind();
|
10
10
|
this.unbindFromAll();
|
11
11
|
this.remove();
|
@@ -13,18 +13,6 @@ _.extend(Support.CompositeView.prototype, Backbone.View.prototype, {
|
|
13
13
|
this._removeFromParent();
|
14
14
|
},
|
15
15
|
|
16
|
-
bindTo: function(source, event, callback) {
|
17
|
-
source.bind(event, callback, this);
|
18
|
-
this.bindings.push({ source: source, event: event, callback: callback });
|
19
|
-
},
|
20
|
-
|
21
|
-
unbindFromAll: function() {
|
22
|
-
this.bindings.each(function(binding) {
|
23
|
-
binding.source.unbind(binding.event, binding.callback);
|
24
|
-
});
|
25
|
-
this.bindings = _([]);
|
26
|
-
},
|
27
|
-
|
28
16
|
renderChild: function(view) {
|
29
17
|
view.render();
|
30
18
|
this.children.push(view);
|
@@ -33,7 +21,7 @@ _.extend(Support.CompositeView.prototype, Backbone.View.prototype, {
|
|
33
21
|
|
34
22
|
renderChildInto: function(view, container) {
|
35
23
|
this.renderChild(view);
|
36
|
-
|
24
|
+
this.$(container).empty().append(view.el);
|
37
25
|
},
|
38
26
|
|
39
27
|
appendChild: function(view) {
|
@@ -43,7 +31,7 @@ _.extend(Support.CompositeView.prototype, Backbone.View.prototype, {
|
|
43
31
|
|
44
32
|
appendChildTo: function (view, container) {
|
45
33
|
this.renderChild(view);
|
46
|
-
|
34
|
+
this.$(container).append(view.el);
|
47
35
|
},
|
48
36
|
|
49
37
|
prependChild: function(view) {
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Support.Observer = function() {};
|
2
|
+
|
3
|
+
_.extend(Support.Observer.prototype, {
|
4
|
+
bindTo: function(source, event, callback) {
|
5
|
+
source.bind(event, callback, this);
|
6
|
+
this.bindings = this.bindings || [];
|
7
|
+
this.bindings.push({ source: source, event: event, callback: callback });
|
8
|
+
},
|
9
|
+
|
10
|
+
unbindFromAll: function() {
|
11
|
+
_.each(this.bindings, function(binding) {
|
12
|
+
binding.source.unbind(binding.event, binding.callback);
|
13
|
+
});
|
14
|
+
this.bindings = []
|
15
|
+
}
|
16
|
+
});
|
@@ -42,12 +42,22 @@ describe("Support.CompositeView", function() {
|
|
42
42
|
describe("#renderChildInto", function() {
|
43
43
|
it("renders child into the given element and replaces content there", function() {
|
44
44
|
$("#test1").text("Replace this!");
|
45
|
+
$("#test").append($("#test1"));
|
45
46
|
|
46
47
|
var view = new blankView({el: "#test"});
|
47
48
|
view.renderChildInto(new orangeView(), "#test1");
|
48
49
|
|
49
|
-
expect($("#test").text()).toEqual("");
|
50
50
|
expect($("#test1").text()).toEqual("Orange!");
|
51
|
+
|
52
|
+
$("#test1").remove();
|
53
|
+
expect($("#test").text()).toEqual("");
|
54
|
+
});
|
55
|
+
|
56
|
+
it("renders child into a sub-element of the view, even if it is not yet added to the document", function() {
|
57
|
+
var view = new blankView({el: $('<div><div class="inside"></div></div>')});
|
58
|
+
view.renderChildInto(new orangeView(), ".inside");
|
59
|
+
|
60
|
+
expect($(view.el).find('.inside').text()).toEqual("Orange!");
|
51
61
|
});
|
52
62
|
});
|
53
63
|
|
@@ -64,12 +74,22 @@ describe("Support.CompositeView", function() {
|
|
64
74
|
describe("#appendChildTo", function() {
|
65
75
|
it("appends child into the given element", function() {
|
66
76
|
$("#test1").text("Append to this!");
|
67
|
-
|
77
|
+
$("#test").append($("#test1"));
|
78
|
+
|
68
79
|
var view = new blankView({el: "#test"});
|
69
80
|
view.appendChildTo(new orangeView(), "#test1");
|
70
|
-
|
71
|
-
expect($("#test").text()).toEqual("");
|
81
|
+
|
72
82
|
expect($("#test1").text()).toEqual("Append to this!Orange!");
|
83
|
+
|
84
|
+
$("#test1").remove();
|
85
|
+
expect($("#test").text()).toEqual("");
|
86
|
+
});
|
87
|
+
|
88
|
+
it("appends child into a sub-element even if it is not added to the document", function() {
|
89
|
+
var view = new blankView({el: $('<div><div class="inside">Append to this!</div></div>')});
|
90
|
+
view.appendChildTo(new orangeView(), ".inside");
|
91
|
+
|
92
|
+
expect($(view.el).find('.inside').text()).toEqual("Append to this!Orange!");
|
73
93
|
});
|
74
94
|
});
|
75
95
|
|
@@ -184,5 +204,61 @@ describe("Support.CompositeView", function() {
|
|
184
204
|
|
185
205
|
expect(eventListener.called).toBeFalsy();
|
186
206
|
});
|
207
|
+
|
208
|
+
it("fires leave event", function() {
|
209
|
+
var eventListener = sinon.spy();
|
210
|
+
var view = new (Support.CompositeView.extend({
|
211
|
+
initialize: function(options) {
|
212
|
+
this.bindTo(this, 'leave', eventListener);
|
213
|
+
}
|
214
|
+
}))({model: {}});
|
215
|
+
|
216
|
+
view.leave();
|
217
|
+
|
218
|
+
expect(eventListener.called).toBeTruthy();
|
219
|
+
});
|
187
220
|
});
|
221
|
+
|
222
|
+
describe("#bindTo", function() {
|
223
|
+
var view = new orangeView();
|
224
|
+
var callback = sinon.spy();
|
225
|
+
var source = new Backbone.Model({
|
226
|
+
title: 'Model or Collection'
|
227
|
+
});
|
228
|
+
|
229
|
+
it("calls the unbindFromAll method when leaving the view", function() {
|
230
|
+
view.bindTo(source, 'foobar', callback);
|
231
|
+
expect(view.bindings.length).toEqual(1);
|
232
|
+
});
|
233
|
+
});
|
234
|
+
|
235
|
+
describe("#unbindFromAll", function() {
|
236
|
+
var view = new orangeView();
|
237
|
+
var spy = sinon.spy(view, 'unbindFromAll');
|
238
|
+
var callback = sinon.spy();
|
239
|
+
var source = new Backbone.Model({
|
240
|
+
title: 'Model or Collection'
|
241
|
+
});
|
242
|
+
|
243
|
+
runs(function() {
|
244
|
+
view.render();
|
245
|
+
view.bindTo(source, 'foo', callback);
|
246
|
+
expect(view.bindings.length).toEqual(1);
|
247
|
+
});
|
248
|
+
|
249
|
+
Helpers.sleep();
|
250
|
+
|
251
|
+
runs(function() {
|
252
|
+
view.leave();
|
253
|
+
});
|
254
|
+
|
255
|
+
Helpers.sleep();
|
256
|
+
|
257
|
+
it("calls the unbindFromAll method when leaving the view", function() {
|
258
|
+
runs(function() {
|
259
|
+
expect(spy.called).toBeTruthy();
|
260
|
+
});
|
261
|
+
});
|
262
|
+
});
|
263
|
+
|
188
264
|
});
|
@@ -0,0 +1,99 @@
|
|
1
|
+
describe('Support.Observer', function() {
|
2
|
+
|
3
|
+
var normalView = Support.CompositeView.extend({
|
4
|
+
render: function() {
|
5
|
+
var text = this.make("span", {}, "Normal!");
|
6
|
+
$(this.el).append(text);
|
7
|
+
},
|
8
|
+
leave: function() {
|
9
|
+
this.unbindFromAll();
|
10
|
+
}
|
11
|
+
});
|
12
|
+
|
13
|
+
beforeEach(function() {
|
14
|
+
Helpers.setup();
|
15
|
+
Helpers.append("test1");
|
16
|
+
Helpers.append("test2");
|
17
|
+
});
|
18
|
+
|
19
|
+
afterEach(function() {
|
20
|
+
Helpers.teardown();
|
21
|
+
});
|
22
|
+
|
23
|
+
describe("#bindTo", function() {
|
24
|
+
var view, spy, source, callback;
|
25
|
+
beforeEach(function() { Helpers.setup();
|
26
|
+
view = new normalView();
|
27
|
+
spy = sinon.spy(view, "bindTo");
|
28
|
+
callback = sinon.spy();
|
29
|
+
|
30
|
+
source = new Backbone.Model({
|
31
|
+
title: 'Model or Collection'
|
32
|
+
});
|
33
|
+
});
|
34
|
+
|
35
|
+
afterEach(function() {
|
36
|
+
view, spy, source, callback = null;
|
37
|
+
});
|
38
|
+
|
39
|
+
it("should add the event to the bindings for the view", function() {
|
40
|
+
view.bindTo(source, 'foobar', callback);
|
41
|
+
expect(view.bindings.length).toEqual(1);
|
42
|
+
});
|
43
|
+
|
44
|
+
it("binds the event to the source object", function() {
|
45
|
+
var mock = sinon.mock(source).expects('bind').once();
|
46
|
+
|
47
|
+
view.bindTo(source, 'change:title', callback);
|
48
|
+
|
49
|
+
mock.verify();
|
50
|
+
});
|
51
|
+
});
|
52
|
+
|
53
|
+
describe("#unbindFromAll", function() {
|
54
|
+
var view, spy, mock;
|
55
|
+
beforeEach(function() {
|
56
|
+
view = new normalView();
|
57
|
+
spy = sinon.spy(view, 'unbindFromAll');
|
58
|
+
callback = sinon.spy();
|
59
|
+
source = new Backbone.Model({
|
60
|
+
title: 'Model or Collection'
|
61
|
+
});
|
62
|
+
unbindSpy = sinon.spy(source, 'unbind');
|
63
|
+
|
64
|
+
runs(function() {
|
65
|
+
view.render();
|
66
|
+
view.bindTo(source, 'foo', callback);
|
67
|
+
view.bindTo(source, 'bar', callback);
|
68
|
+
expect(view.bindings.length).toEqual(2);
|
69
|
+
});
|
70
|
+
|
71
|
+
Helpers.sleep();
|
72
|
+
|
73
|
+
runs(function() {
|
74
|
+
view.leave();
|
75
|
+
});
|
76
|
+
|
77
|
+
Helpers.sleep();
|
78
|
+
});
|
79
|
+
|
80
|
+
it("calls the unbindFromAll method when leaving the view", function() {
|
81
|
+
runs(function() {
|
82
|
+
expect(spy.called).toBeTruthy();
|
83
|
+
});
|
84
|
+
});
|
85
|
+
|
86
|
+
it("calls unbind on the source object", function() {
|
87
|
+
runs(function() {
|
88
|
+
expect(unbindSpy.calledTwice).toBeTruthy();
|
89
|
+
});
|
90
|
+
});
|
91
|
+
|
92
|
+
it("removes all the views bindings attached with bindTo", function() {
|
93
|
+
runs(function() {
|
94
|
+
expect(view.bindings.length).toEqual(0);
|
95
|
+
});
|
96
|
+
});
|
97
|
+
});
|
98
|
+
|
99
|
+
});
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backbone-support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date:
|
15
|
+
date: 2013-03-05 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: jasmine
|
@@ -47,6 +47,7 @@ files:
|
|
47
47
|
- backbone-support.gemspec
|
48
48
|
- lib/assets/javascripts/backbone-support.js
|
49
49
|
- lib/assets/javascripts/backbone-support/composite_view.js
|
50
|
+
- lib/assets/javascripts/backbone-support/observer.js
|
50
51
|
- lib/assets/javascripts/backbone-support/support.js
|
51
52
|
- lib/assets/javascripts/backbone-support/swapping_router.js
|
52
53
|
- lib/backbone-support.rb
|
@@ -55,6 +56,7 @@ files:
|
|
55
56
|
- spec/javascripts/composite_view_spec.js
|
56
57
|
- spec/javascripts/helpers/helpers.js
|
57
58
|
- spec/javascripts/helpers/sinon-1.1.1.js
|
59
|
+
- spec/javascripts/observer_spec.js
|
58
60
|
- spec/javascripts/support/jasmine.yml
|
59
61
|
- spec/javascripts/support/jasmine_config.rb
|
60
62
|
- spec/javascripts/support/jasmine_runner.rb
|
@@ -82,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
84
|
version: '0'
|
83
85
|
requirements: []
|
84
86
|
rubyforge_project:
|
85
|
-
rubygems_version: 1.8.
|
87
|
+
rubygems_version: 1.8.23
|
86
88
|
signing_key:
|
87
89
|
specification_version: 3
|
88
90
|
summary: SwappingController and CompositeView for Backbone.js
|
@@ -90,6 +92,7 @@ test_files:
|
|
90
92
|
- spec/javascripts/composite_view_spec.js
|
91
93
|
- spec/javascripts/helpers/helpers.js
|
92
94
|
- spec/javascripts/helpers/sinon-1.1.1.js
|
95
|
+
- spec/javascripts/observer_spec.js
|
93
96
|
- spec/javascripts/support/jasmine.yml
|
94
97
|
- spec/javascripts/support/jasmine_config.rb
|
95
98
|
- spec/javascripts/support/jasmine_runner.rb
|