bemer 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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