forked from rails/sprockets
-
Notifications
You must be signed in to change notification settings - Fork 1
/
context.rb
112 lines (91 loc) · 3.02 KB
/
context.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
require 'sprockets/errors'
require 'pathname'
require 'set'
#### Sprockets::Context
#
# The context class keeps track of an environment, basepath, and the logical path for a pathname
# TODO Fill in with better explanation
module Sprockets
class Context
attr_reader :environment, :pathname
attr_reader :_required_paths, :_dependency_paths
attr_writer :__LINE__
def initialize(environment, logical_path, pathname)
@environment = environment
@logical_path = logical_path
@pathname = pathname
@__LINE__ = nil
@_required_paths = []
@_dependency_paths = Set.new
end
def root_path
environment.paths.detect { |path| pathname.to_s[path] }
end
def logical_path
@logical_path[/^([^.]+)/, 0]
end
def content_type
environment.content_type_of(pathname)
end
def resolve(path, options = {}, &block)
pathname = Pathname.new(path)
attributes = environment.attributes_for(pathname)
if pathname.absolute?
pathname
elsif content_type = options[:content_type]
content_type = self.content_type if content_type == :self
if attributes.format_extension
if content_type != attributes.content_type
raise ContentTypeMismatch, "#{path} is " +
"'#{attributes.content_type}', not '#{content_type}'"
end
end
resolve(path) do |candidate|
if self.content_type == environment.content_type_of(candidate)
return candidate
end
end
raise FileNotFound, "couldn't find file '#{path}'"
else
environment.resolve(path, :base_path => self.pathname.dirname, &block)
end
end
def depend_on(path)
@_dependency_paths << resolve(path).to_s
end
def evaluate(filename, options = {})
pathname = resolve(filename)
attributes = environment.attributes_for(pathname)
data = options[:data] || pathname.read
engines = options[:engines] || environment.processors(content_type) +
attributes.engines.reverse
engines.inject(data) do |result, engine|
begin
template = engine.new(pathname.to_s) { result }
template.render(self, {})
rescue Exception => e
raise e.class, annotate_error_message(e.message)
end
end
end
def asset_requirable?(path)
pathname = resolve(path)
content_type = environment.content_type_of(pathname)
pathname.file? && (self.content_type.nil? || self.content_type == content_type)
end
def require_asset(path)
pathname = resolve(path, :content_type => :self)
unless @_required_paths.include?(pathname.to_s)
@_dependency_paths << pathname.to_s
@_required_paths << pathname.to_s
end
pathname
end
private
def annotate_error_message(message)
annotation = "in #{@pathname.to_s}"
annotation << ":#{@__LINE__}" if @__LINE__
"#{message}\n#{annotation}"
end
end
end