thorero-assets 0.9.4

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.
@@ -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