rbjs 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in rbjs.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (2011) Stefan Buhrmester
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/rbjs.rb ADDED
@@ -0,0 +1,142 @@
1
+ require "rbjs/version"
2
+ require 'rails'
3
+ require 'active_support'
4
+ require 'json'
5
+
6
+ module Rbjs
7
+
8
+ class Railtie < Rails::Railtie
9
+ initializer 'rbjs.setup' do
10
+ ActiveSupport.on_load(:action_controller) do
11
+ require 'rbjs/setup_action_controller'
12
+ end
13
+ ActiveSupport.on_load(:action_view) do
14
+ require 'rbjs/setup_action_view'
15
+ end
16
+ end
17
+ end
18
+
19
+ class Root
20
+ def initialize view_context, &block
21
+ @_view_context = view_context and
22
+ for instance_var, val in view_context.assigns
23
+ instance_variable_set '@'+instance_var, val
24
+ end
25
+ if @_view_context.respond_to?(:helpers) && @_view_context.helpers
26
+ extend @_view_context.helpers
27
+ end
28
+ @_block = block
29
+ @_called_statements = []
30
+ end
31
+
32
+ def evaluate function_parameters = nil
33
+ instance_exec *function_parameters, &@_block
34
+ @_called_statements.map(&:last_of_chain).reject(&:is_argument).map(&:to_s).join(";\n")
35
+ end
36
+
37
+ def method_missing name, *args, &block
38
+ if @_view_context and @_view_context.respond_to?(name)
39
+ @_view_context.send name, *args, &block
40
+ else
41
+ statement = Statement.new name, @_view_context, *args, &block
42
+ @_called_statements << statement
43
+ statement
44
+ end
45
+ end
46
+
47
+ def << line
48
+ @_called_statements << Statement.new(line)
49
+ end
50
+ end
51
+
52
+ class Statement
53
+ attr_accessor :parent_statement
54
+ attr_accessor :child_statement
55
+ attr_accessor :is_argument
56
+
57
+ def initialize name, view_context, *args, &block
58
+ @name = name.to_s.gsub '!', '()'
59
+ @_view_context = view_context
60
+ args << block if block_given?
61
+ @arguments = args.map{|arg| to_argument(arg)}
62
+ end
63
+
64
+ def method_missing name, *args, &block
65
+ statement = Statement.new name, @_view_context, *args, &block
66
+ statement.parent_statement = self
67
+ self.child_statement = statement
68
+ statement
69
+ end
70
+
71
+ def to_s
72
+ if ['+','-','*','/'].include?(@name)
73
+ @parent_statement.to_s + @name + @arguments.first
74
+ elsif @name == '[]='
75
+ @parent_statement.to_s + '[' + @arguments.first + ']= ' + @arguments.last
76
+ elsif @name == '[]'
77
+ @parent_statement.to_s + '[' + @arguments.first + ']'
78
+ elsif @parent_statement
79
+ @parent_statement.to_s + '.' + @name + argument_list
80
+ else
81
+ @name + argument_list
82
+ end
83
+ end
84
+
85
+ def argument_list
86
+ return '' if @arguments.empty?
87
+
88
+ '(' + @arguments.join(', ') + ')'
89
+ end
90
+
91
+ def last_of_chain
92
+ if @child_statement
93
+ @child_statement.last_of_chain
94
+ else
95
+ self
96
+ end
97
+ end
98
+
99
+ def to_argument arg
100
+ if arg.is_a?(Statement)
101
+ arg.is_argument = true
102
+ arg.to_s
103
+ elsif arg.is_a?(ArgumentProxy)
104
+ arg.to_s
105
+ elsif arg.is_a?(Array)
106
+ '['+arg.map{|val|to_argument(val)}.join(', ')+']'
107
+ elsif arg.is_a?(Hash)
108
+ '{'+arg.map{|key, val|to_argument(key)+': '+to_argument(val)}.join(',')+'}'
109
+ elsif arg.is_a?(Proc)
110
+ begin
111
+ root = Root.new(@_view_context, &arg)
112
+ function_parameters = []
113
+ function_parameter_names = []
114
+ for param in arg.parameters
115
+ function_parameter_names << param[1]
116
+ function_parameters << ArgumentProxy.new(root, param[1])
117
+ end
118
+ "function(#{function_parameter_names.join ', '}) {\n#{root.evaluate function_parameters}}"
119
+ end
120
+ else
121
+ arg.to_json
122
+ end
123
+ end
124
+ end
125
+
126
+ class ArgumentProxy
127
+ def initialize root, name
128
+ @root = root
129
+ @name = name
130
+ end
131
+
132
+ def method_missing name, *args, &block
133
+ statement = @root.send(@name)
134
+ statement.send name, *args, &block
135
+ end
136
+
137
+ def to_s
138
+ @name
139
+ end
140
+ end
141
+
142
+ end
@@ -0,0 +1,13 @@
1
+ module Rbjs
2
+ module ControllerExtensions
3
+ def render *args, &block
4
+ if args.first == :js
5
+ self.content_type = Mime::JS
6
+ self.response_body = Rbjs::Root.new(view_context, &block).evaluate
7
+ else
8
+ super
9
+ end
10
+ end
11
+ end
12
+ ActionController::Base.send :include, ControllerExtensions
13
+ end
@@ -0,0 +1,25 @@
1
+
2
+ ActionView::Helpers::RenderingHelper.module_eval do
3
+ def render_with_js(options = {}, locals = {}, &block)
4
+ if options == :js
5
+ Rbjs::Root.new(self, &block).evaluate
6
+ else
7
+ render_without_js(options, locals, &block)
8
+ end
9
+ end
10
+ alias_method_chain :render, :js
11
+ end
12
+
13
+ module Rbjs
14
+ class TemplateHandler
15
+
16
+ class_attribute :default_format
17
+ self.default_format = Mime::JS
18
+
19
+ def call(template)
20
+ "Rbjs::Root.new self do\n#{template.source}\nend.evaluate"
21
+ end
22
+ end
23
+ end
24
+
25
+ ActionView::Template.register_template_handler :rbjs, Rbjs::TemplateHandler.new
@@ -0,0 +1,3 @@
1
+ module Rbjs
2
+ VERSION = "0.9.7"
3
+ end
data/rbjs.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "rbjs/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "rbjs"
7
+ s.version = Rbjs::VERSION
8
+ s.authors = ["Stefan Buhrmester"]
9
+ s.email = ["buhrmi@gmail.com"]
10
+ s.homepage = "http://buhrmi.github.com/rbjs"
11
+ s.summary = "Remote Javascript re-imagined"
12
+ s.description = "Remote Javascript Builder for Ruby on Rails"
13
+
14
+ s.rubyforge_project = "rbjs"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ s.add_runtime_dependency "json"
24
+ s.add_runtime_dependency "rails"
25
+ s.add_runtime_dependency "activesupport"
26
+ end
data/readme.md ADDED
@@ -0,0 +1,88 @@
1
+ # RJS IS BACK
2
+
3
+ ## And it's better than ever before.
4
+
5
+ Rbjs is a modern RJS extension for Rails 3 and up. It stands for **r**u**b**y**j**ava**s**cript. In contrast to prototype-rails, this library is designed to work with all javascript frameworks.
6
+
7
+ However, it is *not* a drop-in replacement for _.rjs_. It does things quite differently.
8
+
9
+ ### Take a look at a simple example:
10
+
11
+ # controllers/greeter_controller.rb
12
+ def greet_me
13
+ render :js do
14
+ window.alert "Hello, #{current_user_name}"
15
+ end
16
+ end
17
+
18
+ # views/greeter/index.html.erb
19
+ link_to "Hi there!", "greeter#greet_me", :remote => true
20
+
21
+ ### And a more complex example:
22
+
23
+ # controllers/posts_controller.rb
24
+ def refresh
25
+ post = Post.find params[:id]
26
+ render :js do
27
+ post_element = jQuery(post.selector)
28
+ post_element.html(render post)
29
+ post_element.css(:opacity => 0).animate(:opacity => 1)
30
+ end
31
+ end
32
+
33
+ # views/posts/index.html.erb
34
+ link_to "Refresh Post", refresh_post_path(post), :remote => true
35
+
36
+ ### You can also create .rbjs templates:
37
+
38
+ # controllers/posts_controller.rb
39
+ def refresh_all
40
+ @posts = Post.all.limit(10)
41
+ end
42
+
43
+ # views/posts/refresh_all.js.rbjs
44
+ for post in @posts
45
+ jQuery(post.selector).html(render post)
46
+ end
47
+
48
+ ### Do complex stuff:
49
+
50
+ # controllers/posts_controller.rb
51
+ def increase_counter
52
+ @increment = 4
53
+ end
54
+
55
+ # views/posts/increase_counter.js.rbjs
56
+ allCounters = jQuery('.post.counter')
57
+ allCounters.each do |index, element|
58
+ element = jQuery(element)
59
+ currentValue = element.html!.to_i!
60
+ element.html(currentValue + @increment)
61
+ end
62
+
63
+ # And the rendered result. Note the behavior of local variables.
64
+ jQuery(".post.counter").each(
65
+ function(index, element) {
66
+ jQuery(element).html(jQuery(element).html().to_i()+4)
67
+ }
68
+ )
69
+
70
+
71
+ # Here is the same example, but with variables assigned to javascript instead of local ruby variables.
72
+ # views/posts/increase_counter.js.rbjs
73
+ self.allCounters = jQuery('.post.counter')
74
+ self.allCounters.each do |index, element|
75
+ self.element = jQuery(element)
76
+ self.currentValue = element.html!.to_i!
77
+ element.html(currentValue + @increment)
78
+ end
79
+
80
+ # And the rendered result:
81
+ allCounters=(jQuery(".post.counter"));
82
+ allCounters.each(function(index, element) {
83
+ element=(jQuery(element));
84
+ currentValue=(element.html().to_i());
85
+ element.html(currentValue+4)
86
+ })
87
+
88
+ More to come.
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rbjs
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.9.7
6
+ platform: ruby
7
+ authors:
8
+ - Stefan Buhrmester
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-11-03 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: json
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: rails
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: activesupport
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id003
48
+ description: Remote Javascript Builder for Ruby on Rails
49
+ email:
50
+ - buhrmi@gmail.com
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files: []
56
+
57
+ files:
58
+ - .gitignore
59
+ - Gemfile
60
+ - LICENSE
61
+ - Rakefile
62
+ - lib/rbjs.rb
63
+ - lib/rbjs/setup_action_controller.rb
64
+ - lib/rbjs/setup_action_view.rb
65
+ - lib/rbjs/version.rb
66
+ - rbjs.gemspec
67
+ - readme.md
68
+ homepage: http://buhrmi.github.com/rbjs
69
+ licenses: []
70
+
71
+ post_install_message:
72
+ rdoc_options: []
73
+
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "0"
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: "0"
88
+ requirements: []
89
+
90
+ rubyforge_project: rbjs
91
+ rubygems_version: 1.8.11
92
+ signing_key:
93
+ specification_version: 3
94
+ summary: Remote Javascript re-imagined
95
+ test_files: []
96
+