rbexy 0.3.0 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: deef1d8ce0aa71474ace3e813e28df01736d209b043734b7d83f7bb214a8eb5a
4
- data.tar.gz: 31c8f2258bd54bab4a5f31cebcaf510f965b812fb7aca526098bb18878a41ce3
3
+ metadata.gz: a6728982815c307bb37a495c3d11450e9582bf1cd17eef5306c9e940c0c36eea
4
+ data.tar.gz: 5fdfa1cc3c5fc70b573aa730f827b2f5d38b8031f1adc6344b31926ce520b4af
5
5
  SHA512:
6
- metadata.gz: b11967dff6d336fc3360b731ec6178b255b43e5c502580185541361c7ca3b9df41b5cf1f5c408c7cb1b2719722ff237f687d3bcf0f472b07edbb6137317655ec
7
- data.tar.gz: 4f5238c70548687dc966d4a440a424176619f2255fb00f0a0508a21cf6642f888c7070016efba63e0c18f54c47bfe4873612f843b1058560cfc6bb951d378aff
6
+ metadata.gz: 46385e65a3cd976497efd8d6db789eee4a2c73668e085dd6772d8c6a9a835783f6bb80ef923463af97cfec5d5625fffd641229a5a97a1c24e024b75d996969af
7
+ data.tar.gz: 025e25a41d9cc5e848342c668721cdef046ab13e5cff9737acc69a66eaca6cdd3ac06493bfcbb42b735fcbd6e7ae243e8a65588d648d3442924306944addb714
@@ -1,10 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rbexy (0.3.0)
5
- actionview (>= 5.0, < 7.0)
6
- activesupport (>= 5.0, < 7.0)
7
- railties (>= 5.0, < 7.0)
4
+ rbexy (1.1.0)
5
+ actionview (>= 6.0, < 7.0)
6
+ activesupport (>= 6.0, < 7.0)
8
7
 
9
8
  GEM
10
9
  remote: https://rubygems.org/
@@ -201,7 +200,7 @@ PLATFORMS
201
200
  DEPENDENCIES
202
201
  guard-rspec (~> 4.7, >= 4.7.3)
203
202
  pry-byebug
204
- rails (>= 5.0, < 7.0)
203
+ rails (>= 6.0, < 7.0)
205
204
  rake
206
205
  rbexy!
207
206
  rspec (~> 3.9)
data/README.md CHANGED
@@ -48,6 +48,8 @@ Add it to your Gemfile and `bundle install`:
48
48
  gem "rbexy"
49
49
  ```
50
50
 
51
+ _From 1.0 onward, we only support Rails 6. If you're using Rails 5, use the 0.x releases._
52
+
51
53
  In `config/application.rb`:
52
54
 
53
55
  ```ruby
@@ -6,9 +6,9 @@ module Rbexy
6
6
  autoload :Nodes, "rbexy/nodes"
7
7
  autoload :Runtime, "rbexy/runtime"
8
8
  autoload :HashMash, "rbexy/hash_mash"
9
- autoload :OutputBuffer, "rbexy/output_buffer"
10
9
  autoload :ComponentTagBuilder, "rbexy/component_tag_builder"
11
10
  autoload :ViewContextHelper, "rbexy/view_context_helper"
11
+ autoload :ComponentContext, "rbexy/component_context"
12
12
  autoload :Configuration, "rbexy/configuration"
13
13
 
14
14
  ContextNotFound = Class.new(StandardError)
@@ -3,6 +3,8 @@ require "active_support/core_ext/class/attribute"
3
3
 
4
4
  module Rbexy
5
5
  class Component < ActionView::Base
6
+ autoload :BacktraceCleaner, "rbexy/component/backtrace_cleaner"
7
+
6
8
  class TemplatePath < String
7
9
  def to_s
8
10
  self
@@ -43,21 +45,13 @@ module Rbexy
43
45
  path = TemplatePath.new(component_name)
44
46
  template = view_context.lookup_context.find(path)
45
47
  template.render(self, {})
48
+ rescue ActionView::Template::Error => error
49
+ error.set_backtrace clean_template_backtrace(error.backtrace)
50
+ raise error
46
51
  end
47
52
 
48
53
  def content
49
- content_block ? view_context.capture(self, &content_block) : ""
50
- end
51
-
52
- def create_context(name, value)
53
- rbexy_context.last[name] = value
54
- end
55
-
56
- def use_context(name)
57
- index = rbexy_context.rindex { |c| c.has_key?(name) }
58
- index ?
59
- rbexy_context[index][name] :
60
- raise(ContextNotFound, "no parent context `#{name}`")
54
+ content_block ? content_block.call : ""
61
55
  end
