jelly 0.6.5 → 0.8.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -71,7 +71,7 @@ page-specifc function when the page has loaded. Let's look at some code:
71
71
 
72
72
  In public/javascripts/pages/stories.js, we create a simple Jelly file:
73
73
 
74
- Jelly.add("Stories", {
74
+ Jelly.Pages.add("Stories", {
75
75
 
76
76
  index: function() {
77
77
  $('a.clickme').click(function() {
@@ -85,7 +85,7 @@ Jelly will automatically execute the `index` function when the Rails app runs th
85
85
  continue the example by adding more Javascript functions that map to the `new` and `show` Rails actions. We can also
86
86
  specify an `all` function, which will be executed on all actions in the `StoriesController`.
87
87
 
88
- Jelly.add("Stories", {
88
+ Jelly.Pages.add("Stories", {
89
89
 
90
90
  index: function() {
91
91
  $('a.clickme').click(function() {
@@ -134,15 +134,15 @@ method in our view. This can be done either in your layout (for components to at
134
134
 
135
135
  in the `<head>` tag of the layout:
136
136
 
137
- <%= attach_javascript_component('SearchBox') %>
137
+ <% attach_javascript_component('SearchBox') %>
138
138
 
139
139
  or in a view:
140
140
 
141
141
  <% content_for :javascript do -%>
142
- <%= attach_javascript_component('SearchBox') %>
142
+ <% attach_javascript_component('SearchBox') %>
143
143
  <% end -%>
144
144
 
145
- Components always get initialized **after** the page-specific Javascript functions.
145
+ Components are initialized **before** the page-specific Javascript functions by default.
146
146
 
147
147
  AJAX With Jelly
148
148
  ---------------
@@ -179,7 +179,7 @@ The controller, stories_controller.rb
179
179
 
180
180
  The javascript, pages/stories.js:
181
181
 
182
- Jelly.add("Stories", {
182
+ Jelly.Pages.add("Stories", {
183
183
 
184
184
  new: function() {
185
185
  $("#create_story_link").click(function() {
@@ -234,7 +234,7 @@ The controller, stories_controller.rb
234
234
 
235
235
  The javascript, pages/stories.js:
236
236
 
237
- Jelly.add("Stories", {
237
+ Jelly.Pages.add("Stories", {
238
238
 
239
239
  new: function() {
240
240
  $("#create_story_link").click(function() {
@@ -1,5 +1,4 @@
1
1
  ---
2
- :minor: 6
3
- :patch: 5
4
- :build:
2
+ :minor: 8
3
+ :patch: 10
5
4
  :major: 0
@@ -5,7 +5,6 @@ class JellyGenerator < Rails::Generator::Base
5
5
  m.file 'javascripts/ajax_with_jelly.js', "public/javascripts/ajax_with_jelly.js"
6
6
  m.directory('public/javascripts/jquery')
7
7
  m.file 'javascripts/jquery/jquery-1.3.2.js', "public/javascripts/jquery/jquery-1.3.2.js"
8
- m.file 'javascripts/jquery/jquery.protify-0.3.js', "public/javascripts/jquery/jquery.protify-0.3.js"
9
8
  m.directory('public/javascripts/pages')
10
9
  end
11
10
  end
@@ -19,15 +19,13 @@ if(!window.Jelly) Jelly = new Object();
19
19
  authenticity_token: window._token
20
20
  });
21
21
  }
22
+ var observers = otherParams.observers || Jelly.observers;
22
23
  return $.extend({
23
24
  dataType: 'json',
24
25
  cache: false,
25
- success : $.ajaxWithJelly.onSuccess
26
+ success : function(callbacks) {
27
+ Jelly.Observers.notify.call(observers, callbacks);
28
+ }
26
29
  }, otherParams);
27
30
  };
28
-
29
- $.ajaxWithJelly.onSuccess = function(json) {
30
- Jelly.notifyObservers(json);
31
- return true;
32
- };
33
31
  })(jQuery);
@@ -2,7 +2,7 @@
2
2
  * Jelly. a sweet unobtrusive javascript framework
3
3
  * for jQuery and Rails
4
4
  *
5
- * version 0.5
5
+ * version 0.8.10
6
6
  *
7
7
  * Copyright (c) 2009 Pivotal Labs
8
8
  * Licensed under the MIT license.
@@ -12,83 +12,148 @@
12
12
  */
13
13
 
14
14
  if (!window.Jelly) Jelly = new Object();
15
- Jelly.init = function() {
16
- this.components = [];
17
- Jelly.Pages.init();
18
- $(document).ready(function() {
19
- Jelly.Components.init();
20
- });
21
- };
22
-
23
- Jelly.attach = function(component, args) {
24
- this.components.push([component, args]);
25
- };
26
-
27
- Jelly.notifyObservers = function(params) {
28
- var context = params.on ? eval(params.on) : page;
29
- if (context[params.method]) {
30
- context[params.method].apply(context, params.arguments);
31
- }
32
- $.protify(Jelly.components).each(function(componentAndArgs) {
33
- var component = componentAndArgs[0];
34
- if (component[params.method] && component != context) {
35
- component[params.method].apply(component, params.arguments);
15
+ if (!Function.prototype.bind) {
16
+ Function.prototype.bind = function(object) {
17
+ var self = this;
18
+ return function() {
19
+ return self.apply(object, arguments);
36
20
  }
37
- });
38
- };
39
-
40
- Jelly.Components = {
41
- init: function() {
42
- $.protify(Jelly.components).each(function(componentAndArgs) {
43
- var component = componentAndArgs[0];
44
- var args = componentAndArgs[1] || [];
45
- if (component.init) component.init.apply(component, args);
46
- });
47
21
  }
48
- };
49
-
50
- Jelly.Pages = {
22
+ }
23
+ $.extend(Jelly, {
51
24
  init: function() {
52
- this.all = {};
53
- Jelly.all = this.all; // Deprecated
25
+ this.observers = [];
26
+ this.attach = this.Observers.attach;
27
+ this.notifyObservers = this.Observers.notify;
28
+ this.Pages.init();
54
29
  },
55
30
 
56
- add: function(name) {
57
- var page = new Jelly.Page(name);
58
- for (var i = 1; i < arguments.length; i++) {
59
- $.extend(page, arguments[i]);
31
+ Observers: {
32
+ attach: function() {
33
+ if (this == Jelly) {
34
+ return Jelly.Observers.attach.apply(this.observers, arguments);
35
+ }
36
+ for (var i = 0; i < arguments.length; i++) {
37
+ var definitionOrComponent = arguments[i];
38
+ if (definitionOrComponent.component) {
39
+ var component = Jelly.Observers.evaluateComponent(definitionOrComponent.component);
40
+ if (component.init) {
41
+ var initReturnValue = component.init.apply(component, definitionOrComponent.arguments);
42
+ if (initReturnValue === false || initReturnValue === null) {
43
+ } else {
44
+ Jelly.Observers.pushIfObserver.call(this, initReturnValue || component);
45
+ }
46
+ } else {
47
+ Jelly.Observers.pushIfObserver.call(this, component);
48
+ }
49
+ } else {
50
+ Jelly.Observers.pushIfObserver.call(this, Jelly.Observers.evaluateComponent(definitionOrComponent));
51
+ }
52
+ }
53
+ },
54
+
55
+ evaluateComponent: function(component) {
56
+ return (typeof component == "string") ? eval(component) : component;
57
+ },
58
+
59
+ pushIfObserver: function(observer) {
60
+ if (observer) {
61
+ this.push(observer);
62
+ }
63
+ },
64
+
65
+ notify: function(callbacks) {
66
+ if (this == Jelly) {
67
+ return Jelly.Observers.notify.apply(this.observers, arguments);
68
+ }
69
+ if (!$.isArray(callbacks)) {
70
+ callbacks = [callbacks];
71
+ }
72
+
73
+ var observers = this.slice(0);
74
+ for (var i = 0; i < callbacks.length; i++) {
75
+ var callback = callbacks[i];
76
+
77
+ // Deprecate 'on' in favor of making each page action a Component.
78
+ if (callback.on) {
79
+ var additionalObserver = eval(callback.on);
80
+ if (observers.indexOf(additionalObserver) == -1) {
81
+ observers.push(additionalObserver);
82
+ }
83
+ }
84
+
85
+ if (callback.method) {
86
+ for (var j = 0; j < observers.length; j++) {
87
+ var observer = observers[j];
88
+ if (observer[callback.method]) {
89
+ if (observer.detach && observer.detach()) {
90
+ Jelly.Observers.garbageCollectObserver.call(this, observer);
91
+ } else {
92
+ observer[callback.method].apply(observer, callback.arguments);
93
+ }
94
+ }
95
+ }
96
+ }
97
+
98
+ if (callback.attach) {
99
+ Jelly.Observers.attach.apply(this, callback.attach);
100
+ }
101
+ }
102
+ },
103
+
104
+ garbageCollectObserver: function(observer) {
105
+ var index = this.indexOf(observer);
106
+ if (index > -1) {
107
+ Jelly.Observers.remove.call(this, index, index + 1);
108
+ }
109
+ },
110
+
111
+ remove: function(from, to) {
112
+ var rest = this.slice((to || from) + 1 || this.length);
113
+ this.length = from < 0 ? this.length + from : from;
114
+ return this.push.apply(this, rest);
60
115
  }
61
- return page;
62
- }
63
- };
64
- Jelly.add = Jelly.Pages.add; // Deprecated
116
+ },
65
117
 
66
- Jelly.Page = function(name) {
67
- this.documentHref = Jelly.Location.documentHref;
68
-
69
- this.name = name;
70
- this.components = [];
71
- Jelly.Pages.all[name] = this;
72
- };
73
- Jelly.Page.prototype.loaded = false;
74
- Jelly.Page.prototype.all = function() {
75
- };
76
-
77
- Jelly.Page.init = function(controllerName, actionName) {
78
- var page = Jelly.Pages.all[controllerName] || new Jelly.Page(controllerName);
79
- window.page = page;
80
- if (page.all) page.all();
81
- if (page[actionName]) page[actionName].call(page);
82
- page.loaded = true;
83
- };
84
-
85
- Jelly.Location = {
86
- init: function() {
118
+ Pages: {
119
+ init: function() {
120
+ this.all = {};
121
+ Jelly.all = this.all; // Deprecated
122
+ },
123
+
124
+ add: function(name) {
125
+ var page = new Jelly.Page.Constructor(name);
126
+ for (var i = 1; i < arguments.length; i++) {
127
+ $.extend(page, arguments[i]);
128
+ }
129
+ return page;
130
+ }
87
131
  },
88
132
 
89
- on_redirect: function(location) {
90
- top.location.href = location;
133
+ Page: {
134
+ init: function(controllerName, actionName) {
135
+ var page = Jelly.Pages.all[controllerName] || new Jelly.Page.Constructor(controllerName);
136
+ window.page = page;
137
+ if (page.all) page.all();
138
+ if (page[actionName]) page[actionName].call(page);
139
+ page.loaded = true;
140
+ return page;
141
+ },
142
+ Constructor: function(name) {
143
+ this.loaded = false;
144
+ this.documentHref = Jelly.Location.documentHref;
145
+
146
+ this.name = name;
147
+ Jelly.Pages.all[name] = this;
148
+ }
149
+ },
150
+
151
+ Location: {
152
+ on_redirect: function(location) {
153
+ top.location.href = location;
154
+ }
91
155
  }
92
- };
156
+ });
157
+ Jelly.add = Jelly.Pages.add; // Deprecated
93
158
 
94
159
  Jelly.init();
@@ -1,15 +1,15 @@
1
1
  # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{jelly}
8
- s.version = "0.6.5"
8
+ s.version = "0.8.10"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Pivotal Labs, Inc"]
12
- s.date = %q{2009-11-19}
12
+ s.date = %q{2010-01-20}
13
13
  s.description = %q{Jelly provides a set of tools and conventions for creating rich ajax/javascript web applications with jQuery and Ruby on Rails.}
14
14
  s.email = %q{opensource@pivotallabs.com}
15
15
  s.extra_rdoc_files = [
@@ -26,7 +26,6 @@ Gem::Specification.new do |s|
26
26
  "generators/jelly/templates/javascripts/ajax_with_jelly.js",
27
27
  "generators/jelly/templates/javascripts/jelly.js",
28
28
  "generators/jelly/templates/javascripts/jquery/jquery-1.3.2.js",
29
- "generators/jelly/templates/javascripts/jquery/jquery.protify-0.3.js",
30
29
  "install.rb",
31
30
  "jelly.gemspec",
32
31
  "lib/jelly.rb",
@@ -42,8 +41,9 @@ Gem::Specification.new do |s|
42
41
  s.rubygems_version = %q{1.3.5}
43
42
  s.summary = %q{a sweet unobtrusive javascript framework for jQuery and Rails}
44
43
  s.test_files = [
45
- "spec/controllers/jelly_controller_spec.rb",
46
- "spec/helpers/jelly_helper_spec.rb",
44
+ "spec/jelly/common_spec.rb",
45
+ "spec/jelly/jelly_controller_spec.rb",
46
+ "spec/jelly/jelly_helper_spec.rb",
47
47
  "spec/rails_root/app/controllers/application_controller.rb",
48
48
  "spec/rails_root/app/helpers/application_helper.rb",
49
49
  "spec/rails_root/config/boot.rb",
@@ -76,4 +76,3 @@ Gem::Specification.new do |s|
76
76
  s.add_dependency(%q<rails>, [">= 2.3.0"])
77
77
  end
78
78
  end
79
-
@@ -12,6 +12,5 @@ ActionView::Base.class_eval do
12
12
  include JellyHelper
13
13
  end
14
14
 
15
- ActionView::Helpers::AssetTagHelper.register_javascript_expansion :jelly => ["jquery/jquery-1.3.2", "jquery/jquery.protify-0.3",
16
- "ajax_with_jelly", "jelly"]
17
- ActionView::Helpers::AssetTagHelper.register_javascript_expansion :only_jelly => ["jquery/jquery.protify-0.3", "jelly", "ajax_with_jelly"]
15
+ ActionView::Helpers::AssetTagHelper.register_javascript_expansion :jelly => ["jquery/jquery-1.3.2", "ajax_with_jelly", "jelly"]
16
+ ActionView::Helpers::AssetTagHelper.register_javascript_expansion :only_jelly => ["jelly", "ajax_with_jelly"]
@@ -3,5 +3,13 @@ module Jelly
3
3
  def jelly_callback_hash(method, *arguments)
4
4
  {"method" => method, "arguments" => arguments}
5
5
  end
6
+
7
+ def jelly_callback_attach_hash(components=jelly_attachments)
8
+ {"attach" => components}
9
+ end
10
+
11
+ def jelly_attachment_hash(component_name, *args)
12
+ {'component' => component_name, 'arguments' => args}
13
+ end
6
14
  end
7
15
  end
@@ -3,22 +3,39 @@ module JellyController
3
3
  include Jelly::Common
4
4
 
5
5
  def jelly_callback(callback_base_name = @action_name, options = {}, &block)
6
- render :inline => jelly_callback_erb("on_#{callback_base_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_callback_hash("on_#{callback_base_name}", *arguments).merge(options)
10
+ end
7
11
  end
8
12
 
9
- def jelly_callback_erb(callback_name, options, block)
10
- @callback_name = callback_name
11
- @options = options
12
- @block = block
13
- erb = <<-ERB
14
- <%= begin
15
- args = @block ? instance_eval(&@block) : []
16
- args = [args] unless args.is_a?(Array)
17
- jelly_callback_hash(@callback_name, *args).reverse_merge(@options).to_json
18
- end %>
19
- ERB
20
- request.xhr? ? erb : "<textarea>#{erb}</textarea>"
13
+ def raw_jelly_callback(options={}, &block)
14
+ options.symbolize_keys!
15
+ options[:format] ||= if params[:callback]
16
+ :jsonp
17
+ elsif request.xhr?
18
+ :json
19
+ else
20
+ :iframe
21
+ end
22
+ render :inline => jelly_callback_erb(options, &block)
21
23
  end
22
24
 
25
+ def jelly_callback_erb(options={}, &block)
26
+ options[:format] ||= :json
27
+ @jelly_block = block
28
+ case options[:format].to_sym
29
+ when :iframe
30
+ "<textarea>#{jelly_callback_erb_template}</textarea>"
31
+ when :jsonp
32
+ "#{params[:callback]}(#{jelly_callback_erb_template});"
33
+ else
34
+ jelly_callback_erb_template
35
+ end
36
+ end
23
37
 
38
+ def jelly_callback_erb_template
39
+ "<%= instance_eval(&@jelly_block).to_json %>"
40
+ end
24
41
  end
@@ -14,35 +14,43 @@ module JellyHelper
14
14
  def spread_jelly
15
15
  attach_javascript_component("Jelly.Location")
16
16
  attach_javascript_component("Jelly.Page", controller.controller_path.camelcase, controller.action_name)
17
+ <<-HTML
18
+ #{window_token_javascript_tag}
19
+ #{attach_javascript_component_javascript_tag(jelly_attachments)}
20
+ HTML
21
+ end
22
+
23
+ def window_token_javascript_tag
24
+ javascript_tag("window._token = '#{form_authenticity_token}';")
25
+ end
26
+
27
+ def attach_javascript_component_javascript_tag(*components)
28
+ components = [components].flatten
17
29
  javascript_tag <<-JS
18
- window._token = '#{form_authenticity_token}'
19
- #{@content_for_javascript}
20
30
  $(document).ready(function() {
21
- #{@content_for_javascript_on_ready}
31
+ Jelly.attach.apply(Jelly, #{components.to_json});
22
32
  });
23
33
  JS
24
34
  end
25
35
 
26
- def clear_jelly_attached()
27
- @jelly_attached_components = []
36
+ def clear_jelly_attached
37
+ jelly_attachments.clear
28
38
  end
29
39
 
30
40
  def attach_javascript_component(component_name, *args)
31
- @jelly_attached_components ||= []
32
- key = "Jelly.attach(#{component_name}, #{args.to_json});"
33
- unless @jelly_attached_components.include? key
34
- @jelly_attached_components << key
35
- content_for(:javascript, key)
41
+ key = jelly_attachment_hash(component_name, *args)
42
+ unless jelly_attachments.include? key
43
+ jelly_attachments << key
36
44
  end
37
45
  end
38
46
 
39
47
  def attach_javascript_component_on_ready(component_name, *args)
40
- @jelly_attached_components_on_ready ||= []
41
- key = "Jelly.attach(#{component_name}, #{args.to_json});"
42
- unless @jelly_attached_components_on_ready.include? key
43
- @jelly_attached_components_on_ready << key
44
- content_for(:javascript_on_ready, key)
45
- end
48
+ 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")}"
49
+ attach_javascript_component(component_name, *args)
50
+ end
51
+
52
+ def jelly_attachments
53
+ @jelly_attachments ||= []
46
54
  end
47
55
 
48
56
  end