honkster-jelly 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -17,8 +17,8 @@ if(!window.Jelly) window.Jelly = {};
17
17
  return $.extend({
18
18
  dataType: 'json',
19
19
  cache: false,
20
- success : function(callbacks) {
21
- Jelly.Observers.notify.call(otherParams.observers || Jelly.observers, callbacks);
20
+ success : function(ops) {
21
+ Jelly.Observers.run.apply(otherParams.observers || Jelly.observers, ops);
22
22
  }
23
23
  }, otherParams);
24
24
  };
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Jelly. a sweet unobtrusive javascript framework for Rails
3
3
  *
4
- * version 0.12.0
4
+ * version 0.13.0
5
5
  *
6
6
  * Copyright (c) 2009 Pivotal Labs
7
7
  * Licensed under the MIT license.
@@ -32,38 +32,46 @@
32
32
  extend(Jelly, {
33
33
  init:function () {
34
34
  this.observers = [];
35
+ this.run = this.Observers.run;
35
36
  this.attach = this.Observers.attach;
36
37
  this.notifyObservers = this.Observers.notify;
37
38
  this.Pages.init();
38
39
  },
39
40
 
40
41
  Observers:{
41
- attach:function () {
42
+ run:function () {
42
43
  if (this === Jelly) {
43
- return Jelly.Observers.attach.apply(this.observers, arguments);
44
+ return Jelly.Observers.run.apply(this.observers, arguments);
44
45
  }
45
- var self = Jelly.Observers;
46
- for (var i = 0; i < arguments.length; i++) {
47
- var definitionOrComponent = arguments[i];
48
- if (definitionOrComponent.component) {
49
- self.attachFromDefinition.call(
50
- this,
51
- self.evaluateComponent(definitionOrComponent.component),
52
- definitionOrComponent.arguments
53
- );
54
- } else if (Object.prototype.toString.call(definitionOrComponent) === "[object Array]") {
55
- self.attachFromDefinition.call(
56
- this,
57
- self.evaluateComponent(definitionOrComponent[0]),
58
- definitionOrComponent.slice(1)
59
- );
60
- } else {
61
- self.pushIfObserver.call(this, Jelly.Observers.evaluateComponent(definitionOrComponent));
46
+ for (var i=0, len=arguments.length; i < len; i++) {
47
+ var op = arguments[i];
48
+ switch (op[0]) {
49
+ case ("attach"):
50
+ Jelly.Observers.runAttachOp.call(this, op);
51
+ break;
52
+ case ("notify"):
53
+ Jelly.Observers.runNotifyOp.call(this, op);
54
+ break;
62
55
  }
56
+
57
+ }
58
+ },
59
+
60
+ runAttachOp:function (op) {
61
+ if (op[0] !== "attach") {
62
+ throw "op " + JSON.stringify(op) + " is not an attach op"
63
63
  }
64
+ var args = [op[1]];
65
+ args.concat.apply(args, op.slice(2));
66
+ Jelly.Observers.attach.apply(this, args);
64
67
  },
65
68
 
66
- attachFromDefinition:function (component, args) {
69
+ attach:function () {
70
+ if (this === Jelly) {
71
+ return Jelly.Observers.attach.apply(this.observers, arguments);
72
+ }
73
+ var component = Jelly.Observers.evaluateComponent(arguments[0]);
74
+ var args = Array.prototype.slice.call(arguments, 1);
67
75
  if (component.init) {
68
76
  var initReturnValue = component.init.apply(component, args);
69
77
  if (initReturnValue === false || initReturnValue === null) {
@@ -85,50 +93,38 @@
85
93
  }
86
94
  },
87
95
 
88
- notify:function (instructions) {
96
+ runNotifyOp:function(op) {
97
+ if (op[0] !== "notify") {
98
+ throw "op " + JSON.stringify(op) + " is not a notify op"
99
+ }
100
+ var args = [op[1]];
101
+ args.push.apply(args, op.slice(2));
102
+ Jelly.Observers.notify.apply(this, args);
103
+ },
104
+
105
+ notify:function () {
89
106
  if (this === Jelly) {
90
107
  return Jelly.Observers.notify.apply(this.observers, arguments);
91
108
  }
92
- var previousNotifying = Jelly.Observers.notifying;
93
- Jelly.Observers.notifying = true;
94
- if (Object.prototype.toString.call(instructions) !== "[object Array]") {
95
- instructions = [instructions];
96
- }
97
109
 
98
- var pristineObservers = this.slice(0);
99
- var observers;
100
- for (var i = 0; i < instructions.length; i++) {
101
- var instruction = instructions[i];
102
-
103
- // Deprecate 'on' in favor of making each page action a Component.
104
- if (instruction.on) {
105
- observers = [eval(instruction.on)];
106
- } else {
107
- observers = pristineObservers;
108
- }
109
-
110
- if (instruction.method) {
111
- for (var j = 0; j < observers.length; j++) {
112
- var observer = observers[j];
113
- Jelly.Observers.notifyObserver.call(this, observer, instruction.method, instruction.arguments);
114
- Jelly.Observers.notifyObserver.call(this, observer, 'on_notify', [instruction]);
115
- }
116
- }
117
-
118
- if (instruction.attach) {
119
- Jelly.Observers.attach.apply(this, instruction.attach);
120
- }
110
+ var observers = this.slice(0);
111
+ var message = arguments[0];
112
+ var args = Array.prototype.slice.call(arguments, 1);
113
+ var instruction = [message];
114
+ instruction.push.apply(instruction, args);
115
+ for (var i = 0, len = observers.length; i < len; i++) {
116
+ var observer = observers[i];
117
+ Jelly.Observers.notifyObserver.call(this, observer, message, args);
118
+ Jelly.Observers.notifyObserver.call(this, observer, 'on_notify', instruction);
121
119
  }
122
-
123
- Jelly.Observers.notifying = previousNotifying;
124
120
  },
125
121
 
126
- notifyObserver:function (observer, method, arguments) {
122
+ notifyObserver:function (observer, method, args) {
127
123
  if (observer[method]) {
128
124
  if (observer.detach && observer.detach()) {
129
125
  Jelly.Observers.garbageCollectObserver.call(this, observer);
130
126
  } else {
131
- observer[method].apply(observer, arguments);
127
+ observer[method].apply(observer, args);
132
128
  }
133
129
  }
134
130
  },
@@ -1,28 +1,44 @@
1
1
  module Jelly
2
+ class OldMethodError < NotImplementedError
3
+ end
4
+
2
5
  module Common
6
+ def jelly_attach_op(component_name, *args)
7
+ ["attach", component_name, *args]
8
+ end
9
+
10
+ def jelly_notify_op(message_name, *args)
11
+ ["notify", message_name, *args]
12
+ end
13
+
14
+ def jelly_call_op(object, method, *args)
15
+ ["call", object, method, *args]
16
+ end
17
+
18
+ ### Old Methods ###
19
+
3
20
  def jelly_notify_hash(method, *arguments)
4
- {"method" => method, "arguments" => arguments}
21
+ raise Jelly::OldMethodError
5
22
  end
6
23
 
7
24
  def jelly_callback_hash(method, *arguments)
8
- warn "jelly_callback_hash has been deprecated. Please use jelly_notify_hash instead"
9
- jelly_notify_hash(method, *arguments)
25
+ raise Jelly::OldMethodError
10
26
  end
11
27
 
12
28
  def jelly_method_call_hash(object, method, *arguments)
13
- {"on" => object, "method" => method, "arguments" => arguments}
29
+ raise Jelly::OldMethodError
14
30
  end
15
31
 
16
- def jelly_notify_attach_hash (components=jelly_attachments)
17
- {"attach" => components}
32
+ def jelly_notify_attach_hash (components=jelly_ops)
33
+ raise Jelly::OldMethodError
18
34
  end
19
35
 
20
36
  def jelly_attachment_hash(component_name, *args)
21
- {'component' => component_name, 'arguments' => args}
37
+ raise Jelly::OldMethodError
22
38
  end
23
39
 
24
40
  def jelly_attachment_array(component_name, *args)
25
- [component_name, *args]
41
+ raise Jelly::OldMethodError
26
42
  end
27
43
  end
28
44
  end
@@ -2,15 +2,7 @@ module JellyController
2
2
  protected
3
3
  include Jelly::Common
4
4
 
5
- def jelly_callback(callback_base_name = @action_name, options = {}, &block)
6
- raw_jelly_callback(options) do
7
- arguments = block ? instance_eval(&block) : []
8
- arguments = [arguments] unless arguments.is_a?(Array)
9
- jelly_notify_hash("on_#{callback_base_name}", *arguments).merge(options)
10
- end
11
- end
12
-
13
- def raw_jelly_callback(options={}, &block)
5
+ def render_jelly_ops(options={}, &block)
14
6
  options.symbolize_keys!
15
7
  options[:format] ||= if params[:callback]
16
8
  :jsonp
@@ -19,23 +11,52 @@ module JellyController
19
11
  else
20
12
  :iframe
21
13
  end
22
- render :inline => jelly_callback_erb(options, &block)
14
+ render :inline => render_jelly_ops_erb(options, &block)
23
15
  end
24
16
 
25
- def jelly_callback_erb(options={}, &block)
17
+ def render_jelly_ops_erb(options={}, &block)
26
18
  options[:format] ||= :json
27
19
  @jelly_block = block
28
20
  case options[:format].to_sym
29
21
  when :iframe
30
- "<textarea>#{jelly_callback_erb_template}</textarea>"
22
+ <<-ERB
23
+ <textarea>#{render_jelly_ops_erb_template}</textarea>
24
+ ERB
31
25
  when :jsonp
32
- "#{params[:callback]}(#{jelly_callback_erb_template});"
26
+ <<-ERB
27
+ #{params[:callback]}(#{render_jelly_ops_erb_template});
28
+ ERB
33
29
  else
34
- jelly_callback_erb_template
30
+ <<-ERB
31
+ #{render_jelly_ops_erb_template}
32
+ ERB
35
33
  end
36
34
  end
37
35
 
36
+ def render_jelly_ops_erb_template
37
+ <<-ERB
38
+ <%=begin
39
+ instance_eval(&controller.instance_variable_get(:@jelly_block))
40
+ jelly_ops.to_json.html_safe
41
+ end -%>
42
+ ERB
43
+ end
44
+
45
+ ### Old Methods ###
46
+
47
+ def jelly_callback(callback_base_name = @action_name, options = {}, &block)
48
+ raise Jelly::OldMethodError
49
+ end
50
+
51
+ def raw_jelly_callback(options={}, &block)
52
+ raise Jelly::OldMethodError
53
+ end
54
+
55
+ def jelly_callback_erb(options={}, &block)
56
+ raise Jelly::OldMethodError
57
+ end
58
+
38
59
  def jelly_callback_erb_template
39
- %Q{<%= instance_eval(&controller.instance_variable_get(:@jelly_block)).to_json.html_safe %>}
60
+ raise Jelly::OldMethodError
40
61
  end
41
62
  end
@@ -12,33 +12,61 @@ module JellyHelper
12
12
  end
13
13
 
14
14
  def spread_jelly
15
- attach_javascript_component("Jelly.Location")
16
- attach_javascript_component("Jelly.Page", controller.controller_path.camelcase, controller.action_name)
17
- attach_javascript_component_javascript_tag(jelly_attachments)
15
+ jelly_attach("Jelly.Location")
16
+ jelly_attach("Jelly.Page", controller.controller_path.camelcase, controller.action_name)
17
+ jelly_run_javascript_tag(jelly_ops)
18
18
  end
19
19
 
20
+ def jelly_run_javascript_tag(ops)
21
+ javascript_tag jelly_run_javascript(ops)
22
+ end
23
+
24
+ def jelly_run_javascript(ops)
25
+ "Jelly.run.apply(Jelly, #{ops.to_json});"
26
+ end
27
+
28
+ def jelly_clear_ops
29
+ jelly_ops.clear
30
+ end
31
+
32
+ def jelly_attach(component_name, *args)
33
+ op = jelly_attach_op(component_name, *args)
34
+ unless jelly_ops.include? op
35
+ jelly_ops << op
36
+ end
37
+ end
38
+
39
+ def jelly_notify(message_name, *args)
40
+ op = jelly_notify_op(message_name, *args)
41
+ unless jelly_ops.include? op
42
+ jelly_ops << op
43
+ end
44
+ end
45
+
46
+ def jelly_ops
47
+ @jelly_ops ||= []
48
+ end
49
+
50
+ ### Old Methods ###
51
+
20
52
  def attach_javascript_component_javascript_tag(components)
21
- javascript_tag "Jelly.attach.apply(Jelly, #{components.to_json});"
53
+ raise Jelly::OldMethodError
22
54
  end
23
55
 
24
56
  def clear_jelly_attached
25
- jelly_attachments.clear
57
+ raise Jelly::OldMethodError
26
58
  end
27
59
 
28
60
  def attach_javascript_component(component_name, *args)
29
- key = jelly_attachment_array(component_name, *args)
30
- unless jelly_attachments.include? key
31
- jelly_attachments << key
32
- end
61
+ raise Jelly::OldMethodError
33
62
  end
34
63
 
35
- def attach_javascript_component_on_ready(component_name, *args)
36
- warn "attach_javascript_component_on_ready is deprecated since attach_javascript_component adds components to be attached in a $(document).ready block\n#{puts caller.join("\n\t")}"
37
- attach_javascript_component(component_name, *args)
64
+ def jelly_attach_on_ready(component_name, *args)
65
+ raise Jelly::OldMethodError
38
66
  end
39
67
 
40
68
  def jelly_attachments
41
- @jelly_attachments ||= []
69
+ raise Jelly::OldMethodError
42
70
  end
43
71
 
44
72
  end
@@ -1,6 +1,4 @@
1
1
  describe("Jelly", function() {
2
- var our_token;
3
-
4
2
  beforeEach(function() {
5
3
  Jelly.add("MyPage", {
6
4
  on_my_method : function() {
@@ -8,8 +6,6 @@ describe("Jelly", function() {
8
6
  });
9
7
  page = Jelly.all["MyPage"];
10
8
  spyOn($, 'ajax');
11
- our_token = "authenticity token";
12
- window._token = our_token;
13
9
  });
14
10
 
15
11
  afterEach(function() {
@@ -57,14 +53,11 @@ describe("Jelly", function() {
57
53
  observerArgs = [arg1, arg2];
58
54
  }
59
55
  };
60
- Jelly.attach({component: observer, arguments: []});
56
+ Jelly.attach(observer);
61
57
  expect(Jelly.observers).toContain(observer);
62
58
 
63
- var notification = {
64
- "arguments":["arg1", "arg2"],
65
- "method":"on_my_method"
66
- };
67
- $.ajaxWithJelly.params().success(notification);
59
+ var op = ["notify", "on_my_method", "arg1", "arg2"];
60
+ $.ajaxWithJelly.params().success([op]);
68
61
 
69
62
  expect(observerArgs).toEqual(["arg1", "arg2"]);
70
63
  });
@@ -81,11 +74,8 @@ describe("Jelly", function() {
81
74
  var observers = [observer];
82
75
  expect(Jelly.observers).toNotContain(observer);
83
76
 
84
- var notification = {
85
- "arguments":["arg1", "arg2"],
86
- "method":"on_my_method"
87
- };
88
- $.ajaxWithJelly.params({observers: observers}).success(notification);
77
+ var op = ["notify", "on_my_method", "arg1", "arg2"];
78
+ $.ajaxWithJelly.params({observers: observers}).success([op]);
89
79
 
90
80
  expect(observerArgs).toEqual(["arg1", "arg2"]);
91
81
  });
@@ -30,136 +30,71 @@ describe("Jelly", function() {
30
30
  expect(newPage.index).toEqual(indexFn);
31
31
  });
32
32
  });
33
-
34
- describe(".attach", function() {
35
- describe("when the argument contains a 'component' key", function() {
33
+
34
+ describe(".run", function() {
35
+ describe("attach", function() {
36
36
  describe("when the component does not respond to init", function() {
37
37
  describe("when the component is referenced as a String", function() {
38
38
  beforeEach(function() {
39
39
  window.MyComponent = {
40
40
  };
41
41
  });
42
-
42
+
43
43
  afterEach(function() {
44
44
  delete window.MyComponent;
45
45
  });
46
-
46
+
47
47
  it("attaches the component to Jelly.observers", function() {
48
- Jelly.attach({component: "MyComponent"});
48
+ Jelly.run(["attach", "MyComponent"]);
49
49
  expect(Jelly.observers).toContain(MyComponent);
50
50
  });
51
51
  });
52
-
52
+
53
53
  describe("when the component is referenced as itself", function() {
54
54
  it("attaches the component to Jelly.observers", function() {
55
55
  var component = {};
56
- Jelly.attach({component: component});
56
+ Jelly.run(["attach", component]);
57
57
  expect(Jelly.observers).toContain(component);
58
58
  });
59
59
  });
60
- });
61
-
62
- describe("when component responds to init", function() {
63
- describe("when the component's init method returns undefined", function() {
64
- describe("when the component is referenced as a String", function() {
65
- beforeEach(function() {
66
- window.MyComponent = {
67
- init: function() {
68
- }
69
- };
70
- });
71
-
72
- afterEach(function() {
73
- delete window.MyComponent;
74
- });
75
-
76
- it("calls the init method on the component and attaches the component to Jelly.observers", function() {
77
- spyOn(MyComponent, 'init');
78
- Jelly.attach({component: MyComponent, arguments: [1, 2]});
79
- expect(MyComponent.init).wasCalledWith(1, 2);
80
- expect(Jelly.observers).toContain(MyComponent);
81
- });
82
- });
83
-
84
- describe("when the component is referenced as itself", function() {
85
- var component;
86
- beforeEach(function() {
87
- component = {
88
- init: function() {
89
- }
90
- };
91
- });
60
+ })
61
+ });
62
+ });
92
63
 
93
- it("calls the init method on the component and attaches the component to Jelly.observers", function() {
94
- spyOn(component, 'init');
95
- Jelly.attach({component: component, arguments: [1, 2]});
96
- expect(component.init).wasCalledWith(1, 2);
97
- expect(Jelly.observers).toContain(component);
98
- });
99
- });
64
+ describe(".attach", function() {
65
+ describe("when the component does not respond to init", function() {
66
+ describe("when the component is referenced as a String", function() {
67
+ beforeEach(function() {
68
+ window.MyComponent = {
69
+ };
100
70
  });
101
71
 
102
- describe("when the component's init method returns false", function() {
103
- var component;
104
- beforeEach(function() {
105
- component = {
106
- init: function() {
107
- component.initCalled = true;
108
- return false;
109
- }
110
- };
111
- });
112
-
113
- it("calls the init method on the component and does not attaches an observer to Jelly.observers", function() {
114
- var originalObserversLength = Jelly.observers.length;
115
- Jelly.attach({component: component, arguments: [1, 2]});
116
- expect(component.initCalled).toBeTruthy();
117
- expect(Jelly.observers.length).toEqual(originalObserversLength);
118
- expect(Jelly.observers).toNotContain(component);
119
- });
72
+ afterEach(function() {
73
+ delete window.MyComponent;
120
74
  });
121
75
 
122
- describe("when the component's init method returns null", function() {
123
- var component;
124
- beforeEach(function() {
125
- component = {
126
- init: function() {
127
- component.initCalled = true;
128
- return null;
129
- }
130
- };
131
- });
132
-
133
- it("calls the init method on the component and does not attaches an observer to Jelly.observers", function() {
134
- var originalObserversLength = Jelly.observers.length;
135
- Jelly.attach({component: component, arguments: [1, 2]});
136
- expect(component.initCalled).toBeTruthy();
137
- expect(Jelly.observers.length).toEqual(originalObserversLength);
138
- expect(Jelly.observers).toNotContain(component);
139
- });
76
+ it("attaches the component to Jelly.observers", function() {
77
+ Jelly.attach("MyComponent");
78
+ expect(Jelly.observers).toContain(MyComponent);
140
79
  });
80
+ });
141
81
 
142
- describe("when the component's init method returns an object", function() {
143
- it("attaches the returned object (instead of the component) to Jelly.observers", function() {
144
- var observer = new Object();
145
- var component = {
146
- init: function() {
147
- return observer;
148
- }
149
- };
150
- Jelly.attach({component: component, arguments: [1, 2]});
151
- expect(Jelly.observers).toContain(observer);
152
- expect(Jelly.observers).toNotContain(component);
153
- });
82
+ describe("when the component is referenced as itself", function() {
83
+ it("attaches the component to Jelly.observers", function() {
84
+ var component = {};
85
+ Jelly.attach(component);
86
+ expect(Jelly.observers).toContain(component);
154
87
  });
155
88
  });
156
89
  });
157
90
 
158
- describe("when the argument is an array", function() {
159
- describe("when the component does not respond to init", function() {
91
+ describe("when component responds to init", function() {
92
+ describe("when the component's init method returns undefined", function() {
160
93
  describe("when the component is referenced as a String", function() {
161
94
  beforeEach(function() {
162
95
  window.MyComponent = {
96
+ init: function() {
97
+ }
163
98
  };
164
99
  });
165
100
 
@@ -167,148 +102,83 @@ describe("Jelly", function() {
167
102
  delete window.MyComponent;
168
103
  });
169
104
 
170
- it("attaches the component to Jelly.observers", function() {
171
- Jelly.attach(["MyComponent"]);
105
+ it("calls the init method on the component and attaches the component to Jelly.observers", function() {
106
+ spyOn(MyComponent, 'init');
107
+ Jelly.attach(MyComponent, 1, 2);
108
+ expect(MyComponent.init).wasCalledWith(1, 2);
172
109
  expect(Jelly.observers).toContain(MyComponent);
173
110
  });
174
111
  });
175
112
 
176
113
  describe("when the component is referenced as itself", function() {
177
- it("attaches the component to Jelly.observers", function() {
178
- var component = {};
179
- Jelly.attach([component]);
180
- expect(Jelly.observers).toContain(component);
181
- });
182
- });
183
- });
184
-
185
- describe("when component responds to init", function() {
186
- describe("when the component's init method returns undefined", function() {
187
- describe("when the component is referenced as a String", function() {
188
- beforeEach(function() {
189
- window.MyComponent = {
190
- init: function() {
191
- }
192
- };
193
- });
194
-
195
- afterEach(function() {
196
- delete window.MyComponent;
197
- });
198
-
199
- it("calls the init method on the component and attaches the component to Jelly.observers", function() {
200
- spyOn(MyComponent, 'init');
201
- Jelly.attach([MyComponent, 1, 2]);
202
- expect(MyComponent.init).wasCalledWith(1, 2);
203
- expect(Jelly.observers).toContain(MyComponent);
204
- });
205
- });
206
-
207
- describe("when the component is referenced as itself", function() {
208
- var component;
209
- beforeEach(function() {
210
- component = {
211
- init: function() {
212
- }
213
- };
214
- });
215
-
216
- it("calls the init method on the component and attaches the component to Jelly.observers", function() {
217
- spyOn(component, 'init');
218
- Jelly.attach([component, 1, 2]);
219
- expect(component.init).wasCalledWith(1, 2);
220
- expect(Jelly.observers).toContain(component);
221
- });
222
- });
223
- });
224
-
225
- describe("when the component's init method returns false", function() {
226
114
  var component;
227
115
  beforeEach(function() {
228
116
  component = {
229
117
  init: function() {
230
- component.initCalled = true;
231
- return false;
232
118
  }
233
119
  };
234
120
  });
235
121
 
236
- it("calls the init method on the component and does not attaches an observer to Jelly.observers", function() {
237
- var originalObserversLength = Jelly.observers.length;
238
- Jelly.attach([component, 1, 2]);
239
- expect(component.initCalled).toBeTruthy();
240
- expect(Jelly.observers.length).toEqual(originalObserversLength);
241
- expect(Jelly.observers).toNotContain(component);
122
+ it("calls the init method on the component and attaches the component to Jelly.observers", function() {
123
+ spyOn(component, 'init');
124
+ Jelly.attach(component, 1, 2);
125
+ expect(component.init).wasCalledWith(1, 2);
126
+ expect(Jelly.observers).toContain(component);
242
127
  });
243
128
  });
129
+ });
244
130
 
245
- describe("when the component's init method returns null", function() {
246
- var component;
247
- beforeEach(function() {
248
- component = {
249
- init: function() {
250
- component.initCalled = true;
251
- return null;
252
- }
253
- };
254
- });
255
-
256
- it("calls the init method on the component and does not attaches an observer to Jelly.observers", function() {
257
- var originalObserversLength = Jelly.observers.length;
258
- Jelly.attach([component, 1, 2]);
259
- expect(component.initCalled).toBeTruthy();
260
- expect(Jelly.observers.length).toEqual(originalObserversLength);
261
- expect(Jelly.observers).toNotContain(component);
262
- });
131
+ describe("when the component's init method returns false", function() {
132
+ var component;
133
+ beforeEach(function() {
134
+ component = {
135
+ init: function() {
136
+ component.initCalled = true;
137
+ return false;
138
+ }
139
+ };
263
140
  });
264
141
 
265
- describe("when the component's init method returns an object", function() {
266
- it("attaches the returned object (instead of the component) to Jelly.observers", function() {
267
- var observer = new Object();
268
- var component = {
269
- init: function() {
270
- return observer;
271
- }
272
- };
273
- Jelly.attach([component, 1, 2]);
274
- expect(Jelly.observers).toContain(observer);
275
- expect(Jelly.observers).toNotContain(component);
276
- });
142
+ it("calls the init method on the component and does not attaches an observer to Jelly.observers", function() {
143
+ var originalObserversLength = Jelly.observers.length;
144
+ Jelly.attach(component, 1, 2);
145
+ expect(component.initCalled).toBeTruthy();
146
+ expect(Jelly.observers.length).toEqual(originalObserversLength);
147
+ expect(Jelly.observers).toNotContain(component);
277
148
  });
278
149
  });
279
- });
280
150
 
281
- describe("when the argument does not contain a 'component' key", function() {
282
- describe("when the component is referenced as a String", function() {
151
+ describe("when the component's init method returns null", function() {
152
+ var component;
283
153
  beforeEach(function() {
284
- window.MyComponent = {
154
+ component = {
285
155
  init: function() {
156
+ component.initCalled = true;
157
+ return null;
286
158
  }
287
159
  };
288
160
  });
289
161
 
290
- afterEach(function() {
291
- delete window.MyComponent;
292
- });
293
-
294
- it("does not call init and attaches the component to Jelly.observers", function() {
295
- spyOn(MyComponent, 'init');
296
- Jelly.attach("MyComponent");
297
- expect(MyComponent.init).wasNotCalled();
298
- expect(Jelly.observers).toContain(MyComponent);
162
+ it("calls the init method on the component and does not attaches an observer to Jelly.observers", function() {
163
+ var originalObserversLength = Jelly.observers.length;
164
+ Jelly.attach(component, 1, 2);
165
+ expect(component.initCalled).toBeTruthy();
166
+ expect(Jelly.observers.length).toEqual(originalObserversLength);
167
+ expect(Jelly.observers).toNotContain(component);
299
168
  });
300
169
  });
301
170
 
302
- describe("when the component is referenced as itself", function() {
303
- it("does not call init and attaches the component to Jelly.observers", function() {
171
+ describe("when the component's init method returns an object", function() {
172
+ it("attaches the returned object (instead of the component) to Jelly.observers", function() {
173
+ var observer = new Object();
304
174
  var component = {
305
175
  init: function() {
176
+ return observer;
306
177
  }
307
178
  };
308
- spyOn(component, 'init');
309
- Jelly.attach(component);
310
- expect(component.init).wasNotCalled();
311
- expect(Jelly.observers).toContain(component);
179
+ Jelly.attach(component, 1, 2);
180
+ expect(Jelly.observers).toContain(observer);
181
+ expect(Jelly.observers).toNotContain(component);
312
182
  });
313
183
  });
314
184
  });
@@ -320,31 +190,7 @@ describe("Jelly", function() {
320
190
  on_my_method : function() {
321
191
  }
322
192
  });
323
- Jelly.attach({component: "Jelly.Page", arguments: ["MyPage", "index"]});
324
- });
325
-
326
- describe(".notifying", function() {
327
- it("should be set to true only while observers are being notified", function() {
328
- expect(Jelly.Observers.notifying).toBe(false);
329
- var notifyingWasSet = false;
330
- page.on_my_method = function() {
331
- notifyingWasSet = Jelly.Observers.notifying;
332
- }
333
- Jelly.notifyObservers({
334
- "method":"on_my_method"
335
- });
336
- expect(notifyingWasSet).toBe(true);
337
- });
338
-
339
- it("should be reset to its prior value when notification is complete", function() {
340
- Jelly.Observers.notifying = true;
341
- spyOn(page, 'on_my_method');
342
- Jelly.notifyObservers({
343
- "method":"on_my_method"
344
- });
345
- expect(page.on_my_method).wasCalled();
346
- expect(Jelly.Observers.notifying).toBe(true);
347
- });
193
+ Jelly.attach("Jelly.Page", "MyPage", "index");
348
194
  });
349
195
 
350
196
  describe("when bound to the default Jelly.observers collection", function() {
@@ -352,10 +198,7 @@ describe("Jelly", function() {
352
198
  describe("when the notify method is defined on the page", function() {
353
199
  it("should call the notify method on the page", function() {
354
200
  spyOn(page, 'on_my_method');
355
- Jelly.notifyObservers({
356
- "arguments":["arg1", "arg2"],
357
- "method":"on_my_method"
358
- });
201
+ Jelly.notifyObservers("on_my_method", "arg1", "arg2");
359
202
  expect(page.on_my_method).wasCalled();
360
203
  expect(page.on_my_method).wasCalledWith('arg1', 'arg2');
361
204
  });
@@ -366,7 +209,7 @@ describe("Jelly", function() {
366
209
  on_my_method: function() {
367
210
  }
368
211
  };
369
- Jelly.attach({component: component, arguments: []});
212
+ Jelly.attach(component);
370
213
 
371
214
  var functionsCalledInOrder = [];
372
215
  spyOn(page, 'on_my_method').andCallFake(function() {
@@ -375,10 +218,7 @@ describe("Jelly", function() {
375
218
  spyOn(component, 'on_my_method').andCallFake(function() {
376
219
  functionsCalledInOrder.push("component");
377
220
  });
378
- Jelly.notifyObservers({
379
- "arguments":["arg1", "arg2"],
380
- "method":"on_my_method"
381
- });
221
+ Jelly.notifyObservers("on_my_method", "arg1", "arg2");
382
222
  expect(page.on_my_method).wasCalled();
383
223
  expect(page.on_my_method).wasCalledWith('arg1', 'arg2');
384
224
  expect(component.on_my_method).wasCalled();
@@ -391,10 +231,7 @@ describe("Jelly", function() {
391
231
  describe("when the page object does not define the notify method", function() {
392
232
  it("does not blow up", function() {
393
233
  expect(page.on_my_undefined_method).toBe(undefined);
394
- Jelly.notifyObservers({
395
- "arguments":["arg1", "arg2"],
396
- "method":"on_my_undefined_method"
397
- });
234
+ Jelly.notifyObservers("on_my_undefined_method", "arg1", "arg2");
398
235
  });
399
236
  });
400
237
  });
@@ -410,62 +247,6 @@ describe("Jelly", function() {
410
247
  afterEach(function() {
411
248
  delete GlobalObject;
412
249
  });
413
-
414
- describe("when the 'on' parameter is a string", function() {
415
- describe("when the 'on' object defines the notify method", function() {
416
- it("should call on_my_method on that object and not on the rest of the observers", function() {
417
- spyOn(GlobalObject, 'on_my_method');
418
- spyOn(GlobalObject.secondObject, 'on_my_method');
419
- Jelly.attach(GlobalObject);
420
- Jelly.notifyObservers({
421
- "arguments":["arg1", "arg2"],
422
- "method":"on_my_method",
423
- "on":"GlobalObject.secondObject"
424
- });
425
- expect(GlobalObject.on_my_method).wasNotCalled();
426
- expect(GlobalObject.secondObject.on_my_method).wasCalledWith('arg1', 'arg2');
427
- });
428
- });
429
-
430
- describe("when the 'on' object does not define the notify method", function() {
431
- it("does not blow up", function() {
432
- expect(GlobalObject.secondObject.on_my_undefined_method).toBe(undefined);
433
- Jelly.notifyObservers({
434
- "arguments":["arg1", "arg2"],
435
- "method":"on_my_undefined_method",
436
- "on":"GlobalObject.secondObject"
437
- });
438
- });
439
- })
440
- });
441
-
442
- describe("when the 'on' parameter is an object", function() {
443
- describe("when the 'on' object defines the notify method", function() {
444
- it("should call on_my_method on that object and not on the rest of the observers", function() {
445
- spyOn(GlobalObject, 'on_my_method');
446
- spyOn(GlobalObject.secondObject, 'on_my_method');
447
- Jelly.attach(GlobalObject);
448
- Jelly.notifyObservers({
449
- "arguments":["arg1", "arg2"],
450
- "method":"on_my_method",
451
- "on": GlobalObject.secondObject
452
- });
453
- expect(GlobalObject.on_my_method).wasNotCalled();
454
- expect(GlobalObject.secondObject.on_my_method).wasCalledWith('arg1', 'arg2');
455
- });
456
- });
457
-
458
- describe("when the 'on' object does not define the notify method", function() {
459
- it("does not blow up", function() {
460
- expect(GlobalObject.secondObject.on_my_undefined_method).toBe(undefined);
461
- Jelly.notifyObservers({
462
- "arguments":["arg1", "arg2"],
463
- "method":"on_my_undefined_method",
464
- "on": GlobalObject.secondObject
465
- });
466
- });
467
- })
468
- });
469
250
  });
470
251
  });
471
252
 
@@ -475,8 +256,8 @@ describe("Jelly", function() {
475
256
  on_my_method: function() {
476
257
  }
477
258
  };
478
- Jelly.attach({component: "Jelly.Page", arguments: ["MyPage", "index"]});
479
- Jelly.attach({component: component, arguments: []});
259
+ Jelly.attach("Jelly.Page", "MyPage", "index");
260
+ Jelly.attach(component);
480
261
 
481
262
  spyOn(page, 'on_my_method');
482
263
  spyOn(component, 'on_my_method');
@@ -488,10 +269,7 @@ describe("Jelly", function() {
488
269
  }};
489
270
  spyOn(customObserver2, 'on_my_method');
490
271
 
491
- Jelly.notifyObservers.call([customObserver1, customObserver2], {
492
- "arguments":["arg1", "arg2"],
493
- "method":"on_my_method"
494
- });
272
+ Jelly.notifyObservers.call([customObserver1, customObserver2], "on_my_method", "arg1", "arg2");
495
273
 
496
274
  expect(page.on_my_method).wasNotCalled();
497
275
  expect(component.on_my_method).wasNotCalled();
@@ -504,19 +282,16 @@ describe("Jelly", function() {
504
282
  });
505
283
 
506
284
  describe("an observer listening to on_notify", function() {
507
- it("receives a notify event with the notify hash", function() {
285
+ it("receives a notify instruction", function() {
508
286
  var observer = {
509
287
  on_notify: function() {
510
288
  }
511
289
  };
512
290
  spyOn(observer, 'on_notify');
513
291
 
514
- Jelly.notifyObservers.call([observer], {
515
- "arguments":["arg1", "arg2"],
516
- "method":"on_my_method"
517
- });
292
+ Jelly.notifyObservers.call([observer], "on_my_method", "arg1", "arg2");
518
293
 
519
- expect(observer.on_notify).wasCalledWith({method: "on_my_method", arguments: ["arg1", "arg2"]});
294
+ expect(observer.on_notify).wasCalledWith("on_my_method", "arg1", "arg2");
520
295
  });
521
296
  });
522
297
 
@@ -527,7 +302,7 @@ describe("Jelly", function() {
527
302
  on_my_method: function() {
528
303
  }
529
304
  };
530
- Jelly.attach({component: observer, arguments: []});
305
+ Jelly.attach(observer);
531
306
  expect(Jelly.observers).toContain(observer);
532
307
  });
533
308
 
@@ -539,7 +314,7 @@ describe("Jelly", function() {
539
314
  it("leaves the observer in Jelly.observers and calls the notify method on the observer", function() {
540
315
  spyOn(observer, "on_my_method");
541
316
 
542
- Jelly.notifyObservers({method: "on_my_method", arguments: []});
317
+ Jelly.notifyObservers("on_my_method");
543
318
  expect(Jelly.observers).toContain(observer);
544
319
  expect(observer.on_my_method).wasCalled();
545
320
  });
@@ -556,14 +331,14 @@ describe("Jelly", function() {
556
331
  on_my_method: function() {
557
332
  }
558
333
  };
559
- Jelly.attach({component: anotherObserver, arguments: []});
334
+ Jelly.attach(anotherObserver);
560
335
  });
561
336
 
562
337
  it("removes observer in Jelly.observers, does not call the notify method on the observer, and calls the other observers", function() {
563
338
  spyOn(observer, "on_my_method");
564
339
  spyOn(anotherObserver, "on_my_method");
565
340
 
566
- Jelly.notifyObservers({method: "on_my_method", arguments: []});
341
+ Jelly.notifyObservers("on_my_method");
567
342
  expect(Jelly.observers).toNotContain(observer);
568
343
  expect(observer.on_my_method).wasNotCalled();
569
344
  expect(anotherObserver.on_my_method).wasCalled();
@@ -580,80 +355,13 @@ describe("Jelly", function() {
580
355
  it("leaves the observer in Jelly.observers and calls the notify method on the observer", function() {
581
356
  spyOn(observer, "on_my_method");
582
357
 
583
- Jelly.notifyObservers({method: "on_my_method", arguments: []});
358
+ Jelly.notifyObservers("on_my_method");
584
359
  expect(Jelly.observers).toContain(observer);
585
360
  expect(observer.on_my_method).wasCalled();
586
361
  });
587
362
  });
588
363
  });
589
364
  });
590
-
591
- describe("when the 'attach' parameter is present", function() {
592
- var observers;
593
- beforeEach(function() {
594
- MyComponent = {
595
- init: function() {
596
- }
597
- };
598
- spyOn(MyComponent, 'init');
599
- observers = [];
600
- });
601
-
602
- describe("when the method is present", function() {
603
- it("attaches the given attachments to the observers and calls the notify on the recently attached observer", function() {
604
- Jelly.notifyObservers.call(observers, {
605
- "arguments":["arg1", "arg2"],
606
- "method":"on_my_method",
607
- "attach":[
608
- {
609
- component: "MyComponent",
610
- arguments: [1,2]
611
- }
612
- ]
613
- });
614
- expect(MyComponent.init).wasCalledWith(1, 2);
615
- expect(Jelly.observers).toNotContain(MyComponent);
616
- expect(observers).toContain(MyComponent);
617
- });
618
- });
619
-
620
- describe("when there are no other paramaters present", function() {
621
- it("attaches the given attachments to the observers", function() {
622
- Jelly.notifyObservers.call(observers, {
623
- "attach":[
624
- {
625
- component: "MyComponent",
626
- arguments: [1,2]
627
- }
628
- ]
629
- });
630
- expect(Jelly.observers).toNotContain(MyComponent);
631
- expect(observers).toContain(MyComponent);
632
- });
633
- });
634
- });
635
-
636
- describe("when given an array of notify instructions", function() {
637
- it("notifies the observers of all of the notify hashes", function() {
638
- page.on_my_method2 = function() {
639
- };
640
- spyOn(page, 'on_my_method');
641
- spyOn(page, 'on_my_method2');
642
- Jelly.notifyObservers([
643
- {
644
- "arguments":["arg1", "arg2"],
645
- "method":"on_my_method"
646
- },
647
- {
648
- "arguments": ["arg3"],
649
- "method":"on_my_method2"
650
- }
651
- ]);
652
-
653
- expect(page.on_my_method).wasCalledWith('arg1', 'arg2');
654
- expect(page.on_my_method2).wasCalledWith('arg3');
655
- });
656
- });
657
365
  });
658
366
  });
659
367