render_to_parent 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitattributes +22 -0
- data/.gitignore +163 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/lib/render_to_parent.rb +17 -0
- data/lib/render_to_parent/action_controller/action_controller.rb +34 -0
- data/lib/render_to_parent/action_view/helpers/js_helper.rb +343 -0
- data/lib/render_to_parent/action_view/template/handlers/rjs.rb +14 -0
- data/lib/render_to_parent/js-rails/on_load_action_controller.rb +2 -0
- data/lib/render_to_parent/js-rails/on_load_action_view.rb +18 -0
- data/lib/render_to_parent/js-rails/renderers.rb +12 -0
- data/lib/render_to_parent/js-rails/rendering.rb +13 -0
- data/lib/render_to_parent/version.rb +3 -0
- data/render_to_parent.gemspec +17 -0
- metadata +61 -0
data/.gitattributes
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Auto detect text files and perform LF normalization
|
2
|
+
* text=auto
|
3
|
+
|
4
|
+
# Custom for Visual Studio
|
5
|
+
*.cs diff=csharp
|
6
|
+
*.sln merge=union
|
7
|
+
*.csproj merge=union
|
8
|
+
*.vbproj merge=union
|
9
|
+
*.fsproj merge=union
|
10
|
+
*.dbproj merge=union
|
11
|
+
|
12
|
+
# Standard to msysgit
|
13
|
+
*.doc diff=astextplain
|
14
|
+
*.DOC diff=astextplain
|
15
|
+
*.docx diff=astextplain
|
16
|
+
*.DOCX diff=astextplain
|
17
|
+
*.dot diff=astextplain
|
18
|
+
*.DOT diff=astextplain
|
19
|
+
*.pdf diff=astextplain
|
20
|
+
*.PDF diff=astextplain
|
21
|
+
*.rtf diff=astextplain
|
22
|
+
*.RTF diff=astextplain
|
data/.gitignore
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
#################
|
2
|
+
## Eclipse
|
3
|
+
#################
|
4
|
+
|
5
|
+
*.pydevproject
|
6
|
+
.project
|
7
|
+
.metadata
|
8
|
+
bin/
|
9
|
+
tmp/
|
10
|
+
*.tmp
|
11
|
+
*.bak
|
12
|
+
*.swp
|
13
|
+
*~.nib
|
14
|
+
local.properties
|
15
|
+
.classpath
|
16
|
+
.settings/
|
17
|
+
.loadpath
|
18
|
+
|
19
|
+
# External tool builders
|
20
|
+
.externalToolBuilders/
|
21
|
+
|
22
|
+
# Locally stored "Eclipse launch configurations"
|
23
|
+
*.launch
|
24
|
+
|
25
|
+
# CDT-specific
|
26
|
+
.cproject
|
27
|
+
|
28
|
+
# PDT-specific
|
29
|
+
.buildpath
|
30
|
+
|
31
|
+
|
32
|
+
#################
|
33
|
+
## Visual Studio
|
34
|
+
#################
|
35
|
+
|
36
|
+
## Ignore Visual Studio temporary files, build results, and
|
37
|
+
## files generated by popular Visual Studio add-ons.
|
38
|
+
|
39
|
+
# User-specific files
|
40
|
+
*.suo
|
41
|
+
*.user
|
42
|
+
*.sln.docstates
|
43
|
+
|
44
|
+
# Build results
|
45
|
+
[Dd]ebug/
|
46
|
+
[Rr]elease/
|
47
|
+
*_i.c
|
48
|
+
*_p.c
|
49
|
+
*.ilk
|
50
|
+
*.meta
|
51
|
+
*.obj
|
52
|
+
*.pch
|
53
|
+
*.pdb
|
54
|
+
*.pgc
|
55
|
+
*.pgd
|
56
|
+
*.rsp
|
57
|
+
*.sbr
|
58
|
+
*.tlb
|
59
|
+
*.tli
|
60
|
+
*.tlh
|
61
|
+
*.tmp
|
62
|
+
*.vspscc
|
63
|
+
.builds
|
64
|
+
*.dotCover
|
65
|
+
|
66
|
+
## TODO: If you have NuGet Package Restore enabled, uncomment this
|
67
|
+
#packages/
|
68
|
+
|
69
|
+
# Visual C++ cache files
|
70
|
+
ipch/
|
71
|
+
*.aps
|
72
|
+
*.ncb
|
73
|
+
*.opensdf
|
74
|
+
*.sdf
|
75
|
+
|
76
|
+
# Visual Studio profiler
|
77
|
+
*.psess
|
78
|
+
*.vsp
|
79
|
+
|
80
|
+
# ReSharper is a .NET coding add-in
|
81
|
+
_ReSharper*
|
82
|
+
|
83
|
+
# Installshield output folder
|
84
|
+
[Ee]xpress
|
85
|
+
|
86
|
+
# DocProject is a documentation generator add-in
|
87
|
+
DocProject/buildhelp/
|
88
|
+
DocProject/Help/*.HxT
|
89
|
+
DocProject/Help/*.HxC
|
90
|
+
DocProject/Help/*.hhc
|
91
|
+
DocProject/Help/*.hhk
|
92
|
+
DocProject/Help/*.hhp
|
93
|
+
DocProject/Help/Html2
|
94
|
+
DocProject/Help/html
|
95
|
+
|
96
|
+
# Click-Once directory
|
97
|
+
publish
|
98
|
+
|
99
|
+
# Others
|
100
|
+
[Bb]in
|
101
|
+
[Oo]bj
|
102
|
+
sql
|
103
|
+
TestResults
|
104
|
+
*.Cache
|
105
|
+
ClientBin
|
106
|
+
stylecop.*
|
107
|
+
~$*
|
108
|
+
*.dbmdl
|
109
|
+
Generated_Code #added for RIA/Silverlight projects
|
110
|
+
|
111
|
+
# Backup & report files from converting an old project file to a newer
|
112
|
+
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
113
|
+
_UpgradeReport_Files/
|
114
|
+
Backup*/
|
115
|
+
UpgradeLog*.XML
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
############
|
120
|
+
## Windows
|
121
|
+
############
|
122
|
+
|
123
|
+
# Windows image file caches
|
124
|
+
Thumbs.db
|
125
|
+
|
126
|
+
# Folder config file
|
127
|
+
Desktop.ini
|
128
|
+
|
129
|
+
|
130
|
+
#############
|
131
|
+
## Python
|
132
|
+
#############
|
133
|
+
|
134
|
+
*.py[co]
|
135
|
+
|
136
|
+
# Packages
|
137
|
+
*.egg
|
138
|
+
*.egg-info
|
139
|
+
dist
|
140
|
+
build
|
141
|
+
eggs
|
142
|
+
parts
|
143
|
+
bin
|
144
|
+
var
|
145
|
+
sdist
|
146
|
+
develop-eggs
|
147
|
+
.installed.cfg
|
148
|
+
|
149
|
+
# Installer logs
|
150
|
+
pip-log.txt
|
151
|
+
|
152
|
+
# Unit test / coverage reports
|
153
|
+
.coverage
|
154
|
+
.tox
|
155
|
+
|
156
|
+
#Translations
|
157
|
+
*.mo
|
158
|
+
|
159
|
+
#Mr Developer
|
160
|
+
.mr.developer.cfg
|
161
|
+
|
162
|
+
# Mac crap
|
163
|
+
.DS_Store
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 zb
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# RenderToParent
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'render_to_parent'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install render_to_parent
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "render_to_parent/version"
|
2
|
+
require 'rails'
|
3
|
+
require 'active_support'
|
4
|
+
|
5
|
+
module RenderToParent
|
6
|
+
class Engine < Rails::Engine
|
7
|
+
initializer 'js-rails.initialize' do
|
8
|
+
ActiveSupport.on_load(:action_controller) do
|
9
|
+
require 'render_to_parent/js-rails/on_load_action_controller'
|
10
|
+
end
|
11
|
+
|
12
|
+
ActiveSupport.on_load(:action_view) do
|
13
|
+
require 'render_to_parent/js-rails/on_load_action_view'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RenderToParent
|
2
|
+
# Module containing the methods useful for child IFRAME to parent window communication
|
3
|
+
module ActionController
|
4
|
+
# Executes the response body as JavaScript in the context of the parent window.
|
5
|
+
# Use this method of you are posting a form to a hidden IFRAME or if you would like
|
6
|
+
# to use IFRAME base RPC.
|
7
|
+
def render_to_parent(&block)
|
8
|
+
yield
|
9
|
+
|
10
|
+
if performed?
|
11
|
+
# We're returning HTML instead of JS or XML now
|
12
|
+
response.headers['Content-Type'] = 'text/html; charset=UTF-8'
|
13
|
+
|
14
|
+
# Either pull out a redirect or the request body
|
15
|
+
script = response.body || ''
|
16
|
+
|
17
|
+
# Clear out the previous render to prevent double render
|
18
|
+
self.response_body = nil
|
19
|
+
|
20
|
+
# Eval in parent scope and replace document location of this frame
|
21
|
+
# so back button doesn't replay action on targeted forms
|
22
|
+
# loc = document.location to be set after parent is updated for IE
|
23
|
+
# with(window.parent) - pull in variables from parent window
|
24
|
+
# setTimeout - scope the execution in the windows parent for safari
|
25
|
+
# window.eval - legal eval for Opera
|
26
|
+
render :text => "<html><body><script type='text/javascript' charset='utf-8'>
|
27
|
+
var loc = document.location;
|
28
|
+
with(window.parent) { setTimeout(function() { window.eval('#{self.class.helpers.escape_javascript script}'); window.loc && loc.replace('about:blank'); }, 1) }
|
29
|
+
</script></body></html>"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
ActionController::Base.send(:include, RenderToParent::ActionController)
|
@@ -0,0 +1,343 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'active_support/json'
|
3
|
+
require 'active_support/core_ext/object/blank'
|
4
|
+
require 'active_support/core_ext/string/output_safety'
|
5
|
+
|
6
|
+
module ActionView
|
7
|
+
module Helpers
|
8
|
+
#=====JsHelper start
|
9
|
+
module JsHelper
|
10
|
+
# All the methods were moved to GeneratorMethods so that
|
11
|
+
# #include_helpers_from_context has nothing to overwrite.
|
12
|
+
class JavaScriptGenerator #:nodoc:
|
13
|
+
def initialize(context, &block) #:nodoc:
|
14
|
+
@context, @lines = context, []
|
15
|
+
include_helpers_from_context
|
16
|
+
@context.with_output_buffer(@lines) do
|
17
|
+
@context.instance_exec(self, &block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def include_helpers_from_context
|
23
|
+
extend @context.helpers if @context.respond_to?(:helpers) && @context.helpers
|
24
|
+
extend GeneratorMethods
|
25
|
+
end
|
26
|
+
|
27
|
+
# JavaScriptGenerator generates blocks of JavaScript code that allow you
|
28
|
+
# to change the content and presentation of multiple DOM elements. Use
|
29
|
+
# this in your Ajax response bodies, either in a <tt>\<script></tt> tag
|
30
|
+
# or as plain JavaScript sent with a Content-type of "text/javascript".
|
31
|
+
#
|
32
|
+
# Create new instances with PrototypeHelper#update_page or with
|
33
|
+
# ActionController::Base#render, then call +insert_html+, +replace_html+,
|
34
|
+
# +remove+, +show+, +hide+, +visual_effect+, or any other of the built-in
|
35
|
+
# methods on the yielded generator in any order you like to modify the
|
36
|
+
# content and appearance of the current page.
|
37
|
+
#
|
38
|
+
# Example:
|
39
|
+
#
|
40
|
+
# # Generates:
|
41
|
+
# # new Element.insert("list", { bottom: "<li>Some item</li>" });
|
42
|
+
# # new Effect.Highlight("list");
|
43
|
+
# # ["status-indicator", "cancel-link"].each(Element.hide);
|
44
|
+
# update_page do |page|
|
45
|
+
# page.insert_html :bottom, 'list', "<li>#{@item.name}</li>"
|
46
|
+
# page.visual_effect :highlight, 'list'
|
47
|
+
# page.hide 'status-indicator', 'cancel-link'
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
#
|
51
|
+
# Helper methods can be used in conjunction with JavaScriptGenerator.
|
52
|
+
# When a helper method is called inside an update block on the +page+
|
53
|
+
# object, that method will also have access to a +page+ object.
|
54
|
+
#
|
55
|
+
# Example:
|
56
|
+
#
|
57
|
+
# module ApplicationHelper
|
58
|
+
# def update_time
|
59
|
+
# page.replace_html 'time', Time.now.to_s(:db)
|
60
|
+
# page.visual_effect :highlight, 'time'
|
61
|
+
# end
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# # Controller action
|
65
|
+
# def poll
|
66
|
+
# render(:update) { |page| page.update_time }
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
# Calls to JavaScriptGenerator not matching a helper method below
|
70
|
+
# generate a proxy to the JavaScript Class named by the method called.
|
71
|
+
#
|
72
|
+
# Examples:
|
73
|
+
#
|
74
|
+
# # Generates:
|
75
|
+
# # Foo.init();
|
76
|
+
# update_page do |page|
|
77
|
+
# page.foo.init
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
# # Generates:
|
81
|
+
# # Event.observe('one', 'click', function () {
|
82
|
+
# # $('two').show();
|
83
|
+
# # });
|
84
|
+
# update_page do |page|
|
85
|
+
# page.event.observe('one', 'click') do |p|
|
86
|
+
# p[:two].show
|
87
|
+
# end
|
88
|
+
# end
|
89
|
+
#
|
90
|
+
# You can also use PrototypeHelper#update_page_tag instead of
|
91
|
+
# PrototypeHelper#update_page to wrap the generated JavaScript in a
|
92
|
+
# <tt>\<script></tt> tag.
|
93
|
+
module GeneratorMethods
|
94
|
+
def to_s #:nodoc:
|
95
|
+
#(@lines * $/).tap do |javascript|
|
96
|
+
(@lines.map(&:to_s) * $/).tap do |javascript|
|
97
|
+
if ActionView::Base.debug_rjs
|
98
|
+
source = javascript.dup
|
99
|
+
javascript.replace "try {\n#{source}\n} catch (e) "
|
100
|
+
javascript << "{ alert('RJS error:\\n\\n' + e.toString()); alert('#{source.gsub('\\','\0\0').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }}'); throw e }"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns an object whose <tt>to_json</tt> evaluates to +code+. Use this to pass a literal JavaScript
|
106
|
+
# expression as an argument to another JavaScriptGenerator method.
|
107
|
+
def literal(code)
|
108
|
+
::ActiveSupport::JSON::Variable.new(code.to_s)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Displays an alert dialog with the given +message+.
|
112
|
+
#
|
113
|
+
# Example:
|
114
|
+
#
|
115
|
+
# # Generates: alert('This message is from Rails!')
|
116
|
+
# page.alert('This message is from Rails!')
|
117
|
+
def alert(message)
|
118
|
+
call 'alert', message
|
119
|
+
end
|
120
|
+
|
121
|
+
# Redirects the browser to the given +location+ using JavaScript, in the same form as +url_for+.
|
122
|
+
#
|
123
|
+
# Examples:
|
124
|
+
#
|
125
|
+
# # Generates: window.location.href = "/mycontroller";
|
126
|
+
# page.redirect_to(:action => 'index')
|
127
|
+
#
|
128
|
+
# # Generates: window.location.href = "/account/signup";
|
129
|
+
# page.redirect_to(:controller => 'account', :action => 'signup')
|
130
|
+
def redirect_to(location)
|
131
|
+
url = location.is_a?(String) ? location : @context.url_for(location)
|
132
|
+
record "window.location.href = #{url.inspect}"
|
133
|
+
end
|
134
|
+
|
135
|
+
# Reloads the browser's current +location+ using JavaScript
|
136
|
+
#
|
137
|
+
# Examples:
|
138
|
+
#
|
139
|
+
# # Generates: window.location.reload();
|
140
|
+
# page.reload
|
141
|
+
def reload
|
142
|
+
record 'window.location.reload()'
|
143
|
+
end
|
144
|
+
|
145
|
+
# Calls the JavaScript +function+, optionally with the given +arguments+.
|
146
|
+
#
|
147
|
+
# If a block is given, the block will be passed to a new JavaScriptGenerator;
|
148
|
+
# the resulting JavaScript code will then be wrapped inside <tt>function() { ... }</tt>
|
149
|
+
# and passed as the called function's final argument.
|
150
|
+
#
|
151
|
+
# Examples:
|
152
|
+
#
|
153
|
+
# # Generates: Element.replace(my_element, "My content to replace with.")
|
154
|
+
# page.call 'Element.replace', 'my_element', "My content to replace with."
|
155
|
+
#
|
156
|
+
# # Generates: alert('My message!')
|
157
|
+
# page.call 'alert', 'My message!'
|
158
|
+
#
|
159
|
+
# # Generates:
|
160
|
+
# # my_method(function() {
|
161
|
+
# # $("one").show();
|
162
|
+
# # $("two").hide();
|
163
|
+
# # });
|
164
|
+
# page.call(:my_method) do |p|
|
165
|
+
# p[:one].show
|
166
|
+
# p[:two].hide
|
167
|
+
# end
|
168
|
+
def call(function, *arguments, &block)
|
169
|
+
record "#{function}(#{arguments_for_call(arguments, block)})"
|
170
|
+
end
|
171
|
+
|
172
|
+
# Assigns the JavaScript +variable+ the given +value+.
|
173
|
+
#
|
174
|
+
# Examples:
|
175
|
+
#
|
176
|
+
# # Generates: my_string = "This is mine!";
|
177
|
+
# page.assign 'my_string', 'This is mine!'
|
178
|
+
#
|
179
|
+
# # Generates: record_count = 33;
|
180
|
+
# page.assign 'record_count', 33
|
181
|
+
#
|
182
|
+
# # Generates: tabulated_total = 47
|
183
|
+
# page.assign 'tabulated_total', @total_from_cart
|
184
|
+
#
|
185
|
+
def assign(variable, value)
|
186
|
+
record "#{variable} = #{javascript_object_for(value)}"
|
187
|
+
end
|
188
|
+
|
189
|
+
# Writes raw JavaScript to the page.
|
190
|
+
#
|
191
|
+
# Example:
|
192
|
+
#
|
193
|
+
# page << "alert('JavaScript with Prototype.');"
|
194
|
+
def <<(javascript)
|
195
|
+
@lines << javascript
|
196
|
+
end
|
197
|
+
|
198
|
+
# Executes the content of the block after a delay of +seconds+. Example:
|
199
|
+
#
|
200
|
+
# # Generates:
|
201
|
+
# # setTimeout(function() {
|
202
|
+
# # ;
|
203
|
+
# # new Effect.Fade("notice",{});
|
204
|
+
# # }, 20000);
|
205
|
+
# page.delay(20) do
|
206
|
+
# page.visual_effect :fade, 'notice'
|
207
|
+
# end
|
208
|
+
def delay(seconds = 1)
|
209
|
+
record "setTimeout(function() {\n\n"
|
210
|
+
yield
|
211
|
+
record "}, #{(seconds * 1000).to_i})"
|
212
|
+
end
|
213
|
+
|
214
|
+
private
|
215
|
+
def loop_on_multiple_args(method, ids)
|
216
|
+
record(ids.size>1 ?
|
217
|
+
"#{javascript_object_for(ids)}.each(#{method})" :
|
218
|
+
"#{method}(#{javascript_object_for(ids.first)})")
|
219
|
+
end
|
220
|
+
|
221
|
+
def page
|
222
|
+
self
|
223
|
+
end
|
224
|
+
|
225
|
+
def record(line)
|
226
|
+
line = "#{line.to_s.chomp.gsub(/\;\z/, '')};"
|
227
|
+
self << line
|
228
|
+
line
|
229
|
+
end
|
230
|
+
|
231
|
+
def render(*options)
|
232
|
+
with_formats(:html) do
|
233
|
+
case option = options.first
|
234
|
+
when Hash
|
235
|
+
@context.render(*options)
|
236
|
+
else
|
237
|
+
option.to_s
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def with_formats(*args)
|
243
|
+
return yield unless @context
|
244
|
+
|
245
|
+
lookup = @context.lookup_context
|
246
|
+
begin
|
247
|
+
old_formats, lookup.formats = lookup.formats, args
|
248
|
+
yield
|
249
|
+
ensure
|
250
|
+
lookup.formats = old_formats
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
def javascript_object_for(object)
|
255
|
+
::ActiveSupport::JSON.encode(object)
|
256
|
+
end
|
257
|
+
|
258
|
+
def arguments_for_call(arguments, block = nil)
|
259
|
+
arguments << block_to_function(block) if block
|
260
|
+
arguments.map { |argument| javascript_object_for(argument) }.join ', '
|
261
|
+
end
|
262
|
+
|
263
|
+
def block_to_function(block)
|
264
|
+
generator = self.class.new(@context, &block)
|
265
|
+
literal("function() { #{generator.to_s} }")
|
266
|
+
end
|
267
|
+
|
268
|
+
def method_missing(method, *arguments)
|
269
|
+
proxy = JavaScriptGeneratorScope.new(self, method.to_s, *arguments)
|
270
|
+
@lines << proxy
|
271
|
+
proxy
|
272
|
+
#JavaScriptProxy.new(self, method.to_s.camelize)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
class JavaScriptGeneratorScope < JavaScriptGenerator
|
278
|
+
def initialize(generator, method, *arguments)
|
279
|
+
@generator = generator
|
280
|
+
@methods = [[method, arguments]]
|
281
|
+
self
|
282
|
+
end
|
283
|
+
|
284
|
+
def to_s
|
285
|
+
js = []
|
286
|
+
@methods.each do |method, args|
|
287
|
+
js << "#{method}(#{arguments_for_call(args)})"
|
288
|
+
end
|
289
|
+
record(js.join("."))
|
290
|
+
end
|
291
|
+
|
292
|
+
private
|
293
|
+
def method_missing(method, *arguments)
|
294
|
+
@methods << [method, arguments]
|
295
|
+
self
|
296
|
+
end
|
297
|
+
|
298
|
+
def record(line)
|
299
|
+
"#{line.to_s.chomp.gsub(/\;\z/, '')};"
|
300
|
+
end
|
301
|
+
|
302
|
+
def javascript_object_for(object)
|
303
|
+
object.respond_to?(:to_json) ? object.to_json : object.inspect
|
304
|
+
end
|
305
|
+
|
306
|
+
def arguments_for_call(arguments, block = nil)
|
307
|
+
arguments << block_to_function(block) if block
|
308
|
+
arguments.map { |argument| javascript_object_for(argument) }.join ', '
|
309
|
+
end
|
310
|
+
|
311
|
+
def block_to_function(block)
|
312
|
+
generator = self.class.new(@context, &block)
|
313
|
+
literal("function() { #{generator.to_s} }")
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
# Yields a JavaScriptGenerator and returns the generated JavaScript code.
|
318
|
+
# Use this to update multiple elements on a page in an Ajax response.
|
319
|
+
# See JavaScriptGenerator for more information.
|
320
|
+
#
|
321
|
+
# Example:
|
322
|
+
#
|
323
|
+
# update_page do |page|
|
324
|
+
# page.hide 'spinner'
|
325
|
+
# end
|
326
|
+
def update_page(&block)
|
327
|
+
JavaScriptGenerator.new(self, &block).to_s.html_safe
|
328
|
+
end
|
329
|
+
|
330
|
+
# Works like update_page but wraps the generated JavaScript in a
|
331
|
+
# <tt>\<script></tt> tag. Use this to include generated JavaScript in an
|
332
|
+
# ERb template. See JavaScriptGenerator for more information.
|
333
|
+
#
|
334
|
+
# +html_options+ may be a hash of <tt>\<script></tt> attributes to be
|
335
|
+
# passed to ActionView::Helpers::JavaScriptHelper#javascript_tag.
|
336
|
+
def update_page_tag(html_options = {}, &block)
|
337
|
+
javascript_tag update_page(&block), html_options
|
338
|
+
end
|
339
|
+
|
340
|
+
end
|
341
|
+
#=====JsHelper end
|
342
|
+
end
|
343
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ActionView
|
2
|
+
module Template::Handlers
|
3
|
+
class RJS
|
4
|
+
# Default format used by RJS.
|
5
|
+
class_attribute :default_format
|
6
|
+
self.default_format = Mime::JS
|
7
|
+
|
8
|
+
def call(template)
|
9
|
+
"update_page do |page|;#{template.source}\nend"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'render_to_parent/action_view/helpers/js_helper'
|
2
|
+
require 'render_to_parent/action_view/template/handlers/rjs'
|
3
|
+
require 'render_to_parent/js-rails/rendering'
|
4
|
+
|
5
|
+
ActionView::Base.class_eval do
|
6
|
+
cattr_accessor :debug_rjs
|
7
|
+
self.debug_rjs = false
|
8
|
+
end
|
9
|
+
|
10
|
+
ActionView::Base.class_eval do
|
11
|
+
include ActionView::Helpers::JsHelper
|
12
|
+
end
|
13
|
+
|
14
|
+
ActionView::TestCase.class_eval do
|
15
|
+
include ActionView::Helpers::JsHelper
|
16
|
+
end
|
17
|
+
|
18
|
+
ActionView::Template.register_template_handler :rjs, ActionView::Template::Handlers::RJS.new
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'action_controller/metal/renderers'
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
module Renderers
|
5
|
+
add :update do |proc, options|
|
6
|
+
view_context = self.view_context
|
7
|
+
generator = ActionView::Helpers::JsHelper::JavaScriptGenerator.new(view_context, &proc)
|
8
|
+
self.content_type = Mime::JS
|
9
|
+
self.response_body = generator.to_s
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'action_view/helpers/rendering_helper'
|
2
|
+
|
3
|
+
ActionView::Helpers::RenderingHelper.module_eval do
|
4
|
+
def render_with_update(options = {}, locals = {}, &block)
|
5
|
+
if options == :update
|
6
|
+
update_page(&block)
|
7
|
+
else
|
8
|
+
render_without_update(options, locals, &block)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
alias_method_chain :render, :update
|
13
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/render_to_parent/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["zb"]
|
6
|
+
gem.email = ["zhou51736@gmail.com"]
|
7
|
+
gem.description = %q{rails 3.2 for respond to parent}
|
8
|
+
gem.summary = %q{render_to_parent}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "render_to_parent"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = RenderToParent::VERSION
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: render_to_parent
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- zb
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-26 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: rails 3.2 for respond to parent
|
15
|
+
email:
|
16
|
+
- zhou51736@gmail.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitattributes
|
22
|
+
- .gitignore
|
23
|
+
- Gemfile
|
24
|
+
- LICENSE
|
25
|
+
- README.md
|
26
|
+
- Rakefile
|
27
|
+
- lib/render_to_parent.rb
|
28
|
+
- lib/render_to_parent/action_controller/action_controller.rb
|
29
|
+
- lib/render_to_parent/action_view/helpers/js_helper.rb
|
30
|
+
- lib/render_to_parent/action_view/template/handlers/rjs.rb
|
31
|
+
- lib/render_to_parent/js-rails/on_load_action_controller.rb
|
32
|
+
- lib/render_to_parent/js-rails/on_load_action_view.rb
|
33
|
+
- lib/render_to_parent/js-rails/renderers.rb
|
34
|
+
- lib/render_to_parent/js-rails/rendering.rb
|
35
|
+
- lib/render_to_parent/version.rb
|
36
|
+
- render_to_parent.gemspec
|
37
|
+
homepage: ''
|
38
|
+
licenses: []
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
requirements: []
|
56
|
+
rubyforge_project:
|
57
|
+
rubygems_version: 1.8.25
|
58
|
+
signing_key:
|
59
|
+
specification_version: 3
|
60
|
+
summary: render_to_parent
|
61
|
+
test_files: []
|