view_assets 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +59 -0
- data/lib/tasks/view_assets_tasks.rake +22 -0
- data/lib/view_assets.rb +35 -0
- data/lib/view_assets/assets_finder.rb +232 -0
- data/lib/view_assets/css_assets.rb +21 -0
- data/lib/view_assets/directives.rb +108 -0
- data/lib/view_assets/error.rb +6 -0
- data/lib/view_assets/js_assets.rb +21 -0
- data/lib/view_assets/version.rb +3 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/javascripts/bar.js +2 -0
- data/test/dummy/app/assets/javascripts/foo.js +2 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/assets/stylesheets/bar.css +4 -0
- data/test/dummy/app/assets/stylesheets/foo.css +4 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/bar_controller.rb +7 -0
- data/test/dummy/app/controllers/foo_controller.rb +7 -0
- data/test/dummy/app/helpers/application_helper.rb +3 -0
- data/test/dummy/app/helpers/bar_helper.rb +2 -0
- data/test/dummy/app/helpers/foo_helper.rb +2 -0
- data/test/dummy/app/views/bar/index.html.erb +2 -0
- data/test/dummy/app/views/bar/show.html.erb +2 -0
- data/test/dummy/app/views/foo/index.html.erb +2 -0
- data/test/dummy/app/views/foo/show.html.erb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +15 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +40 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +66 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/log/development.log +883 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/app/javascripts/application.js +2 -0
- data/test/dummy/public/app/javascripts/bar/index/index.js +0 -0
- data/test/dummy/public/app/javascripts/bar/index/others.js +0 -0
- data/test/dummy/public/app/javascripts/bar/show.js +0 -0
- data/test/dummy/public/app/javascripts/foo/index/index.js +0 -0
- data/test/dummy/public/app/javascripts/foo/index/others.js +0 -0
- data/test/dummy/public/app/javascripts/foo/show.js +1 -0
- data/test/dummy/public/app/stylesheets/application.css +0 -0
- data/test/dummy/public/app/stylesheets/bar/index/index.css +0 -0
- data/test/dummy/public/app/stylesheets/bar/index/others.css +0 -0
- data/test/dummy/public/app/stylesheets/bar/show.css +0 -0
- data/test/dummy/public/app/stylesheets/foo/index/index.css +0 -0
- data/test/dummy/public/app/stylesheets/foo/index/others.css +0 -0
- data/test/dummy/public/app/stylesheets/foo/show.css +0 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/lib/javascripts/lib1.js +0 -0
- data/test/dummy/public/lib/javascripts/lib2.js +0 -0
- data/test/dummy/public/lib/stylesheets/lib1.css +0 -0
- data/test/dummy/public/lib/stylesheets/lib2.css +0 -0
- data/test/dummy/public/vendor/javascripts/vendor1.js +0 -0
- data/test/dummy/public/vendor/javascripts/vendor2.js +0 -0
- data/test/dummy/public/vendor/stylesheets/vendor1.css +0 -0
- data/test/dummy/public/vendor/stylesheets/vendor2.css +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/test/functional/bar_controller_test.rb +14 -0
- data/test/dummy/test/functional/foo_controller_test.rb +14 -0
- data/test/dummy/test/unit/helpers/bar_helper_test.rb +4 -0
- data/test/dummy/test/unit/helpers/foo_helper_test.rb +4 -0
- data/test/test_helper.rb +15 -0
- data/test/view_assets_test.rb +7 -0
- metadata +230 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 YOURNAME
|
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
data/Rakefile
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'rdoc/task'
|
10
|
+
rescue LoadError
|
11
|
+
require 'rdoc/rdoc'
|
12
|
+
require 'rake/rdoctask'
|
13
|
+
RDoc::Task = Rake::RDocTask
|
14
|
+
end
|
15
|
+
|
16
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'ViewAssets'
|
19
|
+
rdoc.options << '--line-numbers'
|
20
|
+
rdoc.rdoc_files.include('README.rdoc')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
23
|
+
|
24
|
+
Bundler::GemHelper.install_tasks
|
25
|
+
|
26
|
+
require 'rake/testtask'
|
27
|
+
|
28
|
+
Rake::TestTask.new(:test) do |t|
|
29
|
+
t.libs << 'lib'
|
30
|
+
t.libs << 'test'
|
31
|
+
t.pattern = 'test/**/*_test.rb'
|
32
|
+
t.verbose = false
|
33
|
+
end
|
34
|
+
|
35
|
+
task :default => :test
|
36
|
+
|
37
|
+
task :lines do
|
38
|
+
lines, codelines, total_lines, total_codelines = 0, 0, 0, 0
|
39
|
+
|
40
|
+
FileList["#{ ENV['PWD'] }/**/*.rb"].each do |file_name|
|
41
|
+
next if file_name =~ /vendor/
|
42
|
+
File.open(file_name, 'r') do |f|
|
43
|
+
while line = f.gets
|
44
|
+
lines += 1
|
45
|
+
next if line =~ /^\s*$/
|
46
|
+
next if line =~ /^\s*#/
|
47
|
+
codelines += 1
|
48
|
+
end
|
49
|
+
end
|
50
|
+
puts "L: #{sprintf("%4d", lines)}, LOC #{sprintf("%4d", codelines)} | #{file_name}"
|
51
|
+
|
52
|
+
total_lines += lines
|
53
|
+
total_codelines += codelines
|
54
|
+
|
55
|
+
lines, codelines = 0, 0
|
56
|
+
end
|
57
|
+
|
58
|
+
puts "Total: Lines #{total_lines}, LOC #{total_codelines}"
|
59
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# desc "Explaining what the task does"
|
2
|
+
# task :view_assets do
|
3
|
+
# # Task goes here
|
4
|
+
# end
|
5
|
+
|
6
|
+
# todo make a rake tasks to establish the assets tree in public folder
|
7
|
+
|
8
|
+
namespace :view_assets do
|
9
|
+
desc "Init view_assets framework"
|
10
|
+
task :init do
|
11
|
+
public_path = "#{ Rails.root }/public"
|
12
|
+
%w(vendor lib app).map { |d| %w(javascripts stylesheets).map { |t| "#{public_path}/#{d}/#{t}" } }.flatten.each do |dir|
|
13
|
+
FileUtils.mkdir dir
|
14
|
+
puts "\t\033[1;32mCreate\033[0m #{dir}"
|
15
|
+
if dir.include?('app')
|
16
|
+
fn_extension = dir.include?('javascripts') ? 'js' : 'css'
|
17
|
+
FileUtils.touch "Create #{dir}/application.#{fn_extension}"
|
18
|
+
puts "\t\033[1;32mCreate\033[0m #{dir}/application.#{fn_extension}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/view_assets.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
##
|
2
|
+
# TODO documentation
|
3
|
+
module ViewAssets
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
require 'view_assets/error'
|
7
|
+
require 'view_assets/directives'
|
8
|
+
require 'view_assets/assets_finder'
|
9
|
+
require 'view_assets/js_assets'
|
10
|
+
require 'view_assets/css_assets'
|
11
|
+
|
12
|
+
##
|
13
|
+
# To verify all assets and throw exception when find out inexistent asset
|
14
|
+
# Defaults to turn off. DO NOT use it in production.
|
15
|
+
# todo find out how to document constant
|
16
|
+
TO_VERIFY = false
|
17
|
+
|
18
|
+
attr_accessor :js_assets, :css_assets
|
19
|
+
|
20
|
+
# TODO need a new controller-action configuring interface, try to configure them in helper instead of view files
|
21
|
+
def include_assets_with_assets_mvc(controller, action)
|
22
|
+
@va_controller = controller
|
23
|
+
@va_action = action
|
24
|
+
|
25
|
+
raw [css_assets.all, js_assets.all].flatten.uniq.join("\n ")
|
26
|
+
end
|
27
|
+
|
28
|
+
def js_assets
|
29
|
+
@va_js_assets ||= JavascriptAssets.new(Rails.public_path, @va_controller, @va_action)
|
30
|
+
end
|
31
|
+
|
32
|
+
def css_assets
|
33
|
+
@va_css_assets ||= StyleSheetAssets.new(Rails.public_path, @va_controller, @va_action)
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
##
|
2
|
+
# Manifest file is a file that contains some dependency directives on top
|
3
|
+
# of it. Finder will parse these directives if existed and include them
|
4
|
+
# in the html.
|
5
|
+
# Usually, the first manifest file will be application.[js|css] in
|
6
|
+
# /app/assets/[javascripts|stylesheets] folder. However, if there is a
|
7
|
+
# :controller.[js|css] file existed in /app/assets/:controller folder,
|
8
|
+
# then it will replace application as the first manifest file.
|
9
|
+
# It will append assets dependency before every action assets.
|
10
|
+
# If both application and :controller manifest file are not existed,
|
11
|
+
# then the manifest file list will be empty at first.
|
12
|
+
module ViewAssets
|
13
|
+
##
|
14
|
+
# It's an abstract class.
|
15
|
+
class AssetsFinder < Struct.new(:root, :controller_name, :action_name)
|
16
|
+
|
17
|
+
def initialize(*args)
|
18
|
+
@all_assets = []
|
19
|
+
@retrieved = false
|
20
|
+
|
21
|
+
super(*args)
|
22
|
+
end
|
23
|
+
|
24
|
+
# todo try to figure out what really is DUCK TYPING
|
25
|
+
# tag method should be overrided by subclass
|
26
|
+
# def tag
|
27
|
+
# raise UnimplementedError.new "tag method is unimplemented."
|
28
|
+
# end
|
29
|
+
|
30
|
+
##
|
31
|
+
# This method is the ENTRY of assets finder after its initializtion.
|
32
|
+
# It returns all asset paths wrapped inside a appropriated html
|
33
|
+
# tag(`script` | `link`).
|
34
|
+
def all
|
35
|
+
all_assets.map { |asset| tag asset } # tag should be realized in a subclass
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# get all the asset paths in full path
|
40
|
+
# TODO realize this method
|
41
|
+
def full
|
42
|
+
all_assets.map { |asset| absolutely_pathize(asset) }
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# "untagged" means hasn't been wrapped inside a appropriated html tag like
|
47
|
+
# `script` or `link`
|
48
|
+
def all_assets
|
49
|
+
retrieve unless retrieved?
|
50
|
+
|
51
|
+
verify if TO_VERIFY
|
52
|
+
|
53
|
+
@all_assets
|
54
|
+
end
|
55
|
+
|
56
|
+
# TODO document
|
57
|
+
def retrieve
|
58
|
+
@all_assets = controller_assets.concat(action_assets).uniq if @all_assets.empty?
|
59
|
+
@retrieved = true
|
60
|
+
end
|
61
|
+
|
62
|
+
# TODO document
|
63
|
+
def retrieved?
|
64
|
+
@retrieved
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Check out whether all assets is existed or not
|
69
|
+
# It is better to be turned off in production
|
70
|
+
def verify
|
71
|
+
all_assets.each do |asset|
|
72
|
+
asset_file = absolutely_pathize(asset)
|
73
|
+
raise AssetNotFound.new("File #{ asset } DOEST EXIST") if FileTest.exist?(asset_file)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# The env assets are assets that will be required before action assets.
|
79
|
+
# The function of env assets is to allow user to require some assets
|
80
|
+
# that would be used throughout the whole application or controller.
|
81
|
+
# Like views in rails, assets finder will use application.[js|css] existed
|
82
|
+
# in /app/assets/[javascripts|stylesheets] folder if:controller.[js|css]
|
83
|
+
# in /app/assets/[javascripts|stylesheets]/:controller is not existed.
|
84
|
+
def controller_assets
|
85
|
+
return @controller_assets unless @controller_assets.nil?
|
86
|
+
|
87
|
+
@controller_assets = []
|
88
|
+
application_manifest = "#{ root }/#{ app_path }/application.#{ asset_extension }"
|
89
|
+
controller_manifest = "#{ root }/#{ app_path }/#{ controller_name }/#{ controller_name }.#{ asset_extension }"
|
90
|
+
|
91
|
+
manifest = nil
|
92
|
+
manifest = application_manifest if FileTest.exist?(application_manifest)
|
93
|
+
manifest = controller_manifest if FileTest.exist?(controller_manifest)
|
94
|
+
|
95
|
+
# TODO add rspec example
|
96
|
+
return @controller_assets if manifest.nil?
|
97
|
+
|
98
|
+
@controller_assets = manifest.nil? ? [] : retrieve_assets_from(manifest)
|
99
|
+
@controller_assets << unabsolutely_pathize(manifest)
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# If the action assets is only a file, finder will also consider it a
|
104
|
+
# manifest file.
|
105
|
+
# If the action assets is a foler consisting several asset files, finder will
|
106
|
+
# includes all the assets inside this folder. Among these files, a file named
|
107
|
+
# index.[js|css] will be taken as manifest file.
|
108
|
+
def action_assets
|
109
|
+
return @action_assets unless @action_assets.nil?
|
110
|
+
|
111
|
+
@action_assets = []
|
112
|
+
action_path = "#{ root }/#{ app_path }/#{ controller_name }"
|
113
|
+
single_action_path = "#{ action_path }/#{ action_name }.#{ asset_extension }"
|
114
|
+
indexed_action_path = "#{ action_path }/#{ action_name }/index.#{ asset_extension }"
|
115
|
+
|
116
|
+
# find files in the conventional directory
|
117
|
+
manifest = nil
|
118
|
+
manifest = single_action_path if FileTest.exist?(single_action_path)
|
119
|
+
manifest = indexed_action_path if FileTest.exist?(indexed_action_path)
|
120
|
+
|
121
|
+
# TODO add rspec example
|
122
|
+
return @action_assets if manifest.nil?
|
123
|
+
|
124
|
+
@action_assets = manifest.nil? ? [] : retrieve_assets_from(manifest)
|
125
|
+
@action_assets << unabsolutely_pathize(manifest)
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def retrieve_assets_from(manifest)
|
131
|
+
assets = []
|
132
|
+
directive = Directive.new(asset_type)
|
133
|
+
|
134
|
+
Pathname.new(manifest).each_line do |line|
|
135
|
+
# break if directive.ending_directive?(l) # TODO add ending_directive support
|
136
|
+
next unless directive.legal_directive?(line)
|
137
|
+
assets.concat(analyze(*directive.parse(line)))
|
138
|
+
end
|
139
|
+
|
140
|
+
# TODO find another way to realize this instead of using "flatten" method
|
141
|
+
assets.flatten
|
142
|
+
end
|
143
|
+
|
144
|
+
def analyze(asset_category, path_params)
|
145
|
+
case asset_category
|
146
|
+
when 'vendor'
|
147
|
+
path_params.map { |pp| retrieve_vendor_assets(pp) }
|
148
|
+
when 'lib'
|
149
|
+
path_params.map { |pp| retrieve_lib_assets(pp) }
|
150
|
+
when 'app'
|
151
|
+
path_params.map { |pp| retrieve_app_asset(pp) }
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def retrieve_app_asset(required_asset)
|
156
|
+
asset_path = "#{ app_path }#{ required_asset.match(/^\//) ? '' : "/#{ controller_name }" }"
|
157
|
+
|
158
|
+
relatively_pathize(asset_path, required_asset.gsub(/^\//, ''))
|
159
|
+
end
|
160
|
+
|
161
|
+
def retrieve_vendor_assets(manifest)
|
162
|
+
meta_retrieve(vendor_path, manifest)
|
163
|
+
end
|
164
|
+
|
165
|
+
def retrieve_lib_assets(manifest)
|
166
|
+
meta_retrieve(lib_path, manifest)
|
167
|
+
end
|
168
|
+
|
169
|
+
# for lib and vendor assets, finder will assume that it was stored in the
|
170
|
+
# root of vendor|lib and the file itself is a manifest file at first. If
|
171
|
+
# that isn't the case, finder will try to locate it in
|
172
|
+
# vendor|lib/:lib_or_vendor_name and take index.js inside that folder as
|
173
|
+
# manifest.
|
174
|
+
#
|
175
|
+
# NOTE: All assets returned will be "unabsolutely_pathized" here. That
|
176
|
+
# means each string of file path does not contain any root path info.
|
177
|
+
def meta_retrieve(manifest_path, manifest)
|
178
|
+
single_file_lib = absolutely_pathize("#{ manifest_path }/#{ manifest }")
|
179
|
+
|
180
|
+
manifest_dir = "#{ manifest_path }/#{ manifest }"
|
181
|
+
indexing_lib = absolutely_pathize("#{ manifest_dir }/index")
|
182
|
+
all_assets_in_manifest_dir = []
|
183
|
+
|
184
|
+
real_manifest = nil
|
185
|
+
if FileTest.exist?(single_file_lib)
|
186
|
+
real_manifest = single_file_lib
|
187
|
+
else FileTest.exist?(indexing_lib)
|
188
|
+
real_manifest = indexing_lib
|
189
|
+
all_assets_in_manifest_dir = retrieve_all_from(manifest_dir)
|
190
|
+
end
|
191
|
+
|
192
|
+
retrieve_assets_from(real_manifest).flatten
|
193
|
+
.concat(all_assets_in_manifest_dir)
|
194
|
+
.concat([unabsolutely_pathize(real_manifest)])
|
195
|
+
.uniq
|
196
|
+
end
|
197
|
+
|
198
|
+
# TODO add test for dir should be a relative path
|
199
|
+
def retrieve_all_from(dir)
|
200
|
+
Dir["#{ root }/#{ dir }/**/*.#{ asset_extension }"].map { |file| unabsolutely_pathize(file) }
|
201
|
+
end
|
202
|
+
|
203
|
+
def relatively_pathize(asset_dir, asset)
|
204
|
+
"#{ asset_dir }/#{ asset.match(/\.#{ asset_extension }$/) ? asset : "#{ asset }.js" }"
|
205
|
+
end
|
206
|
+
|
207
|
+
# TODO add tests
|
208
|
+
def app_path
|
209
|
+
"app/#{ assets_path }"
|
210
|
+
end
|
211
|
+
|
212
|
+
# TODO add tests
|
213
|
+
def lib_path
|
214
|
+
"lib/#{ assets_path }"
|
215
|
+
end
|
216
|
+
|
217
|
+
# TODO add tests
|
218
|
+
def vendor_path
|
219
|
+
"vendor/#{ assets_path }"
|
220
|
+
end
|
221
|
+
|
222
|
+
# todo document
|
223
|
+
def absolutely_pathize(asset_path)
|
224
|
+
"#{ root }/#{ asset_path.match(/\.#{ asset_extension }$/) ? asset_path : "#{ asset_path }.js" }"
|
225
|
+
end
|
226
|
+
|
227
|
+
# todo document
|
228
|
+
def unabsolutely_pathize(asset_path)
|
229
|
+
asset_path.gsub(/^#{ root }\//, '')
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ViewAssets
|
2
|
+
# TODO add rspec examples
|
3
|
+
class StyleSheetAssets < AssetsFinder
|
4
|
+
def assets_path
|
5
|
+
# 'assets/javascripts'
|
6
|
+
'stylesheets'
|
7
|
+
end
|
8
|
+
|
9
|
+
def asset_extension
|
10
|
+
'css'
|
11
|
+
end
|
12
|
+
|
13
|
+
def asset_type
|
14
|
+
'stylesheet'
|
15
|
+
end
|
16
|
+
|
17
|
+
def tag(css_href)
|
18
|
+
"<link href='#{css_href}' media='screen' rel='stylesheet' />"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module ViewAssets
|
2
|
+
class Directive
|
3
|
+
attr_reader :asset_type
|
4
|
+
def initialize(asset_type)
|
5
|
+
# TODO find out asset_types that can run in both directive.rb and asset_finders
|
6
|
+
# raise ConfigurationError.new('asset type should be "js" or "css"') unless %w(css js).include?(asset_type)
|
7
|
+
raise ConfigurationError.new('asset type should be "javascript" or "stylesheet"') unless %w(javascript stylesheet).include?(asset_type)
|
8
|
+
@asset_type = asset_type
|
9
|
+
end
|
10
|
+
|
11
|
+
# TODO realize this method
|
12
|
+
# remember to take different syntax into consideration
|
13
|
+
def ending_directive?(primitive_params)
|
14
|
+
# primitive_params.match
|
15
|
+
end
|
16
|
+
|
17
|
+
# TODO add docs
|
18
|
+
def legal_directive?(primitive_params)
|
19
|
+
[vendor_directive, lib_directive, app_directive].any? { |d| d =~ primitive_params }
|
20
|
+
end
|
21
|
+
|
22
|
+
# return root folder and all the path params that have been split
|
23
|
+
# TODO this method bellow need refactor
|
24
|
+
def parse(primitive_params)
|
25
|
+
asset_root = ''
|
26
|
+
path_param_str = ''
|
27
|
+
path_params = []
|
28
|
+
unknown_directive = false
|
29
|
+
|
30
|
+
# TODO make sure path_param_str will return nil for non-matched result and array for matched result
|
31
|
+
# rememer to write tests for this section of codes
|
32
|
+
if vendor_directive =~ primitive_params
|
33
|
+
asset_root = 'vendor'
|
34
|
+
path_param_str = primitive_params.match(vendor_directive)[:path_params]
|
35
|
+
elsif lib_directive =~ primitive_params
|
36
|
+
asset_root = 'lib'
|
37
|
+
path_param_str = primitive_params.match(lib_directive)[:path_params]
|
38
|
+
elsif app_directive =~ primitive_params
|
39
|
+
asset_root = 'app'
|
40
|
+
path_param_str = primitive_params.match(app_directive)[:path_params]
|
41
|
+
else
|
42
|
+
# TODO remove UnknownDirectiveError or try to find another way to get thing done
|
43
|
+
# raise UnknownDirectiveError.new "'#{primitive_params}' is not in legal directive format"
|
44
|
+
unknown_directive = true
|
45
|
+
end
|
46
|
+
|
47
|
+
# TODO refactor codes bellow after the above paragraph was refactored
|
48
|
+
would_be_path_params = path_param_str.strip.split(/,\s?/)
|
49
|
+
# would_be_path_params = [would_be_path_params] if would_be_path_params.kind_of?(String)
|
50
|
+
path_params = would_be_path_params unless would_be_path_params.empty?
|
51
|
+
|
52
|
+
# unknown_directive ? [nil, nil] : [asset_root, path_params.strip.split(/,\s?/)]
|
53
|
+
# todo add rspec examples for returning a ['', []] when the primitive_params is illegal
|
54
|
+
[asset_root, path_params]
|
55
|
+
end
|
56
|
+
|
57
|
+
# def all_directives
|
58
|
+
# /#{tree_directive}|#{file_directive}/
|
59
|
+
# end
|
60
|
+
|
61
|
+
def vendor_directive
|
62
|
+
@vendor_directive ||= generate_formula 'require_vendor'
|
63
|
+
end
|
64
|
+
|
65
|
+
def lib_directive
|
66
|
+
@lib_directive ||= generate_formula 'require_lib'
|
67
|
+
end
|
68
|
+
|
69
|
+
def app_directive
|
70
|
+
@app_directive ||= generate_formula
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
##
|
75
|
+
# for javascript
|
76
|
+
# double-slash syntax => "//= require_vendor xxx"
|
77
|
+
# space-asterisk syntax => " *= require_vendor xxx"
|
78
|
+
# slash-asterisk syntax => "/*= require_vendor xxx */"
|
79
|
+
#
|
80
|
+
# for stylesheets
|
81
|
+
# space-asterisk syntax => " *= require_vendor xxx"
|
82
|
+
# slash-asterisk syntax => "/*= require_vendor xxx */"
|
83
|
+
#
|
84
|
+
# TODO refactor: use reasonable and effective regular expression
|
85
|
+
# TODO use "require_app" as app asset directive and make "require" as a relative directive
|
86
|
+
def generate_formula(requiring_type = 'require')
|
87
|
+
if javascript? asset_type
|
88
|
+
%r{
|
89
|
+
^//=\s#{requiring_type}\s(?<path_params>.*)$ # double-slash syntax
|
90
|
+
|
|
91
|
+
^\s\*=\s#{requiring_type}\s(?<path_params>.*)$ # space-asterisk syntax
|
92
|
+
|
|
93
|
+
^/\*=\s#{requiring_type}\s(?<path_params>.*)\s\*/$ # slash-asterisk syntax
|
94
|
+
}x
|
95
|
+
else
|
96
|
+
%r{
|
97
|
+
^\s\*=\s#{requiring_type}\s(?<path_params>.*)$ # space-asterisk syntax
|
98
|
+
|
|
99
|
+
^/\*=\s#{requiring_type}\s(?<path_params>.*)*\s\*/$ # slash-asterisk syntax
|
100
|
+
}x
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def javascript? type
|
105
|
+
%w(js javascript javascripts).include? type
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|