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
data/lib/bemer/entity.rb
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/core_ext/object/blank'
|
|
4
|
+
require 'active_support/core_ext/hash/keys'
|
|
5
|
+
|
|
6
|
+
module Bemer
|
|
7
|
+
class Entity
|
|
8
|
+
attr_accessor :bem_cascade
|
|
9
|
+
attr_reader :bem, :bem_class, :block, :content, :elem, :js, :name, :tag
|
|
10
|
+
|
|
11
|
+
alias element elem
|
|
12
|
+
|
|
13
|
+
def initialize(block = '', element = nil, **options, &content)
|
|
14
|
+
@bem_class = Bemer.bem_class(block, element)
|
|
15
|
+
@block = block
|
|
16
|
+
@content = extract_content(options.delete(:content), &content)
|
|
17
|
+
@elem = element
|
|
18
|
+
@name = Bemer.entity_name(block, element)
|
|
19
|
+
|
|
20
|
+
extract_options!(options)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def attrs
|
|
24
|
+
@attrs ||= build_attrs(html_attrs)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def block?
|
|
28
|
+
!element?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def cls
|
|
32
|
+
@cls ||= build_css_classes(css_classes)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def elem?
|
|
36
|
+
!elem.nil?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
alias element? elem?
|
|
40
|
+
|
|
41
|
+
def mix
|
|
42
|
+
@mix ||= mixins.to_a
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def mods
|
|
46
|
+
@mods ||= modifiers.to_h
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
protected
|
|
50
|
+
|
|
51
|
+
attr_reader :css_classes, :html_attrs, :mixins, :modifiers
|
|
52
|
+
|
|
53
|
+
def extract_content(plain_text, &content)
|
|
54
|
+
block_given? ? content : plain_text
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def extract_options!(options) # rubocop:disable Metrics/AbcSize
|
|
58
|
+
@bem = options.delete(:bem)
|
|
59
|
+
@bem_cascade = options.delete(:bem_cascade)
|
|
60
|
+
@css_classes = [options.delete(:class), options.delete(:cls)]
|
|
61
|
+
@js = options.delete(:js)
|
|
62
|
+
@mixins = MixinList.new(options.delete(:mix))
|
|
63
|
+
@modifiers = ModifierList.new(block, element, options.delete(:mods))
|
|
64
|
+
@tag = build_tag(options.delete(:tag))
|
|
65
|
+
@html_attrs = options
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def build_css_classes(*classes)
|
|
69
|
+
classes.map do |css_class|
|
|
70
|
+
next [] if css_class.blank?
|
|
71
|
+
|
|
72
|
+
case css_class
|
|
73
|
+
when String then css_class.split
|
|
74
|
+
when Array then css_class.map { |css_cls| build_css_classes(css_cls) }
|
|
75
|
+
else Bemer.css_class(css_class)
|
|
76
|
+
end
|
|
77
|
+
end.flatten.uniq
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def build_tag(new_tag)
|
|
81
|
+
return new_tag if new_tag.nil? || new_tag.instance_of?(Symbol)
|
|
82
|
+
|
|
83
|
+
new_tag.blank? ? '' : new_tag.to_sym
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def build_attrs(new_attrs)
|
|
87
|
+
case new_attrs
|
|
88
|
+
when Array then new_attrs.to_h.symbolize_keys
|
|
89
|
+
when Hash then new_attrs.symbolize_keys
|
|
90
|
+
else {}
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/core_ext/object/blank'
|
|
4
|
+
require 'active_support/core_ext/hash/deep_merge'
|
|
5
|
+
|
|
6
|
+
module Bemer
|
|
7
|
+
class EntityBuilder < Entity
|
|
8
|
+
def attrs
|
|
9
|
+
attributes = Hash[super]
|
|
10
|
+
attributes[:class] = cls
|
|
11
|
+
|
|
12
|
+
return attributes unless bem?
|
|
13
|
+
|
|
14
|
+
attributes.deep_merge!(js)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def attrs=(new_attrs, save = true)
|
|
18
|
+
new_attrs = build_attrs(new_attrs)
|
|
19
|
+
|
|
20
|
+
save ? @attrs = new_attrs : new_attrs
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def bem
|
|
24
|
+
bem_via_option? ? super : true
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def bem=(new_bem, save = true)
|
|
28
|
+
save ? @bem = new_bem : new_bem
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def bem?
|
|
32
|
+
bem_enabled_via_option? || bem_cascade_enabled_via_option? || bem_enabled_fully?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def bem_cascade
|
|
36
|
+
bem_cascade_via_option? ? super : true
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def bem_cascade=(new_bem_cascade, save = true)
|
|
40
|
+
save ? @bem_cascade = new_bem_cascade : new_bem_cascade
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def cls
|
|
44
|
+
return super unless bem?
|
|
45
|
+
|
|
46
|
+
js_class = 'i-bem' if @js.present? && bem_class.present?
|
|
47
|
+
|
|
48
|
+
[bem_class, mods, mix, super, js_class].reject(&:blank?)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def cls=(new_cls, save = true)
|
|
52
|
+
new_cls = build_css_classes(new_cls)
|
|
53
|
+
|
|
54
|
+
save ? @cls = new_cls : new_cls
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def content=(new_content, save = true)
|
|
58
|
+
save ? @content = new_content : new_content
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def js
|
|
62
|
+
return {} if @js.blank? || bem_class.blank?
|
|
63
|
+
|
|
64
|
+
attrs = @js.instance_of?(TrueClass) ? {} : super
|
|
65
|
+
|
|
66
|
+
{ data: { bem: { name => attrs } } }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def js=(new_js, save = true)
|
|
70
|
+
save ? @js = new_js : new_js
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def mix=(new_mix, save = true)
|
|
74
|
+
new_mix = MixinList.new(new_mix).to_a
|
|
75
|
+
|
|
76
|
+
save ? @mix = new_mix : new_mix
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def mods
|
|
80
|
+
modifiers.to_a
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def mods=(new_mods, save = true)
|
|
84
|
+
modifiers = ModifierList.new(block, element, new_mods)
|
|
85
|
+
@modifiers = modifiers if save
|
|
86
|
+
|
|
87
|
+
modifiers.to_h
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def tag
|
|
91
|
+
super.nil? ? default_tag : @tag
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def tag=(new_tag, save = true)
|
|
95
|
+
new_tag = build_tag(new_tag)
|
|
96
|
+
|
|
97
|
+
save ? @tag = new_tag : new_tag
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
protected
|
|
101
|
+
|
|
102
|
+
def bem_via_option?
|
|
103
|
+
!@bem.nil?
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def bem_cascade_via_option?
|
|
107
|
+
!@bem_cascade.nil?
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def bem_enabled_via_option?
|
|
111
|
+
bem_via_option? && bem
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def bem_cascade_enabled_via_option?
|
|
115
|
+
bem_cascade_via_option? && bem_cascade && bem
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def bem_enabled_fully?
|
|
119
|
+
Bemer.bem && bem_cascade && bem
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def default_tag
|
|
123
|
+
block? ? Bemer.default_block_tag : Bemer.default_element_tag
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bemer
|
|
4
|
+
module Helpers
|
|
5
|
+
def block_tag(name = '', **options, &content)
|
|
6
|
+
Bemer::Tag.new(name, options, &content).render
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def elem_tag(block = '', element = '', **options, &content)
|
|
10
|
+
Bemer::Tag.new(block, element, options, &content).render
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def bem_mix(*mix)
|
|
14
|
+
Bemer::MixinList.new(mix).to_s
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def bem_mods(*block_and_element, mods)
|
|
18
|
+
block, element = *block_and_element
|
|
19
|
+
|
|
20
|
+
Bemer::ModifierList.new(block, element, mods).to_s
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def render_component(path, **options, &block)
|
|
24
|
+
Bemer::TemplateList.new(self, path, options).compile(&block)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
alias refine_component render_component
|
|
28
|
+
|
|
29
|
+
def define_templates(cached: true, &block)
|
|
30
|
+
Bemer::DefaultTemplateList.new(self, cached).compile(&block)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def define_component(**options, &block)
|
|
34
|
+
Bemer::Component.new(self).render(options, &block)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def component_pack(&block)
|
|
38
|
+
Bemer::ComponentPack.new(self).render(&block)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/core_ext/object/blank'
|
|
4
|
+
|
|
5
|
+
module Bemer
|
|
6
|
+
class MixinList
|
|
7
|
+
def initialize(mix)
|
|
8
|
+
@mix = mix
|
|
9
|
+
@mixins = nil
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def to_a
|
|
13
|
+
build_mixins
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def to_s
|
|
17
|
+
@mix_as_string ||= to_a.join(' ')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
protected
|
|
21
|
+
|
|
22
|
+
attr_reader :mixins
|
|
23
|
+
|
|
24
|
+
def build_mixins
|
|
25
|
+
return mixins unless mixins.nil?
|
|
26
|
+
|
|
27
|
+
mix = @mix.instance_of?(Hash) ? build_mixins_from_hash : build_mixins_from_array
|
|
28
|
+
|
|
29
|
+
@mixins = mix.flatten.reject(&:blank?).uniq
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def build_mixin(mixin)
|
|
33
|
+
return mixin.split if mixin.instance_of?(String)
|
|
34
|
+
|
|
35
|
+
case mixin
|
|
36
|
+
when Symbol then Bemer.bem_class(mixin)
|
|
37
|
+
when Array then build_mixin_from_array(mixin)
|
|
38
|
+
when Hash then build_mixin_from_hash(mixin)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def build_mixin_from_hash(mixin)
|
|
43
|
+
mixin.map do |block, element|
|
|
44
|
+
next Bemer.bem_class(block, element) unless element.instance_of?(Array)
|
|
45
|
+
|
|
46
|
+
element.map { |elem| Bemer.bem_class(block, elem) }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def build_mixin_from_array(mixin)
|
|
51
|
+
block, element = *mixin
|
|
52
|
+
|
|
53
|
+
return Bemer.bem_class(block, element) unless element.instance_of?(Array)
|
|
54
|
+
|
|
55
|
+
element.map { |elem| Bemer.bem_class(block, elem) }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def build_mixins_from_hash
|
|
59
|
+
@mix.map do |mixin|
|
|
60
|
+
next if mixin.blank?
|
|
61
|
+
|
|
62
|
+
build_mixin(mixin)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def build_mixins_from_array
|
|
67
|
+
Array(@mix).map do |mixin|
|
|
68
|
+
next if mixin.blank?
|
|
69
|
+
|
|
70
|
+
mixin.instance_of?(Array) ? mixin.map { |mix| build_mixin(mix) } : build_mixin(mixin)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/core_ext/object/blank'
|
|
4
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
|
5
|
+
|
|
6
|
+
module Bemer
|
|
7
|
+
class ModifierList
|
|
8
|
+
def initialize(block, element, mods)
|
|
9
|
+
@bem_class = Bemer.bem_class(block, element)
|
|
10
|
+
@modifiers = nil
|
|
11
|
+
@mods = mods
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def to_a
|
|
15
|
+
@mods_as_array ||= to_h.map { |name, value| build_css_class(name, value) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_s
|
|
19
|
+
@mods_as_string ||= to_a.join(' ')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def to_h
|
|
23
|
+
modifiers.nil? ? build_modifiers : modifiers
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
protected
|
|
27
|
+
|
|
28
|
+
attr_reader :modifiers
|
|
29
|
+
|
|
30
|
+
def build_modifiers
|
|
31
|
+
@modifiers = ActiveSupport::HashWithIndifferentAccess.new
|
|
32
|
+
|
|
33
|
+
return modifiers if @mods.blank? || @bem_class.blank?
|
|
34
|
+
|
|
35
|
+
Array(@mods).each do |mods|
|
|
36
|
+
next if mods.blank?
|
|
37
|
+
|
|
38
|
+
mods.is_a?(Hash) ? mods.each { |attrs| add_modifier(attrs) } : add_modifier(mods)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
modifiers
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def add_modifier(attrs)
|
|
45
|
+
name, value = normalize(attrs)
|
|
46
|
+
|
|
47
|
+
return if name.blank? || value.blank?
|
|
48
|
+
|
|
49
|
+
modifiers[name] = value
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def normalize(attrs)
|
|
53
|
+
name, value = *attrs, true
|
|
54
|
+
|
|
55
|
+
value = Bemer.css_class(value) unless [TrueClass, FalseClass, NilClass].include?(value.class)
|
|
56
|
+
|
|
57
|
+
[Bemer.css_class(name), value]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def build_css_class(name, value)
|
|
61
|
+
# rubocop:disable Metrics/LineLength
|
|
62
|
+
modifier = value.instance_of?(TrueClass) ? name : [name, value].join(Bemer.modifier_value_separator)
|
|
63
|
+
# rubocop:enable Metrics/LineLength
|
|
64
|
+
|
|
65
|
+
[@bem_class, modifier].join(Bemer.modifier_name_separator)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/dependencies/autoload'
|
|
4
|
+
|
|
5
|
+
module Bemer
|
|
6
|
+
class Pipeline
|
|
7
|
+
extend ActiveSupport::Autoload
|
|
8
|
+
|
|
9
|
+
eager_autoload do
|
|
10
|
+
autoload :Handler
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
ADD_ATTRS_MODE = :add_attrs
|
|
14
|
+
ADD_CLS_MODE = :add_cls
|
|
15
|
+
ADD_MIX_MODE = :add_mix
|
|
16
|
+
ADD_MODS_MODE = :add_mods
|
|
17
|
+
ATTRS_MODE = :attrs
|
|
18
|
+
BEM_MODE = :bem
|
|
19
|
+
CLS_MODE = :cls
|
|
20
|
+
CONTENT_MODE = :content
|
|
21
|
+
JS_MODE = :js
|
|
22
|
+
MIX_MODE = :mix
|
|
23
|
+
MODS_MODE = :mods
|
|
24
|
+
REPLACE_MODE = :replace
|
|
25
|
+
TAG_MODE = :tag
|
|
26
|
+
|
|
27
|
+
ADD_MODES = [ADD_ATTRS_MODE, ADD_CLS_MODE, ADD_MIX_MODE, ADD_MODS_MODE].freeze
|
|
28
|
+
STRUCTURE_RELATED_MODES = [REPLACE_MODE, CONTENT_MODE].freeze
|
|
29
|
+
BEM_RELATED_MODES = [MODS_MODE, MIX_MODE, JS_MODE].freeze
|
|
30
|
+
TAG_RELATED_MODES = [CLS_MODE, ATTRS_MODE, BEM_MODE, *BEM_RELATED_MODES].freeze
|
|
31
|
+
MODES = [REPLACE_MODE, CONTENT_MODE, TAG_MODE, *TAG_RELATED_MODES].freeze
|
|
32
|
+
|
|
33
|
+
def initialize(template_catalog)
|
|
34
|
+
@handlers = {}
|
|
35
|
+
@template_catalog = template_catalog
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def run!(node)
|
|
39
|
+
return node if node.instance_of?(Tree::TextNode)
|
|
40
|
+
|
|
41
|
+
MODES.each do |mode|
|
|
42
|
+
handler_by(node.name).apply!(mode, node)
|
|
43
|
+
|
|
44
|
+
break if processing_completed?(mode, node)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
node
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def apply_next(template, node, **params)
|
|
51
|
+
handler_by(node.name).apply_next(template, node, params)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def apply(mode, template, node, **params)
|
|
55
|
+
handler_by(node.name).apply(mode, template, node, params)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
protected
|
|
59
|
+
|
|
60
|
+
attr_reader :handlers, :template_catalog
|
|
61
|
+
|
|
62
|
+
def processing_completed?(mode, node)
|
|
63
|
+
return true if JS_MODE.eql?(mode)
|
|
64
|
+
|
|
65
|
+
case mode
|
|
66
|
+
when REPLACE_MODE then node.need_replace?
|
|
67
|
+
when TAG_MODE then node.entity_builder.tag.blank?
|
|
68
|
+
when BEM_MODE then !node.entity_builder.bem?
|
|
69
|
+
else false
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def handler_by(name)
|
|
74
|
+
return handlers[name] if handlers.key?(name)
|
|
75
|
+
|
|
76
|
+
templates = compiled_templates.select { |template| template.name_match?(name) }
|
|
77
|
+
|
|
78
|
+
handlers[name] = Handler.new(templates)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def compiled_templates
|
|
82
|
+
@compiled_templates ||= template_catalog.compiled_templates
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|