rbjs 0.9.7

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.
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
+