62
56
 
63
57
  def compiled_method_container
@@ -75,5 +69,10 @@ module Rbexy
75
69
  super
76
70
  end
77
71
  end
72
+
73
+ def clean_template_backtrace(backtrace)
74
+ return backtrace if Rbexy.configuration.debug
75
+ BacktraceCleaner.new(backtrace).call
76
+ end
78
77
  end
79
78
  end
@@ -0,0 +1,59 @@
1
+ module Rbexy
2
+ class Component
3
+ class BacktraceCleaner
4
+ attr_reader :backtrace
5
+
6
+ def initialize(backtrace)
7
+ @backtrace = backtrace
8
+ @found_templates = {}
9
+ end
10
+
11
+ def call
12
+ backtrace
13
+ .reject(&method(:internal_implementation_detail?))
14
+ .map(&method(:strip_rbx_internals_block_mention))
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :found_templates
20
+
21
+ def internal_implementation_detail?(line)
22
+ if template = template_name_if_rbx_internals(line)
23
+ redundant_internal_block?(line, template)
24
+ else
25
+ internal_method_call?(line)
26
+ end
27
+ end
28
+
29
+ def internal_method_call?(line)
30
+ line =~ /lib\/rbexy\/.*\.rb/ ||
31
+ line =~ /lib\/action_view\/.*\.rb/ ||
32
+ line =~ /lib\/active_support\/notifications\.rb/
33
+ end
34
+
35
+ def redundant_internal_block?(line, template)
36
+ if found_templates[template]
37
+ true
38
+ else
39
+ found_templates[template] = true
40
+ false
41
+ end
42
+ end
43
+
44
+ def strip_rbx_internals_block_mention(line)
45
+ if template_name_if_rbx_internals(line)
46
+ line.gsub(/block (\(\d+ levels\))? ?in /, "")
47
+ else
48
+ line
49
+ end
50
+ end
51
+
52
+ def template_name_if_rbx_internals(line)
53
+ if /\/(?<template>[^\/]*)\.rbx:\d+:in `(block |_)/ =~ line
54
+ template
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,18 @@
1
+ module Rbexy
2
+ module ComponentContext
3
+ def rbexy_context
4
+ @rbexy_context ||= [{}]
5
+ end
6
+
7
+ def create_context(name, value)
8
+ rbexy_context.last[name] = value
9
+ end
10
+
11
+ def use_context(name)
12
+ index = rbexy_context.rindex { |c| c.has_key?(name) }
13
+ index ?
14
+ rbexy_context[index][name] :
15
+ raise(ContextNotFound, "no parent context `#{name}`")
16
+ end
17
+ end
18
+ end
@@ -3,6 +3,7 @@ module Rbexy
3
3
  attr_accessor :component_provider
4
4
  attr_accessor :template_paths
5
5
  attr_accessor :enable_context
6
+ attr_accessor :debug
6
7
 
7
8
  def template_paths
8
9
  @template_paths ||= []
