front-end-blender 0.23 → 0.24

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt CHANGED
@@ -35,18 +35,22 @@ source files are the hash values as an array. Here is a sample Blendfile:
35
35
  == Usage
36
36
 
37
37
  Usage: blend [options]
38
- -h, --help Show this message
39
- -V, --version Prints Blender's version number
40
- -g, --generate Generate a stub Blendfile
41
- -f, --file FILE Use given Blendfile
42
- -r, --root ROOT Specify the path to the web root directory
43
- -t, --type TYPE Select file type to blend (css, js)
44
- -m, --min [MINIFIER] Select minifier to use (yui, none)
45
- -c, --cache-buster [BUSTER] Append cache busters to URLs in CSS, defaults to timestamps
46
- --force Force blending when source files aren't newer than output files
47
- --yui=YUIOPTS Pass arguments to YUI Compressor
48
- -d, --data EXPERIMENTAL Convert url(file.ext) to url(data:) in CSS files
49
- -z, --gzip EXPERIMENTAL Also create gzip output files
38
+ -g, --generate Generate a stub Blendfile
39
+ -f, --file FILE Use specified Blendfile
40
+ -r, --root ROOT Specify the path to the web root directory
41
+ -t, --type TYPE Select file type to blend (css, js)
42
+ -m, --min [MINIFIER] Select minifier to use (yui, none)
43
+ -c, --cache-buster [BUSTER] Add cache busters to URLs in CSS
44
+ --force Don't allow output files to be skipped
45
+ --yui=YUIOPTS Pass arguments to YUI Compressor
46
+
47
+ Experimental:
48
+ -d, --data Convert url(file.ext) to url(data:) in CSS
49
+ -z, --gzip Additionally generate gzipped output files
50
+
51
+ Meta:
52
+ -h, --help Show this message
53
+ -V, --version Show the version number
50
54
 
51
55
  == Examples
52
56
 
@@ -65,7 +69,7 @@ Other examples:
65
69
  To install the RubyGem, run the following at the command line (you may need to use a command such as su or sudo):
66
70
  gem install blender
67
71
 
68
- If you're using Windows, you'll also need to run the following:
72
+ If you're using Windows, you'll also want to run the following to get colored command line output:
69
73
  gem install win32console
70
74
 
71
75
  * Java[http://java.com/en/] v1.4 or greater is required
data/bin/blend CHANGED
@@ -11,19 +11,28 @@ require 'front_end_architect/blender'
11
11
 
12
12
  options = {}
13
13
 
14
+ def section(opts, title)
15
+ opts.separator ''
16
+ opts.separator title + ':'
17
+ end
18
+
14
19
  opts = OptionParser.new do |opts|
15
- opts.on('-h', '--help', "Show this message") { puts opts; exit 0 }
16
- opts.on('-V', '--version', "Show the version number") { puts "Front-End Blender v#{FrontEndArchitect::Blender::VERSION}"; exit 0 }
17
- opts.on('-g', '--generate', String, "Generate a stub Blendfile") { options[:generate] = true }
18
- opts.on('-f FILE', '--file FILE', String, "Use given Blendfile") {|f| options[:blendfile] = f }
19
- opts.on('-r ROOT', '--root ROOT', String, "Set the path to the web root directory") {|r| options[:root] = r }
20
- opts.on('-t TYPE', '--type TYPE', [:css, :js], "Select file type to blend (css, js)") {|t| options[:file_type] = t }
21
- opts.on('-m [MINIFIER]', '--min [MINIFIER]', [:yui, :none], "Select minifier to use (yui, none)") {|m| options[:min] = m.nil? ? :none : m.to_sym }
22
- opts.on('-c [BUSTER]', '--cache-buster [BUSTER]', String, "Append cache busters to URLs in CSS, defaults to timestamps") {|b| options[:cache_buster] = b.nil? ? :mtime : b }
23
- opts.on( '--force', String, "Force blending when source files aren't newer than output files") { options[:force] = true }
24
- opts.on( '--yui=YUIOPTS', String, "Pass arguments to YUI Compressor") {|o| options[:yuiopts] = o }
25
- opts.on('-d', '--data', String, "EXPERIMENTAL Convert url(file.ext) to url(data:) in CSS files") { options[:data] = true }
26
- opts.on('-z', '--gzip', String, "EXPERIMENTAL Also create gzip output files") { options[:gzip] = true }
20
+ version = "Front-End Blender v#{FrontEndArchitect::Blender::VERSION}"
21
+
22
+ opts.on('-g', '--generate', String, "Generate a stub Blendfile") { options[:generate] = true }
23
+ opts.on('-f FILE', '--file FILE', String, "Use specified Blendfile") {|f| options[:blendfile] = f; options[:root] = File.dirname(f) }
24
+ opts.on('-r ROOT', '--root ROOT', String, "Specify the path to the web root directory") {|r| options[:root] = r }
25
+ opts.on('-t TYPE', '--type TYPE', [:css, :js], "Select file type to blend (css, js)") {|t| options[:file_type] = t }
26
+ opts.on('-m [MINIFIER]', '--min [MINIFIER]', [:yui, :none], "Select minifier to use (yui, none)") {|m| options[:min] = m.nil? ? :none : m.to_sym }
27
+ opts.on('-c [BUSTER]', '--cache-buster [BUSTER]', String, "Add cache busters to URLs in CSS") {|b| options[:cache_buster] = b.nil? ? :mtime : b }
28
+ opts.on( '--force', String, "Don't allow output files to be skipped") { options[:force] = true }
29
+ opts.on( '--yui=YUIOPTS', String, "Pass arguments to YUI Compressor") {|o| options[:yuiopts] = o }
30
+ section opts, 'Experimental'
31
+ opts.on('-d', '--data', String, "Convert url(file.ext) to url(data:) in CSS") { options[:data] = true }
32
+ opts.on('-z', '--gzip', String, "Additionally generate gzipped output files") { options[:gzip] = true }
33
+ section opts, 'Meta'
34
+ opts.on('-h', '--help', "Show this message") { puts opts; exit 0 }
35
+ opts.on('-V', '--version', "Show the version number") { puts version; exit 0 }
27
36
 
28
37
  opts.parse!(ARGV) rescue return false
29
38
  end
@@ -6,29 +6,31 @@
6
6
  $:.unshift File.join(File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__), *%w[..])
