aboutsummaryrefslogtreecommitdiffstats
path: root/actionview/lib/action_view/digestor.rb
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2016-02-15 14:25:10 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2016-02-16 15:34:15 -0800
commitc9593fc77f31f72bde56e2d370c6aee99fe3e46d (patch)
tree38d779cf2fcc56c3c5659d086ef179ccd62b53c8 /actionview/lib/action_view/digestor.rb
parentec8e0bc89ab71ed41b4e8d5234b5e09ba93480e9 (diff)
downloadrails-c9593fc77f31f72bde56e2d370c6aee99fe3e46d.tar.gz
rails-c9593fc77f31f72bde56e2d370c6aee99fe3e46d.tar.bz2
rails-c9593fc77f31f72bde56e2d370c6aee99fe3e46d.zip
fix recursive templates
Diffstat (limited to 'actionview/lib/action_view/digestor.rb')
-rw-r--r--actionview/lib/action_view/digestor.rb60
1 files changed, 40 insertions, 20 deletions
diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb
index cda380c78d..5a07cec773 100644
--- a/actionview/lib/action_view/digestor.rb
+++ b/actionview/lib/action_view/digestor.rb
@@ -55,25 +55,30 @@ module ActionView
end
end
- def self.tree(name, finder, partial = false, seen = {})
- if obj = seen[name]
- obj
- else
- logical_name = name.gsub(%r|/_|, "/")
+ def self.tree(name, finder, injected = [], partial = false, seen = {})
+ logical_name = name.gsub(%r|/_|, "/")
+ partial = partial || name.include?("/_")
+
+ if finder.disable_cache { finder.exists?(logical_name, [], partial) }
+ template = finder.disable_cache { finder.find(logical_name, [], partial) }
- if finder.disable_cache { finder.exists?(logical_name, [], partial) }
- template = finder.disable_cache { finder.find(logical_name, [], partial) }
- node = seen[name] = Node.new(name, logical_name, template, partial, [])
+ if obj = seen[template.identifier]
+ obj
else
- node = seen[name] = Missing.new(name, logical_name, nil, partial, [])
- return node
- end
+ klass = partial ? Partial : Node
+ node = seen[template.identifier] = klass.new(name, logical_name, template, partial, [])
- deps = DependencyTracker.find_dependencies(name, template, finder.view_paths)
- deps.each do |dep_file|
- node.children << tree(dep_file, finder, true, seen)
+ deps = DependencyTracker.find_dependencies(name, template, finder.view_paths)
+ deps.each do |dep_file|
+ node.children << tree(dep_file, finder, [], true, seen)
+ end
+ injected.each do |template|
+ node.children << Injected.new(template, nil, nil, partial, [])
+ end
+ node
end
- node
+ else
+ seen[name] = Missing.new(name, logical_name, nil, partial, [])
end
end
@@ -86,21 +91,36 @@ module ActionView
end
end
- def digest
- Digest::MD5.hexdigest("#{template.source}-#{dependency_digest}")
+ def digest stack = []
+ Digest::MD5.hexdigest("#{template.source}-#{dependency_digest(stack)}")
end
- def dependency_digest
- children.map(&:digest).join("-")
+ def dependency_digest(stack)
+ children.map do |node|
+ if stack.include?(node)
+ false
+ else
+ stack.push node
+ node.digest(stack).tap { stack.pop }
+ end
+ end.join("-")
end
end
+ class Partial < Node; end
+
class Missing < Node
- def digest
+ def digest(_ = [])
''
end
end
+ class Injected < Node
+ def digest(_ = [])
+ name
+ end
+ end
+
attr_reader :name, :finder, :options
def initialize(name, finder, options = {})