Class: Roda::OpalAssets

Inherits:
Object
  • Object
show all
Defined in:
lib/roda/opal_assets.rb,
lib/roda/opal_assets/version.rb

Constant Summary collapse

VERSION =
"0.3.7"

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ OpalAssets

Returns a new instance of OpalAssets.



11
12
13
14
15
16
17
18
19
# File 'lib/roda/opal_assets.rb', line 11

def initialize options={}
  @env = options.fetch(:env) { ENV.fetch('RACK_ENV') { 'development' } }.to_sym
  @minify = options.fetch(:minify) { production? }
  @assets = []
  @file_cache = {}

  sprockets
  source_maps
end

Instance Method Details

#<<(asset) ⇒ Object



99
100
101
# File 'lib/roda/opal_assets.rb', line 99

def << asset
  @assets << asset
end

#buildObject



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/roda/opal_assets.rb', line 103

def build
  FileUtils.mkdir_p 'public/assets'

  @manifest = @assets.each_with_object({}) do |file, hash|
    print "Compiling #{file}..."
    asset = sprockets[file]
    hash[file] = asset.digest_path
    filename = "public/assets/#{asset.digest_path}"
    FileUtils.mkdir_p File.dirname(filename)
    compile_file file, filename
    puts ' done'
  end

  File.write 'assets.yml', YAML.dump(manifest)
end

#compile(file) ⇒ Object



126
127
128
# File 'lib/roda/opal_assets.rb', line 126

def compile file
  sprockets[file].to_s
end

#compile_file(file, output_filename) ⇒ Object



119
120
121
122
123
124
# File 'lib/roda/opal_assets.rb', line 119

def compile_file file, output_filename
  compiled = sprockets[file].to_s + opal_boot_code(file)

  File.write output_filename, compiled
  nil
end

#image(file, **attrs) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/roda/opal_assets.rb', line 79

def image file, **attrs
  path = if production?
           "/assets/#{manifest[file]}"
         else
           asset = sprockets[file]

           if asset.nil?
             raise "File not found: #{file}"
           end

           "/assets/images/#{asset.digest_path}"
         end

  attrs = attrs.each_with_object('') do |(key, value), string|
    string << " #{key}=#{value}"
  end

  %{<img src="#{path}"#{attrs}/>}
end

#js(file, prefix = nil) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/roda/opal_assets.rb', line 41

def js file, prefix=nil
  file << '.js' unless file.end_with? '.js'
  scripts = ''

  if production?
    scripts << %{<script src="#{prefix}/assets/#{manifest[file]}"></script>\n}
  else
    asset = sprockets[file]

    asset.to_a.each { |dependency|
      scripts << %{<script src="#{prefix}/assets/js/#{dependency.digest_path}?body=1"></script>\n}
    }

    scripts << %{<script>#{opal_boot_code file}</script>}
  end

  scripts
end

#manifestObject



175
176
177
178
179
180
181
182
183
184
# File 'lib/roda/opal_assets.rb', line 175

def manifest
  return @manifest if defined? @manifest

  @manifest = YAML.load_file 'assets.yml'
  unless @manifest
    warn 'Assets manifest is broken'
  end

  @manifest
end

#min_opal_version?(version) ⇒ Boolean

Check for minimum Opal version, but do it in a weird way because Array implements <=> but doesn’t include Comparable

Returns:

  • (Boolean)


206
207
208
# File 'lib/roda/opal_assets.rb', line 206

def min_opal_version? version
  (Opal::VERSION.split('.').map(&:to_i) <=> version.split('.').map(&:to_i)) >= 0
end

#opal_boot_code(file) ⇒ Object



190
191
192
193
194
195
196
197
198
# File 'lib/roda/opal_assets.rb', line 190

def opal_boot_code file
  if min_opal_version? '0.9.0'
    Opal::Sprockets.load_asset(file, sprockets)
  elsif min_opal_version? '0.8.0'
    Opal::Processor.load_asset_code(sprockets, file)
  else
    ''
  end
end

#production?Boolean

Returns:

  • (Boolean)


186
187
188
# File 'lib/roda/opal_assets.rb', line 186

def production?
  @env == :production
end

#route(r) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/roda/opal_assets.rb', line 21

def route r
  unless production?
    r.on source_map_prefix[1..-1] do
      r.run source_maps
    end
    r.on 'assets/js' do
      r.run sprockets
    end
    r.on 'assets/css' do
      r.run sprockets
    end
    r.on 'assets/images' do
      r.run sprockets
    end
    r.on 'assets' do
      r.run sprockets
    end
  end
end

#source_map_prefixObject



147
148
149
# File 'lib/roda/opal_assets.rb', line 147

def source_map_prefix
  '/__OPAL_SOURCE_MAPS__' 
end

#source_mapsObject



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/roda/opal_assets.rb', line 151

def source_maps
  return @source_maps if defined? @source_maps

  source_map_handler = if supports_opal_config?
                         Opal::Config
                       else
                         Opal::Processor
                       end

  source_map_handler.source_map_enabled = !production? && min_opal_version?('0.8.0')

  source_maps = Opal::SourceMapServer.new(sprockets, source_map_prefix)
  if !production? && min_opal_version?('0.8.0')
    ::Opal::Sprockets::SourceMapHeaderPatch.inject!(source_map_prefix)
  end

  @source_maps = Rack::Builder.new do
    use Rack::ConditionalGet
    use Rack::ETag

    run source_maps
  end
end

#sprocketsObject



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/roda/opal_assets.rb', line 130

def sprockets
  return @sprockets if defined? @sprockets

  sprockets = Sprockets::Environment.new
  Opal.paths.each do |path|
    sprockets.append_path path
  end
  sprockets.append_path 'assets/js'
  sprockets.append_path 'assets/css'
  sprockets.append_path 'assets/images'
  sprockets.append_path 'assets'

  sprockets.js_compressor = :uglifier if @minify

  @sprockets = sprockets
end

#stylesheet(file, media: :all) ⇒ Object Also known as: css



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/roda/opal_assets.rb', line 60

def stylesheet file, media: :all
  file << '.css' unless file.end_with? '.css'

  path = if production?
           "/assets/#{manifest[file]}"
         else
           asset = sprockets[file]

           if asset.nil?
             raise "File not found: #{file}"
           end

           "/assets/css/#{asset.digest_path}?body=1"
         end

  %{<link href="#{path}" media="#{media}" rel="stylesheet" />}
end

#supports_opal_config?Boolean

Returns:

  • (Boolean)


200
201
202
# File 'lib/roda/opal_assets.rb', line 200

def supports_opal_config?
  min_opal_version? '0.8.0'
end