7
7
 
8
8
  require 'rubygems'
9
- require 'yaml'
9
+
10
10
  require 'base64'
11
11
  require 'benchmark'
12
12
  require 'colored' unless PLATFORM =~ /win32/ && !Gem.available?('win32console')
13
- require 'mime/types'
14
13
  require 'find'
14
+ require 'mime/types'
15
15
  require 'pathname'
16
16
  require 'zlib'
17
+ require 'yaml'
18
+
17
19
  require 'front_end_architect/hash'
18
20
 
19
21
  module FrontEndArchitect
20
22
  class Blender
21
- VERSION = '0.23'
23
+ VERSION = '0.24'
22
24
 
23
- FILTER_REGEX = /filter: ?[^?]+\(src=(['"])([^\?'"]+)(\?(?:[^'"]+)?)?\1,[^?]+\1\);/im
24
- IMPORT_REGEX = /@import(?: url\(| )(['"]?)([^\?'"\)\s]+)(\?(?:[^'"\)]+)?)?\1\)?(?:[^?;]+)?;/im
25
+ ALPHA_REGEX = /(-ms-)?filter:\s*(['"]?)progid:DXImageTransform\.Microsoft\.AlphaImageLoader\(\s*src=(['"])([^\?'"\)]+)(\?(?:[^'"\)]+)?)?\3,\s*sizingMethod=(['"])(image|scale|crop)\6\s*\)\2/im
26
+ IMPORT_REGEX = /@import(?: url\(| )(['"]?)([^\?'"\)\s]+)(\?(?:[^'"\)]+)?)?\1\)?(?:[^?;]+)?;/im # shouldn't the semicolon be optional?
25
27
  URL_REGEX = /url\((['"]?)([^\?'"\)]+)(\?(?:[^'"\)]+)?)?\1?\)/im
26
28
 
27
29
  DEFAULT_OPTIONS = {
28
30
  :blendfile => 'Blendfile.yaml',
29
31
  :data => false,
30
32
  :force => false,
31
- :root => File.dirname(:blendfile.to_s),
33
+ :root => File.dirname('Blendfile.yaml'),
32
34
  :min => :yui,
33
35
  :colored => (Object.const_defined? :Colored),
34
36
  }
@@ -220,11 +222,14 @@ module FrontEndArchitect
220
222
  if @options[:data]
221
223
  if File.extname(output_name).downcase == '.css'
222
224
  output = output.gsub(URL_REGEX) do
223
- unless $2.downcase.include?('.css')
224
- mime_type = MIME::Types.type_for($2)
225
- url_contents = make_data_uri(IO.read($2), mime_type[0])
225
+ url = $2
226
+ query = $3
227
+
228
+ unless url.downcase.include?('.css')
229
+ mime_type = MIME::Types.type_for(url)
230
+ url_contents = make_data_uri(IO.read(url), mime_type[0])
226
231
  else
227
- url_contents = $2
232
+ url_contents = url
228
233
  end
