class DynamicAssets::Reference

Attributes

name[RW]

Public Class Methods

new(attrs = {}) click to toggle source
# File lib/dynamic_assets/reference.rb, line 21
def initialize(attrs = {})
  @name = attrs[:name]
  @member_names = attrs[:member_names]
end
new_for_type(type, attrs = {}) click to toggle source

Class Methods

# File lib/dynamic_assets/reference.rb, line 13
def self.new_for_type(type, attrs = {})
  case type
  when :stylesheets then StylesheetReference
  when :javascripts then JavascriptReference
  else raise "unknown type: #{type}"
  end.new attrs
end

Public Instance Methods

content(context, for_signature = false) click to toggle source
# File lib/dynamic_assets/reference.rb, line 54
def content(context, for_signature = false)
  @context = context
  s = combine_content for_signature
  s = minify s if DynamicAssets::Manager.minify? && !for_signature
  s
end
formats() click to toggle source

Instance Methods

# File lib/dynamic_assets/reference.rb, line 31
def formats
  raise "subclasses of #{self.class} should implement this method to return an array of formats"
end
member_names() click to toggle source
# File lib/dynamic_assets/reference.rb, line 39
def member_names
  @member_names ||= [name]
end
member_names=(some_names) click to toggle source
# File lib/dynamic_assets/reference.rb, line 35
def member_names=(some_names)
  @member_names = some_names
end
member_root() click to toggle source
# File lib/dynamic_assets/reference.rb, line 47
def member_root
  return @member_root if @member_root

  possible_roots = ["#{Rails.root}/app/assets/#{type.to_s}", "#{Rails.root}/app/views/#{type.to_s}"]
  @member_root = File.find_existing(possible_roots) || possible_roots.first
end
minify(content_string) click to toggle source
# File lib/dynamic_assets/reference.rb, line 72
def minify(content_string)
  raise "subclasses of #{self.class} should implement this method"
end
paths() click to toggle source
# File lib/dynamic_assets/reference.rb, line 43
def paths
  member_names.map { |member_name| path_for_member_name member_name }
end
signature(context) click to toggle source
# File lib/dynamic_assets/reference.rb, line 61
def signature(context)
  # Note that the signature is based on the context at the time the
  # asset helper is called, which is different from the context at
  # the time of asset rendering.
  #
  # To force a change in signature, set or update the ASSET_VERSION
  # config variable.

  (ENV['ASSET_VERSION'] || "") + Digest::SHA1.hexdigest(content(context, true))
end

Protected Instance Methods

combine_content(for_signature) click to toggle source
# File lib/dynamic_assets/reference.rb, line 107
def combine_content(for_signature)
  member_names.map do |member_name|
    read_member member_name, for_signature
  end.join "\n"
end
format_for_member_name(name) click to toggle source
# File lib/dynamic_assets/reference.rb, line 92
def format_for_member_name(name)
  format_for_path path_for_member_name(name)
end
format_for_path(path) click to toggle source
# File lib/dynamic_assets/reference.rb, line 96
def format_for_path(path)
  ext = File.extname path
  ext = File.extname(File.basename path, ext) if ext == ".erb"

  ext[1..-1].to_sym   # Remove the dot, symbolize
end
get_raw_content(path) click to toggle source
# File lib/dynamic_assets/reference.rb, line 134
def get_raw_content(path)
  File.open(path, "r") { |f| f.read }
end
parse_erb_error(error, path, content_string) click to toggle source
# File lib/dynamic_assets/reference.rb, line 138
def parse_erb_error(error, path, content_string)
  # Exception parsing inspired by HelpfulERB

  trace_index = error.backtrace.find_index { |trace_line| trace_line =~ /^.erubis:(\d+):in / }
  return nil unless trace_index

  line_number = $1.to_i
  lines = content_string.split /\n/

  min = [line_number - 5, 0].max
  max = [line_number + 1, lines.length].min

  width = max.to_s.size

  message = "Error in ERB '#{path}' at line #{line_number}:\n\n" +
    (min..max).map do |i|
      n = i + 1
      marker = n == line_number ? "*" : ""
      "%2s %#{width}i %s" % [marker, n, lines[i]]
    end.join("\n") +
    "\n\n#{error.class}: #{error.message}" +
    (trace_index > 0 ? "\n\nEncountered here:\n#{error.backtrace[0..trace_index-1].join "\n"}" : "")
end
path_for_member_name(member_name) click to toggle source
# File lib/dynamic_assets/reference.rb, line 79
def path_for_member_name(member_name)
  formats.each do |format|
    path = "#{member_root}/#{member_name}.#{format}"
    return path if raw_content_exists? path

    path = "#{member_root}/#{member_name}.#{format}.erb"
    return path if raw_content_exists? path
  end

  raise "Couldn't find #{type} asset named #{member_name} in #{member_root} with " +
    "one of these formats: #{formats.join ','}"
end
path_is_erb?(path) click to toggle source
# File lib/dynamic_assets/reference.rb, line 103
def path_is_erb?(path)
  File.extname(path) == ".erb"
end
raw_content_exists?(path) click to toggle source
# File lib/dynamic_assets/reference.rb, line 130
def raw_content_exists?(path)
  File.exists? path
end
read_member(member_name, for_signature) click to toggle source
# File lib/dynamic_assets/reference.rb, line 113
def read_member(member_name, for_signature)
  path = path_for_member_name member_name
  content_string = get_raw_content path

  if path_is_erb?(path)
    raise "ERB requires a context" unless @context
    begin
      content_string = Erubis::Eruby.new(content_string).result @context
    rescue StandardError => e
      raise e.exception(parse_erb_error(e, path, content_string) ||
        "Error in ERB #{path}, unknown line number: #{e}")
    end
  end

  content_string
end