bemer 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +12 -0
- data/.overcommit.yml +59 -0
- data/.rspec +4 -0
- data/.rubocop.yml +12 -1
- data/.rubocop_todo.yml +3 -6
- data/Gemfile +6 -0
- data/LICENSE +21 -0
- data/LICENSE-RU +23 -0
- data/README.md +2 -10
- data/Rakefile +8 -1
- data/bemer.gemspec +19 -6
- data/lib/bemer.rb +93 -2
- data/lib/bemer/asset_matcher.rb +21 -0
- data/lib/bemer/builders.rb +23 -0
- data/lib/bemer/builders/tag/element.rb +22 -0
- data/lib/bemer/builders/template.rb +57 -0
- data/lib/bemer/builders/template_list.rb +56 -0
- data/lib/bemer/builders/tree.rb +35 -0
- data/lib/bemer/builders/tree/element.rb +22 -0
- data/lib/bemer/common_template.rb +29 -0
- data/lib/bemer/component.rb +19 -0
- data/lib/bemer/component_pack.rb +39 -0
- data/lib/bemer/configuration.rb +36 -0
- data/lib/bemer/context.rb +44 -0
- data/lib/bemer/context_extentions.rb +12 -0
- data/lib/bemer/context_extentions/structure.rb +32 -0
- data/lib/bemer/context_extentions/template.rb +15 -0
- data/lib/bemer/default_template_list.rb +35 -0
- data/lib/bemer/entity.rb +94 -0
- data/lib/bemer/entity_builder.rb +126 -0
- data/lib/bemer/helpers.rb +41 -0
- data/lib/bemer/mixin_list.rb +74 -0
- data/lib/bemer/modifier_list.rb +68 -0
- data/lib/bemer/pipeline.rb +85 -0
- data/lib/bemer/pipeline/handler.rb +132 -0
- data/lib/bemer/predicate.rb +63 -0
- data/lib/bemer/railtie.rb +36 -0
- data/lib/bemer/renderer.rb +15 -0
- data/lib/bemer/tag.rb +35 -0
- data/lib/bemer/tag_builder.rb +11 -0
- data/lib/bemer/template.rb +90 -0
- data/lib/bemer/template_catalog.rb +42 -0
- data/lib/bemer/template_catalog/drawer.rb +31 -0
- data/lib/bemer/template_list.rb +62 -0
- data/lib/bemer/tree.rb +143 -0
- data/lib/bemer/tree/base_node.rb +49 -0
- data/lib/bemer/tree/node.rb +129 -0
- data/lib/bemer/tree/text_node.rb +11 -0
- data/lib/bemer/version.rb +1 -1
- data/spec/bemer/entity_spec.rb +37 -0
- data/spec/bemer/mixin_list_spec.rb +99 -0
- data/spec/bemer/modifier_list_spec.rb +83 -0
- data/spec/bemer_spec.rb +36 -0
- data/spec/dummy/Rakefile +8 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +4 -0
- data/spec/dummy/app/jobs/application_job.rb +4 -0
- data/spec/dummy/app/mailers/application_mailer.rb +6 -0
- data/spec/dummy/app/models/application_record.rb +5 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/bundle +5 -0
- data/spec/dummy/bin/rails +6 -0
- data/spec/dummy/bin/rake +6 -0
- data/spec/dummy/bin/setup +39 -0
- data/spec/dummy/bin/update +31 -0
- data/spec/dummy/bin/yarn +13 -0
- data/spec/dummy/config.ru +7 -0
- data/spec/dummy/config/application.rb +27 -0
- data/spec/dummy/config/boot.rb +7 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +7 -0
- data/spec/dummy/config/environments/development.rb +51 -0
- data/spec/dummy/config/environments/production.rb +84 -0
- data/spec/dummy/config/environments/test.rb +44 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +7 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +8 -0
- data/spec/dummy/config/initializers/bemer.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
- data/spec/dummy/config/initializers/inflections.rb +17 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +16 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +58 -0
- data/spec/dummy/config/routes.rb +5 -0
- data/spec/dummy/config/secrets.yml +32 -0
- data/spec/dummy/config/spring.rb +8 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/package.json +5 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/rails_helper.rb +37 -0
- data/spec/spec_helper.rb +41 -0
- metadata +301 -7
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/core_ext/object/blank'
|
|
4
|
+
|
|
5
|
+
module Bemer
|
|
6
|
+
class Pipeline
|
|
7
|
+
class Handler
|
|
8
|
+
def initialize(templates)
|
|
9
|
+
@priorities = Pipeline::MODES.map { |mode| [mode, {}] }.to_h
|
|
10
|
+
@container = Pipeline::MODES.map { |mode| [mode, []] }.to_h
|
|
11
|
+
|
|
12
|
+
prioritize(templates)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def apply!(mode, node)
|
|
16
|
+
return if node.applied_modes[mode].present? || !allowable_mode?(mode)
|
|
17
|
+
|
|
18
|
+
apply_template!(mode, node)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def apply_next(current_template, node, **params)
|
|
22
|
+
position = priorities[current_template.mode][current_template.object_id] + 1
|
|
23
|
+
|
|
24
|
+
apply_template(current_template.mode, node, position, params)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def apply(mode, current_template, node, **params)
|
|
28
|
+
return unless allowable_mode?(mode) && compatible_modes?(mode, current_template.mode)
|
|
29
|
+
|
|
30
|
+
if current_template.mode.eql?(mode)
|
|
31
|
+
apply_next(current_template, node, params)
|
|
32
|
+
else
|
|
33
|
+
apply_template(mode, node, params)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
protected
|
|
38
|
+
|
|
39
|
+
attr_reader :priorities, :container
|
|
40
|
+
|
|
41
|
+
def compatible_modes?(mode, current_mode)
|
|
42
|
+
return true if Pipeline::STRUCTURE_RELATED_MODES.include?(current_mode)
|
|
43
|
+
|
|
44
|
+
!Pipeline::STRUCTURE_RELATED_MODES.include?(mode)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def allowable_mode?(mode)
|
|
48
|
+
Pipeline::MODES.include?(mode)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def apply_template(mode, node, position = 0, **params)
|
|
52
|
+
template = find_template(mode, node, position)
|
|
53
|
+
old_params = Hash[node.params]
|
|
54
|
+
|
|
55
|
+
node.params.merge!(params)
|
|
56
|
+
|
|
57
|
+
output = template.nil? ? CommonTemplate.new(mode).apply!(node) : template.apply(node)
|
|
58
|
+
node.params = old_params
|
|
59
|
+
|
|
60
|
+
output
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def apply_template!(mode, node)
|
|
64
|
+
node.applied_modes[mode] = true
|
|
65
|
+
template = find_template(mode, node)
|
|
66
|
+
output = template ? template.apply!(node) : nil
|
|
67
|
+
|
|
68
|
+
disable_related_modes!(mode, node)
|
|
69
|
+
|
|
70
|
+
output
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def disable_related_modes!(mode, node)
|
|
74
|
+
return unless [Pipeline::TAG_MODE, Pipeline::BEM_MODE].include?(mode)
|
|
75
|
+
|
|
76
|
+
if Pipeline::TAG_MODE.eql?(mode)
|
|
77
|
+
disable_tag_related_modes!(node)
|
|
78
|
+
else
|
|
79
|
+
disable_bem_related_modes!(node)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def disable_tag_related_modes!(node)
|
|
84
|
+
return if node.entity_builder.tag.present?
|
|
85
|
+
|
|
86
|
+
Pipeline::TAG_RELATED_MODES.each { |mode| node.applied_modes[mode] = true }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def disable_bem_related_modes!(node)
|
|
90
|
+
return if node.entity_builder.bem?
|
|
91
|
+
|
|
92
|
+
Pipeline::BEM_RELATED_MODES.each { |mode| node.applied_modes[mode] = true }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def prioritize(templates) # rubocop:disable Metrics/AbcSize
|
|
96
|
+
wildcard_container = Pipeline::MODES.map { |mode| [mode, []] }.to_h
|
|
97
|
+
|
|
98
|
+
templates.each do |template|
|
|
99
|
+
next wildcard_container[template.mode].push(template) if template.wildcard?
|
|
100
|
+
|
|
101
|
+
priorities[template.mode][template.object_id] = container[template.mode].length
|
|
102
|
+
|
|
103
|
+
container[template.mode].push(template)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
wildcard_container.each do |mode, wildcard_templates|
|
|
107
|
+
prepend_wildcard_templates(mode, wildcard_templates)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def prepend_wildcard_templates(mode, templates)
|
|
112
|
+
return if templates.empty?
|
|
113
|
+
|
|
114
|
+
templates.reverse_each do |template|
|
|
115
|
+
priorities[mode].each { |id, priority| priorities[mode][id] = priority + 1 }
|
|
116
|
+
|
|
117
|
+
priorities[mode][template.object_id] = 0
|
|
118
|
+
|
|
119
|
+
container[mode].unshift(template)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def find_template(mode, node, start = 0)
|
|
124
|
+
templates = container[mode][start..-1]
|
|
125
|
+
|
|
126
|
+
return if templates.empty?
|
|
127
|
+
|
|
128
|
+
templates.detect { |template| template.match?(node) }
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bemer
|
|
4
|
+
class Predicate
|
|
5
|
+
def initialize(**options)
|
|
6
|
+
@block = options[:block]
|
|
7
|
+
@condition = options[:condition].nil? ? true : options[:condition]
|
|
8
|
+
@element = options[:elem]
|
|
9
|
+
@mask = build_mask(options[:block], options[:elem])
|
|
10
|
+
@mixins = MixinList.new(options[:mix])
|
|
11
|
+
@modifiers = ModifierList.new(:block, :elem, options[:mods])
|
|
12
|
+
@wildcard = nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def match?(node)
|
|
16
|
+
condition?(node) && mix?(node.mix) && mods?(node.mods)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def name_match?(name)
|
|
20
|
+
Bemer.can_use_new_matcher? ? mask.match?(name) : mask =~ name
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def wildcard?
|
|
24
|
+
return wildcard unless wildcard.nil?
|
|
25
|
+
|
|
26
|
+
@wildcard = name.include?('*')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
protected
|
|
30
|
+
|
|
31
|
+
attr_reader :block, :element, :condition, :mask, :mixins, :name, :wildcard
|
|
32
|
+
|
|
33
|
+
def condition?(node)
|
|
34
|
+
return condition unless condition.respond_to?(:call)
|
|
35
|
+
|
|
36
|
+
condition.call Context.new(node)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def mix?(mix)
|
|
40
|
+
(mixins.to_a - mix).empty?
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def mods?(mods)
|
|
44
|
+
return false if modifiers.keys.length > mods.keys.length
|
|
45
|
+
|
|
46
|
+
modifiers.all? do |name, value|
|
|
47
|
+
val = mods[name]
|
|
48
|
+
|
|
49
|
+
val.nil? ? false : (Array(value) - Array(val)).empty?
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def modifiers
|
|
54
|
+
@modifiers.to_h
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def build_mask(block, element)
|
|
58
|
+
@name = Bemer.entity_name(block, element)
|
|
59
|
+
|
|
60
|
+
name.eql?('*') ? /^((?!#{Bemer.element_name_separator}).)*$/ : /^#{name.gsub('*', '.*')}$/
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bemer
|
|
4
|
+
class Railtie < ::Rails::Railtie
|
|
5
|
+
config.eager_load_namespaces << Bemer if config.respond_to?(:eager_load_namespaces)
|
|
6
|
+
|
|
7
|
+
config.after_initialize do
|
|
8
|
+
ActionController::Base.prepend_view_path([Bemer.path, *Bemer.paths])
|
|
9
|
+
ActionMailer::Base.prepend_view_path([Bemer.path, *Bemer.paths])
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
initializer 'bemer.helpers' do
|
|
13
|
+
ActiveSupport.on_load(:action_view) { include Bemer::Helpers }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
initializer_name =
|
|
17
|
+
case ::Rails::VERSION::MAJOR
|
|
18
|
+
when 5 then :append_assets_path
|
|
19
|
+
when 3..4 then :load_config_initializers
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
initializer 'bemer.prepend_asset_paths', group: :all, after: initializer_name do |app|
|
|
23
|
+
next unless defined?(::Sprockets) && Bemer.prepend_asset_paths?
|
|
24
|
+
|
|
25
|
+
app.config.assets.paths.unshift(Bemer.path.to_s, *Bemer.asset_paths)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
initializer 'bemer.assets_precompile', group: :all, after: :load_config_initializers do |app|
|
|
29
|
+
next if ::Rails::VERSION::MAJOR > 3 || !defined?(::Sprockets)
|
|
30
|
+
|
|
31
|
+
asset_matcher = Bemer::AssetMatcher.new(app.config.assets.precompile.shift)
|
|
32
|
+
|
|
33
|
+
app.config.assets.precompile.unshift(asset_matcher)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'action_view/helpers/tag_helper'
|
|
4
|
+
|
|
5
|
+
module Bemer
|
|
6
|
+
class Renderer
|
|
7
|
+
include ::ActionView::Helpers::TagHelper
|
|
8
|
+
|
|
9
|
+
def render(builder)
|
|
10
|
+
return builder.content if builder.tag.blank?
|
|
11
|
+
|
|
12
|
+
content_tag(builder.tag, builder.content, builder.attrs)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
data/lib/bemer/tag.rb
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
|
|
5
|
+
module Bemer
|
|
6
|
+
class Tag
|
|
7
|
+
extend Forwardable
|
|
8
|
+
|
|
9
|
+
def initialize(block = '', element = nil, **options, &content)
|
|
10
|
+
@bem_cascade = options[:bem_cascade]
|
|
11
|
+
@tag_builder = TagBuilder.new(block, element, options, &content)
|
|
12
|
+
@renderer = Renderer.new
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def render
|
|
16
|
+
tag_builder.content = capture_content
|
|
17
|
+
|
|
18
|
+
renderer.render(tag_builder)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
protected
|
|
22
|
+
|
|
23
|
+
attr_reader :bem_cascade, :renderer, :tag_builder
|
|
24
|
+
|
|
25
|
+
def_delegators :tag_builder, :block, :block?, :content
|
|
26
|
+
|
|
27
|
+
def capture_content
|
|
28
|
+
return content unless content.respond_to?(:call)
|
|
29
|
+
|
|
30
|
+
builder = Builders::Tag::Element.new(block, bem_cascade) if block?
|
|
31
|
+
|
|
32
|
+
content.binding.receiver.capture(builder, &content)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
|
|
5
|
+
module Bemer
|
|
6
|
+
class Template < CommonTemplate
|
|
7
|
+
extend Forwardable
|
|
8
|
+
|
|
9
|
+
def_delegators :predicate, :wildcard?, :match?, :name_match?
|
|
10
|
+
|
|
11
|
+
def initialize(mode, body, predicate)
|
|
12
|
+
super(mode)
|
|
13
|
+
|
|
14
|
+
@add_mode = !@mode.eql?(mode)
|
|
15
|
+
@body = body
|
|
16
|
+
@method = [@mode, '='].join.to_sym
|
|
17
|
+
@predicate = predicate
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def apply(node)
|
|
21
|
+
case mode
|
|
22
|
+
when Pipeline::REPLACE_MODE then replace(node)
|
|
23
|
+
when Pipeline::CONTENT_MODE then capture_content(node)
|
|
24
|
+
else node.entity_builder.public_send(method, capture_body(node), false)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def apply!(node)
|
|
29
|
+
return replace!(node) if Pipeline::REPLACE_MODE.eql?(mode)
|
|
30
|
+
|
|
31
|
+
content = Pipeline::CONTENT_MODE.eql?(mode) ? capture_content!(node) : capture_body(node)
|
|
32
|
+
|
|
33
|
+
node.entity_builder.public_send(method, content)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
protected
|
|
37
|
+
|
|
38
|
+
attr_reader :add_mode, :body, :method, :predicate
|
|
39
|
+
|
|
40
|
+
alias add_mode? add_mode
|
|
41
|
+
|
|
42
|
+
def capture_content(node)
|
|
43
|
+
return body unless body.respond_to?(:call)
|
|
44
|
+
|
|
45
|
+
builder = Builders::Tree.new(node.tree)
|
|
46
|
+
|
|
47
|
+
body.binding.receiver.capture(build_context(node), builder, &body)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def capture_body(node)
|
|
51
|
+
output = body.respond_to?(:call) ? body.call(build_context(node)) : body
|
|
52
|
+
|
|
53
|
+
return output unless add_mode?
|
|
54
|
+
|
|
55
|
+
normalized_output = node.entity_builder.public_send(method, output, false)
|
|
56
|
+
|
|
57
|
+
[*node.apply(mode, self), *normalized_output]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def replace(node)
|
|
61
|
+
output = capture_content(node)
|
|
62
|
+
|
|
63
|
+
return if output.blank?
|
|
64
|
+
|
|
65
|
+
node.replacers.unshift Tree::TextNode.new(node.tree, output)
|
|
66
|
+
|
|
67
|
+
nil
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def replace!(node)
|
|
71
|
+
node.need_replace = true
|
|
72
|
+
|
|
73
|
+
node.replace_parent_and_execute { replace(node) }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def capture_content!(node)
|
|
77
|
+
node.content_replaced = true
|
|
78
|
+
|
|
79
|
+
node.replace_parent_and_execute { capture_content(node) }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def build_context(node)
|
|
83
|
+
context = Context.new(node, self).extend(ContextExtentions::Template)
|
|
84
|
+
|
|
85
|
+
return context unless Pipeline::STRUCTURE_RELATED_MODES.include?(mode)
|
|
86
|
+
|
|
87
|
+
context.extend(ContextExtentions::Structure)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/dependencies/autoload'
|
|
4
|
+
|
|
5
|
+
module Bemer
|
|
6
|
+
class TemplateCatalog
|
|
7
|
+
extend ActiveSupport::Autoload
|
|
8
|
+
|
|
9
|
+
eager_autoload do
|
|
10
|
+
autoload :Drawer
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
attr_reader :owner
|
|
14
|
+
|
|
15
|
+
def initialize(owner)
|
|
16
|
+
@drawers = {}
|
|
17
|
+
@owner = owner
|
|
18
|
+
@template_queue = []
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def compiled_templates
|
|
22
|
+
template_queue = @template_queue
|
|
23
|
+
@template_queue = []
|
|
24
|
+
|
|
25
|
+
template_queue.flat_map { |id| drawers[id].compiled_templates }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def add(path, cached = false, &block)
|
|
29
|
+
return unless block_given?
|
|
30
|
+
|
|
31
|
+
id = [block.source_location, path].join(':')
|
|
32
|
+
|
|
33
|
+
@template_queue << id
|
|
34
|
+
|
|
35
|
+
drawers[id] = Drawer.new(cached, &block) unless drawers.key?(id) && drawers[id].cached?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
protected
|
|
39
|
+
|
|
40
|
+
attr_reader :drawers
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bemer
|
|
4
|
+
class TemplateCatalog
|
|
5
|
+
class Drawer
|
|
6
|
+
attr_reader :cached
|
|
7
|
+
|
|
8
|
+
alias cached? cached
|
|
9
|
+
|
|
10
|
+
def initialize(cached = false, &block)
|
|
11
|
+
@block = block
|
|
12
|
+
@cached = cached
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def compiled_templates
|
|
16
|
+
@compiled_templates ||= begin
|
|
17
|
+
new_templates = []
|
|
18
|
+
builder = Builders::TemplateList.new(new_templates)
|
|
19
|
+
|
|
20
|
+
block.binding.receiver.capture(builder, &block)
|
|
21
|
+
|
|
22
|
+
new_templates
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
protected
|
|
27
|
+
|
|
28
|
+
attr_reader :block
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|