sinatra-js 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+ doc
21
+
22
+ ## PROJECT::SPECIFIC
23
+ spec/fixtures/public/system
data/CHANGES ADDED
@@ -0,0 +1,4 @@
1
+
2
+ rel 0.1.0 (2010-03-03)
3
+
4
+ * initial release
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 kematzy
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/README.rdoc ADDED
@@ -0,0 +1,265 @@
1
+ = Sinatra::JS
2
+
3
+ A Sinatra Extension that makes working with JS easy.
4
+
5
+
6
+
7
+ == Installation
8
+
9
+ # Add RubyGems.org (former Gemcutter) to your RubyGems sources
10
+ $ gem sources -a http://rubygems.org
11
+
12
+ $ (sudo)? gem install sinatra-js
13
+
14
+ == Dependencies
15
+
16
+ This Gem depends upon the following:
17
+
18
+ === Runtime:
19
+
20
+ * sinatra ( >= 1.0.a )
21
+ * sinatra-tags[http://github.com/kematzy/sinatra-tags] ( >= 0.1.0 )
22
+ * sinatra-outputbuffer[http://github.com/kematzy/sinatra-outputbuffer] ( >= 0.1.0 )
23
+ * sinatra-basics[http://github.com/kematzy/sinatra-basics] ( >= 0.5.0 )
24
+
25
+ Optionals:
26
+
27
+ * sinatra-settings[http://github.com/kematzy/sinatra-settings] (>= 0.1.1) # to view default settings in a browser display.
28
+ * sinatra-logger[http://github.com/kematzy/sinatra-logger] (>= 0.1.0) # to capture error messages in the log file.
29
+
30
+
31
+ === Development & Tests:
32
+
33
+ * sinatra-tests (>= 0.1.6)
34
+ * rspec (>= 1.3.0 )
35
+ * rack-test (>= 0.5.3)
36
+ * rspec_hpricot_matchers (>= 0.1.0)
37
+
38
+
39
+ == Getting Started
40
+
41
+ To start using Sinatra::JS, just require and register the extension in your App...
42
+
43
+ require 'sinatra/js'
44
+
45
+ class YourApp < Sinatra::Base
46
+ register(Sinatra::JS)
47
+
48
+ <snip...>
49
+
50
+ end
51
+
52
+
53
+ You then get access to 6 useful helper methods:
54
+
55
+
56
+ === <tt>js() / javascript()</tt>
57
+
58
+ This method serves two purposes:
59
+
60
+ a) Return a stylesheet <tt><script src=""></script></tt> tag with the <tt>path</tt> given.
61
+
62
+ js('jquery') # =>
63
+
64
+ <script src="/jquery.js" type="text/javascript" charset="utf-8"></script>
65
+
66
+ js('/js/jquery-tools.js') # =>
67
+
68
+ <script src="/js/jquery-tools.js" type="text/javascript" charset="utf-8"></script>
69
+
70
+
71
+ You can even pass an array of files to the method, which then outputs the <tt><script></tt>
72
+ tags for each file.
73
+
74
+ js( ['/js/jquery.js', '/js/jquery.ui'] ) # =>
75
+
76
+ <script src="/js/jquery.js" type="text/javascript" charset="utf-8"></script>
77
+ <script src="/js/jquery.ui.js" type="text/javascript" charset="utf-8"></script>
78
+
79
+
80
+
81
+ b) When passed a *block*, a <tt><script></tt> tag will be created with the yielded block
82
+ as its contents.
83
+
84
+ js do
85
+ "document.write('hi');"
86
+ end
87
+ # =>
88
+
89
+ <script type="text/javascript" charset="utf-8">
90
+ document.write('hi');
91
+ </script>
92
+
93
+
94
+ === <tt>js_custom() & js_custom_add()</tt>
95
+
96
+ These two methods works together, like this:
97
+
98
+ First you add the <tt>js_custom()</tt> method to your layout(s) (../views/layout.erb):
99
+
100
+ <html>
101
+ <head>
102
+ <snip...>
103
+
104
+ <%= js_custom %>
105
+
106
+ </head>
107
+
108
+
109
+
110
+ Then in your views, you can use the <tt>js_custom_add()</tt> method to add custom JS
111
+ to the page, like this:
112
+
113
+ # in ../views/template.erb
114
+ <%= js_custom_add( "window.alert('this works');" )
115
+
116
+ # in ../views/shared/sidebar.erb
117
+ <%= js_custom_add( "document.write('this also works');" )
118
+
119
+
120
+ Which outputs the following in the <tt><head></tt> element of your page.
121
+
122
+ <html>
123
+ <head>
124
+ <snip...>
125
+
126
+ <script type="text/javascript" charset="utf-8">
127
+ window.alert('this works');
128
+ document.write('this also works');
129
+ </script>
130
+
131
+
132
+ This functionality makes it very easy to add special JS functionality to any page,
133
+ even from within multiple views.
134
+
135
+
136
+ === <tt>js_custom_files() & js_custom_add_file()</tt>
137
+
138
+ These two methods also works together in a similar fashion, like this:
139
+
140
+ First of, add the <tt>js_custom_files()</tt> method to your layout(s) (../views/layout.erb):
141
+
142
+ <html>
143
+ <head>
144
+ <snip...>
145
+
146
+ <%= js_custom_files %>
147
+
148
+ </head>
149
+
150
+
151
+ Then in your views, you can use the <tt>js_custom_add_file()</tt> method to add a custom JS
152
+ file to the page, like this:
153
+
154
+ <%= js_custom_add_file('home') #=>
155
+
156
+ <script src="/home.js" type="text/javascript" charset="utf-8"></script>
157
+
158
+
159
+ You can also use the method to embed the content of a .js file into the <tt><head></tt>
160
+ part of any page, like this:
161
+
162
+ # NB! path is starting from APP_ROOT/public/
163
+
164
+ js_custom_add_file('home.js',:insert_into_html) #=>
165
+
166
+ <html>
167
+ <head>
168
+ <snip...>
169
+
170
+ <script type="text/javascript" charset="utf-8">
171
+ // the contents of ../public/home.js
172
+ </script>
173
+
174
+
175
+ You can even give a file system path to embed the content of a globaly shared .js file
176
+ outside of your applications path. Providing an easy way to resuse common snippets of code.
177
+
178
+
179
+ # NB! make sure the path and .js file works together as a real path.
180
+
181
+ # the :path value should always be a directory without the trailing slash.
182
+
183
+ js_custom_add_file('win.open.js',:insert_into_html, '/path/2/some/directory')
184
+
185
+
186
+ <html>
187
+ <head>
188
+ <snip...>
189
+
190
+ <script type="text/javascript" charset="utf-8">
191
+ // the contents of /path/2/some/directory/win.open.js
192
+ </script>
193
+
194
+
195
+
196
+ === <tt>js_insert_file()</tt>
197
+
198
+ This is a simple convenicence method that takes a path to a JS file
199
+ and inserts its content straight into the current view, without any enclosing HTML tags.
200
+
201
+ The method depends upon the settings of the <tt>:js_shared_source_files_dir</tt>
202
+ configuration variable defined inside your application.
203
+ By default this is set to <tt>'ENV['HOME']/.alt/js'</tt>.
204
+
205
+ An example of how to use this functionality:
206
+
207
+ # in your app's routes configurations
208
+
209
+ get('/js/app.js') do
210
+ content_type 'text/javascript'
211
+ erb('js/app'.to_sym, :layout => false)
212
+ end
213
+
214
+
215
+ # in views/js/app.erb
216
+
217
+ <%= js_insert_file('jquery') %>
218
+
219
+ # => insert the contents of ENV['HOME']/.alt/js/jquery.js
220
+
221
+
222
+ You can also load and insert local files, ie files in your app's <tt>public/js/</tt> directory
223
+ by adding the <tt>:local</tt> flag to the call.
224
+
225
+ <%= js_insert_file('tweets', :local) %>
226
+
227
+ # => insert the contents of /path/2/your/app/public/js/tweets.js
228
+
229
+
230
+
231
+ == RTFM
232
+
233
+ If the above is not clear enough, please check the Specs for a better understanding.
234
+
235
+
236
+ == Errors / Bugs
237
+
238
+ If something is not behaving intuitively, it is a bug, and should be reported.
239
+ Report it here: http://github.com/kematzy/sinatra-js/issues
240
+
241
+
242
+ == TODOs
243
+
244
+ * Keep it up to date with any changes in Sinatra.
245
+
246
+ * Add bundle functionality from Sinatra::Bundles gem.
247
+
248
+ * Improve the specs a bit and add missing tests.
249
+
250
+ * Any other improvements I or You can think of.
251
+
252
+
253
+ == Note on Patches/Pull Requests
254
+
255
+ * Fork the project.
256
+ * Make your feature addition or bug fix.
257
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
258
+ * Commit, do not mess with rakefile, version, or history.
259
+ * (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
260
+ * Send me a pull request. Bonus points for topic branches.
261
+
262
+ == Copyright
263
+
264
+ Copyright (c) 2010 kematzy. See LICENSE for details.
265
+
data/Rakefile ADDED
@@ -0,0 +1,91 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "sinatra-js"
8
+ gem.summary = %Q{A Sinatra Extension that makes working with JS easy.}
9
+ gem.description = %Q{A Sinatra Extension that makes working with JS easy.}
10
+ gem.email = "kematzy@gmail.com"
11
+ gem.homepage = "http://github.com/kematzy/sinatra-js"
12
+ gem.authors = ["kematzy"]
13
+ gem.add_dependency "sinatra", ">= 1.0"
14
+ gem.add_dependency "sinatra-tags"
15
+ gem.add_dependency "sinatra-assets"
16
+ gem.add_development_dependency "sinatra-tests", ">= 0.1.6"
17
+ gem.add_development_dependency "rspec", ">= 1.3.0"
18
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
19
+ end
20
+ Jeweler::GemcutterTasks.new
21
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
23
+ end
24
+
25
+ require 'spec/rake/spectask'
26
+ Spec::Rake::SpecTask.new(:spec) do |spec|
27
+ spec.libs << 'lib' << 'spec'
28
+ spec.spec_opts = ["--color", "--format", "specdoc", "--require", "spec/spec_helper.rb"]
29
+ spec.spec_files = FileList['spec/**/*_spec.rb']
30
+ end
31
+
32
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
33
+ spec.libs << 'lib' << 'spec'
34
+ spec.spec_opts = ["--color", "--format", "specdoc", "--require", "spec/spec_helper.rb"]
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ namespace :spec do
40
+
41
+ desc "Run all specifications quietly"
42
+ Spec::Rake::SpecTask.new(:quiet) do |t|
43
+ t.libs << "lib"
44
+ t.spec_opts = ["--color", "--require", "spec/spec_helper.rb"]
45
+ end
46
+
47
+ desc "Run specific spec verbosely (SPEC=/path/2/file)"
48
+ Spec::Rake::SpecTask.new(:select) do |t|
49
+ t.libs << "lib"
50
+ t.spec_files = [ENV["SPEC"]]
51
+ t.spec_opts = ["--color", "--format", "specdoc", "--require", "spec/spec_helper.rb"]
52
+ end
53
+
54
+ end
55
+
56
+ task :spec => :check_dependencies
57
+
58
+ task :default => :spec
59
+
60
+ require 'rake/rdoctask'
61
+ Rake::RDocTask.new do |rdoc|
62
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
63
+
64
+ rdoc.rdoc_dir = 'rdoc'
65
+ rdoc.title = "Sinatra::JS #{version}"
66
+ rdoc.rdoc_files.include('README*')
67
+ rdoc.rdoc_files.include('lib/**/*.rb')
68
+ end
69
+
70
+ desc 'Build the rdoc HTML Files'
71
+ task :docs do
72
+ version = File.exist?('VERSION') ? IO.read('VERSION').chomp : "[Unknown]"
73
+
74
+ sh "sdoc -N --title 'Sinatra::JS v#{version}' lib/ README.rdoc"
75
+ end
76
+
77
+ namespace :docs do
78
+
79
+ desc 'Remove rdoc products'
80
+ task :remove => [:clobber_rdoc]
81
+
82
+ desc 'Force a rebuild of the RDOC files'
83
+ task :rebuild => [:rerdoc]
84
+
85
+ desc 'Build docs, and open in browser for viewing (specify BROWSER)'
86
+ task :open => [:docs] do
87
+ browser = ENV["BROWSER"] || "safari"
88
+ sh "open -a #{browser} doc/index.html"
89
+ end
90
+
91
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.5
data/lib/sinatra/js.rb ADDED
@@ -0,0 +1,564 @@
1
+
2
+ require 'sinatra/base'
3
+ require 'sinatra/tags'
4
+ require 'sinatra/assets'
5
+
6
+ module Tilt
7
+
8
+ ## RJS (RubyJS) support, piggy-backing onto the ERBTemplate
9
+ # so that we can use <% %> tags with Ruby code inside the .rjs file
10
+ register 'rjs', ERBTemplate
11
+
12
+ end #/module Tilt
13
+
14
+ module Sinatra
15
+
16
+ module Templates
17
+
18
+ ## add support for .rjs
19
+ def rjs(template, options={}, locals={})
20
+ options[:outvar] = '@_out_buf'
21
+ options[:layout] = false
22
+ render :rjs, template, options, locals
23
+ end
24
+
25
+ end #/module Templates
26
+
27
+ # = Sinatra::JS
28
+ #
29
+ # A Sinatra Extension that makes working with JS easy.
30
+ #
31
+ #
32
+ #
33
+ # == Installation
34
+ #
35
+ # # Add RubyGems.org (former Gemcutter) to your RubyGems sources
36
+ # $ gem sources -a http://rubygems.org
37
+ #
38
+ # $ (sudo)? gem install sinatra-js
39
+ #
40
+ # == Dependencies
41
+ #
42
+ # This Gem depends upon the following:
43
+ #
44
+ # === Runtime:
45
+ #
46
+ # * sinatra ( >= 1.0.a )
47
+ # * sinatra-tags[http://github.com/kematzy/sinatra-tags] ( >= 0.1.0 )
48
+ # * sinatra-outputbuffer[http://github.com/kematzy/sinatra-outputbuffer] ( >= 0.1.0 )
49
+ # * sinatra-basics[http://github.com/kematzy/sinatra-basics] ( >= 0.5.0 )
50
+ #
51
+ # Optionals:
52
+ #
53
+ # * sinatra-settings[http://github.com/kematzy/sinatra-settings] (>= 0.1.1) # to view default settings in a browser display.
54
+ # * sinatra-logger[http://github.com/kematzy/sinatra-logger] (>= 0.1.0) # to capture error messages in the log file.
55
+ #
56
+ #
57
+ # === Development & Tests:
58
+ #
59
+ # * sinatra-tests (>= 0.1.6)
60
+ # * rspec (>= 1.3.0 )
61
+ # * rack-test (>= 0.5.3)
62
+ # * rspec_hpricot_matchers (>= 0.1.0)
63
+ #
64
+ #
65
+ # == Getting Started
66
+ #
67
+ # To start using Sinatra::JS, just require and register the extension in your App...
68
+ #
69
+ # require 'sinatra/js'
70
+ #
71
+ # class YourApp < Sinatra::Base
72
+ # register(Sinatra::JS)
73
+ #
74
+ # <snip...>
75
+ #
76
+ # end
77
+ #
78
+ #
79
+ # You then get access to 6 useful helper methods:
80
+ #
81
+ #
82
+ # === <tt>js() / javascript()</tt>
83
+ #
84
+ # This method serves two purposes:
85
+ #
86
+ # a) Return a stylesheet <tt><script src=""></script></tt> tag with the <tt>path</tt> given.
87
+ #
88
+ # js('jquery') # =>
89
+ #
90
+ # <script src="/jquery.js" type="text/javascript" charset="utf-8"></script>
91
+ #
92
+ # js('/js/jquery-tools.js') # =>
93
+ #
94
+ # <script src="/js/jquery-tools.js" type="text/javascript" charset="utf-8"></script>
95
+ #
96
+ #
97
+ # You can even pass an array of files to the method, which then outputs the <tt><script></tt>
98
+ # tags for each file.
99
+ #
100
+ # js( ['/js/jquery.js', '/js/jquery.ui'] ) # =>
101
+ #
102
+ # <script src="/js/jquery.js" type="text/javascript" charset="utf-8"></script>
103
+ # <script src="/js/jquery.ui.js" type="text/javascript" charset="utf-8"></script>
104
+ #
105
+ #
106
+ #
107
+ # b) When passed a *block*, a <tt><script></tt> tag will be created with the yielded block
108
+ # as its contents.
109
+ #
110
+ # js do
111
+ # "document.write('hi');"
112
+ # end
113
+ # # =>
114
+ #
115
+ # <script type="text/javascript" charset="utf-8">
116
+ # document.write('hi');
117
+ # </script>
118
+ #
119
+ #
120
+ # === <tt>js_custom() & js_custom_add()</tt>
121
+ #
122
+ # These two methods works together, like this:
123
+ #
124
+ # First you add the <tt>js_custom()</tt> method to your layout(s) (../views/layout.erb):
125
+ #
126
+ # <html>
127
+ # <head>
128
+ # <snip...>
129
+ #
130
+ # <%= js_custom %>
131
+ #
132
+ # </head>
133
+ #
134
+ #
135
+ #
136
+ # Then in your views, you can use the <tt>js_custom_add()</tt> method to add custom JS
137
+ # to the page, like this:
138
+ #
139
+ # # in ../views/template.erb
140
+ # <%= js_custom_add( "window.alert('this works');" )
141
+ #
142
+ # # in ../views/shared/sidebar.erb
143
+ # <%= js_custom_add( "document.write('this also works');" )
144
+ #
145
+ #
146
+ # Which outputs the following in the <tt><head></tt> element of your page.
147
+ #
148
+ # <html>
149
+ # <head>
150
+ # <snip...>
151
+ #
152
+ # <script type="text/javascript" charset="utf-8">
153
+ # window.alert('this works');
154
+ # document.write('this also works');
155
+ # </script>
156
+ #
157
+ #
158
+ # This functionality makes it very easy to add special JS functionality to any page,
159
+ # even from within multiple views.
160
+ #
161
+ #
162
+ # === <tt>js_custom_files() & js_custom_add_file()</tt>
163
+ #
164
+ # These two methods also works together in a similar fashion, like this:
165
+ #
166
+ # First of, add the <tt>js_custom_files()</tt> method to your layout(s) (../views/layout.erb):
167
+ #
168
+ # <html>
169
+ # <head>
170
+ # <snip...>
171
+ #
172
+ # <%= js_custom_files %>
173
+ #
174
+ # </head>
175
+ #
176
+ #
177
+ # Then in your views, you can use the <tt>js_custom_add_file()</tt> method to add a custom JS
178
+ # file to the page, like this:
179
+ #
180
+ # <%= js_custom_add_file('home') #=>
181
+ #
182
+ # <script src="/home.js" type="text/javascript" charset="utf-8"></script>
183
+ #
184
+ #
185
+ # You can also use the method to embed the content of a .js file into the <tt><head></tt>
186
+ # part of any page, like this:
187
+ #
188
+ # # NB! path is starting from APP_ROOT/public/
189
+ #
190
+ # js_custom_add_file('home.js',:insert_into_html) #=>
191
+ #
192
+ # <html>
193
+ # <head>
194
+ # <snip...>
195
+ #
196
+ # <script type="text/javascript" charset="utf-8">
197
+ # // the contents of ../public/home.js
198
+ # </script>
199
+ #
200
+ #
201
+ # You can even give a file system path to embed the content of a globaly shared .js file
202
+ # outside of your applications path. Providing an easy way to resuse common snippets of code.
203
+ #
204
+ #
205
+ # # NB! make sure the path and .js file works together as a real path.
206
+ #
207
+ # # the :path value should always be a directory without the trailing slash.
208
+ #
209
+ # js_custom_add_file('win.open.js',:insert_into_html, '/path/2/some/directory')
210
+ #
211
+ #
212
+ # <html>
213
+ # <head>
214
+ # <snip...>
215
+ #
216
+ # <script type="text/javascript" charset="utf-8">
217
+ # // the contents of /path/2/some/directory/win.open.js
218
+ # </script>
219
+ #
220
+ #
221
+ #
222
+ # === <tt>js_insert_file()</tt>
223
+ #
224
+ # This is a simple convenicence method that takes a path to a JS file
225
+ # and inserts its content straight into the current view, without any enclosing HTML tags.
226
+ #
227
+ # The method depends upon the settings of the <tt>:js_shared_source_files_dir</tt>
228
+ # configuration variable defined inside your application.
229
+ # By default this is set to <tt>'ENV['HOME']/.alt/js'</tt>.
230
+ #
231
+ # An example of how to use this functionality:
232
+ #
233
+ # # in your app's routes configurations
234
+ #
235
+ # get('/js/app.js') do
236
+ # content_type 'text/javascript'
237
+ # erb('js/app'.to_sym, :layout => false)
238
+ # end
239
+ #
240
+ #
241
+ # # in views/js/app.erb
242
+ #
243
+ # <%= js_insert_file('jquery') %>
244
+ #
245
+ # # => insert the contents of ENV['HOME']/.alt/js/jquery.js
246
+ #
247
+ #
248
+ # You can also load and insert local files, ie files in your app's <tt>public/js/</tt> directory
249
+ # by adding the <tt>:local</tt> flag to the call.
250
+ #
251
+ # <%= js_insert_file('tweets', :local) %>
252
+ #
253
+ # # => insert the contents of /path/2/your/app/public/js/tweets.js
254
+ #
255
+ #
256
+ # == TODOs
257
+ #
258
+ # * Keep it up to date with any changes in Sinatra.
259
+ #
260
+ # * Add bundle functionality from Sinatra::Bundles gem.
261
+ #
262
+ # * Improve the specs a bit and add missing tests.
263
+ #
264
+ # * Any other improvements I or You can think of.
265
+ #
266
+ # == Copyright
267
+ #
268
+ # Copyright (c) 2010 kematzy. See LICENSE for details.
269
+ #
270
+ module JS
271
+
272
+ VERSION = '0.1.5' unless const_defined?(:VERSION)
273
+ def self.version; "Sinatra::JS v#{VERSION}"; end
274
+
275
+
276
+ module Helpers
277
+
278
+
279
+ attr_accessor :sinatra_js_custom_code, :sinatra_js_custom_files
280
+
281
+ ##
282
+ # Return script tag to _path_. When a _block_ is passed,
283
+ # a script tag will be created with the yielded value as
284
+ # its contents.
285
+ #
286
+ # ==== Examples
287
+ #
288
+ # js do
289
+ # "document.write('hi');"
290
+ # end
291
+ # # =>
292
+ #
293
+ # js('jquery') # =>
294
+ #
295
+ # <script src="/jquery.js" type="text/javascript" charset="utf-8"></script>
296
+ #
297
+ # js('/js/jquery-tools.js') # =>
298
+ #
299
+ # <script src="/js/jquery-tools.js" type="text/javascript" charset="utf-8"></script>
300
+ #
301
+ #
302
+ # You can even pass an array of files to the method, which then outputs the <tt><script></tt>
303
+ # tags for each file.
304
+ #
305
+ # js( ['/js/jquery.js', '/js/jquery.ui'] ) # =>
306
+ #
307
+ # <script src="/js/jquery.js" type="text/javascript" charset="utf-8"></script>
308
+ # <script src="/js/jquery.ui.js" type="text/javascript" charset="utf-8"></script>
309
+ #
310
+ # @api public
311
+ def js(path = nil, attrs = {}, &block)
312
+ attrs = { :type => 'text/javascript', :charset => "utf-8" }.merge(attrs)
313
+ return tag(:script, yield, attrs) if block_given?
314
+ unless path.nil?
315
+ if path.is_a?(Array)
316
+ out = ''
317
+ path.each do |f|
318
+ fpath = url_for("#{f.sub(/\.js$/,'')}.js") unless remote_asset?(f)
319
+ attrs[:src] = fpath
320
+ out << tag(:script, { :newline => false }.merge(attrs) )
321
+ end
322
+ out
323
+ else
324
+ path = url_for("#{path.sub(/\.js$/,'')}.js") unless remote_asset?(path)
325
+ attrs[:src] = path
326
+ tag(:script, { :newline => false }.merge(attrs) )
327
+ end
328
+ end
329
+ end
330
+ alias_method :javascript, :js
331
+
332
+ ##
333
+ # Adds custom JS to the page load from within a view, helper method and so on
334
+ #
335
+ # ==== Examples
336
+ #
337
+ # js_custom_add("window.alert('this works');") => void (output is handled through the :js_custom method)
338
+ #
339
+ # @api public
340
+ def js_custom_add(js)
341
+ @sinatra_js_custom_code ||= []
342
+ @sinatra_js_custom_code << js
343
+ end
344
+
345
+ ##
346
+ # Add a custom JS file to the page load from within a view, helper method and so on
347
+ #
348
+ # ==== Examples
349
+ #
350
+ # js_custom_add_file(:filename || path to remote file) => void (output handled through the :js_custom_files method)
351
+ #
352
+ # # You can also embed the code from a .js file into the head element of a page.
353
+ # NB! path is starting from APP_ROOT/public/
354
+ #
355
+ # js_custom_add_file('home.js',:insert_into_html)
356
+ # => <script type="text/javascript"..> JS content </script>
357
+ #
358
+ # You can even give a file system path to embed the styles of a .js file.
359
+ #
360
+ # js_custom_add_file('home.js',:insert_into_html, '/path/2/some/directory')
361
+ # => <script type="text/javascript"..> Some JS content </script>
362
+ #
363
+ # @api public
364
+ def js_custom_add_file(file, insert_into_html = nil, path = nil)
365
+ if insert_into_html.nil?
366
+ @sinatra_js_custom_files ||= []
367
+ if file.is_a?(Array)
368
+ file.each {|f| @sinatra_js_custom_files << f }
369
+ else
370
+ @sinatra_js_custom_files << file
371
+ end
372
+ else
373
+ # read the file into js_custom_add
374
+ path_js = path.nil? ? self.class.public : path
375
+ file_js = "#{path_js}/#{file.sub('.js','')}.js"
376
+ if test(?f, file_js)
377
+ js_custom_add(IO.read(file_js))
378
+ else
379
+ err_msg = "ERROR: js_custom_add_file(:insert_into_html) method could NOT find and embed this JS file=[ #{file_js} ]"
380
+ if self.respond_to?(:logger)
381
+ logger.warn(err_msg)
382
+ else
383
+ warn(err_msg)
384
+ end
385
+ end
386
+ end
387
+ end
388
+
389
+ ##
390
+ # Simple convenicence method that takes a path to a JS file
391
+ # and inserts its content into the current <tt>.js.erb</tt> file
392
+ #
393
+ # Depends upon the settings of the <tt>:js_source_files_dir</tt> configuration variable
394
+ # defined inside your application. By default it is set to <tt>'/$HOME/.alt/css'</tt>
395
+ #
396
+ # ==== Examples
397
+ #
398
+ # # in your app's routes configurations
399
+ # get('/js/app.js') do
400
+ # content_type 'application/javascript'
401
+ # erb('js/app.js'.to_sym, :layout => false)
402
+ # end
403
+ #
404
+ #
405
+ #
406
+ # # in views/js/app.js.erb
407
+ # js_insert_file('min/jquery') => path/2/js/files/min/jquery.js
408
+ #
409
+ # which inserts the JS code from that file into the output.
410
+ #
411
+ #
412
+ #
413
+ #
414
+ # @api public
415
+ def js_insert_file(path = '', local = nil )
416
+ file_path = local.nil? ? "#{self.class.js_shared_source_files_dir}/#{path}" : path
417
+ file_path = file_path.sub(/\.js$/,'') << ".js"
418
+ if test(?f, file_path)
419
+ content = IO.read(file_path)
420
+ else
421
+ content = "// ERROR: the JS file [#{file_path}] could NOT be found"
422
+ end
423
+ content
424
+ end
425
+
426
+ ##
427
+ # Outputs given custom JS if provided from within a view, helper method and so on
428
+ #
429
+ # ==== Examples
430
+ #
431
+ # js_custom => <script...> var custom = 'it works'; </script>
432
+ #
433
+ #
434
+ # You can also add the JQuery document.ready code to the output, by simply
435
+ # adding <tt>:jquery_block</tt> to the method.
436
+ #
437
+ # <%= js_custom(:jquery_block) %>
438
+ #
439
+ # <script type="text/javascript" charset="utf-8">
440
+ # $(document).ready( function () {
441
+ # // some custom JS code here
442
+ # });
443
+ # </script>
444
+ #
445
+ #
446
+ # @api public
447
+ def js_custom(js=nil, add_jquery_block = nil)
448
+ if js.is_a?(Symbol)
449
+ js = nil
450
+ add_jquery_block = :jquery
451
+ end
452
+ out = ''
453
+ out << js unless js.nil?
454
+ unless @sinatra_js_custom_code.nil?
455
+ @sinatra_js_custom_code.each { |i| out << " #{i}\n" }
456
+ end
457
+ if add_jquery_block.nil?
458
+ code_js = out.strip
459
+ else
460
+ code_js = "$(document).ready( function () {\n #{out.strip}\n } );"
461
+ end
462
+ out = out.empty? ?
463
+ '' : %Q[<script type="text/javascript" charset="utf-8">\n#{code_js}\n</script>\n]
464
+ end
465
+
466
+ ##
467
+ # Outputs given custom JS files that have been included
468
+ #
469
+ # ==== Examples
470
+ #
471
+ # <%= js_custom_files %> =>
472
+ # <script src="/js/custom1.js" ...>
473
+ # <script src="/js/custom2.js" ...>
474
+ #
475
+ # @api public
476
+ def js_custom_files
477
+ unless @sinatra_js_custom_files.nil?
478
+ out = "<!-- custom js files -->\n"
479
+ @sinatra_js_custom_files.each do |file|
480
+ # file = url_for("#{file.to_s.sub(/\.js$/,'')}.js") unless remote_asset?(file)
481
+ file = "#{file.to_s.sub(/\.js$/,'')}.js" unless remote_asset?(file)
482
+ out << js(file)
483
+ # out << %Q[ <script src="#{file}" type="text/javascript" charset="utf-8"></script>\n]
484
+ end
485
+ out << " <!-- /custom js files -->\n"
486
+ else
487
+ '' # return empty string, it's better than nil in this case
488
+ end
489
+ end
490
+
491
+ end #/ Helpers
492
+
493
+
494
+ ##
495
+ # Handles all JS requests, and returns the RJS (RubyJS) file version of it,
496
+ # or else passes the request on to the file system.
497
+ #
498
+ # NB! the path value given is NOT used as the name of the source directory in app/views,
499
+ # so ensure that there is always an app/views/js directory in place.
500
+ #
501
+ # ie:
502
+ # get_all_js_requests() => expects a app/views/js dir with the .rjs files
503
+
504
+ # get_all_js_requests('/javascripts') => expects a app/views/js dir with the .rjs files
505
+ #
506
+ # ==== Examples
507
+ #
508
+ # get_all_js_requests() => catches 'site.com/js/app.js
509
+ # get_all_js_requests('/javascripts') => catches 'site.com/javascripts/app.js
510
+ #
511
+ # @api public
512
+ def get_all_js_requests(path='/js', options = {})
513
+ path, options = '/js', path if path.is_a?(Hash)
514
+
515
+ get("#{path}/*.js", {} ) do
516
+ begin
517
+ options = { :cache => false, :layout => false }.merge(options)
518
+ content_type 'text/javascript', :charset => 'utf-8'
519
+ rjs("js/#{params[:splat].first}".to_sym, options ).gsub(/\n\r?$/,"")
520
+ rescue Errno::ENOENT
521
+ content_type 'text/html' # reset the content_type
522
+ pass
523
+ end
524
+ end
525
+ end
526
+
527
+
528
+ ##
529
+ # Registers these Extensions:
530
+ #
531
+ # * Sinatra::Tags
532
+ # * Sinatra::Basics::Assets
533
+ #
534
+ # Default Settings:
535
+ #
536
+ # * +:js_shared_source_files_dir+ => set the path to the Shared directory with compliled JS templates.
537
+ # Default is: <tt>'ENV['HOME']/.alt/js'</tt>
538
+ #
539
+ # @api public
540
+ def self.registered(app)
541
+ app.register(Sinatra::Tags)
542
+ app.register(Sinatra::Assets)
543
+
544
+ app.helpers Sinatra::JS::Helpers
545
+
546
+ # set the path to the Shared directory with compliled JS templates
547
+ app.set :js_shared_source_files_dir, File.join(File.expand_path(ENV['HOME']) ,'.alt', 'js')
548
+
549
+
550
+ ## add the extension specific options to those inspectable by :settings_inspect method
551
+ # provided by the Sinatra::Settings extension
552
+ if app.respond_to?(:sinatra_settings_for_inspection)
553
+ %w( js_shared_source_files_dir ).each do |m|
554
+ app.sinatra_settings_for_inspection << m
555
+ end
556
+ end
557
+
558
+ end #/ self.registered
559
+
560
+ end #/ JS
561
+
562
+ register(Sinatra::JS)
563
+
564
+ end #/ Sinatra