btakita-jelly 0.6.1 → 0.8.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -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() {
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :build:
3
- :patch: 1
3
+ :minor: 8
4
+ :patch: 5
4
5
  :major: 0
5
- :minor: 6
@@ -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.5
6
6
  *
7
7
  * Copyright (c) 2009 Pivotal Labs
8
8
  * Licensed under the MIT license.
@@ -11,87 +11,141 @@
11
11
  *
12
12
  */
13
13
 
14
- if(!window.Jelly) Jelly = new Object();
15
- Jelly.all = {};
16
-
17
- Jelly.add = function(name) {
18
- var page = new Jelly.Page(name);
19
- for(var i=1; i < arguments.length; i++) {
20
- $.extend(page, arguments[i]);
21
- }
22
- return page;
23
- };
24
-
25
- var page;
26
- Jelly.activatePage = function(controllerName, actionName) {
27
- page = Jelly.all[controllerName] || new Jelly.Page(controllerName);
28
- $(document).ready(function(){
29
- Jelly._activatePage(actionName);
30
- });
31
- };
32
-
33
- Jelly._activatePage = function(actionName){
34
- Jelly.initComponents();
35
- if(page.all) page.all();
36
- if(page[actionName]) page[actionName].call(page);
37
- page.loaded = true;
38
- };
39
-
40
- Jelly.initComponents = function() {
41
- $.protify(page.components).each(function(componentAndArgs) {
42
- var component = componentAndArgs[0];
43
- var args = componentAndArgs[1] || [];
44
- if(component.init) component.init.apply(component, args);
45
- });
46
- };
47
-
48
- Jelly.notifyObservers = function(params) {
49
- var context = params.on ? eval(params.on) : page;
50
- if(context[params.method]) {
51
- context[params.method].apply(context, params.arguments);
52
- }
53
- $.protify(page.components).each(function(componentAndArgs) {
54
- var component = componentAndArgs[0];
55
- if(component[params.method]) {
56
- component[params.method].apply(component, params.arguments);
14
+ if (!window.Jelly) Jelly = new Object();
15
+ if (!Function.prototype.bind) {
16
+ Function.prototype.bind = function(object) {
17
+ var self = this;
18
+ return function() {
19
+ return self.apply(object, arguments);
57
20
  }
58
- });
59
- };
60
-
61
- Jelly.Page = function(name) {
62
- this.name = name;
63
- this.components = [];
64
- Jelly.all[name] = this;
65
- };
66
-
67
- Jelly.Page.prototype.loaded = false;
68
- Jelly.Page.prototype.all = function() {
69
- };
70
- Jelly.Page.prototype.documentHref = function() {
71
- return document.location.href;
72
- };
73
- Jelly.Page.prototype.on_redirect = function(location){
74
- top.location.href = location;
75
- };
76
-
77
- Jelly.Page.prototype.attach = function(component, args) {
78
- var methodNames = [];
79
- for(var methodName in component.pageMixin) {
80
- methodNames.push(methodName);
81
21
  }
82
- var self = this;
83
- $.protify(methodNames).each(function(methodName) {
84
- // TODO: is anybody using these before_/after_ hooks? if not, delete them and use components as observers
85
- self[methodName] = function() {
86
- if(this['before_' + methodName]) {
87
- this['before_' + methodName].apply(this, arguments);
22
+ }
23
+ $.extend(Jelly, {
24
+ init: function() {
25
+ this.observers = [];
26
+ this.attach = this.Observers.attach;
27
+ this.notifyObservers = this.Observers.notify;
28
+ this.Pages.init();
29
+ },
30
+
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
+ var observer;
39
+ if (definitionOrComponent.component) {
40
+ var component = Jelly.Observers.evaluateComponent(definitionOrComponent.component);
41
+ if (component.init) {
42
+ observer = component.init.apply(component, definitionOrComponent.arguments) || component;
43
+ } else {
44
+ observer = component;
45
+ }
46
+ } else {
47
+ observer = Jelly.Observers.evaluateComponent(definitionOrComponent);
48
+ }
49
+ this.push(observer);
50
+ }
51
+ },
52
+
53
+ evaluateComponent: function(component) {
54
+ return (typeof component == "string") ? eval(component) : component;
55
+ },
56
+
57
+ notify: function(callbacks) {
58
+ if (this == Jelly) {
59
+ return Jelly.Observers.notify.apply(this.observers, arguments);
60
+ }
61
+ if (!$.isArray(callbacks)) {
62
+ callbacks = [callbacks];
63
+ }
64
+
65
+ var observers = this.slice(0);
66
+ for (var i = 0; i < callbacks.length; i++) {
67
+ var callback = callbacks[i];
68
+
69
+ // Deprecate 'on' in favor of making each page action a Component.
70
+ if (callback.on) {
71
+ var additionalObserver = eval(callback.on);
72
+ if (observers.indexOf(additionalObserver) == -1) {
73
+ observers.push(additionalObserver);
74
+ }
75
+ }
76
+
77
+ if (callback.method) {
78
+ for (var j = 0; j < observers.length; j++) {
79
+ var observer = observers[j];
80
+ if (observer[callback.method]) {
81
+ if (observer.detach && observer.detach()) {
82
+ Jelly.Observers.garbageCollectObserver.call(this, observer);
83
+ } else {
84
+ observer[callback.method].apply(observer, callback.arguments);
85
+ }
86
+ }
87
+ }
88
+ }
89
+
90
+ if (callback.attach) {
91
+ Jelly.Observers.attach.apply(this, callback.attach);
92
+ }
88
93
  }
89
- var returnValue = component.pageMixin[methodName].apply(this, arguments);
90
- if(this['after_' + methodName]) {
91
- this['after_' + methodName].apply(this, arguments);
94
+ },
95
+
96
+ garbageCollectObserver: function(observer) {
97
+ var index = this.indexOf(observer);
98
+ if (index > -1) {
99
+ Jelly.Observers.remove.call(this, index, index + 1);
92
100
  }
93
- return returnValue;
94
- };
95
- });
96
- page.components.push([component, args]);
97
- };
101
+ },
102
+
103
+ remove: function(from, to) {
104
+ var rest = this.slice((to || from) + 1 || this.length);
105
+ this.length = from < 0 ? this.length + from : from;
106
+ return this.push.apply(this, rest);
107
+ }
108
+ },
109
+
110
+ Pages: {
111
+ init: function() {
112
+ this.all = {};
113
+ Jelly.all = this.all; // Deprecated
114
+ },
115
+
116
+ add: function(name) {
117
+ var page = new Jelly.Page.Constructor(name);
118
+ for (var i = 1; i < arguments.length; i++) {
119
+ $.extend(page, arguments[i]);
120
+ }
121
+ return page;
122
+ }
123
+ },
124
+
125
+ Page: {
126
+ init: function(controllerName, actionName) {
127
+ var page = Jelly.Pages.all[controllerName] || new Jelly.Page.Constructor(controllerName);
128
+ window.page = page;
129
+ if (page.all) page.all();
130
+ if (page[actionName]) page[actionName].call(page);
131
+ page.loaded = true;
132
+ return page;
133
+ },
134
+ Constructor: function(name) {
135
+ this.loaded = false;
136
+ this.documentHref = Jelly.Location.documentHref;
137
+
138
+ this.name = name;
139
+ Jelly.Pages.all[name] = this;
140
+ }
141
+ },
142
+
143
+ Location: {
144
+ on_redirect: function(location) {
145
+ top.location.href = location;
146
+ }
147
+ }
148
+ });
149
+ Jelly.add = Jelly.Pages.add; // Deprecated
150
+
151
+ Jelly.init();
data/jelly.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{jelly}
8
- s.version = "0.5.9"
8
+ s.version = "0.8.5"
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-10-30}
12
+ s.date = %q{2010-01-03}
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,10 +26,10 @@ 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",
32
+ "lib/jelly/common.rb",
33
33
  "lib/jelly/jelly_controller.rb",
34
34
  "lib/jelly/jelly_helper.rb",
35
35
  "tasks/jelly_tasks.rake",
@@ -41,24 +41,25 @@ Gem::Specification.new do |s|
41
41
  s.rubygems_version = %q{1.3.5}
42
42
  s.summary = %q{a sweet unobtrusive javascript framework for jQuery and Rails}
43
43
  s.test_files = [
44
- "spec/controllers/jelly_controller_spec.rb",
45
- "spec/spec_helper.rb",
44
+ "spec/spec_suite.rb",
45
+ "spec/helpers/jelly_helper_spec.rb",
46
+ "spec/controllers/jelly_controller_spec.rb",
46
47
  "spec/rails_root/test/performance/browsing_test.rb",
47
48
  "spec/rails_root/test/test_helper.rb",
48
- "spec/rails_root/app/controllers/application_controller.rb",
49
- "spec/rails_root/app/helpers/application_helper.rb",
50
- "spec/rails_root/config/environment.rb",
51
49
  "spec/rails_root/config/environments/production.rb",
52
50
  "spec/rails_root/config/environments/development.rb",
53
51
  "spec/rails_root/config/environments/test.rb",
54
- "spec/rails_root/config/routes.rb",
55
52
  "spec/rails_root/config/boot.rb",
56
- "spec/rails_root/config/initializers/backtrace_silencers.rb",
53
+ "spec/rails_root/config/environment.rb",
57
54
  "spec/rails_root/config/initializers/new_rails_defaults.rb",
58
- "spec/rails_root/config/initializers/mime_types.rb",
59
55
  "spec/rails_root/config/initializers/inflections.rb",
56
+ "spec/rails_root/config/initializers/mime_types.rb",
60
57
  "spec/rails_root/config/initializers/session_store.rb",
61
- "spec/helpers/jelly_helper_spec.rb"
58
+ "spec/rails_root/config/initializers/backtrace_silencers.rb",
59
+ "spec/rails_root/config/routes.rb",
60
+ "spec/rails_root/app/helpers/application_helper.rb",
61
+ "spec/rails_root/app/controllers/application_controller.rb",
62
+ "spec/spec_helper.rb"
62
63
  ]
63
64
 
64
65
  if s.respond_to? :specification_version then
data/lib/jelly.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  raise "Jelly must be used in a Rails environment." unless defined?(ActionController)
2
2
 
3
+ require 'jelly/common'
3
4
  require 'jelly/jelly_controller'
4
5
  require 'jelly/jelly_helper'
5
6
 
@@ -11,6 +12,5 @@ ActionView::Base.class_eval do
11
12
  include JellyHelper
12
13
  end
13
14
 
14
- ActionView::Helpers::AssetTagHelper.register_javascript_expansion :jelly => ["jquery/jquery-1.3.2", "jquery/jquery.protify-0.3",
15
- "ajax_with_jelly", "jelly"]
16
- 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"]
@@ -0,0 +1,11 @@
1
+ module Jelly
2
+ module Common
3
+ def jelly_callback_hash(method, *arguments)
4
+ {"method" => method, "arguments" => arguments}
5
+ end
6
+
7
+ def jelly_attach_component_definition_hash(component_name, *args)
8
+ {'component' => component_name, 'arguments' => args}
9
+ end
10
+ end
11
+ end
@@ -1,23 +1,41 @@
1
1
  module JellyController
2
2
  protected
3
+ include Jelly::Common
3
4
 
4
5
  def jelly_callback(callback_base_name = @action_name, options = {}, &block)
5
- 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
6
11
  end
7
12
 
8
- def jelly_callback_erb(callback_name, options, block)
9
- @callback_name = callback_name
10
- @options = options
11
- @block = block
12
- erb = <<-ERB
13
- <%= begin
14
- args = @block ? instance_eval(&@block) : []
15
- args = [args] unless args.is_a?(Array)
16
- {"method" => @callback_name, "arguments" => args}.reverse_merge(@options).to_json
17
- end %>
18
- ERB
19
- request.xhr? ? erb : "<textarea>#{erb}</textarea>"
13
+ def raw_jelly_callback(options={}, &block)
14
+ options.symbolize_keys!
15
+ options[:format] ||= if request.xhr?
16
+ :json
17
+ elsif params[:callback]
18
+ :jsonp
19
+ else
20
+ :iframe
21
+ end
22
+ render :inline => jelly_callback_erb(options, &block)
20
23
  end
21
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
22
37
 
38
+ def jelly_callback_erb_template
39
+ "<%= instance_eval(&@jelly_block).to_json %>"
40
+ end
23
41
  end