class Condenser::Context

They are typically accessed by ERB templates. You can mix in custom helpers by injecting them into `Environment#context_class`. Do not mix them into `Context` directly.

environment.context_class.class_eval do
  include MyHelper
  def asset_url; end
end

<%= asset_url "foo.png" %>

The `Context` also collects dependencies declared by assets. See `DirectiveProcessor` for an example of this.

Attributes

content_type[R]

Returns content type of file

'application/javascript'
'text/css'
environment[R]
filename[R]
load_path[R]

Returns the environment path that contains the file.

If `app/javascripts` and `app/stylesheets` are in your path, and current file is `app/javascripts/foo/bar.js`, `load_path` would return `app/javascripts`.

logical_path[R]

Returns logical path without any file extensions.

'app/javascripts/application.js'
# => 'application'
root_path[R]

Returns the environment path that contains the file.

If `app/javascripts` and `app/stylesheets` are in your path, and current file is `app/javascripts/foo/bar.js`, `load_path` would return `app/javascripts`.

Public Class Methods

new(environment) click to toggle source
# File lib/condenser/context.rb, line 40
def initialize(environment)
  @environment  = environment
  @dependencies = Set.new
  @links = Set.new
end

Public Instance Methods

asset_data_uri(path) click to toggle source

Returns a `data:` URI with the contents of the asset at the specified path, and marks that path as a dependency of the current file.

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

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

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

$('<img>').attr('src', '<%= asset_data_uri 'avatar.jpg' %>')
# File lib/condenser/context.rb, line 169
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
asset_path(path, options = {}) click to toggle source

Expands logical path to full url to asset.

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

# File lib/condenser/context.rb, line 184
    def asset_path(path, options = {})
      message = <<-EOS
Custom asset_path helper is not implemented

Extend your environment context with a custom method.

    environment.context_class.class_eval do
      def asset_path(path, options = {})
      end
    end
      EOS
      raise LoadError, message # Rack does not catch NotImplementedError
    end
audio_path(path) click to toggle source

Expand logical audio asset path.

# File lib/condenser/context.rb, line 209
def audio_path(path)
  asset_path(path, type: :audio)
end
depend_on(path) click to toggle source

`depend_on` allows you to state a dependency on a file without including it.

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

# File lib/condenser/context.rb, line 116
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
depend_on_asset(path) click to toggle source

`depend_on_asset` allows you to state an asset dependency without including it.

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

# File lib/condenser/context.rb, line 132
def depend_on_asset(path)
  asset = environment.find!(path)
  @dependencies << asset.source_file
  asset
end
depend_on_env(key) click to toggle source

`depend_on_env` allows you to state a dependency on an environment variable.

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

# File lib/condenser/context.rb, line 143
def depend_on_env(key)
  @dependencies << "env:#{key}"
end
env_proxy() click to toggle source
# File lib/condenser/context.rb, line 53
def env_proxy
  ENVProxy.new(self)
end
font_path(path) click to toggle source

Expand logical font asset path.

# File lib/condenser/context.rb, line 214
def font_path(path)
  asset_path(path, type: :font)
end
image_path(path) click to toggle source

Expand logical image asset path.

# File lib/condenser/context.rb, line 199
def image_path(path)
  asset_path(path, type: :image)
end
javascript_path(path) click to toggle source

Expand logical javascript asset path.

# File lib/condenser/context.rb, line 219
def javascript_path(path)
  asset_path(path, type: :javascript)
end
load(uri) click to toggle source

Public: Load Asset by AssetURI and track it as a dependency.

uri - AssetURI

Returns Asset.

# File lib/condenser/context.rb, line 104
def load(uri)
  asset = environment.load(uri)
  @dependencies.merge(asset.metadata[:dependencies])
  asset
end
metadata() click to toggle source
# File lib/condenser/context.rb, line 46
def metadata
  {
    links: @links,
    dependencies: @dependencies
  }
end
resolve(path, **kargs) click to toggle source

Public: Given a logical path, `resolve` will find and return an Asset URI. Relative paths will also be resolved. An accept type maybe given to restrict the search.

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

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

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

Returns an Asset URI String.

# File lib/condenser/context.rb, line 93
def resolve(path, **kargs)
  uri, deps = environment.resolve!(path, @dirname, **kargs)
  @dependencies.merge(deps)
  uri
end
stylesheet_path(path) click to toggle source

Expand logical stylesheet asset path.

# File lib/condenser/context.rb, line 224
def stylesheet_path(path)
  asset_path(path, type: :stylesheet)
end
video_path(path) click to toggle source

Expand logical video asset path.

# File lib/condenser/context.rb, line 204
def video_path(path)
  asset_path(path, type: :video)
end

Protected Instance Methods

base64_asset_data_uri(asset) click to toggle source

Returns a Base64-encoded data URI.

# File lib/condenser/context.rb, line 240
def base64_asset_data_uri(asset)
  data = URI.encode_www_form_component(EncodingUtils.base64(asset.source))
  "data:#{asset.content_type};base64,#{data}"
end
optimize_quoted_uri_escapes!(escaped) click to toggle source

Un-escapes characters in the given URI-escaped string that do not need escaping in “-quoted data URIs.

# File lib/condenser/context.rb, line 265
def optimize_quoted_uri_escapes!(escaped)
  escaped.gsub!('%3D', '=')
  escaped.gsub!('%3A', ':')
  escaped.gsub!('%2F', '/')
  escaped.gsub!('%27', "'")
  escaped.tr!('+', ' ')
end
optimize_svg_for_uri_escaping!(svg) click to toggle source

Optimizes an SVG for being URI-escaped.

This method only performs these basic but crucial optimizations:

  • Replaces “ with ', because ' does not need escaping.

  • Removes comments, meta, doctype, and newlines.

  • Collapses whitespace.

# File lib/condenser/context.rb, line 251
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
svg_asset_data_uri(asset) click to toggle source

Returns a URI-encoded data URI (always “-quoted).

# File lib/condenser/context.rb, line 231
def svg_asset_data_uri(asset)
  svg = asset.source.dup
  optimize_svg_for_uri_escaping!(svg)
  data = URI.encode_www_form_component(svg)
  optimize_quoted_uri_escapes!(data)
  "\"data:#{asset.content_type};charset=utf-8,#{data}\""
end