require'pathname'require'rack/utils'require'set'require'sprockets/errors'moduleSprockets# Deprecated: `Context` provides helper methods to all `Template` processors.# 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.classContextattr_reader:environment,:filename,:pathname# Deprecatedattr_accessor:__LINE__definitialize(input)@environment=input[:environment]@metadata=input[:metadata]@load_path=input[:load_path]@logical_path=input[:name]@filename=input[:filename]@dirname=File.dirname(@filename)@pathname=Pathname.new(@filename)@content_type=input[:content_type]@required=Set.new(@metadata[:required])@stubbed=Set.new(@metadata[:stubbed])@links=Set.new(@metadata[:links])@dependency_paths=Set.new(@metadata[:dependency_paths])enddefmetadata{required: @required,stubbed: @stubbed,links: @links,dependency_paths: @dependency_paths}end# 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`.attr_reader:load_pathalias_method:root_path,:load_path# Returns logical path without any file extensions.## 'app/javascripts/application.js'# # => 'application'#attr_reader:logical_path# Returns content type of file## 'application/javascript'# 'text/css'#attr_reader:content_type# Internal# TODO: Cleanup relative resolver logic shared between directive processor.def_resolve(method,path,options={})options[:content_type]=self.content_typeifoptions[:content_type]==:selfoptions[:accept]=options.delete(:content_type)ifenvironment.absolute_path?(path)filename=pathelsifenvironment.relative_path?(path)path=File.expand_path(path,@dirname)iflogical_path=@environment.split_subpath(load_path,path)iffilename=environment.send(method,logical_path,options.merge(load_paths: [load_path]))accept=options[:accept]message="couldn't find file '#{logical_path}' under '#{load_path}'"message<<" with type '#{accept}'"ifacceptraiseFileNotFound,messageendelseraiseFileOutsidePaths,"#{path} isn't under path: #{load_path}"endelsefilename=environment.send(method,path,options)endiffilenamefilenameelseaccept=options[:accept]message="couldn't find file '#{path}'"message<<" with type '#{accept}'"ifacceptraiseFileNotFound,messageendend# Given a logical path, `resolve` will find and return the fully# expanded path. Relative paths will also be resolved. An optional# `:content_type` restriction can be supplied to restrict the# search.## resolve("foo.js")# # => "/path/to/app/javascripts/foo.js"## resolve("./bar.js")# # => "/path/to/app/javascripts/bar.js"#defresolve(path,options={})_resolve(:resolve,path,options)enddeflocate(path,options={})ifAssetURI.valid?(path)pathelse_resolve(:locate,path,options)endend# `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 with invalidate the cache of the# source file.defdepend_on(path)@dependency_paths<<resolve(path).to_snilend# `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 include recursively include# the target asset's dependencies.defdepend_on_asset(path)ifasset=@environment.load(locate(path))@dependency_paths.merge(asset.metadata[:dependency_paths])endnilend# `require_asset` declares `path` as a dependency of the file. The# dependency will be inserted before the file and will only be# included once.## If ERB processing is enabled, you can use it to dynamically# require assets.## <%= require_asset "#{framework}.js" %>#defrequire_asset(path)@required<<locate(path,accept: @content_type,bundle: false)nilend# `stub_asset` blacklists `path` from being included in the bundle.# `path` must be an asset which may or may not already be included# in the bundle.defstub_asset(path)@stubbed<<locate(path,accept: @content_type,bundle: false)nilend# `link_asset` declares an external dependency on an asset without directly# including it. The target asset is returned from this function making it# easy to construct a link to it.## Returns an Asset or nil.deflink_asset(path)ifasset=@environment.load(locate(path))@dependency_paths.merge(asset.metadata[:dependency_paths])@links<<asset.uriendassetend# Returns a Base64-encoded `data:` URI with the contents of the# asset at the specified path, and marks that path as a dependency# of the current file.## 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' %>')#defasset_data_uri(path)depend_on_asset(path)asset=environment.find_asset(path,accept_encoding: 'base64')"data:#{asset.content_type};base64,#{Rack::Utils.escape(asset.to_s)}"end# 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.defasset_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
EOSraiseNotImplementedError,messageend# Expand logical image asset path.defimage_path(path)asset_path(path,type: :image)end# Expand logical video asset path.defvideo_path(path)asset_path(path,type: :video)end# Expand logical audio asset path.defaudio_path(path)asset_path(path,type: :audio)end# Expand logical font asset path.deffont_path(path)asset_path(path,type: :font)end# Expand logical javascript asset path.defjavascript_path(path)asset_path(path,type: :javascript)end# Expand logical stylesheet asset path.defstylesheet_path(path)asset_path(path,type: :stylesheet)endendend