Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 140 lines (112 sloc) 4.637 kB
6a609db @joshk incorporated most of the feedback from José
joshk authored
1 require 'active_support/core_ext/class/attribute'
6747ae2 @joshk reduced duplication between the javascript and stylesheet asset tag m…
joshk authored
2 require 'active_support/core_ext/string/inflections'
3 require 'active_support/core_ext/file'
4 require 'action_view/helpers/tag_helper'
5 require 'action_view/helpers/asset_tag_helpers/common_asset_helpers'
6 require 'action_view/helpers/asset_tag_helpers/asset_id_caching'
7
8
9 module ActionView
10 module Helpers
11 module AssetTagHelper
12
13 class AssetIncludeTag
14 include CommonAssetHelpers
6a609db @joshk incorporated most of the feedback from José
joshk authored
15 include AssetIdCaching
6747ae2 @joshk reduced duplication between the javascript and stylesheet asset tag m…
joshk authored
16
6a609db @joshk incorporated most of the feedback from José
joshk authored
17 attr_reader :config, :controller
6747ae2 @joshk reduced duplication between the javascript and stylesheet asset tag m…
joshk authored
18
6a609db @joshk incorporated most of the feedback from José
joshk authored
19 class_attribute :expansions
20 self.expansions = { }
6747ae2 @joshk reduced duplication between the javascript and stylesheet asset tag m…
joshk authored
21
6a609db @joshk incorporated most of the feedback from José
joshk authored
22 def initialize(config, controller)
6747ae2 @joshk reduced duplication between the javascript and stylesheet asset tag m…
joshk authored
23 @config = config
24 @controller = controller
6a609db @joshk incorporated most of the feedback from José
joshk authored
25 end
26
27 def asset_name
28 raise NotImplementedError
29 end
30
31 def extension
32 raise NotImplementedError
6747ae2 @joshk reduced duplication between the javascript and stylesheet asset tag m…
joshk authored
33 end
34
35 def custom_dir
36 raise NotImplementedError
37 end
38
39 def asset_tag(source, options)
40 raise NotImplementedError
41 end
42
43 def include_tag(*sources)
44 options = sources.extract_options!.stringify_keys
45 concat = options.delete("concat")
46 cache = concat || options.delete("cache")
47 recursive = options.delete("recursive")
48
49 if concat || (config.perform_caching && cache)
50 joined_name = (cache == true ? "all" : cache) + ".#{extension}"
51 joined_path = File.join((joined_name[/^#{File::SEPARATOR}/] ? config.assets_dir : custom_dir), joined_name)
52 unless config.perform_caching && File.exists?(joined_path)
53 write_asset_file_contents(joined_path, compute_paths(sources, recursive))
54 end
55 asset_tag(joined_name, options)
56 else
57 sources = expand_sources(sources, recursive)
58 ensure_sources!(sources) if cache
59 sources.collect { |source| asset_tag(source, options) }.join("\n").html_safe
60 end
61 end
62
63
64 private
65
66 def path_to_asset(source)
67 compute_public_path(source, asset_name.to_s.pluralize, extension)
68 end
69
70 def compute_paths(*args)
71 expand_sources(*args).collect { |source| compute_public_path(source, asset_name.pluralize, extension, false) }
72 end
73
74 def expand_sources(sources, recursive)
75 if sources.first == :all
76 collect_asset_files(custom_dir, ('**' if recursive), "*.#{extension}")
77 else
78 sources.collect do |source|
79 determine_source(source, expansions)
80 end.flatten
81 end
82 end
83
84 def ensure_sources!(sources)
85 sources.each do |source|
86 asset_file_path!(compute_public_path(source, asset_name.pluralize, extension))
87 end
88 return sources
89 end
90
91 def collect_asset_files(*path)
92 dir = path.first
93
94 Dir[File.join(*path.compact)].collect do |file|
95 file[-(file.size - dir.size - 1)..-1].sub(/\.\w+$/, '')
96 end.sort
97 end
98
99 def determine_source(source, collection)
100 case source
101 when Symbol
102 collection[source] || raise(ArgumentError, "No expansion found for #{source.inspect}")
103 else
104 source
105 end
106 end
107
108 def join_asset_file_contents(paths)
109 paths.collect { |path| File.read(asset_file_path!(path, true)) }.join("\n\n")
110 end
111
112 def write_asset_file_contents(joined_asset_path, asset_paths)
113 FileUtils.mkdir_p(File.dirname(joined_asset_path))
114 File.atomic_write(joined_asset_path) { |cache| cache.write(join_asset_file_contents(asset_paths)) }
115
116 # Set mtime to the latest of the combined files to allow for
117 # consistent ETag without a shared filesystem.
118 mt = asset_paths.map { |p| File.mtime(asset_file_path(p)) }.max
119 File.utime(mt, mt, joined_asset_path)
120 end
121
122 def asset_file_path(path)
123 File.join(config.assets_dir, path.split('?').first)
124 end
125
126 def asset_file_path!(path, error_if_file_is_uri = false)
127 if is_uri?(path)
128 raise(Errno::ENOENT, "Asset file #{path} is uri and cannot be merged into single file") if error_if_file_is_uri
129 else
130 absolute_path = asset_file_path(path)
131 raise(Errno::ENOENT, "Asset file not found at '#{absolute_path}'" ) unless File.exist?(absolute_path)
132 return absolute_path
133 end
134 end
135 end
136
137 end
138 end
139 end
Something went wrong with that request. Please try again.