class Sprockets::Context

assets. See ‘DirectiveProcessor` for an example of this.
The `Context` also collects dependencies declared by
<%= asset_url “foo.png” %>
end
def asset_url; end
include MyHelper
environment.context_class.class_eval do
`Context` directly.
by injecting them into `Environment#context_class`. Do not mix them into
They are typically accessed by ERB templates. You can mix in custom helpers

def asset_data_uri(path)


$('').attr('src', '<%= asset_data_uri 'avatar.jpg' %>')

#logo { background: url(<%= asset_data_uri 'logo.png' %>) }

Use `asset_data_uri` from ERB with CSS or JavaScript assets:

Uses URI encoding for SVG files, base64 encoding for all the other files.

path, and marks that path as a dependency of the current file.
Returns a `data:` URI with the contents of the asset at the specified
def asset_data_uri(path)
  asset = depend_on_asset(path)
  if asset.content_type == 'image/svg+xml'
    svg_asset_data_uri(asset)
  else
    base64_asset_data_uri(asset)
  end
end

def asset_path(path, options = {})

are required to be overridden.
basic implementation may be provided with different methods that
customized by the application. Though, in the future, some
NOTE: This helper is currently not implemented and should be

Expands logical path to full url to asset.
def asset_path(path, options = {})
  message = <<-EOS
om asset_path helper is not implemented
nd your environment context with a custom method.
environment.context_class.class_eval do
  def asset_path(path, options = {})
  end
end
  EOS
  raise NotImplementedError, message
end

def audio_path(path)

Expand logical audio asset path.
def audio_path(path)
  asset_path(path, type: :audio)
end

def base64_asset_data_uri(asset)

Returns a Base64-encoded data URI.
def base64_asset_data_uri(asset)
  data = Rack::Utils.escape(EncodingUtils.base64(asset.source))
  "data:#{asset.content_type};base64,#{data}"
end

def depend_on(path)

source file.
the dependency file will invalidate the cache of the
This is used for caching purposes. Any changes made to

including it.
`depend_on` allows you to state a dependency on a file without
def depend_on(path)
  if environment.absolute_path?(path) && environment.stat(path)
    @dependencies << environment.build_file_digest_uri(path)
  else
    resolve(path)
  end
  nil
end

def depend_on_asset(path)

the target asset's dependencies.
file. Unlike `depend_on`, this will recursively include
invalidate the dependency asset will invalidate the source
This is used for caching purposes. Any changes that would

without including it.
`depend_on_asset` allows you to state an asset dependency
def depend_on_asset(path)
  load(resolve(path))
end

def depend_on_env(key)

environment variable will invalidate the cache of the source file.
This is used for caching purposes. Any changes in the value of the

variable.
`depend_on_env` allows you to state a dependency on an environment
def depend_on_env(key)
  @dependencies << "env:#{key}"
end

def env_proxy

def env_proxy
  ENVProxy.new(self)
end

def font_path(path)

Expand logical font asset path.
def font_path(path)
  asset_path(path, type: :font)
end

def image_path(path)

Expand logical image asset path.
def image_path(path)
  asset_path(path, type: :image)
end

def initialize(input)

def initialize(input)
  @environment  = input[:environment]
  @metadata     = input[:metadata]
  @load_path    = input[:load_path]
  @logical_path = input[:name]
  @filename     = input[:filename]
  @dirname      = File.dirname(@filename)
  @content_type = input[:content_type]
  @required     = Set.new(@metadata[:required])
  @stubbed      = Set.new(@metadata[:stubbed])
  @links        = Set.new(@metadata[:links])
  @dependencies = Set.new(input[:metadata][:dependencies])
end

def javascript_path(path)

Expand logical javascript asset path.
def javascript_path(path)
  asset_path(path, type: :javascript)
end

def link_asset(path)

Returns an Asset or nil.

easy to construct a link to it.
including it. The target asset is returned from this function making it
`link_asset` declares an external dependency on an asset without directly
def link_asset(path)
  asset = depend_on_asset(path)
  @links << asset.uri
  asset
end

def load(uri)

Returns Asset.

uri - AssetURI

Public: Load Asset by AssetURI and track it as a dependency.
def load(uri)
  asset = environment.load(uri)
  @dependencies.merge(asset.metadata[:dependencies])
  asset
end

def metadata

def metadata
  { required: @required,
    stubbed: @stubbed,
    links: @links,
    dependencies: @dependencies }
end

def optimize_quoted_uri_escapes!(escaped)

escaping in "-quoted data URIs.
Un-escapes characters in the given URI-escaped string that do not need
def optimize_quoted_uri_escapes!(escaped)
  escaped.gsub!('%3D', '=')
  escaped.gsub!('%3A', ':')
  escaped.gsub!('%2F', '/')
  escaped.gsub!('%27', "'")
  escaped.tr!('+', ' ')
end

def optimize_svg_for_uri_escaping!(svg)

* Collapses whitespace.
* Removes comments, meta, doctype, and newlines.
* Replaces " with ', because ' does not need escaping.
This method only performs these basic but crucial optimizations:

Optimizes an SVG for being URI-escaped.
def optimize_svg_for_uri_escaping!(svg)
  # Remove comments, xml meta, and doctype
  svg.gsub!(/<!--.*?-->|<\?.*?\?>|<!.*?>/m, '')
  # Replace consecutive whitespace and newlines with a space
  svg.gsub!(/\s+/, ' ')
  # Collapse inter-tag whitespace
  svg.gsub!('> <', '><')
  # Replace " with '
  svg.gsub!(/([\w:])="(.*?)"/, "\\1='\\2'")
  svg.strip!
end

def require_asset(path)


<%= require_asset "#{framework}.js" %>

require assets.
If ERB processing is enabled, you can use it to dynamically

included once.
dependency will be inserted before the file and will only be
`require_asset` declares `path` as a dependency of the file. The
def require_asset(path)
  @required << resolve(path, accept: @content_type, pipeline: :self)
  nil
end

def resolve(path, **kargs)

Returns an Asset URI String.

accept - String content accept type
path - String logical or absolute path

# => "file:///path/to/app/javascripts/bar.js?type=application/javascript"
resolve("./bar.js")

# => "file:///path/to/app/javascripts/foo.js?type=application/javascript"
resolve("foo.js")

restrict the search.
Relative paths will also be resolved. An accept type maybe given to
Public: Given a logical path, `resolve` will find and return an Asset URI.
def resolve(path, **kargs)
  kargs[:base_path] = @dirname
  uri, deps = environment.resolve!(path, **kargs)
  @dependencies.merge(deps)
  uri
end

def stub_asset(path)

in the bundle.
`path` must be an asset which may or may not already be included
`stub_asset` blacklists `path` from being included in the bundle.
def stub_asset(path)
  @stubbed << resolve(path, accept: @content_type, pipeline: :self)
  nil
end

def stylesheet_path(path)

Expand logical stylesheet asset path.
def stylesheet_path(path)
  asset_path(path, type: :stylesheet)
end

def svg_asset_data_uri(asset)

Returns a URI-encoded data URI (always "-quoted).
def svg_asset_data_uri(asset)
  svg = asset.source.dup
  optimize_svg_for_uri_escaping!(svg)
  data = Rack::Utils.escape(svg)
  optimize_quoted_uri_escapes!(data)
  "\"data:#{asset.content_type};charset=utf-8,#{data}\""
end

def video_path(path)

Expand logical video asset path.
def video_path(path)
  asset_path(path, type: :video)
end