ilex 0.1.3 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 05f0478149655dc4fc56136bc17054bd1b89a2a7ba20a701f0043c96a5ccf423
4
- data.tar.gz: 8161c073bc92aa9ef0698dd3526181a4f3d96ce986130dba0eab4efac47bb83f
3
+ metadata.gz: 0270cc4a6ad17198cccaa8dfe059fc68a8acb05d9d690ac54d2b4590bed94e16
4
+ data.tar.gz: faa95ab242ab07977737971bb7b98c76afbf5b3a7f5450c919716a92fcdc393c
5
5
  SHA512:
6
- metadata.gz: 2aa4d959ae5d0e38db60a6ce4b5dc79bb80034a555a485d839d08c9da9e39b3c2fdc7f096954d9b27c2187234f96036042efde2ba8658125069e402d6bc353aa
7
- data.tar.gz: d4f7a0c6f6c3e046f201b823a306684a0717eccdbcd078687927dcd2bbda7c7532515a2d7056cacbf370f24a860424fbc4e69e72e065474c65c8c10530407d62
6
+ metadata.gz: 7730bd1a0fd1552619a659347437fc206ca393c57859ff85e3270002274d9619005a2c97f813e591b29fd0488cc89d1a4b9802c1332a795baea90d272da0f2dd
7
+ data.tar.gz: 7b8dfb00406cb0916000945feb3c0df9188f6d4c941777e64bde12a16ecdbcf19524913bdad2ec382c254677a9be67e8a735251aaa1af08b35c802717273efb2
data/.versionrc.json CHANGED
@@ -1,7 +1,7 @@
1
- {
2
- "skip": {
3
- "tag": true
4
- },
5
- "NAME": "Ilex",
6
- "VERSION": "0.1.0"
7
- }
1
+ {
2
+ "skip": {
3
+ "tag": true
4
+ },
5
+ "NAME": "Ilex",
6
+ "VERSION": "0.1.6"
7
+ }
data/CHANGELOG.md CHANGED
@@ -2,6 +2,50 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.1.8](https://github.com/joshleblanc/ilex/compare/v0.1.7...v0.1.8) (2021-06-16)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * handle rendering arrays ([fd09349](https://github.com/joshleblanc/ilex/commit/fd093493a790ada7403acfa8cf2496783cdfbfce))
11
+ * handle root level slot text nodes ([6913197](https://github.com/joshleblanc/ilex/commit/6913197ab4286115734bbbbb4b2fc1c01f286d84))
12
+
13
+ ### [0.1.7](https://github.com/joshleblanc/ilex/compare/v0.1.6...v0.1.7) (2021-06-16)
14
+
15
+
16
+ ### Bug Fixes
17
+
18
+ * try and convert component arrays into strings ([13e0438](https://github.com/joshleblanc/ilex/commit/13e0438d1da6ebd0bc0b46c9ca7cc6828bd99a7f))
19
+
20
+ ### [0.1.6](https://github.com/joshleblanc/cedar/compare/v0.1.5...v0.1.6) (2021-04-18)
21
+
22
+
23
+ ### Bug Fixes
24
+
25
+ * allow rendering form helpers with blocks ([9a24ed7](https://github.com/joshleblanc/cedar/commit/9a24ed7388c60f7a7ed4398dc4871974302c87f3)), closes [activeadmin/arbre#64](https://github.com/activeadmin/arbre/issues/64)
26
+
27
+ ### [0.1.5](https://github.com/joshleblanc/cedar/compare/v0.1.4...v0.1.5) (2021-04-17)
28
+
29
+
30
+ ### Features
31
+
32
+ * add helpers for rendering namespaced components ([3b0a5af](https://github.com/joshleblanc/cedar/commit/3b0a5af421e4b4c9a3b45b07b11647df65908552))
33
+
34
+
35
+ ### Bug Fixes
36
+
37
+ * allow appending helpers with _component ([7097420](https://github.com/joshleblanc/cedar/commit/7097420d3529533910fd5174af175aae15c16aa0))
38
+ * appease intellisense with unused splat ([854c8a8](https://github.com/joshleblanc/cedar/commit/854c8a8c7f121d4f531bb5a6d56b487f29772bb8))
39
+ * component content wasn't rendering ([041efb2](https://github.com/joshleblanc/cedar/commit/041efb21cbc0760ac94d1fa0093dc57d5185d0d0))
40
+ * override arbre render method ([235763b](https://github.com/joshleblanc/cedar/commit/235763b5820fbcbf7faaee934e14c90f381b128a))
41
+
42
+ ### [0.1.4](https://github.com/joshleblanc/cedar/compare/v0.1.3...v0.1.4) (2021-04-16)
43
+
44
+
45
+ ### Bug Fixes
46
+
47
+ * redirect content to view_component ([b13943f](https://github.com/joshleblanc/cedar/commit/b13943fec1fe22e4a9c47c6300ba306eb1bd248a))
48
+
5
49
  ### [0.1.3](https://github.com/joshleblanc/cedar/compare/v0.1.2...v0.1.3) (2021-04-16)
6
50
 
7
51
  ### [0.1.2](https://github.com/joshleblanc/ilex/compare/v0.1.1...v0.1.2) (2021-04-16)
data/Gemfile.lock CHANGED
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ilex (0.1.3)
4
+ ilex (0.1.8)
5
5
  arbre
6
+ rails (>= 5.2, < 7.0)
6
7
 
7
8
  GEM
8
9
  remote: https://rubygems.org/
@@ -90,6 +91,8 @@ GEM
90
91
  nio4r (2.5.7)
91
92
  nokogiri (1.11.2-x64-mingw32)
92
93
  racc (~> 1.4)
94
+ nokogiri (1.11.2-x86_64-linux)
95
+ racc (~> 1.4)
93
96
  parallel (1.20.1)
94
97
  parser (3.0.0.0)
95
98
  ast (~> 2.4.1)
@@ -163,6 +166,7 @@ GEM
163
166
 
164
167
  PLATFORMS
165
168
  x64-mingw32
169
+ x86_64-linux
166
170
 
167
171
  DEPENDENCIES
168
172
  ilex!
data/cedar.gemspec CHANGED
@@ -32,6 +32,7 @@ Gem::Specification.new do |spec|
32
32
  # Uncomment to register a new dependency of your gem
33
33
  # spec.add_dependency "example-gem", "~> 1.0"
34
34
  spec.add_dependency "arbre"
35
+ spec.add_dependency "rails", [">= 5.2", "< 7.0"]
35
36
 
36
37
  # For more information and examples about making a new gem, checkout our
37
38
  # guide at: https://bundler.io/guides/creating_gem.html
data/lib/ilex.rb CHANGED
@@ -6,8 +6,14 @@ require_relative "ilex/component_warden"
6
6
  require_relative "ilex/component_wardens"
7
7
  require_relative "ilex/context"
8
8
  require_relative "ilex/component"
9
+ require_relative "ilex/arbre_ext/element"
10
+ require_relative "ilex/arbre_ext/element/builder_methods"
11
+ require_relative "ilex/arbre_ext/html/text_node"
12
+ require_relative "ilex/rails_ext/action_view/base"
13
+ require_relative "ilex/engine"
9
14
 
10
15
  module Ilex
11
16
  class Error < StandardError; end
12
17
  # Your code goes here...
13
18
  end
19
+
@@ -0,0 +1,27 @@
1
+ module Ilex
2
+ module ArbreExt
3
+ module Element
4
+ ruby2_keywords def method_missing(name, *args, &block)
5
+ if current_arbre_element.respond_to?(name)
6
+ current_arbre_element.send name, *args, &block
7
+ elsif assigns && assigns.has_key?(name)
8
+ assigns[name]
9
+ elsif helpers.respond_to?(name)
10
+ helper_capture(name, *args, &block)
11
+ else
12
+ super
13
+ end
14
+ end
15
+
16
+ # The helper might have a block that builds Arbre elements
17
+ # which will be rendered (#to_s) inside ActionView::Base#capture.
18
+ # We do not want such elements added to self, so we push a dummy
19
+ # current_arbre_element.
20
+ def helper_capture(name, *args, &block)
21
+ s = ""
22
+ within(Element.new) { s = helpers.send(name, *args, &block) }
23
+ s.is_a?(Element) ? s.to_s : s
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ module Ilex
2
+ module ArbreExt
3
+ module Element
4
+ module BuilderMethods
5
+ private
6
+
7
+ def append_return_block(tag)
8
+ return nil if current_arbre_element.children?
9
+ return unless appendable_tag?(tag)
10
+
11
+ current_arbre_element << if tag.is_a? Array
12
+ Arbre::HTML::TextNode.from_string(tag.join.html_safe)
13
+ else
14
+ Arbre::HTML::TextNode.from_string(tag.to_s)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module Ilex
2
+ module ArbreExt
3
+ module HTML
4
+ module TextNode
5
+ def build(string)
6
+ @content = if string.is_a? Array
7
+ string.join.html_safe
8
+ else
9
+ string
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,45 +1,49 @@
1
- # frozen_string_literal: true
2
-
3
- module Ilex
4
-
5
- ##
6
- # InlineRender provides a `render` dsl to your components
7
- # which will render any arbre tree within.
8
- #
9
- # It will also convert snake case component names to component instances
10
- # for example, this would be equivalent to `ButtonComponent.new(label: "Test")`
11
- #
12
- # ```ruby
13
- # render do
14
- # div do
15
- # button label: "Test"
16
- # end
17
- # end
18
- # ```
19
- module Component
20
- include Arbre::HTML
21
-
22
- # The empty first arg is just to trick rubymine
23
- # when using `render` inside the arbre context
24
- def render(&blk)
25
- define_method :call do
26
- ctx = Context.new(self)
27
- ctx.instance_eval(&blk).to_s
28
- end
29
- end
30
-
31
- def find_component(name)
32
- if const_defined?(name)
33
- const_get(name)
34
- else
35
- if superclass.respond_to?(:find_component)
36
- superclass.find_component(name)
37
- else
38
- adjusted_name = name.chomp("Component").underscore
39
- raise(NameError, "undefined local variable or method `#{adjusted_name}` for #{self}")
40
- end
41
-
42
- end
43
- end
44
- end
45
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Ilex
4
+
5
+ ##
6
+ # InlineRender provides a `render` dsl to your components
7
+ # which will render any arbre tree within.
8
+ #
9
+ # It will also convert snake case component names to component instances
10
+ # for example, this would be equivalent to `ButtonComponent.new(label: "Test")`
11
+ #
12
+ # ```ruby
13
+ # render do
14
+ # div do
15
+ # button label: "Test"
16
+ # end
17
+ # end
18
+ # ```
19
+ module Component
20
+ include Arbre::HTML
21
+
22
+ def render(*args, &blk)
23
+ define_method :call do
24
+ ctx = Context.new(self)
25
+ ctx.instance_eval(&blk).to_s
26
+ end
27
+ end
28
+
29
+ def find_component(name, base_module = nil)
30
+ target = if base_module
31
+ base_module
32
+ else
33
+ self
34
+ end
35
+
36
+ if target.const_defined?(name)
37
+ target.const_get(name)
38
+ else
39
+ if target.superclass.respond_to?(:find_component)
40
+ target.superclass.find_component(name)
41
+ else
42
+ adjusted_name = name.chomp("Component").underscore
43
+ raise(NameError, "undefined local variable or method `#{adjusted_name}` for #{self}")
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,45 +1,65 @@
1
- # frozen_string_literal: true
2
-
3
- module Ilex
4
- ##
5
- # A ComponentWarden is responsible for locating potential components
6
- # given a snake_case representation of that component.
7
- #
8
- # If a component exists, the warden is also responsible for calling the correct
9
- # instantiation method, depending if the component is a collection or not
10
- class ComponentWarden
11
- def initialize(component, string)
12
- @component = component
13
- @raw_input = string
14
-
15
- @collection = @raw_input.end_with? "_collection"
16
- @input = @raw_input.to_s.chomp("_collection")
17
- end
18
-
19
- def collection?
20
- @collection
21
- end
22
-
23
- def component_name
24
- "#{@input}_component".camelize
25
- end
26
-
27
- def component_class
28
- @component_class ||= @component.class.find_component(component_name)
29
- end
30
-
31
- def exists?
32
- component_class.present?
33
- end
34
-
35
- def new(*args, &block)
36
- return nil unless exists?
37
-
38
- if collection?
39
- component_class.with_collection(*args, &block)
40
- else
41
- component_class.new(*args, &block)
42
- end
43
- end
44
- end
45
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Ilex
4
+ ##
5
+ # A ComponentWarden is responsible for locating potential components
6
+ # given a snake_case representation of that component.
7
+ #
8
+ # If a component exists, the warden is also responsible for calling the correct
9
+ # instantiation method, depending if the component is a collection or not
10
+ class ComponentWarden
11
+ def initialize(component, string)
12
+ @component = component
13
+ @input = string.to_s
14
+
15
+ @collection = @input.end_with? "_collection"
16
+ @nested = @input.include? "__"
17
+
18
+ process_input!(@input)
19
+ end
20
+
21
+ def collection?
22
+ @collection
23
+ end
24
+
25
+ def nested?
26
+ @nested
27
+ end
28
+
29
+ def component_name
30
+ "#{@input}_component".camelize
31
+ end
32
+
33
+ def component_class
34
+ @component_class ||= @component.class.find_component(component_name, @base_module)
35
+ end
36
+
37
+ def exists?
38
+ component_class.present?
39
+ end
40
+
41
+ def new(*args, &block)
42
+ return nil unless exists?
43
+
44
+ if collection?
45
+ component_class.with_collection(*args)
46
+ else
47
+ component_class.new(*args)
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def process_input!(input)
54
+ @input.chomp! "_collection"
55
+ @input.chomp! "_component"
56
+
57
+ if nested?
58
+ parts = @input.split("__")
59
+ @input = parts.pop
60
+
61
+ @base_module = parts.map(&:camelize).join("::").constantize
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,18 +1,18 @@
1
- # frozen_string_literal: true
2
-
3
- module Ilex
4
- ##
5
- # Thin wrapper around a hash of component wardens
6
- # such that the default is always an instance of ComponentWarden
7
- class ComponentWardens
8
- def initialize(component)
9
- @wardens = Hash.new do |hash, key|
10
- hash[key] = ComponentWarden.new(component, key)
11
- end
12
- end
13
-
14
- def [](key)
15
- @wardens[key]
16
- end
17
- end
18
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Ilex
4
+ ##
5
+ # Thin wrapper around a hash of component wardens
6
+ # such that the default is always an instance of ComponentWarden
7
+ class ComponentWardens
8
+ def initialize(component)
9
+ @wardens = Hash.new do |hash, key|
10
+ hash[key] = ComponentWarden.new(component, key)
11
+ end
12
+ end
13
+
14
+ def [](key)
15
+ @wardens[key]
16
+ end
17
+ end
18
+ end
data/lib/ilex/context.rb CHANGED
@@ -1,37 +1,69 @@
1
- # frozen_string_literal: true
2
-
3
- module Ilex
4
- ##
5
- # Inject a component's instance variables into arbre's default context
6
- # as well as provide implicit handling of snake-cased component names as
7
- # tags
8
- class Context < Arbre::Context
9
-
10
- def initialize(component)
11
- super({}, component)
12
-
13
- @component = component
14
- @component_wardens = ComponentWardens.new(@component)
15
-
16
- # Copy all of the instance variables from the component to the context,
17
- # so we have access to them when rendering
18
- @component.instance_variables.each do |iv|
19
- instance_variable_set(iv, @component.instance_variable_get(iv))
20
- end
21
- end
22
-
23
- def respond_to_missing?(method, include_all)
24
- @component.respond_to?(method) || @component_wardens[method].exists? || super
25
- end
26
-
27
- def method_missing(method, *args, &content_block)
28
- if @component.respond_to?(method)
29
- @component.send(method, *args, &content_block)
30
- elsif @component_wardens[method].exists?
31
- render @component_wardens[method].new(*args, &content_block)
32
- else
33
- super
34
- end
35
- end
36
- end
37
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Ilex
4
+ ##
5
+ # Inject a component's instance variables into arbre's default context
6
+ # as well as provide implicit handling of snake-cased component names as
7
+ # tags
8
+ class Context < Arbre::Context
9
+
10
+ def initialize(component, &blk)
11
+ @component = component
12
+
13
+
14
+ # Copy all of the instance variables from the component to the context,
15
+ # so we have access to them when rendering
16
+ @component.instance_variables.each do |iv|
17
+ instance_variable_set(iv, @component.instance_variable_get(iv))
18
+ end
19
+
20
+ super({}, component, &blk)
21
+ end
22
+
23
+ def content
24
+ @component.send :content
25
+ end
26
+
27
+ def component_wardens
28
+ @component_wardens ||= ComponentWardens.new(@component)
29
+ end
30
+
31
+ # This is overriding arbre::rails::rendering
32
+ # It performs the same actions, but returns html_safe on a passed block
33
+ #
34
+ # Not 100% sure this is needed, but view_components won't render their
35
+ # contents without it, when rendered in an arbre tree
36
+ def render(*args)
37
+ rendered = helpers.render(*args) do
38
+ if block_given?
39
+ contents = yield
40
+ if contents.is_a? Array
41
+ contents.join.html_safe
42
+ else
43
+ contents.html_safe
44
+ end
45
+ end
46
+ end
47
+ case rendered
48
+ when Arbre::Context
49
+ current_arbre_element.add_child rendered
50
+ else
51
+ text_node rendered
52
+ end
53
+ end
54
+
55
+ def respond_to_missing?(method, include_all)
56
+ @component.respond_to?(method) || component_wardens[method].exists? || super
57
+ end
58
+
59
+ def method_missing(method, *args, &content_block)
60
+ if @component.respond_to?(method)
61
+ @component.send(method, *args, &content_block)
62
+ elsif component_wardens[method].exists?
63
+ render component_wardens[method].new(*args), &content_block
64
+ else
65
+ super
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,11 @@
1
+ module Ilex
2
+ class Engine < ::Rails::Engine
3
+
4
+ config.to_prepare do
5
+ ActionView::Base.prepend RailsExt::ActionView::Base
6
+ Arbre::Element.prepend ArbreExt::Element
7
+ Arbre::Element::BuilderMethods.prepend ArbreExt::Element::BuilderMethods
8
+ Arbre::HTML::TextNode.prepend ArbreExt::HTML::TextNode
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,21 @@
1
+ module Ilex
2
+ module RailsExt
3
+ module ActionView
4
+ module Base
5
+ def capture(*args)
6
+ value = nil
7
+ buffer = with_output_buffer { value = yield(*args) }
8
+
9
+ # Override to handle Arbre elements inside helper blocks.
10
+ # See https://github.com/rails/rails/issues/17661
11
+ # and https://github.com/rails/rails/pull/18024#commitcomment-8975180
12
+ value = value.to_s if value.is_a?(Arbre::Element)
13
+
14
+ if (string = buffer.presence || value) && string.is_a?(String)
15
+ ERB::Util.html_escape string
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
data/lib/ilex/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ilex
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.8"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ilex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua LeBlanc
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-04-16 00:00:00.000000000 Z
11
+ date: 2021-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: arbre
@@ -24,6 +24,26 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '5.2'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '7.0'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '5.2'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '7.0'
27
47
  description: Extends view components to allow rendering inline arbre templates
28
48
  email:
29
49
  - jleblanc@hey.com
@@ -46,10 +66,15 @@ files:
46
66
  - bin/setup
47
67
  - cedar.gemspec
48
68
  - lib/ilex.rb
69
+ - lib/ilex/arbre_ext/element.rb
70
+ - lib/ilex/arbre_ext/element/builder_methods.rb
71
+ - lib/ilex/arbre_ext/html/text_node.rb
49
72
  - lib/ilex/component.rb
50
73
  - lib/ilex/component_warden.rb
51
74
  - lib/ilex/component_wardens.rb
52
75
  - lib/ilex/context.rb
76
+ - lib/ilex/engine.rb
77
+ - lib/ilex/rails_ext/action_view/base.rb
53
78
  - lib/ilex/version.rb
54
79
  homepage: https://github.com/joshleblanc/ilex
55
80
  licenses:
@@ -59,7 +84,7 @@ metadata:
59
84
  homepage_uri: https://github.com/joshleblanc/ilex
60
85
  source_code_uri: https://github.com/joshleblanc/ilex
61
86
  changelog_uri: https://github.com/joshleblanc/ilex
62
- post_install_message:
87
+ post_install_message:
63
88
  rdoc_options: []
64
89
  require_paths:
65
90
  - lib
@@ -74,8 +99,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
99
  - !ruby/object:Gem::Version
75
100
  version: '0'
76
101
  requirements: []
77
- rubygems_version: 3.1.4
78
- signing_key:
102
+ rubygems_version: 3.2.15
103
+ signing_key:
79
104
  specification_version: 4
80
105
  summary: Provides inline rendering to view components
81
106
  test_files: []