juicer 0.2.6 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. data/History.txt +28 -0
  2. data/Rakefile +84 -36
  3. data/Readme.rdoc +192 -23
  4. data/VERSION +1 -0
  5. data/bin/juicer +2 -4
  6. data/lib/juicer.rb +9 -10
  7. data/lib/juicer/asset/path.rb +275 -0
  8. data/lib/juicer/asset/path_resolver.rb +79 -0
  9. data/lib/juicer/binary.rb +3 -5
  10. data/lib/juicer/cache_buster.rb +112 -27
  11. data/lib/juicer/command/install.rb +4 -2
  12. data/lib/juicer/command/list.rb +16 -9
  13. data/lib/juicer/command/merge.rb +30 -14
  14. data/lib/juicer/command/verify.rb +1 -1
  15. data/lib/juicer/css_cache_buster.rb +31 -47
  16. data/lib/juicer/datafy/datafy.rb +20 -0
  17. data/lib/juicer/dependency_resolver/css_dependency_resolver.rb +29 -0
  18. data/lib/juicer/dependency_resolver/dependency_resolver.rb +101 -0
  19. data/lib/juicer/dependency_resolver/javascript_dependency_resolver.rb +23 -0
  20. data/lib/juicer/ext/logger.rb +5 -0
  21. data/lib/juicer/ext/string.rb +47 -0
  22. data/lib/juicer/ext/symbol.rb +15 -0
  23. data/lib/juicer/image_embed.rb +129 -0
  24. data/lib/juicer/install/base.rb +2 -2
  25. data/lib/juicer/install/closure_compiler_installer.rb +69 -0
  26. data/lib/juicer/install/jslint_installer.rb +3 -3
  27. data/lib/juicer/install/rhino_installer.rb +3 -2
  28. data/lib/juicer/install/yui_compressor_installer.rb +3 -2
  29. data/lib/juicer/jslint.rb +1 -1
  30. data/lib/juicer/merger/base.rb +1 -1
  31. data/lib/juicer/merger/javascript_merger.rb +3 -4
  32. data/lib/juicer/merger/stylesheet_merger.rb +13 -15
  33. data/lib/juicer/minifyer/closure_compiler.rb +90 -0
  34. data/lib/juicer/minifyer/java_base.rb +77 -0
  35. data/lib/juicer/minifyer/yui_compressor.rb +15 -48
  36. data/test/bin/jslint-1.0.js +523 -0
  37. data/test/bin/jslint.js +523 -0
  38. data/test/bin/rhino1_7R1.zip +0 -0
  39. data/test/bin/rhino1_7R2-RC1.jar +0 -0
  40. data/test/bin/rhino1_7R2-RC1.zip +0 -0
  41. data/test/bin/yuicompressor +0 -0
  42. data/test/bin/yuicompressor-2.3.5.zip +0 -0
  43. data/test/bin/yuicompressor-2.4.2.jar +0 -0
  44. data/test/bin/yuicompressor-2.4.2.zip +0 -0
  45. data/test/data/Changelog.txt +10 -0
  46. data/test/data/a.css +3 -0
  47. data/test/data/a.js +5 -0
  48. data/test/data/a1.css +5 -0
  49. data/test/data/b.css +1 -0
  50. data/test/data/b.js +5 -0
  51. data/test/data/b1.css +5 -0
  52. data/test/data/c1.css +3 -0
  53. data/test/data/css/2.gif +1 -0
  54. data/test/data/css/test.css +11 -0
  55. data/test/data/css/test2.css +1 -0
  56. data/test/data/d1.css +3 -0
  57. data/test/data/images/1.png +1 -0
  58. data/test/data/my_app.js +2 -0
  59. data/test/data/not-ok.js +2 -0
  60. data/test/data/ok.js +3 -0
  61. data/test/data/path_test.css +5 -0
  62. data/test/data/path_test2.css +14 -0
  63. data/test/data/pkg/module/moda.js +2 -0
  64. data/test/data/pkg/module/modb.js +3 -0
  65. data/test/data/pkg/pkg.js +1 -0
  66. data/test/fixtures/yui-download.html +425 -0
  67. data/test/test_helper.rb +36 -7
  68. data/test/unit/juicer/asset/path_resolver_test.rb +76 -0
  69. data/test/unit/juicer/asset/path_test.rb +370 -0
  70. data/test/unit/juicer/cache_buster_test.rb +104 -0
  71. data/test/{juicer/test_chainable.rb → unit/juicer/chainable_test.rb} +1 -1
  72. data/test/unit/juicer/command/install_test.rb +58 -0
  73. data/test/{juicer/command/test_list.rb → unit/juicer/command/list_test.rb} +26 -14
  74. data/test/unit/juicer/command/merge_test.rb +162 -0
  75. data/test/{juicer/command/test_util.rb → unit/juicer/command/util_test.rb} +10 -6
  76. data/test/unit/juicer/command/verify_test.rb +48 -0
  77. data/test/{juicer/test_css_cache_buster.rb → unit/juicer/css_cache_buster_test.rb} +10 -30
  78. data/test/unit/juicer/datafy_test.rb +37 -0
  79. data/test/{juicer/merger/test_css_dependency_resolver.rb → unit/juicer/dependency_resolver/css_dependency_resolver_test.rb} +2 -2
  80. data/test/{juicer/merger/test_javascript_dependency_resolver.rb → unit/juicer/dependency_resolver/javascript_dependency_resolver_test.rb} +13 -2
  81. data/test/unit/juicer/ext/{#string_test.rb# → string_test.rb} +0 -7
  82. data/test/unit/juicer/ext/symbol_test.rb +27 -0
  83. data/test/unit/juicer/image_embed_test.rb +271 -0
  84. data/test/unit/juicer/install/installer_base_test.rb +214 -0
  85. data/test/{juicer/install/test_jslint_installer.rb → unit/juicer/install/jslint_installer_test.rb} +1 -1
  86. data/test/{juicer/install/test_rhino_installer.rb → unit/juicer/install/rhino_installer_test.rb} +1 -1
  87. data/test/{juicer/install/test_yui_compressor_installer.rb → unit/juicer/install/yui_compressor_test.rb} +16 -16
  88. data/test/unit/juicer/jslint_test.rb +60 -0
  89. data/test/{juicer/merger/test_base.rb → unit/juicer/merger/base_test.rb} +1 -1
  90. data/test/{juicer/merger/test_javascript_merger.rb → unit/juicer/merger/javascript_merger_test.rb} +2 -2
  91. data/test/{juicer/merger/test_stylesheet_merger.rb → unit/juicer/merger/stylesheet_merger_test.rb} +15 -13
  92. data/test/unit/juicer/minifyer/closure_compressor_test.rb +107 -0
  93. data/test/{integration → unit}/juicer/minifyer/yui_compressor_test.rb +30 -47
  94. data/test/unit/juicer_test.rb +1 -0
  95. metadata +207 -113
  96. data/lib/juicer/core.rb +0 -61
  97. data/lib/juicer/merger/css_dependency_resolver.rb +0 -25
  98. data/lib/juicer/merger/dependency_resolver.rb +0 -82
  99. data/lib/juicer/merger/javascript_dependency_resolver.rb +0 -21
  100. data/tasks/ann.rake +0 -80
  101. data/tasks/bones.rake +0 -20
  102. data/tasks/gem.rake +0 -201
  103. data/tasks/git.rake +0 -40
  104. data/tasks/notes.rake +0 -27
  105. data/tasks/post_load.rake +0 -34
  106. data/tasks/rdoc.rake +0 -51
  107. data/tasks/rubyforge.rake +0 -55
  108. data/tasks/setup.rb +0 -292
  109. data/tasks/spec.rake +0 -54
  110. data/tasks/svn.rake +0 -47
  111. data/tasks/test.rake +0 -40
  112. data/tasks/test/setup.rake +0 -35
  113. data/tasks/zentest.rake +0 -36
  114. data/test/juicer/command/test_install.rb +0 -53
  115. data/test/juicer/command/test_merge.rb +0 -160
  116. data/test/juicer/command/test_verify.rb +0 -33
  117. data/test/juicer/install/test_installer_base.rb +0 -195
  118. data/test/juicer/minifyer/test_yui_compressor.rb +0 -159
  119. data/test/juicer/test_cache_buster.rb +0 -58
  120. data/test/juicer/test_core.rb +0 -47
  121. data/test/juicer/test_jslint.rb +0 -33
  122. data/test/test_juicer.rb +0 -4
@@ -0,0 +1,23 @@
1
+ require "juicer/dependency_resolver/dependency_resolver"
2
+
3
+ module Juicer
4
+ # Resolves @depends and @depend statements in comments in JavaScript files.
5
+ # Only the first comment in a JavaScript file is parsed
6
+ #
7
+ class JavaScriptDependencyResolver < DependencyResolver
8
+ @@depends_pattern = /\@depends?\s+([^\s\'\"\;]+)/
9
+
10
+ private
11
+ def parse(line, imported_file = nil)
12
+ return $1 if line =~ @@depends_pattern
13
+
14
+ # If we have already skimmed through some @depend/@depends or a
15
+ # closing comment we're done.
16
+ throw :done unless imported_file.nil? || !(line =~ /\*\//)
17
+ end
18
+
19
+ def extension
20
+ ".js"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ class Logger
2
+ def format_message(severity, datetime, progname, msg)
3
+ "#{msg}\n"
4
+ end
5
+ end
@@ -0,0 +1,47 @@
1
+ #
2
+ # Additions to core Ruby objects
3
+ #
4
+
5
+ class String
6
+
7
+ unless String.method_defined?(:camel_case)
8
+ #
9
+ # Turn an underscored string into camel case, ie this_becomes -> ThisBecomes
10
+ #
11
+ def camel_case
12
+ self.split("_").inject("") { |str, piece| str + piece.capitalize }
13
+ end
14
+ end
15
+
16
+ unless String.method_defined?(:to_class)
17
+ #
18
+ # Treat a string as a class name and return the class. Optionally provide a
19
+ # module to look up the class in.
20
+ #
21
+ def to_class(mod = nil)
22
+ res = "#{mod}::#{self}".sub(/^::/, "").split("::").inject(Object) do |mod, obj|
23
+ raise "No such class/module" unless mod.const_defined?(obj)
24
+ mod = mod.const_get(obj)
25
+ end
26
+ end
27
+ end
28
+
29
+ unless String.method_defined?(:classify)
30
+ #
31
+ # Turn a string in either underscore or camel case form into a class directly
32
+ #
33
+ def classify(mod = nil)
34
+ self.camel_case.to_class(mod)
35
+ end
36
+ end
37
+
38
+ unless String.method_defined?(:underscore)
39
+ #
40
+ # Turn a camelcase string into underscore string
41
+ #
42
+ def underscore
43
+ self.split(/([A-Z][^A-Z]*)/).find_all { |str| str != "" }.join("_").downcase
44
+ end
45
+ end
46
+ end
47
+
@@ -0,0 +1,15 @@
1
+ class Symbol
2
+ #
3
+ # Converts symbol to string and calls String#camel_case
4
+ #
5
+ def camel_case
6
+ self.to_s.camel_case
7
+ end
8
+
9
+ #
10
+ # Converts symbol to string and calls String#classify
11
+ #
12
+ def classify(mod = nil)
13
+ self.to_s.classify(mod)
14
+ end
15
+ end
@@ -0,0 +1,129 @@
1
+ require "juicer/chainable"
2
+ require "juicer/cache_buster"
3
+ require "juicer/asset/path_resolver"
4
+
5
+ module Juicer
6
+ #
7
+ # The ImageEmbed is a tool that can parse a CSS file and substitute all
8
+ # referenced URLs by a data uri
9
+ #
10
+ # - data uri (http://en.wikipedia.org/wiki/Data_URI_scheme)
11
+ #
12
+ # Only local resources will be processed this way, external resources referenced
13
+ # by absolute urls will be left alone
14
+ #
15
+ class ImageEmbed
16
+ include Juicer::Chainable
17
+
18
+ # The maximum supported limit for modern browsers, See the Readme.rdoc for details
19
+ SIZE_LIMIT = 32768
20
+
21
+ #
22
+ # Returns the size limit
23
+ #
24
+ def size_limit
25
+ SIZE_LIMIT
26
+ end
27
+
28
+ def initialize(options = {})
29
+ @document_root = options[:document_root]
30
+ @document_root.sub!(%r{/?$}, "") if @document_root # Remove trailing slash
31
+ @type = options[:type] || :none
32
+ @contents = nil
33
+ @hosts = options[:hosts]
34
+ @path_resolver = Juicer::Asset::PathResolver.new(:document_root => options[:document_root],
35
+ :hosts => options[:hosts])
36
+ end
37
+
38
+ #
39
+ # Update file. If no +output+ is provided, the input file is overwritten
40
+ #
41
+ def save(file, output = nil)
42
+ return unless @type == :data_uri
43
+
44
+ output_file = output || file
45
+ @contents = File.read(file)
46
+ used = []
47
+
48
+ @path_resolver = Juicer::Asset::PathResolver.new(:document_root => @document_root,
49
+ :hosts => @hosts,
50
+ :base => File.dirname(file))
51
+
52
+ assets = urls(file)
53
+
54
+ # TODO: Remove "?embed=true" from duplicate urls
55
+ duplicates = duplicate_urls(assets)
56
+
57
+ if duplicates.length > 0
58
+ Juicer::LOGGER.warn("Duplicate image urls detected, these images will not be embedded: #{duplicates.collect { |v| v.gsub('?embed=true', '') }.inspect}")
59
+ end
60
+
61
+ assets.each do |asset|
62
+ begin
63
+ next if used.include?(asset) || duplicates.include?(asset.path)
64
+ used << asset
65
+
66
+ # make sure we do not exceed SIZE_LIMIT
67
+ new_path = embed_data_uri(asset.filename)
68
+
69
+ if new_path.length < SIZE_LIMIT
70
+ # replace the url in the css file with the data uri
71
+ @contents.gsub!(asset.path, embed_data_uri(asset.path))
72
+ else
73
+ Juicer::LOGGER.warn("The final data uri for the image located at #{asset.path.gsub('?embed=true', '')} exceeds #{SIZE_LIMIT} and will not be embedded to maintain compatability.")
74
+ end
75
+ rescue Errno::ENOENT
76
+ puts "Unable to locate file #{asset.path}, skipping image embedding"
77
+ end
78
+ end
79
+
80
+ File.open(output || file, "w") { |f| f.puts @contents }
81
+ @contents = nil
82
+ end
83
+
84
+ chain_method :save
85
+
86
+ def embed_data_uri( path )
87
+ new_path = path
88
+
89
+ if path.match( /\?embed=true$/ )
90
+ supported_file_matches = path.match( /(?:\.)(png|gif|jpg|jpeg)(?:\?embed=true)$/i )
91
+ filetype = supported_file_matches[1] if supported_file_matches
92
+
93
+ if ( filetype )
94
+ filename = path.gsub('?embed=true','')
95
+
96
+ # check if file exists, throw an error if it doesn't exist
97
+ if File.exist?( filename )
98
+
99
+ # read contents of file into memory
100
+ content = File.read( filename )
101
+ content_type = "image/#{filetype}"
102
+
103
+ # encode the url
104
+ new_path = Datafy::make_data_uri( content, content_type )
105
+ else
106
+ puts "Unable to locate file #{filename} on local file system, skipping image embedding"
107
+ end
108
+ end
109
+ end
110
+ return new_path
111
+ end
112
+
113
+ #
114
+ # Returns all referenced URLs in +file+.
115
+ #
116
+ def urls(file)
117
+ @contents = File.read(file) unless @contents
118
+
119
+ @contents.scan(/url\([\s"']*([^\)"'\s]*)[\s"']*\)/m).collect do |match|
120
+ @path_resolver.resolve(match.first)
121
+ end
122
+ end
123
+
124
+ private
125
+ def duplicate_urls(urls)
126
+ urls.inject({}) { |h,v| h[v.path] = h[v.path].to_i+1; h }.reject{ |k,v| v == 1 }.keys
127
+ end
128
+ end
129
+ end
@@ -1,7 +1,7 @@
1
- require 'hpricot'
1
+ require 'nokogiri'
2
2
  require 'open-uri'
3
3
  require 'fileutils'
4
- require File.expand_path(File.join(File.dirname(__FILE__), %w[.. .. juicer])) unless defined?(Juicer)
4
+ require "juicer"
5
5
 
6
6
  module Juicer
7
7
  module Install
@@ -0,0 +1,69 @@
1
+ require "juicer"
2
+ require "juicer/install/base"
3
+ require "zip/zip"
4
+
5
+ module Juicer
6
+ module Install
7
+ #
8
+ # Install and uninstall routines for the Google Closure Compiler.
9
+ # Installation downloads the Closure Compiler distribution, unzips it and
10
+ # storesthe jar file on disk along with the README.
11
+ #
12
+ class ClosureCompilerInstaller < Base
13
+ def initialize(install_dir = Juicer.home)
14
+ super(install_dir)
15
+ @latest = nil
16
+ @website = "http://code.google.com/p/closure-compiler/downloads/list"
17
+ @download_link = "http://closure-compiler.googlecode.com/files/compiler-%s.zip"
18
+ end
19
+
20
+ #
21
+ # Install the Closure Compiler. Downloads the distribution and keeps the jar
22
+ # file inside PATH/closure_compiler/bin and the README in
23
+ # PATH/closere_compiler/yyyymmdd/ where yyyymmdd is the version, most recent if
24
+ # not specified otherwise.
25
+ #
26
+ # Path defaults to environment variable $JUICER_HOME or default Juicer
27
+ # home
28
+ #
29
+ def install(version = nil)
30
+ version = super(version)
31
+ base = "closure-compiler-#{version}"
32
+ filename = download(@download_link % version)
33
+ target = File.join(@install_dir, path)
34
+
35
+ Zip::ZipFile.open(filename) do |file|
36
+ file.extract("README", File.join(target, version, "README"))
37
+ file.extract("compiler.jar", File.join(target, "bin", "#{base}.jar"))
38
+ end
39
+ end
40
+
41
+ #
42
+ # Uninstalls the given version of Closure Compiler. If no location is
43
+ # provided the environment variable $JUICER_HOME or Juicers default home
44
+ # directory is used.
45
+ #
46
+ # If no version is provided the most recent version is assumed.
47
+ #
48
+ # If there are no more files left in INSTALLATION_PATH/closure_compiler, the
49
+ # whole directory is removed.
50
+ #
51
+ def uninstall(version = nil)
52
+ super(version) do |dir, version|
53
+ File.delete(File.join(dir, "bin/closure-compiler-#{version}.jar"))
54
+ end
55
+ end
56
+
57
+ #
58
+ # Check which version is the most recent
59
+ #
60
+ def latest
61
+ return @latest if @latest
62
+ webpage = Nokogiri::HTML(open(@website))
63
+ @latest = (webpage / "//table[@id='resultstable']//td/a[contains(@href, 'compiler')]").map{|link|
64
+ link.get_attribute('href')[/\d{8}/].to_i
65
+ }.sort.last.to_s
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,5 +1,5 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), %w[.. .. juicer])) unless defined?(Juicer)
2
- require File.expand_path(File.join(File.dirname(__FILE__), "base"))
1
+ require "juicer"
2
+ require "juicer/install/base"
3
3
  require "zip/zip"
4
4
 
5
5
  module Juicer
@@ -28,7 +28,7 @@ module Juicer
28
28
  def install(version = nil)
29
29
  version = super(version)
30
30
  filename = download(File.join(@website, "rhino/jslint.js"))
31
- File.copy(filename, File.join(@install_dir, path, "bin", "jslint-#{version}.js"))
31
+ FileUtils.copy(filename, File.join(@install_dir, path, "bin", "jslint-#{version}.js"))
32
32
  end
33
33
 
34
34
  #
@@ -1,4 +1,5 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), %w[.. .. juicer])) unless defined?(Juicer)
1
+ require "juicer"
2
+ require "juicer/install/base"
2
3
  require "zip/zip"
