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.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +12 -0
  3. data/.overcommit.yml +59 -0
  4. data/.rspec +4 -0
  5. data/.rubocop.yml +12 -1
  6. data/.rubocop_todo.yml +3 -6
  7. data/Gemfile +6 -0
  8. data/LICENSE +21 -0
  9. data/LICENSE-RU +23 -0
  10. data/README.md +2 -10
  11. data/Rakefile +8 -1
  12. data/bemer.gemspec +19 -6
  13. data/lib/bemer.rb +93 -2
  14. data/lib/bemer/asset_matcher.rb +21 -0
  15. data/lib/bemer/builders.rb +23 -0
  16. data/lib/bemer/builders/tag/element.rb +22 -0
  17. data/lib/bemer/builders/template.rb +57 -0
  18. data/lib/bemer/builders/template_list.rb +56 -0
  19. data/lib/bemer/builders/tree.rb +35 -0
  20. data/lib/bemer/builders/tree/element.rb +22 -0
  21. data/lib/bemer/common_template.rb +29 -0
  22. data/lib/bemer/component.rb +19 -0
  23. data/lib/bemer/component_pack.rb +39 -0
  24. data/lib/bemer/configuration.rb +36 -0
  25. data/lib/bemer/context.rb +44 -0
  26. data/lib/bemer/context_extentions.rb +12 -0
  27. data/lib/bemer/context_extentions/structure.rb +32 -0
  28. data/lib/bemer/context_extentions/template.rb +15 -0
  29. data/lib/bemer/default_template_list.rb +35 -0
  30. data/lib/bemer/entity.rb +94 -0
  31. data/lib/bemer/entity_builder.rb +126 -0
  32. data/lib/bemer/helpers.rb +41 -0
  33. data/lib/bemer/mixin_list.rb +74 -0
  34. data/lib/bemer/modifier_list.rb +68 -0
  35. data/lib/bemer/pipeline.rb +85 -0
  36. data/lib/bemer/pipeline/handler.rb +132 -0
  37. data/lib/bemer/predicate.rb +63 -0
  38. data/lib/bemer/railtie.rb +36 -0
  39. data/lib/bemer/renderer.rb +15 -0
  40. data/lib/bemer/tag.rb +35 -0
  41. data/lib/bemer/tag_builder.rb +11 -0
  42. data/lib/bemer/template.rb +90 -0
  43. data/lib/bemer/template_catalog.rb +42 -0
  44. data/lib/bemer/template_catalog/drawer.rb +31 -0
  45. data/lib/bemer/template_list.rb +62 -0
  46. data/lib/bemer/tree.rb +143 -0
  47. data/lib/bemer/tree/base_node.rb +49 -0
  48. data/lib/bemer/tree/node.rb +129 -0
  49. data/lib/bemer/tree/text_node.rb +11 -0
  50. data/lib/bemer/version.rb +1 -1
  51. data/spec/bemer/entity_spec.rb +37 -0
  52. data/spec/bemer/mixin_list_spec.rb +99 -0
  53. data/spec/bemer/modifier_list_spec.rb +83 -0
  54. data/spec/bemer_spec.rb +36 -0
  55. data/spec/dummy/Rakefile +8 -0
  56. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  57. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  58. data/spec/dummy/app/helpers/application_helper.rb +4 -0
  59. data/spec/dummy/app/jobs/application_job.rb +4 -0
  60. data/spec/dummy/app/mailers/application_mailer.rb +6 -0
  61. data/spec/dummy/app/models/application_record.rb +5 -0
  62. data/spec/dummy/app/models/concerns/.keep +0 -0
  63. data/spec/dummy/app/views/layouts/application.html.erb +13 -0
  64. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  65. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  66. data/spec/dummy/bin/bundle +5 -0
  67. data/spec/dummy/bin/rails +6 -0
  68. data/spec/dummy/bin/rake +6 -0
  69. data/spec/dummy/bin/setup +39 -0
  70. data/spec/dummy/bin/update +31 -0
  71. data/spec/dummy/bin/yarn +13 -0
  72. data/spec/dummy/config.ru +7 -0
  73. data/spec/dummy/config/application.rb +27 -0
  74. data/spec/dummy/config/boot.rb +7 -0
  75. data/spec/dummy/config/cable.yml +10 -0
  76. data/spec/dummy/config/database.yml +25 -0
  77. data/spec/dummy/config/environment.rb +7 -0
  78. data/spec/dummy/config/environments/development.rb +51 -0
  79. data/spec/dummy/config/environments/production.rb +84 -0
  80. data/spec/dummy/config/environments/test.rb +44 -0
  81. data/spec/dummy/config/initializers/application_controller_renderer.rb +7 -0
  82. data/spec/dummy/config/initializers/backtrace_silencers.rb +8 -0
  83. data/spec/dummy/config/initializers/bemer.rb +7 -0
  84. data/spec/dummy/config/initializers/cookies_serializer.rb +7 -0
  85. data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  86. data/spec/dummy/config/initializers/inflections.rb +17 -0
  87. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  88. data/spec/dummy/config/initializers/wrap_parameters.rb +16 -0
  89. data/spec/dummy/config/locales/en.yml +33 -0
  90. data/spec/dummy/config/puma.rb +58 -0
  91. data/spec/dummy/config/routes.rb +5 -0
  92. data/spec/dummy/config/secrets.yml +32 -0
  93. data/spec/dummy/config/spring.rb +8 -0
  94. data/spec/dummy/lib/assets/.keep +0 -0
  95. data/spec/dummy/log/.keep +0 -0
  96. data/spec/dummy/package.json +5 -0
  97. data/spec/dummy/public/404.html +67 -0
  98. data/spec/dummy/public/422.html +67 -0
  99. data/spec/dummy/public/500.html +66 -0
  100. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  101. data/spec/dummy/public/apple-touch-icon.png +0 -0
  102. data/spec/dummy/public/favicon.ico +0 -0
  103. data/spec/rails_helper.rb +37 -0
  104. data/spec/spec_helper.rb +41 -0
  105. metadata +301 -7
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bemer
4
+ module Builders
5
+ class Template
6
+ ALL_METHODS = [*Pipeline::MODES, *Pipeline::ADD_MODES].freeze
7
+ MULTI_ARGUMENT_METHODS = [Pipeline::ADD_CLS_MODE, Pipeline::ADD_MIX_MODE,
8
+ Pipeline::CLS_MODE, Pipeline::MIX_MODE].freeze
9
+
10
+ private_constant :ALL_METHODS, :MULTI_ARGUMENT_METHODS
11
+
12
+ def initialize(templates, block: '*', elem: nil, condition: true, **options)
13
+ @block = block
14
+ @element = elem
15
+ @condition = condition
16
+ @options = options
17
+ @predicate = Bemer::Predicate.new(block: block, elem: elem, condition: condition, **options)
18
+ @templates = templates
19
+ end
20
+
21
+ (ALL_METHODS - MULTI_ARGUMENT_METHODS - Pipeline::STRUCTURE_RELATED_MODES).each do |mode|
22
+ define_method(mode) do |body|
23
+ templates.unshift Bemer::Template.new(mode, body, predicate)
24
+ end
25
+ end
26
+
27
+ MULTI_ARGUMENT_METHODS.each do |mode|
28
+ define_method(mode) do |*body|
29
+ body, = *body if body[0].respond_to?(:call)
30
+
31
+ templates.unshift Bemer::Template.new(mode, body, predicate)
32
+ end
33
+ end
34
+
35
+ Pipeline::STRUCTURE_RELATED_MODES.each do |mode|
36
+ define_method(mode) do |body = nil, &block|
37
+ body = block if block.respond_to?(:call)
38
+
39
+ templates.unshift Bemer::Template.new(mode, body, predicate)
40
+ end
41
+ end
42
+
43
+ def specify(condition = @condition, block: @block, elem: @element, **new_options)
44
+ block = @block.eql?('*') ? block : @block
45
+ elem = @element.nil? || @element.eql?('*') ? elem : @element
46
+ params = { **new_options, **options, condition: condition, block: block, elem: elem }
47
+ builder = Builders::Template.new(templates, params)
48
+
49
+ block_given? ? yield(builder) : builder
50
+ end
51
+
52
+ protected
53
+
54
+ attr_reader :templates, :predicate, :options
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bemer
4
+ module Builders
5
+ class TemplateList
6
+ def initialize(templates)
7
+ @templates = templates
8
+ end
9
+
10
+ def block(name = '*', condition = true, **options)
11
+ params = { **options, condition: condition, block: name, elem: nil }
12
+
13
+ builder = Builders::Template.new(templates, params)
14
+
15
+ block_given? ? yield(builder) : builder
16
+ end
17
+
18
+ def elem(name = '*', condition = true, block: '*', **options)
19
+ params = { **options, condition: condition, block: block || '*', elem: name }
20
+
21
+ builder = Builders::Template.new(templates, params)
22
+
23
+ block_given? ? yield(builder) : builder
24
+ end
25
+
26
+ def match(condition = true, block: '*', elem: '*', **options)
27
+ entities = []
28
+
29
+ entities << { block: block } if need_block?(block, elem)
30
+ entities << { block: block || '*', elem: elem } if need_element?(elem)
31
+
32
+ builders = entities.map do |entity|
33
+ Builders::Template.new(templates, **options, condition: condition, **entity)
34
+ end
35
+
36
+ return yield(builders[0], builders[1]) if block_given?
37
+
38
+ builders.length.odd? ? builders[0] : builders
39
+ end
40
+
41
+ protected
42
+
43
+ attr_reader :templates
44
+
45
+ def need_block?(block, element)
46
+ return true if block.eql?('*') && element.eql?('*')
47
+
48
+ !block.nil? && !block.instance_of?(FalseClass) && !need_element?(element)
49
+ end
50
+
51
+ def need_element?(element)
52
+ !element.nil? && !element.instance_of?(FalseClass)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/dependencies/autoload'
4
+
5
+ module Bemer
6
+ module Builders
7
+ class Tree
8
+ extend ActiveSupport::Autoload
9
+
10
+ eager_autoload do
11
+ autoload :Element
12
+ end
13
+
14
+ def initialize(tree)
15
+ @tree = tree
16
+ end
17
+
18
+ def block(name = '', **options, &content)
19
+ tree.add_node(name, options, &content)
20
+ end
21
+
22
+ def elem(block = '', name = '', **options, &content)
23
+ tree.add_node(block, name, options, &content)
24
+ end
25
+
26
+ def text(content = nil, &callback)
27
+ tree.add_text_node(content, &callback)
28
+ end
29
+
30
+ protected
31
+
32
+ attr_reader :tree
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bemer
4
+ module Builders
5
+ class Tree
6
+ class Element
7
+ def initialize(tree, block)
8
+ @tree = tree
9
+ @block = block
10
+ end
11
+
12
+ def elem(name = '', **options, &content)
13
+ tree.add_node(block, name, options, &content)
14
+ end
15
+
16
+ protected
17
+
18
+ attr_reader :tree, :block
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bemer
4
+ class CommonTemplate
5
+ attr_reader :mode
6
+
7
+ def initialize(mode)
8
+ @mode = mode.to_s.sub('add_', '').to_sym
9
+ end
10
+
11
+ def apply!(node)
12
+ case mode
13
+ when Pipeline::REPLACE_MODE then replace!(node)
14
+ when Pipeline::CONTENT_MODE then node.add_child_nodes
15
+ else node.public_send(mode)
16
+ end
17
+ end
18
+
19
+ protected
20
+
21
+ def replace!(node)
22
+ node.need_replace = true
23
+
24
+ node.replacers << node.dup
25
+
26
+ nil
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bemer
4
+ class Component
5
+ def initialize(view)
6
+ @template_catalog = view.instance_variable_get(:@bemer_template_catalog)
7
+ end
8
+
9
+ def render(**options, &block)
10
+ return if !block_given? || template_catalog.nil?
11
+
12
+ Tree.new(template_catalog, options).render(&block)
13
+ end
14
+
15
+ protected
16
+
17
+ attr_reader :template_catalog
18
+ end
19
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bemer
4
+ class ComponentPack
5
+ def initialize(view)
6
+ @view = view
7
+ end
8
+
9
+ def render
10
+ return unless block_given?
11
+
12
+ create_template_catalog!
13
+
14
+ yield
15
+
16
+ remove_template_catalog!
17
+
18
+ nil
19
+ end
20
+
21
+ protected
22
+
23
+ attr_reader :view
24
+
25
+ def create_template_catalog!
26
+ return unless view.instance_variable_get(:@bemer_template_catalog).nil?
27
+
28
+ view.assign(bemer_template_catalog: TemplateCatalog.new(object_id))
29
+ end
30
+
31
+ def remove_template_catalog!
32
+ template_catalog = view.instance_variable_get(:@bemer_template_catalog)
33
+
34
+ return if template_catalog.nil? || !template_catalog.owner.eql?(object_id)
35
+
36
+ view.remove_instance_variable(:@bemer_template_catalog)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'singleton'
4
+
5
+ module Bemer
6
+ class Configuration
7
+ include Singleton
8
+
9
+ attr_accessor :bem, :default_block_tag, :default_element_tag, :default_path_prefix,
10
+ :element_name_separator, :modifier_name_separator, :modifier_value_separator,
11
+ :prepend_asset_paths, :paths, :asset_paths
12
+ attr_reader :can_use_new_matcher
13
+ attr_writer :path
14
+
15
+ alias can_use_new_matcher? can_use_new_matcher
16
+
17
+ def initialize # rubocop:disable Metrics/MethodLength
18
+ @asset_paths = []
19
+ @bem = false
20
+ @can_use_new_matcher = RUBY_VERSION >= '2.4.0'
21
+ @default_block_tag = :div
22
+ @default_element_tag = :div
23
+ @default_path_prefix = nil
24
+ @element_name_separator = '__'
25
+ @modifier_name_separator = '_'
26
+ @modifier_value_separator = '_'
27
+ @path = 'app/bemer_components'
28
+ @paths = []
29
+ @prepend_asset_paths = true
30
+ end
31
+
32
+ def path
33
+ Rails.root.join(@path)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module Bemer
6
+ class Context
7
+ extend Forwardable
8
+
9
+ def_delegators :node, :bem, :bem_cascade, :block, :elem, :first?, :last?, :name, :position, :tag
10
+
11
+ def initialize(node, template = nil)
12
+ @node = node
13
+ @template = template
14
+ end
15
+
16
+ def params
17
+ @params ||= Hash[node.params]
18
+ end
19
+
20
+ def attrs
21
+ @attrs ||= Hash[node.attrs]
22
+ end
23
+
24
+ def cls
25
+ @cls ||= node.cls.dup
26
+ end
27
+
28
+ def js
29
+ @js ||= node.js.dup
30
+ end
31
+
32
+ def mix
33
+ @mix ||= node.mix.dup
34
+ end
35
+
36
+ def mods
37
+ @mods ||= ActiveSupport::HashWithIndifferentAccess[node.mods]
38
+ end
39
+
40
+ protected
41
+
42
+ attr_reader :template, :node
43
+ end
44
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/dependencies/autoload'
4
+
5
+ module Bemer
6
+ module ContextExtentions
7
+ extend ActiveSupport::Autoload
8
+
9
+ autoload :Structure
10
+ autoload :Template
11
+ end
12
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bemer
4
+ module ContextExtentions
5
+ module Structure
6
+ def content(**options)
7
+ old_params = Hash[node.params]
8
+
9
+ node.params.merge!(options)
10
+
11
+ output = node.add_child_nodes
12
+ node.params = old_params
13
+
14
+ output
15
+ end
16
+
17
+ def ctx(**options)
18
+ duplicate = node.dup
19
+
20
+ duplicate.params.merge!(options)
21
+
22
+ bem_cascade = node.tree.parent_node.bem_cascade
23
+ duplicate.entity.bem_cascade = bem_cascade
24
+ duplicate.entity_builder.bem_cascade = bem_cascade
25
+
26
+ node.tree.add(duplicate)
27
+
28
+ nil
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bemer
4
+ module ContextExtentions
5
+ module Template
6
+ def apply_next(**options)
7
+ node.apply_next(template, options)
8
+ end
9
+
10
+ def apply(mode, **options)
11
+ node.apply(mode, template, options)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bemer
4
+ class DefaultTemplateList
5
+ def initialize(view, cached = true)
6
+ @path = ''
7
+ @view = view
8
+ @cached = cached
9
+ end
10
+
11
+ def compile(&block)
12
+ template_catalog.add(path, cached, &block)
13
+ end
14
+
15
+ protected
16
+
17
+ attr_reader :cached, :path, :view
18
+
19
+ def template_catalog
20
+ template_catalog = view.instance_variable_get(:@bemer_template_catalog)
21
+
22
+ return template_catalog unless template_catalog.nil?
23
+
24
+ build_template_catalog!
25
+ end
26
+
27
+ def build_template_catalog!
28
+ template_catalog = TemplateCatalog.new(object_id)
29
+
30
+ view.assign(bemer_template_catalog: template_catalog)
31
+
32
+ template_catalog
33
+ end
34
+ end
35
+ end