rbexy 0.3.1 → 2.0.0.beta1
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 +4 -4
- data/Gemfile.lock +6 -5
- data/README.md +20 -0
- data/lib/rbexy.rb +27 -10
- data/lib/rbexy/ast_transformer.rb +21 -0
- data/lib/rbexy/component.rb +12 -18
- data/lib/rbexy/component/backtrace_cleaner.rb +59 -0
- data/lib/rbexy/component_context.rb +18 -0
- data/lib/rbexy/component_resolver.rb +60 -0
- data/lib/rbexy/configuration.rb +19 -1
- data/lib/rbexy/lexer.rb +20 -14
- data/lib/rbexy/nodes.rb +15 -141
- data/lib/rbexy/nodes/abstract_attr.rb +12 -0
- data/lib/rbexy/nodes/abstract_element.rb +13 -0
- data/lib/rbexy/nodes/abstract_node.rb +58 -0
- data/lib/rbexy/nodes/component_element.rb +69 -0
- data/lib/rbexy/nodes/component_prop.rb +29 -0
- data/lib/rbexy/nodes/declaration.rb +15 -0
- data/lib/rbexy/nodes/expression.rb +15 -0
- data/lib/rbexy/nodes/expression_group.rb +55 -0
- data/lib/rbexy/nodes/html_attr.rb +13 -0
- data/lib/rbexy/nodes/html_element.rb +48 -0
- data/lib/rbexy/nodes/newline.rb +9 -0
- data/lib/rbexy/nodes/raw.rb +23 -0
- data/lib/rbexy/nodes/root.rb +19 -0
- data/lib/rbexy/nodes/text.rb +15 -0
- data/lib/rbexy/nodes/util.rb +9 -0
- data/lib/rbexy/parser.rb +22 -16
- data/lib/rbexy/rails/component_template_resolver.rb +3 -3
- data/lib/rbexy/rails/controller_helper.rb +5 -4
- data/lib/rbexy/rails/engine.rb +1 -11
- data/lib/rbexy/refinements.rb +5 -0
- data/lib/rbexy/refinements/array.rb +9 -0
- data/lib/rbexy/refinements/array/find_map.rb +13 -0
- data/lib/rbexy/refinements/array/insert_between_types.rb +26 -0
- data/lib/rbexy/refinements/array/map_type_when_neighboring_type.rb +26 -0
- data/lib/rbexy/runtime.rb +17 -23
- data/lib/rbexy/template.rb +12 -0
- data/lib/rbexy/version.rb +1 -1
- data/rbexy.gemspec +4 -4
- metadata +49 -38
- data/example.rb +0 -113
- data/lib/rbexy/component_providers/namespaced_rbexy_provider.rb +0 -20
- data/lib/rbexy/component_providers/rbexy_provider.rb +0 -21
- data/lib/rbexy/component_providers/view_component_provider.rb +0 -21
- data/lib/rbexy/component_tag_builder.rb +0 -19
- data/lib/rbexy/hash_mash.rb +0 -15
- data/lib/rbexy/output_buffer.rb +0 -10
- data/lib/rbexy/view_context_helper.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c25ae0414d2229676a67b1ec6ee63c6092d00bb699668cd1213c93d50dee2356
|
4
|
+
data.tar.gz: 00d80e6099de62ca467cf6c75b661cf43eeb8641fe15c510163ba6f02a1fcc99
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e29d842f6f9d90c2908be38c58e8d86a365496eb60b093dacc15364f19af00238457a8e7d4877f8db9305a88a29db5c5a6682b2684c41abd8c0ffa19b8279cb4
|
7
|
+
data.tar.gz: 8298b8fa13abef5f8a85f0df96d9abda969cc0b98417c5668f34b644ba79a9d0821c372989f0111149b4abc1b9851eb4d69e8aa79b5d69a91f425a931845e24d
|
data/Gemfile.lock
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rbexy (0.
|
5
|
-
actionview (>=
|
6
|
-
activesupport (>=
|
7
|
-
railties (>= 5.0, < 7.0)
|
4
|
+
rbexy (2.0.0.beta1)
|
5
|
+
actionview (>= 6.0, < 7.0)
|
6
|
+
activesupport (>= 6.0, < 7.0)
|
8
7
|
|
9
8
|
GEM
|
10
9
|
remote: https://rubygems.org/
|
@@ -102,6 +101,7 @@ GEM
|
|
102
101
|
mini_mime (>= 0.1.1)
|
103
102
|
marcel (0.3.3)
|
104
103
|
mimemagic (~> 0.3.2)
|
104
|
+
memory_profiler (0.9.14)
|
105
105
|
method_source (1.0.0)
|
106
106
|
mimemagic (0.3.5)
|
107
107
|
mini_mime (1.0.2)
|
@@ -200,8 +200,9 @@ PLATFORMS
|
|
200
200
|
|
201
201
|
DEPENDENCIES
|
202
202
|
guard-rspec (~> 4.7, >= 4.7.3)
|
203
|
+
memory_profiler (~> 0.9.14)
|
203
204
|
pry-byebug
|
204
|
-
rails (>=
|
205
|
+
rails (>= 6.0, < 7.0)
|
205
206
|
rake
|
206
207
|
rbexy!
|
207
208
|
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
|
@@ -171,6 +173,14 @@ Loops:
|
|
171
173
|
</ul>
|
172
174
|
```
|
173
175
|
|
176
|
+
Blocks:
|
177
|
+
|
178
|
+
```jsx
|
179
|
+
{link_to "/" do
|
180
|
+
<span>Click me</span>
|
181
|
+
end}
|
182
|
+
```
|
183
|
+
|
174
184
|
As an attribute:
|
175
185
|
|
176
186
|
```jsx
|
@@ -187,6 +197,16 @@ Pass a lambda to a prop, that when called returns a tag:
|
|
187
197
|
</Hero>
|
188
198
|
```
|
189
199
|
|
200
|
+
_Note that when using tags inside blocks, the block must evaluate to a single root element. Rbexy behaves similar to JSX in this way. E.g.:_
|
201
|
+
|
202
|
+
```
|
203
|
+
# Do
|
204
|
+
-> { <span><i>Hello</i> World</span> }
|
205
|
+
|
206
|
+
# Don't
|
207
|
+
-> { <i>Hello</i> World }
|
208
|
+
```
|
209
|
+
|
190
210
|
### Tags
|
191
211
|
|
192
212
|
You can put standard HTML tags anywhere.
|
data/lib/rbexy.rb
CHANGED
@@ -1,15 +1,22 @@
|
|
1
1
|
require "rbexy/version"
|
2
|
+
require "active_support/inflector"
|
3
|
+
require "active_support/concern"
|
4
|
+
require "action_view/helpers/output_safety_helper"
|
5
|
+
require "action_view/helpers/capture_helper"
|
6
|
+
require "action_view/helpers/tag_helper"
|
7
|
+
require "action_view/context"
|
2
8
|
|
3
9
|
module Rbexy
|
4
10
|
autoload :Lexer, "rbexy/lexer"
|
5
11
|
autoload :Parser, "rbexy/parser"
|
6
12
|
autoload :Nodes, "rbexy/nodes"
|
7
13
|
autoload :Runtime, "rbexy/runtime"
|
8
|
-
autoload :
|
9
|
-
autoload :OutputBuffer, "rbexy/output_buffer"
|
10
|
-
autoload :ComponentTagBuilder, "rbexy/component_tag_builder"
|
11
|
-
autoload :ViewContextHelper, "rbexy/view_context_helper"
|
14
|
+
autoload :ComponentContext, "rbexy/component_context"
|
12
15
|
autoload :Configuration, "rbexy/configuration"
|
16
|
+
autoload :ComponentResolver, "rbexy/component_resolver"
|
17
|
+
autoload :Template, "rbexy/template"
|
18
|
+
autoload :Refinements, "rbexy/refinements"
|
19
|
+
autoload :ASTTransformer, "rbexy/ast_transformer"
|
13
20
|
|
14
21
|
ContextNotFound = Class.new(StandardError)
|
15
22
|
|
@@ -22,14 +29,24 @@ module Rbexy
|
|
22
29
|
@configuration ||= Configuration.new
|
23
30
|
end
|
24
31
|
|
25
|
-
def compile(
|
26
|
-
tokens =
|
27
|
-
|
28
|
-
|
32
|
+
def compile(template, context = build_default_compile_context(template))
|
33
|
+
tokens = Lexer.new(template, context.element_resolver).tokenize
|
34
|
+
root = Parser.new(tokens).parse
|
35
|
+
root.inject_compile_context(context)
|
36
|
+
root.transform!
|
37
|
+
root.precompile.compile
|
29
38
|
end
|
30
39
|
|
31
|
-
def evaluate(template_string, runtime)
|
32
|
-
runtime.evaluate compile(template_string)
|
40
|
+
def evaluate(template_string, runtime = Rbexy::Runtime.new)
|
41
|
+
runtime.evaluate compile(Template.new(template_string))
|
42
|
+
end
|
43
|
+
|
44
|
+
def build_default_compile_context(template)
|
45
|
+
OpenStruct.new(
|
46
|
+
template: template,
|
47
|
+
element_resolver: configuration.element_resolver,
|
48
|
+
ast_transformer: configuration.transforms
|
49
|
+
)
|
33
50
|
end
|
34
51
|
end
|
35
52
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Rbexy
|
2
|
+
class ASTTransformer
|
3
|
+
attr_reader :registry
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
clear!
|
7
|
+
end
|
8
|
+
|
9
|
+
def register(*node_classes, &block)
|
10
|
+
node_classes.each { |k| (registry[k] ||= []) << block }
|
11
|
+
end
|
12
|
+
|
13
|
+
def transform(node, context)
|
14
|
+
registry[node.class]&.each { |t| t.call(node, context) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def clear!
|
18
|
+
@registry = {}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/rbexy/component.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require "action_view"
|
2
|
-
require "active_support/core_ext/class/attribute"
|
3
2
|
|
4
3
|
module Rbexy
|
5
4
|
class Component < ActionView::Base
|
5
|
+
autoload :BacktraceCleaner, "rbexy/component/backtrace_cleaner"
|
6
|
+
|
6
7
|
class TemplatePath < String
|
7
8
|
def to_s
|
8
9
|
self
|
@@ -43,21 +44,13 @@ module Rbexy
|
|
43
44
|
path = TemplatePath.new(component_name)
|
44
45
|
template = view_context.lookup_context.find(path)
|
45
46
|
template.render(self, {})
|
47
|
+
rescue ActionView::Template::Error => error
|
48
|
+
error.set_backtrace clean_template_backtrace(error.backtrace)
|
49
|
+
raise error
|
46
50
|
end
|
47
51
|
|
48
52
|
def content
|
49
|
-
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}`")
|
53
|
+
content_block ? content_block.call : ""
|
61
54
|
end
|
62
55
|
|
63
56
|
def compiled_method_container
|
@@ -69,11 +62,12 @@ module Rbexy
|
|
69
62
|
attr_reader :view_context, :content_block
|
70
63
|
|
71
64
|
def method_missing(meth, *args, &block)
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
65
|
+
view_context.send(meth, *args, &block)
|
66
|
+
end
|
67
|
+
|
68
|
+
def clean_template_backtrace(backtrace)
|
69
|
+
return backtrace if Rbexy.configuration.debug
|
70
|
+
BacktraceCleaner.new(backtrace).call
|
77
71
|
end
|
78
72
|
end
|
79
73
|
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
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Rbexy
|
2
|
+
class ComponentResolver
|
3
|
+
using Rbexy::Refinements::Array::FindMap
|
4
|
+
|
5
|
+
KNOWN_HTML_ELEMENTS = %w(
|
6
|
+
a abbr acronym address animate animateMotion animateTransform applet area article aside audio b base basefont
|
7
|
+
bdi bdo bgsound big blink blockquote body br button canvas caption center circle cite clipPath code col colgroup
|
8
|
+
color-profile command content data datalist dd defs del desc details dfn dialog dir discard div dl dt element
|
9
|
+
ellipse em embed feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting
|
10
|
+
feDisplacementMap feDistantLight feDropShadow feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage
|
11
|
+
feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence
|
12
|
+
fieldset figcaption figure filter font footer foreignObject form frame frameset g h1 h2 h3 h4 h5 h6 hatch
|
13
|
+
hatchpath head header hgroup hr html i iframe image img input ins isindex kbd keygen label legend li line
|
14
|
+
linearGradient link listing main map mark marker marquee mask menu menuitem mesh meshgradient meshpatch meshrow
|
15
|
+
meta metadata meter mpath multicol nav nextid nobr noembed noframes noscript object ol optgroup option output p
|
16
|
+
param path pattern picture plaintext polygon polyline pre progress q radialGradient rb rect rp rt rtc ruby s
|
17
|
+
samp script section select set shadow slot small solidcolor source spacer span stop strike strong style sub
|
18
|
+
summary sup svg switch symbol table tbody td template text textarea textPath tfoot th thead time title tr track
|
19
|
+
tspan tt u ul unknown use var video view wbr xmp
|
20
|
+
).to_set
|
21
|
+
|
22
|
+
attr_reader :component_namespaces
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
self.component_namespaces = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def component_namespaces=(hash)
|
29
|
+
@component_namespaces = hash.transform_keys(&:to_s)
|
30
|
+
end
|
31
|
+
|
32
|
+
def component?(name, template)
|
33
|
+
return false if KNOWN_HTML_ELEMENTS.include?(name)
|
34
|
+
return true if component_class(name, template)
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
38
|
+
def component_class(name, template)
|
39
|
+
possible_names = matching_namespaces(template).map { |ns| "#{ns}.#{name}" } << name
|
40
|
+
possible_names.find_map(&method(:find))
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def find(name)
|
46
|
+
find!(name)
|
47
|
+
rescue NameError => e
|
48
|
+
raise e unless e.message =~ /wrong constant name/ || e.message =~ /uninitialized constant/
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def matching_namespaces(template)
|
53
|
+
component_namespaces.select { |path, ns| template.identifier.start_with?(path) }.values.flatten.uniq
|
54
|
+
end
|
55
|
+
|
56
|
+
def find!(name)
|
57
|
+
ActiveSupport::Inflector.constantize("#{name.gsub(".", "::")}Component")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/rbexy/configuration.rb
CHANGED
@@ -1,11 +1,29 @@
|
|
1
1
|
module Rbexy
|
2
2
|
class Configuration
|
3
|
-
attr_accessor :
|
3
|
+
attr_accessor :element_resolver
|
4
4
|
attr_accessor :template_paths
|
5
5
|
attr_accessor :enable_context
|
6
|
+
attr_accessor :debug
|
7
|
+
attr_accessor :component_rendering_templates
|
8
|
+
attr_accessor :transforms
|
6
9
|
|
7
10
|
def template_paths
|
8
11
|
@template_paths ||= []
|
9
12
|
end
|
13
|
+
|
14
|
+
def element_resolver
|
15
|
+
@element_resolver ||= ComponentResolver.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def transforms
|
19
|
+
@transforms ||= ASTTransformer.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def component_rendering_templates
|
23
|
+
@component_rendering_templates ||= {
|
24
|
+
children: "{capture{%{children}}}",
|
25
|
+
component: "::%{component_class}.new(%{view_context},%{kwargs}).render%{children_block}"
|
26
|
+
}
|
27
|
+
end
|
10
28
|
end
|
11
29
|
end
|
data/lib/rbexy/lexer.rb
CHANGED
@@ -10,7 +10,7 @@ module Rbexy
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
Patterns =
|
13
|
+
Patterns = OpenStruct.new(
|
14
14
|
open_expression: /{/,
|
15
15
|
close_expression: /}/,
|
16
16
|
expression_content: /[^}{"'<]+/,
|
@@ -33,19 +33,19 @@ module Rbexy
|
|
33
33
|
declaration: /<![^>]*>/
|
34
34
|
)
|
35
35
|
|
36
|
-
attr_reader :stack, :tokens, :scanner, :
|
37
|
-
attr_accessor :
|
36
|
+
attr_reader :stack, :tokens, :scanner, :element_resolver, :template
|
37
|
+
attr_accessor :curr_expr, :curr_default_text,
|
38
38
|
:curr_quoted_text
|
39
39
|
|
40
|
-
def initialize(
|
40
|
+
def initialize(template, element_resolver)
|
41
|
+
@template = template
|
42
|
+
@scanner = StringScanner.new(template.source)
|
43
|
+
@element_resolver = element_resolver
|
41
44
|
@stack = [:default]
|
42
|
-
@curr_expr_bracket_levels = 0
|
43
|
-
@curr_expr_quote_levels = { single: 0, double: 0 }
|
44
45
|
@curr_expr = ""
|
45
46
|
@curr_default_text = ""
|
46
47
|
@curr_quoted_text = ""
|
47
48
|
@tokens = []
|
48
|
-
@scanner = StringScanner.new(code)
|
49
49
|
end
|
50
50
|
|
51
51
|
def tokenize
|
@@ -59,7 +59,7 @@ module Rbexy
|
|
59
59
|
elsif scanner.scan(Patterns.open_expression)
|
60
60
|
open_expression
|
61
61
|
elsif scanner.scan(Patterns.comment)
|
62
|
-
tokens << [:
|
62
|
+
tokens << [:NEWLINE]
|
63
63
|
elsif scanner.check(Patterns.text_content)
|
64
64
|
stack.push(:default_text)
|
65
65
|
else
|
@@ -74,7 +74,7 @@ module Rbexy
|
|
74
74
|
elsif scanner.scan(Patterns.open_expression)
|
75
75
|
open_expression
|
76
76
|
elsif scanner.scan(Patterns.comment)
|
77
|
-
tokens << [:
|
77
|
+
tokens << [:NEWLINE]
|
78
78
|
elsif scanner.check(Patterns.text_content)
|
79
79
|
stack.push(:default_text)
|
80
80
|
else
|
@@ -163,9 +163,9 @@ module Rbexy
|
|
163
163
|
tokens << [:CLOSE_TAG_DEF]
|
164
164
|
stack.pop
|
165
165
|
elsif scanner.scan(Patterns.tag_name)
|
166
|
-
tokens << [:
|
166
|
+
tokens << [:TAG_DETAILS, tag_details(scanner.matched)]
|
167
167
|
elsif scanner.scan(Patterns.whitespace)
|
168
|
-
scanner.matched.count("\n").times { tokens << [:
|
168
|
+
scanner.matched.count("\n").times { tokens << [:NEWLINE] }
|
169
169
|
tokens << [:OPEN_ATTRS]
|
170
170
|
stack.push(:tag_attrs)
|
171
171
|
else
|
@@ -182,7 +182,7 @@ module Rbexy
|
|
182
182
|
end
|
183
183
|
when :tag_attrs
|
184
184
|
if scanner.scan(Patterns.whitespace)
|
185
|
-
scanner.matched.count("\n").times { tokens << [:
|
185
|
+
scanner.matched.count("\n").times { tokens << [:NEWLINE] }
|
186
186
|
elsif scanner.check(Patterns.close_tag)
|
187
187
|
tokens << [:CLOSE_ATTRS]
|
188
188
|
stack.pop
|
@@ -205,7 +205,7 @@ module Rbexy
|
|
205
205
|
open_expression
|
206
206
|
elsif scanner.scan(Patterns.whitespace) || scanner.check(Patterns.close_tag)
|
207
207
|
tokens << [:CLOSE_ATTR_VALUE]
|
208
|
-
scanner.matched.count("\n").times { tokens << [:
|
208
|
+
scanner.matched.count("\n").times { tokens << [:NEWLINE] }
|
209
209
|
stack.pop
|
210
210
|
else
|
211
211
|
raise SyntaxError, self
|
@@ -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 = ""
|
@@ -287,5 +286,12 @@ module Rbexy
|
|
287
286
|
# etc).
|
288
287
|
scanner.scan(Patterns.expression_content) || scanner.scan(Patterns.open_tag_end)
|
289
288
|
end
|
289
|
+
|
290
|
+
def tag_details(name)
|
291
|
+
type = element_resolver.component?(name, template) ? :component : :html
|
292
|
+
details = { name: scanner.matched, type: type }
|
293
|
+
details[:component_class] = element_resolver.component_class(name, template) if type == :component
|
294
|
+
details
|
295
|
+
end
|
290
296
|
end
|
291
297
|
end
|