rbjs 0.9.14 → 0.9.15
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/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
|