thorero-assets 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README +250 -0
- data/Rakefile +63 -0
- data/TODO +5 -0
- data/lib/merb-assets.rb +14 -0
- data/lib/merb-assets/assets.rb +242 -0
- data/lib/merb-assets/assets_mixin.rb +635 -0
- data/spec/merb-assets_spec.rb +257 -0
- data/spec/spec_helper.rb +18 -0
- metadata +73 -0
@@ -0,0 +1,635 @@
|
|
1
|
+
module Merb
|
2
|
+
# The AssetsMixin module provides a number of helper methods to views for
|
3
|
+
# linking to assets and other pages, dealing with JavaScript and CSS.
|
4
|
+
module AssetsMixin
|
5
|
+
include Merb::Assets::AssetHelpers
|
6
|
+
# :section: Accessing Assets
|
7
|
+
# Merb provides views with convenience methods for links images and other
|
8
|
+
# assets.
|
9
|
+
|
10
|
+
|
11
|
+
# ==== Parameters
|
12
|
+
# none
|
13
|
+
#
|
14
|
+
# ==== Returns
|
15
|
+
# html<String>
|
16
|
+
#
|
17
|
+
# ==== Examples
|
18
|
+
# We want all possible matches in the FileSys up to the action name
|
19
|
+
# Given: controller_name = "namespace/controller"
|
20
|
+
# action_name = "action"
|
21
|
+
# If all files are present should generate link/script tags for:
|
22
|
+
# namespace.(css|js)
|
23
|
+
# namespace/controller.(css|js)
|
24
|
+
# namespace/controller/action.(css|js)
|
25
|
+
#
|
26
|
+
def auto_link
|
27
|
+
html = ""
|
28
|
+
prefix = ""
|
29
|
+
(controller_name / action_name).split("/").each do |path|
|
30
|
+
path = prefix + path
|
31
|
+
|
32
|
+
css_path = path + ".css"
|
33
|
+
if File.exists? Merb.root / "public" / "stylesheets" / css_path
|
34
|
+
html << %{<link rel="stylesheet" type="text/css" href="/stylesheets/#{css_path}" /> }
|
35
|
+
end
|
36
|
+
|
37
|
+
js_path = path + ".js"
|
38
|
+
if File.exists? Merb.root / "public" / "javascripts" / js_path
|
39
|
+
html << %{<script type="text/javascript" language="javascript" src="/javascripts/#{js_path}"></script>}
|
40
|
+
end
|
41
|
+
|
42
|
+
#Update the prefix for the next iteration
|
43
|
+
prefix += path / ""
|
44
|
+
end
|
45
|
+
|
46
|
+
#Return the generated HTML
|
47
|
+
html
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
# ==== Parameters
|
52
|
+
# name<~to_s>:: The text of the link.
|
53
|
+
# url<~to_s>:: The URL to link to. Defaults to an empty string.
|
54
|
+
# opts<Hash>:: Additional HTML options for the link.
|
55
|
+
#
|
56
|
+
# ==== Examples
|
57
|
+
# link_to("The Merb home page", "http://www.merbivore.com/")
|
58
|
+
# # => <a href="http://www.merbivore.com/">The Merb home page</a>
|
59
|
+
#
|
60
|
+
# link_to("The Ruby home page", "http://www.ruby-lang.org", {'class' => 'special', 'target' => 'blank'})
|
61
|
+
# # => <a href="http://www.ruby-lang.org" class="special" target="blank">The Ruby home page</a>
|
62
|
+
#
|
63
|
+
# link_to p.title, "/blog/show/#{p.id}"
|
64
|
+
# # => <a href="/blog/show/13">The Entry Title</a>
|
65
|
+
#
|
66
|
+
def link_to(name, url='', opts={})
|
67
|
+
opts[:href] ||= url
|
68
|
+
%{<a #{ opts.to_xml_attributes }>#{name}</a>}
|
69
|
+
end
|
70
|
+
|
71
|
+
# ==== Parameters
|
72
|
+
# img<~to_s>:: The image path.
|
73
|
+
# opts<Hash>:: Additional options for the image tag (see below).
|
74
|
+
#
|
75
|
+
# ==== Options (opts)
|
76
|
+
# :path<String>::
|
77
|
+
# Sets the path prefix for the image. Defaults to "/images/" or whatever
|
78
|
+
# is specified in Merb::Config. This is ignored if img is an absolute
|
79
|
+
# path or full URL.
|
80
|
+
#
|
81
|
+
# All other options set HTML attributes on the tag.
|
82
|
+
#
|
83
|
+
# ==== Examples
|
84
|
+
# image_tag('foo.gif')
|
85
|
+
# # => <img src='/images/foo.gif' />
|
86
|
+
#
|
87
|
+
# image_tag('foo.gif', :class => 'bar')
|
88
|
+
# # => <img src='/images/foo.gif' class='bar' />
|
89
|
+
#
|
90
|
+
# image_tag('foo.gif', :path => '/files/')
|
91
|
+
# # => <img src='/files/foo.gif' />
|
92
|
+
#
|
93
|
+
# image_tag('http://test.com/foo.gif')
|
94
|
+
# # => <img src="http://test.com/foo.gif">
|
95
|
+
#
|
96
|
+
# image_tag('charts', :path => '/dynamic/')
|
97
|
+
# or
|
98
|
+
# image_tag('/dynamic/charts')
|
99
|
+
# # => <img src="/dynamic/charts">
|
100
|
+
def image_tag(img, opts={})
|
101
|
+
if img[0].chr == '/'
|
102
|
+
opts[:src] = img
|
103
|
+
else
|
104
|
+
opts[:path] ||=
|
105
|
+
if img =~ %r{^https?://}
|
106
|
+
''
|
107
|
+
else
|
108
|
+
if Merb::Config[:path_prefix]
|
109
|
+
Merb::Config[:path_prefix] + '/images/'
|
110
|
+
else
|
111
|
+
'/images/'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
opts[:src] ||= opts.delete(:path) + img
|
115
|
+
end
|
116
|
+
%{<img #{ opts.to_xml_attributes } />}
|
117
|
+
end
|
118
|
+
|
119
|
+
# :section: JavaScript related functions
|
120
|
+
#
|
121
|
+
|
122
|
+
# ==== Parameters
|
123
|
+
# javascript<String>:: Text to escape for use in JavaScript.
|
124
|
+
#
|
125
|
+
# ==== Examples
|
126
|
+
# escape_js("'Lorem ipsum!' -- Some guy")
|
127
|
+
# # => "\\'Lorem ipsum!\\' -- Some guy"
|
128
|
+
#
|
129
|
+
# escape_js("Please keep text\nlines as skinny\nas possible.")
|
130
|
+
# # => "Please keep text\\nlines as skinny\\nas possible."
|
131
|
+
def escape_js(javascript)
|
132
|
+
(javascript || '').gsub('\\','\0\0').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }
|
133
|
+
end
|
134
|
+
|
135
|
+
# ==== Parameters
|
136
|
+
# data<Object>::
|
137
|
+
# Object to translate into JSON. If the object does not respond to
|
138
|
+
# :to_json, then data.inspect.to_json is returned instead.
|
139
|
+
#
|
140
|
+
# ==== Examples
|
141
|
+
# js({'user' => 'Lewis', 'page' => 'home'})
|
142
|
+
# # => "{\"user\":\"Lewis\",\"page\":\"home\"}"
|
143
|
+
#
|
144
|
+
# js([ 1, 2, {"a"=>3.141}, false, true, nil, 4..10 ])
|
145
|
+
# # => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
|
146
|
+
def js(data)
|
147
|
+
if data.respond_to? :to_json
|
148
|
+
data.to_json
|
149
|
+
else
|
150
|
+
data.inspect.to_json
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# :section: External JavaScript and Stylesheets
|
155
|
+
#
|
156
|
+
# You can use require_js(:prototype) or require_css(:shinystyles)
|
157
|
+
# from any view or layout, and the scripts will only be included once
|
158
|
+
# in the head of the final page. To get this effect, the head of your
|
159
|
+
# layout you will need to include a call to include_required_js and
|
160
|
+
# include_required_css.
|
161
|
+
#
|
162
|
+
# ==== Examples
|
163
|
+
# # File: app/views/layouts/application.html.erb
|
164
|
+
#
|
165
|
+
# <html>
|
166
|
+
# <head>
|
167
|
+
# <%= include_required_js %>
|
168
|
+
# <%= include_required_css %>
|
169
|
+
# </head>
|
170
|
+
# <body>
|
171
|
+
# <%= catch_content :layout %>
|
172
|
+
# </body>
|
173
|
+
# </html>
|
174
|
+
#
|
175
|
+
# # File: app/views/whatever/_part1.herb
|
176
|
+
#
|
177
|
+
# <% require_js 'this' -%>
|
178
|
+
# <% require_css 'that', 'another_one' -%>
|
179
|
+
#
|
180
|
+
# # File: app/views/whatever/_part2.herb
|
181
|
+
#
|
182
|
+
# <% require_js 'this', 'something_else' -%>
|
183
|
+
# <% require_css 'that' -%>
|
184
|
+
#
|
185
|
+
# # File: app/views/whatever/index.herb
|
186
|
+
#
|
187
|
+
# <%= partial(:part1) %>
|
188
|
+
# <%= partial(:part2) %>
|
189
|
+
#
|
190
|
+
# # Will generate the following in the final page...
|
191
|
+
# <html>
|
192
|
+
# <head>
|
193
|
+
# <script src="/javascripts/this.js" type="text/javascript"></script>
|
194
|
+
# <script src="/javascripts/something_else.js" type="text/javascript"></script>
|
195
|
+
# <link href="/stylesheets/that.css" media="all" rel="Stylesheet" type="text/css"/>
|
196
|
+
# <link href="/stylesheets/another_one.css" media="all" rel="Stylesheet" type="text/css"/>
|
197
|
+
# </head>
|
198
|
+
# .
|
199
|
+
# .
|
200
|
+
# .
|
201
|
+
# </html>
|
202
|
+
#
|
203
|
+
# See each method's documentation for more information.
|
204
|
+
|
205
|
+
# :section: Bundling Asset Files
|
206
|
+
#
|
207
|
+
# The key to making a fast web application is to reduce both the amount of
|
208
|
+
# data transfered and the number of client-server interactions. While having
|
209
|
+
# many small, module Javascript or stylesheet files aids in the development
|
210
|
+
# process, your web application will benefit from bundling those assets in
|
211
|
+
# the production environment.
|
212
|
+
#
|
213
|
+
# An asset bundle is a set of asset files which are combined into a single
|
214
|
+
# file. This reduces the number of requests required to render a page, and
|
215
|
+
# can reduce the amount of data transfer required if you're using gzip
|
216
|
+
# encoding.
|
217
|
+
#
|
218
|
+
# Asset bundling is always enabled in production mode, and can be optionally
|
219
|
+
# enabled in all environments by setting the <tt>:bundle_assets</tt> value
|
220
|
+
# in <tt>config/merb.yml</tt> to +true+.
|
221
|
+
#
|
222
|
+
# ==== Examples
|
223
|
+
#
|
224
|
+
# In the development environment, this:
|
225
|
+
#
|
226
|
+
# js_include_tag :prototype, :lowpro, :bundle => true
|
227
|
+
#
|
228
|
+
# will produce two <script> elements. In the production mode, however, the
|
229
|
+
# two files will be concatenated in the order given into a single file,
|
230
|
+
# <tt>all.js</tt>, in the <tt>public/javascripts</tt> directory.
|
231
|
+
#
|
232
|
+
# To specify a different bundle name:
|
233
|
+
#
|
234
|
+
# css_include_tag :typography, :whitespace, :bundle => :base
|
235
|
+
# css_include_tag :header, :footer, :bundle => "content"
|
236
|
+
# css_include_tag :lightbox, :images, :bundle => "lb.css"
|
237
|
+
#
|
238
|
+
# (<tt>base.css</tt>, <tt>content.css</tt>, and <tt>lb.css</tt> will all be
|
239
|
+
# created in the <tt>public/stylesheets</tt> directory.)
|
240
|
+
#
|
241
|
+
# == Callbacks
|
242
|
+
#
|
243
|
+
# To use a Javascript or CSS compressor, like JSMin or YUI Compressor:
|
244
|
+
#
|
245
|
+
# Merb::Assets::JavascriptAssetBundler.add_callback do |filename|
|
246
|
+
# system("/usr/local/bin/yui-compress #{filename}")
|
247
|
+
# end
|
248
|
+
#
|
249
|
+
# Merb::Assets::StylesheetAssetBundler.add_callback do |filename|
|
250
|
+
# system("/usr/local/bin/css-min #{filename}")
|
251
|
+
# end
|
252
|
+
#
|
253
|
+
# These blocks will be run after a bundle is created.
|
254
|
+
#
|
255
|
+
# == Bundling Required Assets
|
256
|
+
#
|
257
|
+
# Combining the +require_css+ and +require_js+ helpers with bundling can be
|
258
|
+
# problematic. You may want to separate out the common assets for your
|
259
|
+
# application -- Javascript frameworks, common CSS, etc. -- and bundle those
|
260
|
+
# in a "base" bundle. Then, for each section of your site, bundle the
|
261
|
+
# required assets into a section-specific bundle.
|
262
|
+
#
|
263
|
+
# <b>N.B.: If you bundle an inconsistent set of assets with the same name,
|
264
|
+
# you will have inconsistent results. Be thorough and test often.</b>
|
265
|
+
#
|
266
|
+
# ==== Example
|
267
|
+
#
|
268
|
+
# In your application layout:
|
269
|
+
#
|
270
|
+
# js_include_tag :prototype, :lowpro, :bundle => :base
|
271
|
+
#
|
272
|
+
# In your controller layout:
|
273
|
+
#
|
274
|
+
# require_js :bundle => :posts
|
275
|
+
|
276
|
+
# The require_js method can be used to require any JavaScript file anywhere
|
277
|
+
# in your templates. Regardless of how many times a single script is
|
278
|
+
# included with require_js, Merb will only include it once in the header.
|
279
|
+
#
|
280
|
+
# ==== Parameters
|
281
|
+
# *js<~to_s>:: JavaScript files to include.
|
282
|
+
#
|
283
|
+
# ==== Examples
|
284
|
+
# <% require_js 'jquery' %>
|
285
|
+
# # A subsequent call to include_required_js will render...
|
286
|
+
# # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
|
287
|
+
#
|
288
|
+
# <% require_js 'jquery', 'effects' %>
|
289
|
+
# # A subsequent call to include_required_js will render...
|
290
|
+
# # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
|
291
|
+
# # <script src="/javascripts/effects.js" type="text/javascript"></script>
|
292
|
+
#
|
293
|
+
def require_js(*js)
|
294
|
+
@required_js ||= []
|
295
|
+
@required_js << js
|
296
|
+
end
|
297
|
+
|
298
|
+
# All javascript files to include, without duplicates.
|
299
|
+
#
|
300
|
+
# ==== Parameters
|
301
|
+
# options<Hash>:: Default options to pass to js_include_tag.
|
302
|
+
def required_js(options = {})
|
303
|
+
extract_required_files(@required_js, options)
|
304
|
+
end
|
305
|
+
|
306
|
+
# The require_css method can be used to require any CSS file anywhere in
|
307
|
+
# your templates. Regardless of how many times a single stylesheet is
|
308
|
+
# included with require_css, Merb will only include it once in the header.
|
309
|
+
#
|
310
|
+
# ==== Parameters
|
311
|
+
# *css<~to_s>:: CSS files to include.
|
312
|
+
#
|
313
|
+
# ==== Examples
|
314
|
+
# <% require_css('style') %>
|
315
|
+
# # A subsequent call to include_required_css will render...
|
316
|
+
# # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/>
|
317
|
+
#
|
318
|
+
# <% require_css('style', 'ie-specific') %>
|
319
|
+
# # A subsequent call to include_required_css will render...
|
320
|
+
# # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/>
|
321
|
+
# # <link href="/stylesheets/ie-specific.css" media="all" rel="Stylesheet" type="text/css"/>
|
322
|
+
#
|
323
|
+
def require_css(*css)
|
324
|
+
@required_css ||= []
|
325
|
+
@required_css << css
|
326
|
+
end
|
327
|
+
|
328
|
+
# All css files to include, without duplicates.
|
329
|
+
#
|
330
|
+
# ==== Parameters
|
331
|
+
# options<Hash>:: Default options to pass to css_include_tag.
|
332
|
+
def required_css(options = {})
|
333
|
+
extract_required_files(@required_css, options)
|
334
|
+
end
|
335
|
+
|
336
|
+
# A method used in the layout of an application to create +<script>+ tags
|
337
|
+
# to include JavaScripts required in in templates and subtemplates using
|
338
|
+
# require_js.
|
339
|
+
#
|
340
|
+
# ==== Parameters
|
341
|
+
# options<Hash>:: Options to pass to js_include_tag.
|
342
|
+
#
|
343
|
+
# ==== Options
|
344
|
+
# :bundle<~to_s>::
|
345
|
+
# The name of the bundle the scripts should be combined into.
|
346
|
+
#
|
347
|
+
# ==== Returns
|
348
|
+
# String:: The JavaScript tag.
|
349
|
+
#
|
350
|
+
# ==== Examples
|
351
|
+
# # my_action.herb has a call to require_js 'jquery'
|
352
|
+
# # File: layout/application.html.erb
|
353
|
+
# include_required_js
|
354
|
+
# # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
|
355
|
+
#
|
356
|
+
# # my_action.herb has a call to require_js 'jquery', 'effects', 'validation'
|
357
|
+
# # File: layout/application.html.erb
|
358
|
+
# include_required_js
|
359
|
+
# # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
|
360
|
+
# # <script src="/javascripts/effects.js" type="text/javascript"></script>
|
361
|
+
# # <script src="/javascripts/validation.js" type="text/javascript"></script>
|
362
|
+
#
|
363
|
+
def include_required_js(options = {})
|
364
|
+
required_js(options).map { |req_js| js_include_tag(*req_js) }.join
|
365
|
+
end
|
366
|
+
|
367
|
+
# A method used in the layout of an application to create +<link>+ tags for
|
368
|
+
# CSS stylesheets required in in templates and subtemplates using
|
369
|
+
# require_css.
|
370
|
+
#
|
371
|
+
# ==== Parameters
|
372
|
+
# options<Hash>:: Options to pass to css_include_tag.
|
373
|
+
#
|
374
|
+
# ==== Returns
|
375
|
+
# String:: The CSS tag.
|
376
|
+
#
|
377
|
+
# ==== Options
|
378
|
+
# :bundle<~to_s>::
|
379
|
+
# The name of the bundle the stylesheets should be combined into.
|
380
|
+
# :media<~to_s>::
|
381
|
+
# The media attribute for the generated link element. Defaults to :all.
|
382
|
+
#
|
383
|
+
# ==== Examples
|
384
|
+
# # my_action.herb has a call to require_css 'style'
|
385
|
+
# # File: layout/application.html.erb
|
386
|
+
# include_required_css
|
387
|
+
# # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/>
|
388
|
+
#
|
389
|
+
# # my_action.herb has a call to require_css 'style', 'ie-specific'
|
390
|
+
# # File: layout/application.html.erb
|
391
|
+
# include_required_css
|
392
|
+
# # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css"/>
|
393
|
+
# # <link href="/stylesheets/ie-specific.css" media="all" rel="Stylesheet" type="text/css"/>
|
394
|
+
#
|
395
|
+
def include_required_css(options = {})
|
396
|
+
required_css(options).map { |req_js| css_include_tag(*req_js) }.join
|
397
|
+
end
|
398
|
+
|
399
|
+
# ==== Parameters
|
400
|
+
# *scripts::
|
401
|
+
# The scripts to include. If the last element is a Hash, it will be used
|
402
|
+
# as options (see below). If ".js" is left out from the script names, it
|
403
|
+
# will be added to them.
|
404
|
+
#
|
405
|
+
# ==== Options
|
406
|
+
# :bundle<~to_s>::
|
407
|
+
# The name of the bundle the scripts should be combined into.
|
408
|
+
#
|
409
|
+
# ==== Returns
|
410
|
+
# String:: The JavaScript include tag(s).
|
411
|
+
#
|
412
|
+
# ==== Examples
|
413
|
+
# js_include_tag 'jquery'
|
414
|
+
# # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
|
415
|
+
#
|
416
|
+
# js_include_tag 'moofx.js', 'upload'
|
417
|
+
# # => <script src="/javascripts/moofx.js" type="text/javascript"></script>
|
418
|
+
# # <script src="/javascripts/upload.js" type="text/javascript"></script>
|
419
|
+
#
|
420
|
+
# js_include_tag :effects
|
421
|
+
# # => <script src="/javascripts/effects.js" type="text/javascript"></script>
|
422
|
+
#
|
423
|
+
# js_include_tag :jquery, :validation
|
424
|
+
# # => <script src="/javascripts/jquery.js" type="text/javascript"></script>
|
425
|
+
# # <script src="/javascripts/validation.js" type="text/javascript"></script>
|
426
|
+
#
|
427
|
+
def js_include_tag(*scripts)
|
428
|
+
options = scripts.last.is_a?(Hash) ? scripts.pop : {}
|
429
|
+
return nil if scripts.empty?
|
430
|
+
|
431
|
+
if (bundle_name = options[:bundle]) && Merb::Assets.bundle? && scripts.size > 1
|
432
|
+
bundler = Merb::Assets::JavascriptAssetBundler.new(bundle_name, *scripts)
|
433
|
+
bundled_asset = bundler.bundle!
|
434
|
+
return js_include_tag(bundled_asset)
|
435
|
+
end
|
436
|
+
|
437
|
+
tags = ""
|
438
|
+
|
439
|
+
for script in scripts
|
440
|
+
attrs = {
|
441
|
+
:src => asset_path(:javascript, script),
|
442
|
+
:type => "text/javascript"
|
443
|
+
}
|
444
|
+
tags << %Q{<script #{attrs.to_xml_attributes}></script>}
|
445
|
+
end
|
446
|
+
|
447
|
+
return tags
|
448
|
+
end
|
449
|
+
|
450
|
+
# ==== Parameters
|
451
|
+
# *stylesheets::
|
452
|
+
# The stylesheets to include. If the last element is a Hash, it will be
|
453
|
+
# used as options (see below). If ".css" is left out from the stylesheet
|
454
|
+
# names, it will be added to them.
|
455
|
+
#
|
456
|
+
# ==== Options
|
457
|
+
# :bundle<~to_s>::
|
458
|
+
# The name of the bundle the stylesheets should be combined into.
|
459
|
+
# :media<~to_s>::
|
460
|
+
# The media attribute for the generated link element. Defaults to :all.
|
461
|
+
#
|
462
|
+
# ==== Returns
|
463
|
+
# String:: The CSS include tag(s).
|
464
|
+
#
|
465
|
+
# ==== Examples
|
466
|
+
# css_include_tag 'style'
|
467
|
+
# # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" />
|
468
|
+
#
|
469
|
+
# css_include_tag 'style.css', 'layout'
|
470
|
+
# # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" />
|
471
|
+
# # <link href="/stylesheets/layout.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" />
|
472
|
+
#
|
473
|
+
# css_include_tag :menu
|
474
|
+
# # => <link href="/stylesheets/menu.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" />
|
475
|
+
#
|
476
|
+
# css_include_tag :style, :screen
|
477
|
+
# # => <link href="/stylesheets/style.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" />
|
478
|
+
# # <link href="/stylesheets/screen.css" media="all" rel="Stylesheet" type="text/css" charset="utf-8" />
|
479
|
+
#
|
480
|
+
# css_include_tag :style, :media => :print
|
481
|
+
# # => <link href="/stylesheets/style.css" media="print" rel="Stylesheet" type="text/css" charset="utf-8" />
|
482
|
+
#
|
483
|
+
# css_include_tag :style, :charset => 'iso-8859-1'
|
484
|
+
# # => <link href="/stylesheets/style.css" media="print" rel="Stylesheet" type="text/css" charset="iso-8859-1" />
|
485
|
+
def css_include_tag(*stylesheets)
|
486
|
+
options = stylesheets.last.is_a?(Hash) ? stylesheets.pop : {}
|
487
|
+
return nil if stylesheets.empty?
|
488
|
+
|
489
|
+
if (bundle_name = options[:bundle]) && Merb::Assets.bundle? && stylesheets.size > 1
|
490
|
+
bundler = Merb::Assets::StylesheetAssetBundler.new(bundle_name, *stylesheets)
|
491
|
+
bundled_asset = bundler.bundle!
|
492
|
+
return css_include_tag(bundled_asset)
|
493
|
+
end
|
494
|
+
|
495
|
+
tags = ""
|
496
|
+
|
497
|
+
for stylesheet in stylesheets
|
498
|
+
attrs = {
|
499
|
+
:href => asset_path(:stylesheet, stylesheet),
|
500
|
+
:type => "text/css",
|
501
|
+
:rel => "Stylesheet",
|
502
|
+
:charset => options[:charset] || 'utf-8',
|
503
|
+
:media => options[:media] || :all
|
504
|
+
}
|
505
|
+
tags << %Q{<link #{attrs.to_xml_attributes} />}
|
506
|
+
end
|
507
|
+
|
508
|
+
return tags
|
509
|
+
end
|
510
|
+
|
511
|
+
# ==== Parameters
|
512
|
+
# *assets::
|
513
|
+
# The assets to include. These should be the full paths to any static served file
|
514
|
+
#
|
515
|
+
# ==== Returns
|
516
|
+
# Array:: Full unique paths to assets OR
|
517
|
+
# String:: if only a single path is requested
|
518
|
+
# ==== Examples
|
519
|
+
# uniq_path("/javascripts/my.js","/javascripts/my.css")
|
520
|
+
# #=> ["http://assets2.my-awesome-domain.com/javascripts/my.js", "http://assets1.my-awesome-domain.com/javascripts/my.css"]
|
521
|
+
#
|
522
|
+
# uniq_path(["/javascripts/my.js","/stylesheets/my.css"])
|
523
|
+
# #=> ["http://assets2.my-awesome-domain.com/javascripts/my.js", "http://assets1.my-awesome-domain.com/stylesheets/my.css"]
|
524
|
+
#
|
525
|
+
# uniq_path(%w(/javascripts/my.js /stylesheets/my.css))
|
526
|
+
# #=> ["http://assets2.my-awesome-domain.com/javascripts/my.js", "http://assets1.my-awesome-domain.com/stylesheets/my.css"]
|
527
|
+
#
|
528
|
+
# uniq_path('/stylesheets/somearbitrary.css')
|
529
|
+
# #=> "http://assets3.my-awesome-domain.com/stylesheets/somearbitrary.css"
|
530
|
+
#
|
531
|
+
# uniq_path('/images/hostsexypicture.jpg')
|
532
|
+
# #=>"http://assets1.my-awesome-domain.com/images/hostsexypicture.jpg"
|
533
|
+
def uniq_path(*assets)
|
534
|
+
paths = []
|
535
|
+
assets.collect.flatten.each do |filename|
|
536
|
+
paths.push(Merb::Assets::UniqueAssetPath.build(filename))
|
537
|
+
end
|
538
|
+
paths.length > 1 ? paths : paths.first
|
539
|
+
end
|
540
|
+
|
541
|
+
# ==== Parameters
|
542
|
+
# *assets::
|
543
|
+
# Creates unique paths for javascript files (prepends "/javascripts" and appends ".js")
|
544
|
+
#
|
545
|
+
# ==== Returns
|
546
|
+
# Array:: Full unique paths to assets OR
|
547
|
+
# String:: if only a single path is requested
|
548
|
+
# ==== Examples
|
549
|
+
# uniq_js_path("my")
|
550
|
+
# #=> "http://assets2.my-awesome-domain.com/javascripts/my.js"
|
551
|
+
#
|
552
|
+
# uniq_js_path(["admin/secrets","home/signup"])
|
553
|
+
# #=> ["http://assets2.my-awesome-domain.com/javascripts/admin/secrets.js",
|
554
|
+
# "http://assets1.my-awesome-domain.com/javascripts/home/signup.js"]
|
555
|
+
def uniq_js_path(*assets)
|
556
|
+
paths = []
|
557
|
+
assets.collect.flatten.each do |filename|
|
558
|
+
paths.push(Merb::Assets::UniqueAssetPath.build(asset_path(:javascript,filename)))
|
559
|
+
end
|
560
|
+
paths.length > 1 ? paths : paths.first
|
561
|
+
end
|
562
|
+
|
563
|
+
# ==== Parameters
|
564
|
+
# *assets::
|
565
|
+
# Creates unique paths for stylesheet files (prepends "/stylesheets" and appends ".css")
|
566
|
+
#
|
567
|
+
# ==== Returns
|
568
|
+
# Array:: Full unique paths to assets OR
|
569
|
+
# String:: if only a single path is requested
|
570
|
+
# ==== Examples
|
571
|
+
# uniq_css_path("my")
|
572
|
+
# #=> "http://assets2.my-awesome-domain.com/stylesheets/my.css"
|
573
|
+
#
|
574
|
+
# uniq_css_path(["admin/secrets","home/signup"])
|
575
|
+
# #=> ["http://assets2.my-awesome-domain.com/stylesheets/admin/secrets.css",
|
576
|
+
# "http://assets1.my-awesome-domain.com/stylesheets/home/signup.css"]
|
577
|
+
def uniq_css_path(*assets)
|
578
|
+
paths = []
|
579
|
+
assets.collect.flatten.each do |filename|
|
580
|
+
paths.push(Merb::Assets::UniqueAssetPath.build(asset_path(:stylesheet,filename)))
|
581
|
+
end
|
582
|
+
paths.length > 1 ? paths : paths.first
|
583
|
+
end
|
584
|
+
|
585
|
+
# ==== Parameters
|
586
|
+
# *assets::
|
587
|
+
# As js_include_tag but has unique path
|
588
|
+
#
|
589
|
+
# ==== Returns
|
590
|
+
# Array:: Full unique paths to assets OR
|
591
|
+
# String:: if only a single path is requested
|
592
|
+
# ==== Examples
|
593
|
+
# uniq_js_tag("my")
|
594
|
+
# #=> <script type="text/javascript" src="http://assets2.my-awesome-domain.com/javascripts/my.js"></script>
|
595
|
+
def uniq_js_tag(*assets)
|
596
|
+
js_include_tag(*uniq_js_path(assets))
|
597
|
+
end
|
598
|
+
|
599
|
+
# ==== Parameters
|
600
|
+
# *assets::
|
601
|
+
# As uniq_css_tag but has unique path
|
602
|
+
#
|
603
|
+
# ==== Returns
|
604
|
+
# Array:: Full unique paths to assets OR
|
605
|
+
# String:: if only a single path is requested
|
606
|
+
# ==== Examples
|
607
|
+
# uniq_css_tag("my")
|
608
|
+
# #=> <link href="http://assets2.my-awesome-domain.com/stylesheets/my.css" type="text/css" />
|
609
|
+
def uniq_css_tag(*assets)
|
610
|
+
css_include_tag(*uniq_css_path(assets))
|
611
|
+
end
|
612
|
+
|
613
|
+
private
|
614
|
+
|
615
|
+
# Helper method to filter out duplicate files.
|
616
|
+
#
|
617
|
+
# ==== Parameters
|
618
|
+
# options<Hash>:: Options to pass to include tag methods.
|
619
|
+
def extract_required_files(files, options = {})
|
620
|
+
return [] if files.nil? || files.empty?
|
621
|
+
seen = []
|
622
|
+
files.inject([]) do |extracted, req_js|
|
623
|
+
include_files, include_options = if req_js.last.is_a?(Hash)
|
624
|
+
[req_js[0..-2], options.merge(req_js.last)]
|
625
|
+
else
|
626
|
+
[req_js, options]
|
627
|
+
end
|
628
|
+
seen += (includes = include_files - seen)
|
629
|
+
extracted << (includes + [include_options]) unless includes.empty?
|
630
|
+
extracted
|
631
|
+
end
|
632
|
+
end
|
633
|
+
|
634
|
+
end
|
635
|
+
end
|