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