front-end-blender 0.23 → 0.24

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