3
4
 
4
5
  module Juicer
@@ -12,7 +13,7 @@ module Juicer
12
13
  def initialize(install_dir = Juicer.home)
13
14
  super(install_dir)
14
15
  @latest = "1_7R2-RC1"
15
- @website = "ftp://ftp.mozilla.org/pub/mozilla.org/js/"
16
+ @website = "http://ftp.mozilla.org/pub/mozilla.org/js/"
16
17
  end
17
18
 
18
19
  #
@@ -1,4 +1,5 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), %w[.. .. juicer])) unless defined?(Juicer)
1
+ require "juicer"
2
+ require "juicer/install/base"
2
3
  require "zip/zip"
3
4
 
4
5
  module Juicer
@@ -58,7 +59,7 @@ module Juicer
58
59
  #
59
60
  def latest
60
61
  return @latest if @latest
61
- webpage = Hpricot(open(@website))
62
+ webpage = Nokogiri::HTML(open(@website))
62
63
  @latest = (webpage / "//h2[@id='yuicompressor']/../../../..//a")[0].get_attribute("href").match(/(\d\.\d\.\d)/)[1]
63
64
  end
64
65
  end
data/lib/juicer/jslint.rb CHANGED
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), "binary"))
1
+ require "juicer/binary"
2
2
 
3
3
  module Juicer
