Class: AssetsBooster::Merger::CSS

Inherits:
Base
  • Object
show all
Defined in:
lib/assets_booster/merger/css.rb

Instance Attribute Summary

Attributes inherited from Base

#assets

Instance Method Summary collapse

Methods inherited from Base

#initialize, #mtime

Constructor Details

This class inherits a constructor from AssetsBooster::Merger::Base

Instance Method Details

#absolute_url?(url) ⇒ Boolean

Returns:

  • (Boolean)


73
74
75
# File 'lib/assets_booster/merger/css.rb', line 73

def absolute_url?(url)
  !!(url =~ /^(\/|https?:\/\/)/i)
end

#dirname(path) ⇒ Object



77
78
79
# File 'lib/assets_booster/merger/css.rb', line 77

def dirname(path)
  path.include?("/") ? File.dirname(path) : ""
end

#load_source(source) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/assets_booster/merger/css.rb', line 36

def load_source(source)
  super(source)
  asset = assets.pop
  source_folder = dirname(asset[:source])
  source_folder << "/" unless source_folder == ""
  asset[:css].gsub!(/@import\s+([^;\n]+)[;\n]*/).each do |import|
    url = $1.gsub(/^url\((.+)\)/i, '\1')
    url, quotes = unquote(url.strip)
    
    # we don't want to statically import external stylesheets
    next import if absolute_url?(url)

    # recursively process the imported css
    load_source(source_folder+url)
    ""
  end
  assets << asset
end

#merge(target) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/assets_booster/merger/css.rb', line 9

def merge(target)
  target_folder = dirname(target)
  code = assets.inject("") do |code, asset|
    source_folder = dirname(asset[:source])
    asset[:css]= rewrite_urls(asset[:css], source_folder, target_folder)
    code << asset[:css]
    code << "\n"
  end.strip
  
  charset = nil
  code.gsub!(/@charset\s+([^;\n]+)[;\n]*/).each do
    current_charset, quotes = unquote($1)
    current_charset.downcase!
    if charset && charset != current_charset
      raise ArgumentError, "source files have conflicting charsets (#{charset} != #{current_charset})"
    end
    charset = current_charset
    ""
  end
  
  if charset
    code = "@charset \"#{charset}\";\n"+code
  end

  code
end

#nameObject



5
6
7
# File 'lib/assets_booster/merger/css.rb', line 5

def name
  "CSS Merger"
end

#path_difference(source, target) ⇒ Object



81
82
83
84
85
86
87
# File 'lib/assets_booster/merger/css.rb', line 81

def path_difference(source, target)
  return source if target == ""
  if source[0..target.length-1] != target
    raise ArgumentError, "source and target to not share a common base path [#{source}, #{target}]"
  end
  source[target.length+1..-1] || ""
end

#rewrite_urls(css, source_folder, target_folder) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/assets_booster/merger/css.rb', line 55

def rewrite_urls(css, source_folder, target_folder)
  url_prepend = path_difference(source_folder, target_folder)
  return css if url_prepend == ""
  
  css.gsub(/url\(([^)]+)\)/i) do |match|
    url, quotes = unquote($1.strip)

    # we don't want to change references to external assets
    next match if absolute_url?(url) 

    "url(#{quotes}#{url_prepend}/#{url}#{quotes})"
  end
end

#unquote(quoted) ⇒ Object



69
70
71
# File 'lib/assets_booster/merger/css.rb', line 69

def unquote(quoted)
  (quoted[0].chr =~ /["']/) ? [quoted.slice(1, quoted.length-2), quoted[0].chr] : [quoted, ""]
end