@@ -22,7 +22,7 @@ module Rbexy
22
22
  text_content: /[^<{#]+/,
23
23
  comment: /^\p{Blank}*#.*(\n|\z)/,
24
24
  whitespace: /\s+/,
25
- attr: /[A-Za-z0-9\-_\.]+/,
25
+ attr: /[A-Za-z0-9\-_\.:]+/,
26
26
  open_attr_splat: /{\*\*/,
27
27
  attr_assignment: /=/,
28
28
  double_quote: /"/,
@@ -237,7 +237,6 @@ module Rbexy
237
237
  end
238
238
 
239
239
  def potential_expression_inner_tag
240
- # binding.pry
241
240
  if self.curr_expr =~ Patterns.expression_internal_tag_prefixes
242
241
  tokens << [:EXPRESSION_BODY, curr_expr]
243
242
  self.curr_expr = ""
@@ -18,11 +18,7 @@ module Rbexy
18
18
  end
19
19
 
20
20
  def compile
21
- [
22
- "Rbexy::OutputBuffer.new.tap { |output|",
23
- children.map(&:compile).map { |c| "output << (#{c})"}.join(";"),
24
- "}.html_safe"
25
- ].join(" ")
21
+ "#{children.map(&:compile).map { |c| "@output_buffer << rbexy_prep_output(#{c})"}.join(";")};@output_buffer"
26
22
  end
27
23
  end
28
24
 
@@ -75,26 +71,24 @@ module Rbexy
75
71
  base_tag = "rbexy_tag.#{Util.safe_tag_name(name)}(#{compile_members})"
76
72
  tag = if children.length > 0
77
73
  [
78
- "#{base_tag} {",
79
- "Rbexy::OutputBuffer.new.tap { |output|",
80
- children.map(&:compile).map { |c| "output << (#{c})"}.join(";"),
81
- "}.html_safe",
82
- "}"
83
- ].join(" ")
74
+ "#{base_tag} { capture {",
75
+ children.map(&:compile).map { |c| "@output_buffer << rbexy_prep_output(#{c})" }.join(";"),
76
+ "} }"
77
+ ].join
84
78
  else
85
79
  base_tag
86
- end
87
-
88
- context_open = Rbexy.configuration.enable_context ? "rbexy_context.push({});" : nil
89
- context_close = Rbexy.configuration.enable_context ? "rbexy_context.pop;" : nil
80
+ end + ".html_safe"
90
81
 
91
- [
92
- "Rbexy::OutputBuffer.new.tap { |output|",
93
- context_open,
94
- "output << (#{tag}).html_safe;",
95
- context_close,
96
- "}.html_safe"
97
- ].join(" ")
82
+ if Rbexy.configuration.enable_context
83
+ [
84
+ "(",
85
+ "rbexy_context.push({});",
86
+ "#{tag}.tap { rbexy_context.pop }",
87
+ ")"
88
+ ].join
89
+ else
90
+ tag
91
+ end
98
92
  end
99
93
 
100
94
  def compile_members
@@ -4,14 +4,21 @@ module Rbexy
4
4
  module Rails
5
5
  module ControllerHelper
6
6
  extend ActiveSupport::Concern
7
+ include ComponentContext
7
8
 
8
9
  def rbexy_component_provider; end
9
10
 
11
+ included do
12
+ helper ViewContextHelper
13
+ helper_method :rbexy_component_provider
14
+ helper_method :rbexy_context, :create_context, :use_context
15
+ end
16
+
10
17
  class_methods do
11
18
  def inherited(klass)
12
19
  super
13
20
  Rbexy.configuration.template_paths.each do |path|
14
- prepend_view_path(Rbexy::Rails::ComponentTemplateResolver.new(path))
21
+ prepend_view_path(ComponentTemplateResolver.new(path))
15
22
  end
16
23
  end
17
24
  end
@@ -4,25 +4,21 @@ module Rbexy
4
4
  module Rails
5
5
  class Engine < ::Rails::Engine
6
6
  initializer "rbexy" do |app|
7
- template_handler = ::Rails.version.to_f >= 6.0 ?
8
- proc { |template, source| Rbexy.compile(source) } :
9
- proc { |template| Rbexy.compile(template.source) }
7
+ template_handler = proc { |template, source| Rbexy.compile(source) }
10
8
 
11
9
  ActionView::Template.register_template_handler(:rbx, template_handler)
12
10
 
13
11
  ActiveSupport.on_load :action_controller_base do
14
- helper Rbexy::ViewContextHelper
15
- helper_method :rbexy_component_provider
16
12
  include ControllerHelper
17
13
  end
18
14
 
19
15
  if defined?(ViewComponent)
20
- ViewComponent::Base.include Rbexy::ViewContextHelper
16
+ ViewComponent::Base.include ViewContextHelper
21
17
  end
22
18
 
23
19
  Rbexy.configure do |config|
24
20
  require "rbexy/component_providers/rbexy_provider"
25
- config.component_provider = Rbexy::ComponentProviders::RbexyProvider.new
21
+ config.component_provider = ComponentProviders::RbexyProvider.new
26
22
  config.template_paths << ::Rails.root.join("app", "components")
27
23
  config.enable_context = true
28
24
  end
@@ -8,6 +8,7 @@ module Rbexy
8
8
  include ActionView::Context
9
9
  include ActionView::Helpers::TagHelper
10
10
  include ViewContextHelper
11
+ include ComponentContext
11
12
 
12
13
  DefaultTagBuilder = ActionView::Helpers::TagHelper::TagBuilder
13
14
 
@@ -34,6 +35,7 @@ module Rbexy
34
35
  end
35
36
 
36
37
  def evaluate(code)
38
+ @output_buffer = ActionView::OutputBuffer.new
37
39
  instance_eval(code)
38
40
  rescue => e
39
41
  e.set_backtrace(e.backtrace.map { |l| l.gsub("(eval)", "(rbx template string)") })
@@ -1,3 +1,3 @@
1
1
  module Rbexy
2
- VERSION = "0.3.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -4,8 +4,16 @@ module Rbexy
4
4
  @rbexy_tag ||= Runtime.create_tag_builder(self)
5
5
  end
6
6
 
7
- def rbexy_context
8
- @rbexy_context ||= [{}]
7
+ def rbexy_prep_output(*value)
8
+ return if value.length == 0
9
+ value = value.first
10
+
11
+ value = rbexy_is_html_safe_array?(value) ? value.join.html_safe : value
12
+ [nil, false].include?(value) ? "" : value.to_s
13
+ end
14
+
15
+ def rbexy_is_html_safe_array?(value)
16
+ value.is_a?(Array) && value.all? { |v| v.respond_to?(:html_safe?) && v.html_safe? }
9
17
  end
10
18
  end
11
19
  end
@@ -25,11 +25,10 @@ Gem::Specification.new do |spec|
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
26
  spec.require_paths = ["lib"]
27
27
 
28
- spec.add_dependency "activesupport", ">= 5.0", "< 7.0"
29
- spec.add_dependency "actionview", ">= 5.0", "< 7.0"
30
- spec.add_dependency "railties", ">= 5.0", "< 7.0"
28
+ spec.add_dependency "activesupport", ">= 6.0", "< 7.0"
29
+ spec.add_dependency "actionview", ">= 6.0", "< 7.0"
31
30
 
32
- spec.add_development_dependency "rails", ">= 5.0", "< 7.0"
31
+ spec.add_development_dependency "rails", ">= 6.0", "< 7.0"
33
32
  spec.add_development_dependency "rspec", "~> 3.9"
34
33
  spec.add_development_dependency "guard-rspec", "~> 4.7", ">= 4.7.3"
35
34
  spec.add_development_dependency "rspec-rails", "~> 4.0", ">= 4.0.1"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbexy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Giancola
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-28 00:00:00.000000000 Z
11
+ date: 2020-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '5.0'
19
+ version: '6.0'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '7.0'
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '5.0'
29
+ version: '6.0'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '7.0'
@@ -36,7 +36,7 @@ dependencies:
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: '5.0'
39
+ version: '6.0'
40
40
  - - "<"
41
41
  - !ruby/object:Gem::Version
42
42
  version: '7.0'
@@ -46,27 +46,7 @@ dependencies:
46
46
  requirements:
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: '5.0'
50
- - - "<"
51
- - !ruby/object:Gem::Version
52
- version: '7.0'
53
- - !ruby/object:Gem::Dependency
54
- name: railties
55
- requirement: !ruby/object:Gem::Requirement
56
- requirements:
57
- - - ">="
58
- - !ruby/object:Gem::Version
59
- version: '5.0'
60
- - - "<"
61
- - !ruby/object:Gem::Version
62
- version: '7.0'
63
- type: :runtime
64
- prerelease: false
65
- version_requirements: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- version: '5.0'
49
+ version: '6.0'
70
50
  - - "<"
71
51
  - !ruby/object:Gem::Version
72
52
  version: '7.0'
@@ -76,7 +56,7 @@ dependencies:
76
56
  requirements:
77
57
  - - ">="
78
58
  - !ruby/object:Gem::Version
79
- version: '5.0'
59
+ version: '6.0'
80
60
  - - "<"
81
61
  - !ruby/object:Gem::Version
82
62
  version: '7.0'
@@ -86,7 +66,7 @@ dependencies:
86
66
  requirements:
87
67
  - - ">="
88
68
  - !ruby/object:Gem::Version
89
- version: '5.0'
69
+ version: '6.0'
90
70
  - - "<"
91
71
  - !ruby/object:Gem::Version
92
72
  version: '7.0'
@@ -224,6 +204,8 @@ files:
224
204
  - example.rb
225
205
  - lib/rbexy.rb
226
206
  - lib/rbexy/component.rb
207
+ - lib/rbexy/component/backtrace_cleaner.rb
208
+ - lib/rbexy/component_context.rb
227
209
  - lib/rbexy/component_providers/namespaced_rbexy_provider.rb
228
210
  - lib/rbexy/component_providers/rbexy_provider.rb
229
211
  - lib/rbexy/component_providers/view_component_provider.rb
@@ -232,7 +214,6 @@ files:
232
214
  - lib/rbexy/hash_mash.rb
233
215
  - lib/rbexy/lexer.rb
234
216
  - lib/rbexy/nodes.rb
235
- - lib/rbexy/output_buffer.rb
236
217
  - lib/rbexy/parser.rb
237
218
  - lib/rbexy/rails.rb
238
219
  - lib/rbexy/rails/component_template_resolver.rb
@@ -1,10 +0,0 @@
1
- require "active_support/core_ext/string/output_safety"
2
-
3
- module Rbexy
4
- class OutputBuffer < ActiveSupport::SafeBuffer
5
- def <<(content)
6
- value = content.is_a?(Array) ? content.join.html_safe : content
7
- super([nil, false].include?(value) ? "" : value.to_s)
8
- end
9
- end
10
- end