4
4
  #
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), "..", "chainable"))
1
+ require "juicer/chainable"
2
2
 
3
3
  # Merge several files into one single output file
4
4
  module Juicer
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
- ['base', 'javascript_dependency_resolver'].each do |lib|
3
- require File.expand_path(File.join(File.dirname(__FILE__), lib))
4
- end
2
+ require "juicer/merger/base"
3
+ require "juicer/dependency_resolver/javascript_dependency_resolver"
5
4
 
6
5
  module Juicer
7
6
  module Merger
@@ -22,7 +21,7 @@ end
22
21
  # or similar.
23
22
  #
24
23
  if $0 == __FILE__
25
- return puts("Usage: javascript_merger.rb file[...] output") if $*.length < 2
24
+ puts("Usage: javascript_merger.rb file[...] output") and exit if $*.length < 2
26
25
 
27
26
  fm = JavaScriptMerger.new()
28
27
  fm << $*[0..-2]
@@ -1,8 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
- ['base', 'css_dependency_resolver'].each do |lib|
3
- require File.expand_path(File.join(File.dirname(__FILE__), lib))
4
- end
5
-
2
+ require "juicer/merger/base"
3
+ require "juicer/dependency_resolver/css_dependency_resolver"
6
4
  require 'pathname'
7
5
 
8
6
  module Juicer
@@ -15,7 +13,7 @@ module Juicer
15
13
  # Constructor
16
14
  #
17
15
  # Options:
18
- # * <tt>:web_root</tt> - Path to web root if there is any @import statements
16
+ # * <tt>:document_root</tt> - Path to web root if there is any @import statements
19
17
  # using absolute URLs
20
18
  #
21
19
  def initialize(files = [], options = {})
@@ -25,8 +23,8 @@ module Juicer
25
23
  @host_num = 0
26
24
  @use_absolute = options.key?(:absolute_urls) ? options[:absolute_urls] : false
27
25
  @use_relative = options.key?(:relative_urls) ? options[:relative_urls] : false
28
- @web_root = options[:web_root]
29
- @web_root = File.expand_path(@web_root).sub(/\/?$/, "") if @web_root # Make sure path doesn't end in a /
26
+ @document_root = options[:document_root]
27
+ @document_root = File.expand_path(@document_root).sub(/\/?$/, "") if @document_root # Make sure path doesn't end in a /
30
28
  end
31
29
 
32
30
  private
@@ -42,10 +40,10 @@ module Juicer
42
40
  # The options hash decides how Juicer recalculates referenced URLs:
43
41
  #
44
42
  # options[:absolute_urls] When true, all paths are converted to absolute
45
- # URLs. Requires options[:web_root] to define
43
+ # URLs. Requires options[:document_root] to define
46
44
  # root directory to resolve absolute URLs from.
47
45
  # options[:relative_urls] When true, all paths are converted to relative
48
- # paths. Requires options[:web_root] to define
46
+ # paths. Requires options[:document_root] to define
49
47
  # root directory to resolve absolute URLs from.
50
48
  #
51
49
  # If none if these are set then relative URLs are recalculated to match
@@ -55,7 +53,7 @@ module Juicer
55
53
  # for all absolute URLs regardless of absolute/relative URL strategy.
56
54
  #
57
55
  def merge(file)
58
- content = super.gsub(/^\s*\@import\s("|')(.*)("|')\;?/, '')
56
+ content = super.gsub(/^\s*@import(?:\surl\(|\s)(['"]?)([^\?'"\)\s]+)(\?(?:[^'"\)]+)?)?\1\)?(?:[^?;]+)?;?/i, "")
59
57
  dir = File.expand_path(File.dirname(file))
60
58
 
61
59
  content.scan(/url\([\s"']*([^\)"'\s]*)[\s"']*\)/m).uniq.collect do |url|
@@ -75,15 +73,15 @@ module Juicer
75
73
 
76
74
  # Absolute URLs
77
75
  if url =~ %r{^/} && @use_relative
78
- raise ArgumentError.new("Unable to handle absolute URLs without :web_root option") if !@web_root
79
- path = Pathname.new(File.join(@web_root, url)).relative_path_from(@root).to_s
76
+ raise ArgumentError.new("Unable to handle absolute URLs without :document_root option") if !@document_root
77
+ path = Pathname.new(File.join(@document_root, url)).relative_path_from(@root).to_s
80
78
  end
81
79
 
82
80
  # All URLs that don't start with a protocol
83
81
  if url !~ %r{^/} && url !~ %r{^[a-z]+://}
84
82
  if @use_absolute
85
- raise ArgumentError.new("Unable to handle absolute URLs without :web_root option") if !@web_root
86
- path = File.expand_path(File.join(dir, url)).sub(@web_root, "") # Make absolute
83
+ raise ArgumentError.new("Unable to handle absolute URLs without :document_root option") if !@document_root
84
+ path = File.expand_path(File.join(dir, url)).sub(@document_root, "") # Make absolute
87
85
  else
88
86
  path = Pathname.new(File.join(dir, url)).relative_path_from(@root).to_s # ...or redefine relative ref
89
87
  end
@@ -104,7 +102,7 @@ end
104
102
  # Run file from command line
105
103
  #
106
104
  if $0 == __FILE__
107
- return puts("Usage: stylesheet_merger.rb file[...] output") if $*.length < 2
105
+ puts("Usage: stylesheet_merger.rb file[...] output") and exit if $*.length < 2
108
106
 
109
107
  fm = Juicer::Merger::StylesheetMerger.new()
110
108
  fm << $*[0..-2]