ilex 0.1.5 → 0.1.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fbd721cabba89d7f34b23841b6afcfd3d38b79bb35d947a620161e67e6f38cfd
4
- data.tar.gz: 3aca8a08c6ae10f7918bcb239bbe103cd03073d18e1c30fc746a509c30c127f9
3
+ metadata.gz: 52dca54a1d2d71e2ef66b74507d0ac0e6d72c68ade1c7993cfd524564869636a
4
+ data.tar.gz: 765e2c30ac981634ea6fcb4b07f484ef6fecdf9cb99947ccb783d816e5787e74
5
5
  SHA512:
6
- metadata.gz: cb7d4800158d6b0dfb093ffd0f44abbb6009bc8bb8c706125e108fe89c5dbff0e16c50a1d8502b12c846416f8986a61d6b7a5fa9c5e52a5ca0f0600ae8df2816
7
- data.tar.gz: af85c50eedefbbe3ce29849e07c80f38de08037277a57bc71477bd04d67326d8f8af7ae973fb18ddd93d0b13e11c15acf09d588389a46ad65b843f9808dc84a2
6
+ metadata.gz: 55d1bbc9f3153568d3d13e03fd4c11a7aef6450bdd30c16065ef1a0e6e95967158418817d8fe2bed8a5975fef03c4b4eee1a9e8908882b5cbba7f72f615a4e89
7
+ data.tar.gz: 29074aba634643602d17ab0a3f4a7841711fa525fd33836dbf3c1c8fcd2eae7f4e5985ba25c9df692fc71043715a5c2f70f38a498dfecd32a6d325a8a3c0bd5c
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,35 @@
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.9](https://github.com/joshleblanc/ilex/compare/v0.1.8...v0.1.9) (2021-07-24)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * when block returns an arbre element, render context ([e3eda72](https://github.com/joshleblanc/ilex/commit/e3eda728fd30bcb15ebb3f5234229b644bbcf59a))
11
+
12
+ ### [0.1.8](https://github.com/joshleblanc/ilex/compare/v0.1.7...v0.1.8) (2021-06-16)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * handle rendering arrays ([fd09349](https://github.com/joshleblanc/ilex/commit/fd093493a790ada7403acfa8cf2496783cdfbfce))
18
+ * handle root level slot text nodes ([6913197](https://github.com/joshleblanc/ilex/commit/6913197ab4286115734bbbbb4b2fc1c01f286d84))
19
+
20
+ ### [0.1.7](https://github.com/joshleblanc/ilex/compare/v0.1.6...v0.1.7) (2021-06-16)
21
+
22
+
23
+ ### Bug Fixes
24
+
25
+ * try and convert component arrays into strings ([13e0438](https://github.com/joshleblanc/ilex/commit/13e0438d1da6ebd0bc0b46c9ca7cc6828bd99a7f))
26
+
27
+ ### [0.1.6](https://github.com/joshleblanc/cedar/compare/v0.1.5...v0.1.6) (2021-04-18)
28
+
29
+
30
+ ### Bug Fixes
31
+
32
+ * 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)
33
+
5
34
  ### [0.1.5](https://github.com/joshleblanc/cedar/compare/v0.1.4...v0.1.5) (2021-04-17)
6
35
 
7
36
 
data/Gemfile.lock CHANGED
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ilex (0.1.5)
4
+ ilex (0.1.9)
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)
@@ -139,7 +142,7 @@ GEM
139
142
  rubocop-ast (1.4.1)
140
143
  parser (>= 2.7.1.5)
141
144
  ruby-progressbar (1.11.0)
142
- ruby2_keywords (0.0.4)
145
+ ruby2_keywords (0.0.5)
143
146
  sprockets (4.0.2)
144
147
  concurrent-ruby (~> 1.0)
145
148
  rack (> 1, < 3)
@@ -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,49 +1,48 @@
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
+ # 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).html_safe
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
+ end
46
+ end
47
+ end
48
+ end
@@ -1,65 +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
- @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
+ # 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,62 +1,49 @@
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
- yield.html_safe if block_given?
39
- end
40
- case rendered
41
- when Arbre::Context
42
- current_arbre_element.add_child rendered
43
- else
44
- text_node rendered
45
- end
46
- end
47
-
48
- def respond_to_missing?(method, include_all)
49
- @component.respond_to?(method) || component_wardens[method].exists? || super
50
- end
51
-
52
- def method_missing(method, *args, &content_block)
53
- if @component.respond_to?(method)
54
- @component.send(method, *args, &content_block)
55
- elsif component_wardens[method].exists?
56
- render component_wardens[method].new(*args), &content_block
57
- else
58
- super
59
- end
60
- end
61
- end
62
- 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
+ def render(*args, &blk)
32
+ helpers.render(*args, &blk)
33
+ end
34
+
35
+ def respond_to_missing?(method, include_all)
36
+ @component.respond_to?(method) || component_wardens[method].exists? || super
37
+ end
38
+
39
+ def method_missing(method, *args, &content_block)
40
+ if @component.respond_to?(method)
41
+ @component.send(method, *args, &content_block)
42
+ elsif component_wardens[method].exists?
43
+ render component_wardens[method].new(*args), &content_block
44
+ else
45
+ super
46
+ end
47
+ end
48
+ end
49
+ 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,28 @@
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
+ # if args.first&.respond_to? :ctx
10
+ # value = args.first.ctx.children.to_s
11
+ # end
12
+ # We're only capturing the last returned arbre element
13
+ # This uses that element to get the current context, and
14
+ # get the html for the whole tree
15
+ # We have to collect the children manually because
16
+ # `content` is overridden
17
+ if value.is_a? Arbre::Element
18
+ value = value.arbre_context.children.to_s
19
+ end
20
+
21
+ if (string = buffer.presence || value) && string.is_a?(String)
22
+ ERB::Util.html_escape string
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ 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.5"
4
+ VERSION = "0.1.9"
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.5
4
+ version: 0.1.9
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-17 00:00:00.000000000 Z
11
+ date: 2021-07-24 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: []