rbjs 0.9.14 → 0.9.15
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rbjs.rb +25 -23
- data/lib/rbjs/version.rb +1 -1
- data/readme.md +8 -104
- data/spec/rbjs_spec.rb +136 -0
- metadata +5 -4
data/lib/rbjs.rb
CHANGED
@@ -26,33 +26,33 @@ module Rbjs
|
|
26
26
|
extend @_view_context.helpers
|
27
27
|
end
|
28
28
|
@_block = block
|
29
|
-
@
|
29
|
+
@_called_expressions = []
|
30
30
|
end
|
31
31
|
|
32
32
|
def evaluate function_parameters = nil
|
33
33
|
instance_exec *function_parameters, &@_block
|
34
|
-
@
|
34
|
+
@_called_expressions.map(&:last_of_chain).reject(&:is_argument).map(&:to_s).join(";\n")
|
35
35
|
end
|
36
36
|
|
37
37
|
def method_missing name, *args, &block
|
38
38
|
if @_view_context and @_view_context.respond_to?(name)
|
39
39
|
@_view_context.send name, *args, &block
|
40
40
|
else
|
41
|
-
|
42
|
-
@
|
43
|
-
|
41
|
+
expression = Expression.new name, @_view_context, *args, &block
|
42
|
+
@_called_expressions << expression
|
43
|
+
expression
|
44
44
|
end
|
45
45
|
end
|
46
46
|
alias_method :const_missing, :method_missing
|
47
47
|
|
48
48
|
def << line
|
49
|
-
@
|
49
|
+
@_called_expressions << Expression.new(line)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
class
|
54
|
-
attr_accessor :
|
55
|
-
attr_accessor :
|
53
|
+
class Expression
|
54
|
+
attr_accessor :parent_expression
|
55
|
+
attr_accessor :child_expression
|
56
56
|
attr_accessor :is_argument
|
57
57
|
|
58
58
|
def initialize name, view_context = nil, *args, &block
|
@@ -63,21 +63,21 @@ module Rbjs
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def method_missing name, *args, &block
|
66
|
-
|
67
|
-
|
68
|
-
self.
|
69
|
-
|
66
|
+
expression = Expression.new name, @_view_context, *args, &block
|
67
|
+
expression.parent_expression = self
|
68
|
+
self.child_expression = expression
|
69
|
+
expression
|
70
70
|
end
|
71
71
|
|
72
72
|
def to_s
|
73
73
|
if ['+','-','*','/'].include?(@name)
|
74
|
-
@
|
74
|
+
@parent_expression.to_s + @name + @arguments.first
|
75
75
|
elsif @name == '[]='
|
76
|
-
@
|
76
|
+
@parent_expression.to_s + '[' + @arguments.first + ']= ' + @arguments.last
|
77
77
|
elsif @name == '[]'
|
78
|
-
@
|
79
|
-
elsif @
|
80
|
-
parent_str = @
|
78
|
+
@parent_expression.to_s + '[' + @arguments.first + ']'
|
79
|
+
elsif @parent_expression
|
80
|
+
parent_str = @parent_expression.to_s
|
81
81
|
parent_str += parent_str == 'var' ? ' ' : '.'
|
82
82
|
parent_str + @name + argument_list
|
83
83
|
else
|
@@ -91,15 +91,15 @@ module Rbjs
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def last_of_chain
|
94
|
-
if @
|
95
|
-
@
|
94
|
+
if @child_expression
|
95
|
+
@child_expression.last_of_chain
|
96
96
|
else
|
97
97
|
self
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
101
|
def to_argument arg
|
102
|
-
if arg.is_a?(
|
102
|
+
if arg.is_a?(Expression)
|
103
103
|
arg.is_argument = true
|
104
104
|
arg.to_s
|
105
105
|
elsif arg.is_a?(ArgumentProxy)
|
@@ -117,6 +117,8 @@ module Rbjs
|
|
117
117
|
function_parameters << ArgumentProxy.new(root, param[1])
|
118
118
|
end
|
119
119
|
"function(#{function_parameter_names.join ', '}) {\n#{root.evaluate function_parameters}}"
|
120
|
+
elsif arg.is_a?(Regexp)
|
121
|
+
arg.inspect
|
120
122
|
else
|
121
123
|
arg.to_json
|
122
124
|
end
|
@@ -130,8 +132,8 @@ module Rbjs
|
|
130
132
|
end
|
131
133
|
|
132
134
|
def method_missing name, *args, &block
|
133
|
-
|
134
|
-
|
135
|
+
expression = @root.send(@name)
|
136
|
+
expression.send name, *args, &block
|
135
137
|
end
|
136
138
|
|
137
139
|
def to_s
|
data/lib/rbjs/version.rb
CHANGED
data/readme.md
CHANGED
@@ -1,113 +1,17 @@
|
|
1
|
-
|
1
|
+
# Remote Javascript for Ruby on Rails 3.1
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
Rbjs is a modern RJS (remote javascript) 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
|
-
This is a very fresh gem. Feel free to test it while the documentation and tests are still being written. I've added some examples to this readme file. These should help you get a general idea of what this is about.
|
3
|
+
Rbjs is a ruby gem that enables you to write remote javascript in Rails 3. It keeps the browser logic-less. [read more](http://buhrmi.github.com/rbjs)
|
10
4
|
|
11
5
|
## Installation
|
12
6
|
|
13
|
-
Add the
|
14
|
-
|
15
|
-
> gem 'rbjs'
|
16
|
-
|
17
|
-
and run _bundle install_ to install the gem and it's dependencies.
|
18
|
-
|
19
|
-
## Examples
|
20
|
-
|
21
|
-
### Take a look at a simple example:
|
22
|
-
|
23
|
-
# controllers/greeter_controller.rb
|
24
|
-
def greet_me
|
25
|
-
render :js do
|
26
|
-
window.alert "Hello, #{current_user_name}"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
# views/greeter/index.html.erb
|
31
|
-
link_to "Hi there!", "/greeter/greet_me", :remote => true
|
32
|
-
|
33
|
-
### And a more complex example:
|
34
|
-
|
35
|
-
# controllers/posts_controller.rb
|
36
|
-
def refresh
|
37
|
-
post = Post.find params[:id]
|
38
|
-
render :js do
|
39
|
-
post_element = jQuery(post.selector)
|
40
|
-
post_element.html(render post)
|
41
|
-
post_element.css(:opacity => 0).animate(:opacity => 1)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
# views/posts/index.html.erb
|
46
|
-
link_to "Refresh Post", refresh_post_path(post), :remote => true
|
7
|
+
Add the line
|
47
8
|
|
48
|
-
|
49
|
-
|
50
|
-
# controllers/posts_controller.rb
|
51
|
-
def refresh_all
|
52
|
-
@posts = Post.limit(10)
|
53
|
-
end
|
54
|
-
|
55
|
-
# views/posts/refresh_all.js.rbjs
|
56
|
-
for post in @posts
|
57
|
-
jQuery(post.selector).html(render post)
|
58
|
-
end
|
59
|
-
|
60
|
-
### Do complex stuff:
|
61
|
-
|
62
|
-
# controllers/posts_controller.rb
|
63
|
-
def increase_counter
|
64
|
-
@increment = 4
|
65
|
-
end
|
66
|
-
|
67
|
-
# views/posts/increase_counter.js.rbjs
|
68
|
-
allCounters = jQuery('.post.counter')
|
69
|
-
allCounters.each do |index, element|
|
70
|
-
element = jQuery(element)
|
71
|
-
currentValue = element.html!.to_i!
|
72
|
-
element.html(currentValue + @increment)
|
73
|
-
end
|
9
|
+
gem 'rbjs'
|
74
10
|
|
75
|
-
|
76
|
-
jQuery(".post.counter").each(
|
77
|
-
function(index, element) {
|
78
|
-
jQuery(element).html(jQuery(element).html().to_i()+4)
|
79
|
-
}
|
80
|
-
)
|
81
|
-
|
82
|
-
|
83
|
-
# Here is the same example, this time declaring the variables in javascript
|
84
|
-
# by prefixing them with var.
|
85
|
-
# views/posts/increase_counter.js.rbjs
|
86
|
-
var.allCounters = jQuery('.post.counter')
|
87
|
-
allCounters.each do |index, element|
|
88
|
-
var.element = jQuery(element)
|
89
|
-
var.currentValue = element.html!.to_i!
|
90
|
-
element.html(currentValue + @increment)
|
91
|
-
end
|
11
|
+
to your Gemfile and run
|
92
12
|
|
93
|
-
|
94
|
-
var allCounters=(jQuery(".post.counter"));
|
95
|
-
allCounters.each(function(index, element) {
|
96
|
-
var element=(jQuery(element));
|
97
|
-
var currentValue=(element.html().to_i());
|
98
|
-
element.html(currentValue+4)
|
99
|
-
})
|
13
|
+
bundle install
|
100
14
|
|
101
|
-
|
15
|
+
## Usage
|
102
16
|
|
103
|
-
|
104
|
-
self << 'myFunc($)'
|
105
|
-
|
106
|
-
# Hashes and Arrays
|
107
|
-
foo[3]= {name => @user.name}
|
108
|
-
|
109
|
-
# lambdas
|
110
|
-
func = lambda{ window.alert(@message)}
|
111
|
-
setTimeout func, 1000
|
112
|
-
|
113
|
-
More to come.
|
17
|
+
Please refer to the [documentation](http://buhrmi.github.com/rbjs) for a quick example and usage guide.
|
data/spec/rbjs_spec.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'rbjs'
|
2
|
+
|
3
|
+
describe Rbjs::Root, '#evaluate' do
|
4
|
+
|
5
|
+
def dummy_context
|
6
|
+
Struct.new(:assigns).new 'instance_var' => "Instance"
|
7
|
+
#@instance_var = "Instance"
|
8
|
+
end
|
9
|
+
|
10
|
+
def build &block
|
11
|
+
js = Rbjs::Root.new dummy_context, &block
|
12
|
+
js.evaluate
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should call simple functions" do
|
16
|
+
js = build do
|
17
|
+
alert "hi"
|
18
|
+
end
|
19
|
+
js.strip.should == 'alert("hi")'
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
it "should call nested functions" do
|
24
|
+
js = build do
|
25
|
+
alert(hey(123, :foo), ho('wow', level3(:yey)))
|
26
|
+
end
|
27
|
+
js.strip.should == 'alert(hey(123, "foo"), ho("wow", level3("yey")))'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should call simple functions on objects" do
|
31
|
+
js = build do
|
32
|
+
window.alert "hi"
|
33
|
+
end
|
34
|
+
js.strip.should == 'window.alert("hi")'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should distinguish between property access and method calls" do
|
38
|
+
js = build do
|
39
|
+
window.alert
|
40
|
+
window.alert!
|
41
|
+
end
|
42
|
+
js.strip.should == "window.alert;\nwindow.alert()"
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should convert symbols into strings' do
|
46
|
+
js = build do
|
47
|
+
alert :hi
|
48
|
+
end
|
49
|
+
js.strip.should == 'alert("hi")'
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should convert blocks to functions" do
|
53
|
+
js = build do
|
54
|
+
func do |an_argument, another_arg|
|
55
|
+
an_argument.some_func!
|
56
|
+
alert(another_arg)
|
57
|
+
alert(another_arg.some_property)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
js.strip.should == "func(function(an_argument, another_arg) {\nan_argument.some_func();\nalert(another_arg);\nalert(another_arg.some_property)})"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should convert procs to functions" do
|
64
|
+
js = build do
|
65
|
+
some_proc = ->(an_argument, another_arg) do
|
66
|
+
an_argument.some_func!
|
67
|
+
alert(another_arg)
|
68
|
+
alert(another_arg.some_property)
|
69
|
+
end
|
70
|
+
setTimeout some_proc, 1000
|
71
|
+
end
|
72
|
+
js.strip.should == "setTimeout(function(an_argument, another_arg) {\nan_argument.some_func();\nalert(another_arg);\nalert(another_arg.some_property)}, 1000)"
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should convert hashes to javascript objects" do
|
76
|
+
js = build do
|
77
|
+
func(a_key => :a_value)
|
78
|
+
end
|
79
|
+
js.strip.should == 'func({a_key: "a_value"})'
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should correctly nest property access" do
|
83
|
+
js = build do
|
84
|
+
foo.bar!.bla ble => some!.thing(with => :alot), :of_stuff => 1234
|
85
|
+
end
|
86
|
+
js.strip.should == 'foo.bar().bla({ble: some().thing({with: "alot"}),"of_stuff": 1234})'
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should support array conversion" do
|
90
|
+
js = build do
|
91
|
+
self.my_array = [1,:asd, some(innermethod)];
|
92
|
+
end
|
93
|
+
js.strip.should == 'my_array=([1, "asd", some(innermethod)])'
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should support array access" do
|
97
|
+
js = build do
|
98
|
+
alert(something[:name])
|
99
|
+
end
|
100
|
+
js.strip.should == 'alert(something["name"])'
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should support array assignment" do
|
104
|
+
js = build do
|
105
|
+
something[:name] = 123
|
106
|
+
end
|
107
|
+
js.strip.should == 'something["name"]= 123'
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should escape javascript" do
|
111
|
+
js = build do
|
112
|
+
alert("This is a quote: \", this is a backslash: \\")
|
113
|
+
end
|
114
|
+
js.strip.should == 'alert("This is a quote: \\", this is a backslash: \\\\")'
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should can access outer local scope and the view context" do
|
118
|
+
|
119
|
+
local_var = "Local"
|
120
|
+
js = build do
|
121
|
+
alert(@instance_var+local_var)
|
122
|
+
end
|
123
|
+
js.strip.should == 'alert("InstanceLocal")'
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should convert regexp to javascript" do
|
127
|
+
js = build do
|
128
|
+
docs.map do |doc|
|
129
|
+
w.match /^_/
|
130
|
+
emit doc
|
131
|
+
end
|
132
|
+
end
|
133
|
+
js.strip.should == "docs.map(function(doc) {\nw.match(/^_/);\nemit(doc)})"
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: rbjs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.9.
|
5
|
+
version: 0.9.15
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Stefan Buhrmester
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-11-
|
13
|
+
date: 2011-11-07 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
@@ -65,6 +65,7 @@ files:
|
|
65
65
|
- lib/rbjs/version.rb
|
66
66
|
- rbjs.gemspec
|
67
67
|
- readme.md
|
68
|
+
- spec/rbjs_spec.rb
|
68
69
|
homepage: http://github.com/buhrmi/rbjs
|
69
70
|
licenses: []
|
70
71
|
|
@@ -92,5 +93,5 @@ rubygems_version: 1.8.11
|
|
92
93
|
signing_key:
|
93
94
|
specification_version: 3
|
94
95
|
summary: Remote Javascript re-imagined
|
95
|
-
test_files:
|
96
|
-
|
96
|
+
test_files:
|
97
|
+
- spec/rbjs_spec.rb
|