229
234
  %Q!url(#{url_contents})!
230
235
  end
@@ -257,45 +262,50 @@ module FrontEndArchitect
257
262
 
258
263
  # Find filter statements and append cache busters to URLs
259
264
  if @options[:cache_buster]
260
- input = input.gsub(FILTER_REGEX) do |filter|
261
- uri = $2
262
- cbuster = $3
263
- unless uri.match(/^(https:\/\/|http:\/\/|\/\/)/i)
264
- full_path = File.expand_path($2, File.dirname(input_file))
265
- buster = make_cache_buster(full_path, $3)
266
- new_path = uri.to_s + buster
267
-
268
- %Q!filter='#{new_path}'!
269
- else
270
- %Q!filter='#{uri}#{cbuster}'!
265
+ input = input.gsub(ALPHA_REGEX) do |alpha|
266
+ prefix = $1
267
+ outter_quote = $2
268
+ inner_quote1 = $3
269
+ url = $4
270
+ query = $5
271
+ inner_quote2 = $6
272
+ sizing = $7
273
+
274
+ # TODO Rewrite to root relative (if :root specified?)
275
+
276
+ unless url.match(/^(https:\/\/|http:\/\/|\/\/)/i)
277
+ full_path = File.expand_path(url, File.dirname(input_file))
278
+ query = make_cache_buster(full_path, query)
271
279
  end
280
+
281
+ "#{prefix}filter:#{outter_quote}progid:DXImageTransform.Microsoft.AlphaImageLoader(src=#{inner_quote1}#{url}#{query}#{inner_quote1},sizingMethod=#{inner_quote2}#{sizing}#{inner_quote2})#{outter_quote}"
272
282
  end
273
283
  end
274
284
 
275
285
  # Handle @import statements URL rewrite and adding cache busters
276
286
  input = input.gsub(IMPORT_REGEX) do |import|
277
- uri = $2
278
- asset_path = Pathname.new(File.expand_path(uri, input_path))
287
+ url = $2
288
+ query = $3
289
+ asset_path = Pathname.new(File.expand_path(url, input_path))
279
290
 
280
- if uri.match(/^(\/[^\/]+.+)$/)
281
- asset_path = Pathname.new(File.join(File.expand_path(@options[:root]), uri))
291
+ if url.match(/^(\/[^\/]+.+)$/)
292
+ asset_path = Pathname.new(File.join(File.expand_path(@options[:root]), url))
282
293
  end
283
294
 
284
- unless uri.match(/^(https:\/\/|http:\/\/|\/\/)/i)
295
+ unless url.match(/^(https:\/\/|http:\/\/|\/\/)/i)
285
296
  if (output_path != input_path)
286
-
287
297
  new_path = asset_path.relative_path_from(output_path)
288
298
 
289
299
  if @options[:cache_buster]
290
- buster = make_cache_buster(asset_path, $3)
291
- import.gsub!(uri, new_path.to_s+buster)
300
+ buster = make_cache_buster(asset_path, query)
301
+ import.gsub!(url, new_path.to_s + buster)
292
302
  else
293
- import.gsub!(uri, new_path)
303
+ import.gsub!(url, new_path)
294
304
  end
295
305
  else
296
306
  if @options[:cache_buster]
297
- buster = make_cache_buster(asset_path, $3)
298
- import.gsub!(uri, asset_path.to_s+buster)
307
+ buster = make_cache_buster(asset_path, query)
308
+ import.gsub!(url, asset_path.to_s + buster)
299
309
  end
300
310
  end
301
311
  end
@@ -308,39 +318,39 @@ module FrontEndArchitect
308
318
  if output_path == input_path
309
319
  if @options[:data]
310
320
  input = input.gsub(URL_REGEX) do
311
- uri = $2
312
- cbuster = $3
321
+ url = $2
322
+ query = $3
313
323
 
314
- unless uri.match(/^(https:\/\/|http:\/\/|\/\/)/i)
315
- new_path = File.expand_path($2, File.dirname(input_file))
324
+ unless url.match(/^(https:\/\/|http:\/\/|\/\/)/i)
325
+ new_path = File.expand_path(url, File.dirname(input_file))
316
326
 
317
- if uri.match(/^(\/[^\/]+.+)$/)
318
- new_path = Pathname.new(File.join(File.expand_path(@options[:root]), uri))
327
+ if url.match(/^(\/[^\/]+.+)$/)
328
+ new_path = Pathname.new(File.join(File.expand_path(@options[:root]), url))
319
329
  end
320
330
 
321
331
  %Q!url(#{new_path})!
322
332
  else
323
- %Q!url(#{uri}#{cbuster})!
333
+ %Q!url(#{url}#{query})!
324
334
  end
325
335
  end
326
336
  elsif @options[:cache_buster]
327
337
  input = input.gsub(URL_REGEX) do
328
- unless uri.match(/^(https:\/\/|http:\/\/|\/\/)/i)
329
- uri = $2
330
- cbuster = $3
331
-
332
- if uri.match(/^(\/[^\/]+.+)$/)
333
- uri = Pathname.new(File.join(File.expand_path(@options[:root]), uri))
338
+ url = $2
339
+ query = $3
340
+
341
+ unless url.match(/^(https:\/\/|http:\/\/|\/\/)/i)
342
+ if url.match(/^(\/[^\/]+.+)$/)
343
+ url = Pathname.new(File.join(File.expand_path(@options[:root]), url))
334
344
  end
335
345
 
336
346
  if @options[:cache_buster]
337
- buster = make_cache_buster(uri, $3)
338
- new_path = uri.to_s+buster
347
+ buster = make_cache_buster(url, query)
348
+ new_path = url.to_s + buster
339
349
  end
340
350
 
341
351
  %Q!url(#{new_path})!
342
352
  else
343
- %Q!url(#{uri}#{cbuster})!
353
+ %Q!url(#{url}#{query})!
344
354
  end
345
355
  end
346
356
  end
@@ -349,37 +359,37 @@ module FrontEndArchitect
349
359
  else
350
360
  # Find all url(.ext) in file and rewrite relative url from output directory.
351
361
  input = input.gsub(URL_REGEX) do
352
- uri = $2
353
- cbuster = $3
362
+ url = $2
363
+ query = $3
354
364
 
355
- unless uri.match(/^(https:\/\/|http:\/\/|\/\/)/i)
365
+ unless url.match(/^(https:\/\/|http:\/\/|\/\/)/i)
356
366
  if @options[:data]
357
367
  # if doing data conversion rewrite url as an absolute path
358
- new_path = File.expand_path(uri, File.dirname(input_file))
368
+ new_path = File.expand_path(url, File.dirname(input_file))
359
369
 
360
- if uri.match(/^(\/[^\/]+.+)$/)
361
- new_path = Pathname.new(File.join(File.expand_path(@options[:root]), uri))
370
+ if url.match(/^(\/[^\/]+.+)$/)
371
+ new_path = Pathname.new(File.join(File.expand_path(@options[:root]), url))
362
372
  end
363
373
  else
364
- asset_path = Pathname.new(File.expand_path(uri, File.dirname(input_file)))
374
+ asset_path = Pathname.new(File.expand_path(url, File.dirname(input_file)))
365
375
 
366
- if uri.match(/^(\/[^\/]+.+)$/)
367
- asset_path = Pathname.new(File.join(File.expand_path(@options[:root]), uri))
376
+ if url.match(/^(\/[^\/]+.+)$/)
377
+ asset_path = Pathname.new(File.join(File.expand_path(@options[:root]), url))
368
378
  end
369
379
 
370
380
  new_path = asset_path.relative_path_from(output_path)
371
381
 
372
382
  if @options[:cache_buster]
373
- buster = make_cache_buster(asset_path, $3)
374
- new_path = new_path.to_s+buster
383
+ buster = make_cache_buster(asset_path, query)
384
+ new_path = new_path.to_s + buster
375
385
  else
376
- new_path = new_path.to_s+$3 unless $3.nil?
386
+ new_path = new_path.to_s + query unless query.nil?
377
387
  end
378
388
  end
379
389
 
380
390
  %Q!url(#{new_path})!
381
391
  else
382
- %Q!url(#{uri}#{cbuster})!
392
+ %Q!url(#{url}#{query})!
383
393
  end
384
394
  end
385
395
 
@@ -387,18 +397,18 @@ module FrontEndArchitect
387
397
  end
388
398
  end
389
399
 
390
- def make_cache_buster(asset_path, query_string)
391
- unless query_string.nil?
392
- query_string += '&'
400
+ def make_cache_buster(asset_path, query)
401
+ unless query.nil?
402
+ query += '&'
393
403
  else
394
- query_string = '?'
404
+ query = '?'
395
405
  end
396
406
 
397
407
  if @options[:cache_buster] == :mtime
398
408
  file_mtime = File.mtime(asset_path).to_i
399
- buster = query_string + file_mtime.to_s
409
+ buster = query + file_mtime.to_s
400
410
  else
401
- buster = query_string + @options[:cache_buster]
411
+ buster = query + @options[:cache_buster]
402
412
  end
403
413
 
404
414
  return buster
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: front-end-blender
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.23"
4
+ version: "0.24"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Blake Elshire
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2008-11-23 00:00:00 -08:00
13
+ date: 2008-12-08 00:00:00 -08:00
14
14
  default_executable: blend
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency