jelly 0.6.5 → 0.8.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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