phlex 0.4.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of phlex might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.rubocop.yml +21 -1
- data/Gemfile +26 -13
- data/README.md +1 -1
- data/SECURITY.md +1 -1
- data/bench.rb +7 -0
- data/config/sus.rb +15 -0
- data/docs/assets/application.css +6 -0
- data/docs/build.rb +2 -0
- data/docs/components/callout.rb +1 -1
- data/docs/components/code_block.rb +2 -2
- data/docs/components/code_span.rb +1 -1
- data/docs/components/example.rb +4 -4
- data/docs/components/heading.rb +2 -2
- data/docs/components/layout.rb +55 -32
- data/docs/components/markdown.rb +13 -28
- data/docs/components/nav/item.rb +1 -1
- data/docs/components/nav.rb +1 -1
- data/docs/components/tabs/tab.rb +1 -1
- data/docs/components/tabs.rb +1 -1
- data/docs/components/title.rb +2 -2
- data/docs/pages/application_page.rb +1 -1
- data/docs/pages/helpers.rb +5 -5
- data/docs/pages/library/collections.rb +4 -22
- data/docs/pages/rails/getting_started.rb +7 -3
- data/docs/pages/rails/helpers.rb +3 -1
- data/docs/pages/rails/layouts.rb +2 -2
- data/docs/pages/rails/rendering_views.rb +1 -1
- data/docs/pages/templates.rb +6 -6
- data/docs/pages/testing/capybara.rb +48 -0
- data/docs/pages/testing/getting_started.rb +44 -0
- data/docs/pages/testing/nokogiri.rb +83 -0
- data/docs/pages/testing/rails.rb +17 -0
- data/docs/pages/translations.rb +81 -0
- data/docs/pages/views.rb +56 -8
- data/fixtures/compiler_test_helpers.rb +19 -0
- data/fixtures/content.rb +60 -0
- data/fixtures/dummy/app/views/application_view.rb +8 -0
- data/fixtures/dummy/app/views/articles/form.rb +1 -1
- data/fixtures/dummy/app/views/card.rb +1 -1
- data/fixtures/dummy/app/views/comments/comment.rb +1 -1
- data/fixtures/dummy/app/views/comments/reaction.rb +1 -1
- data/fixtures/dummy/app/views/heading.rb +1 -1
- data/fixtures/layout.rb +5 -5
- data/fixtures/page.rb +18 -24
- data/fixtures/{test_helper.rb → rails_helper.rb} +3 -8
- data/fixtures/standard_element.rb +87 -0
- data/fixtures/view_helper.rb +1 -1
- data/fixtures/void_element.rb +31 -0
- data/lib/generators/phlex/collection/templates/collection.rb.erb +2 -1
- data/lib/generators/phlex/controller/USAGE +10 -0
- data/lib/generators/phlex/controller/controller_generator.rb +54 -0
- data/lib/generators/phlex/controller/templates/controller.rb.erb +10 -0
- data/lib/generators/phlex/controller/templates/view.rb.erb +14 -0
- data/lib/generators/phlex/layout/templates/layout.rb.erb +2 -1
- data/lib/generators/phlex/page/templates/page.rb.erb +3 -1
- data/lib/generators/phlex/table/templates/table.rb.erb +3 -1
- data/lib/generators/phlex/view/templates/view.rb.erb +7 -1
- data/lib/generators/phlex/view/view_generator.rb +9 -1
- data/lib/install/phlex.rb +10 -1
- data/lib/phlex/block.rb +2 -4
- data/lib/phlex/buffered.rb +6 -8
- data/lib/phlex/callable.rb +9 -0
- data/lib/phlex/collection.rb +2 -27
- data/lib/phlex/compiler/elements.rb +49 -0
- data/lib/phlex/compiler/generators/content.rb +103 -0
- data/lib/phlex/compiler/generators/element.rb +61 -0
- data/lib/phlex/compiler/nodes/base.rb +19 -0
- data/lib/phlex/compiler/nodes/call.rb +9 -0
- data/lib/phlex/compiler/nodes/command.rb +13 -0
- data/lib/phlex/compiler/nodes/fcall.rb +18 -0
- data/lib/phlex/compiler/nodes/method_add_block.rb +33 -0
- data/lib/phlex/compiler/nodes/vcall.rb +9 -0
- data/lib/phlex/compiler/optimizer.rb +66 -0
- data/lib/phlex/compiler/visitors/base.rb +15 -0
- data/lib/phlex/compiler/visitors/file.rb +23 -11
- data/lib/phlex/compiler/visitors/stable_scope.rb +28 -0
- data/lib/phlex/compiler/visitors/statements.rb +36 -0
- data/lib/phlex/compiler/visitors/view.rb +19 -0
- data/lib/phlex/compiler/visitors/view_method.rb +59 -0
- data/lib/phlex/compiler.rb +23 -3
- data/lib/phlex/elements.rb +57 -0
- data/lib/phlex/helpers.rb +59 -0
- data/lib/phlex/html/callbacks.rb +11 -0
- data/lib/phlex/html.rb +208 -47
- data/lib/phlex/markdown.rb +76 -0
- data/lib/phlex/rails/form.rb +67 -0
- data/lib/phlex/rails/helpers.rb +39 -2
- data/lib/phlex/rails.rb +10 -0
- data/lib/phlex/renderable.rb +9 -3
- data/lib/phlex/testing/capybara.rb +25 -0
- data/lib/phlex/testing/nokogiri.rb +24 -0
- data/lib/phlex/testing/rails.rb +19 -0
- data/lib/phlex/testing/view_helper.rb +15 -0
- data/lib/phlex/translation.rb +23 -0
- data/lib/phlex/turbo/frame.rb +21 -0
- data/lib/phlex/turbo/stream.rb +18 -0
- data/lib/phlex/version.rb +1 -1
- data/lib/phlex.rb +23 -24
- metadata +62 -14
- data/.rspec +0 -1
- data/fixtures/compilation/vcall.rb +0 -38
- data/lib/phlex/compiler/generators/standard_element.rb +0 -30
- data/lib/phlex/compiler/generators/void_element.rb +0 -29
- data/lib/phlex/compiler/optimizers/base_optimizer.rb +0 -34
- data/lib/phlex/compiler/optimizers/vcall.rb +0 -29
- data/lib/phlex/compiler/visitors/base_visitor.rb +0 -19
- data/lib/phlex/compiler/visitors/component.rb +0 -28
- data/lib/phlex/compiler/visitors/component_method.rb +0 -28
- data/lib/phlex/view.rb +0 -229
data/lib/phlex.rb
CHANGED
@@ -1,34 +1,40 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "hescape"
|
4
4
|
require "zeitwerk"
|
5
5
|
require "syntax_tree"
|
6
6
|
|
7
|
-
loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
|
8
|
-
loader.ignore("#{__dir__}/generators")
|
9
|
-
loader.ignore("#{__dir__}/install")
|
10
|
-
loader.inflector.inflect("html" => "HTML")
|
11
|
-
loader.inflector.inflect("vcall" => "VCall")
|
12
|
-
loader.inflector.inflect("fcall" => "FCall")
|
13
|
-
loader.setup
|
14
|
-
|
15
7
|
module Phlex
|
8
|
+
Loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false).tap do |loader|
|
9
|
+
loader.ignore("#{__dir__}/generators")
|
10
|
+
loader.ignore("#{__dir__}/install")
|
11
|
+
|
12
|
+
loader.ignore("#{__dir__}/phlex/testing")
|
13
|
+
loader.ignore("#{__dir__}/phlex/markdown")
|
14
|
+
|
15
|
+
loader.ignore("#{__dir__}/phlex/rails.rb")
|
16
|
+
loader.ignore("#{__dir__}/phlex/rails")
|
17
|
+
|
18
|
+
loader.inflector.inflect("html" => "HTML")
|
19
|
+
loader.inflector.inflect("vcall" => "VCall")
|
20
|
+
loader.inflector.inflect("fcall" => "FCall")
|
21
|
+
loader.setup
|
22
|
+
end
|
23
|
+
|
16
24
|
Error = Module.new
|
17
25
|
ArgumentError = Class.new(ArgumentError) { include Error }
|
18
26
|
NameError = Class.new(NameError) { include Error }
|
19
27
|
|
28
|
+
def self.const_missing(name)
|
29
|
+
if name == :View
|
30
|
+
raise NameError, "👋 Phlex::View has been renamed (again 🙄) to Phlex::HTML."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
20
34
|
extend self
|
21
35
|
|
22
36
|
ATTRIBUTE_CACHE = {}
|
23
37
|
|
24
|
-
def const_missing(name)
|
25
|
-
if name == :Component
|
26
|
-
raise NameError, "👋 Phlex::Component is now Phlex::View"
|
27
|
-
else
|
28
|
-
super
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
38
|
def configuration
|
33
39
|
@configuration ||= Configuration.new
|
34
40
|
end
|
@@ -37,10 +43,3 @@ module Phlex
|
|
37
43
|
yield configuration
|
38
44
|
end
|
39
45
|
end
|
40
|
-
|
41
|
-
begin
|
42
|
-
require "rails"
|
43
|
-
require "phlex/engine"
|
44
|
-
rescue LoadError
|
45
|
-
# Rails isn't in this env, don't load the engine.
|
46
|
-
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: phlex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Drapper
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: hescape
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: syntax_tree
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -60,7 +74,6 @@ extensions: []
|
|
60
74
|
extra_rdoc_files: []
|
61
75
|
files:
|
62
76
|
- ".editorconfig"
|
63
|
-
- ".rspec"
|
64
77
|
- ".rubocop.yml"
|
65
78
|
- CODE_OF_CONDUCT.md
|
66
79
|
- CONTRIBUTING.md
|
@@ -72,6 +85,7 @@ files:
|
|
72
85
|
- SECURITY.md
|
73
86
|
- bench.rb
|
74
87
|
- config.ru
|
88
|
+
- config/sus.rb
|
75
89
|
- docs/assets/application.css
|
76
90
|
- docs/assets/logo.png
|
77
91
|
- docs/build.rb
|
@@ -99,8 +113,14 @@ files:
|
|
99
113
|
- docs/pages/rails/rendering_views.rb
|
100
114
|
- docs/pages/rails_integration.rb
|
101
115
|
- docs/pages/templates.rb
|
116
|
+
- docs/pages/testing/capybara.rb
|
117
|
+
- docs/pages/testing/getting_started.rb
|
118
|
+
- docs/pages/testing/nokogiri.rb
|
119
|
+
- docs/pages/testing/rails.rb
|
120
|
+
- docs/pages/translations.rb
|
102
121
|
- docs/pages/views.rb
|
103
|
-
- fixtures/
|
122
|
+
- fixtures/compiler_test_helpers.rb
|
123
|
+
- fixtures/content.rb
|
104
124
|
- fixtures/dummy/app/assets/config/manifest.js
|
105
125
|
- fixtures/dummy/app/components/comment_component.html.erb
|
106
126
|
- fixtures/dummy/app/components/comment_component.rb
|
@@ -108,6 +128,7 @@ files:
|
|
108
128
|
- fixtures/dummy/app/components/reaction_component.rb
|
109
129
|
- fixtures/dummy/app/controllers/articles_controller.rb
|
110
130
|
- fixtures/dummy/app/controllers/comments_controller.rb
|
131
|
+
- fixtures/dummy/app/views/application_view.rb
|
111
132
|
- fixtures/dummy/app/views/articles/form.rb
|
112
133
|
- fixtures/dummy/app/views/articles/index.html.erb
|
113
134
|
- fixtures/dummy/app/views/articles/new.html.erb
|
@@ -125,11 +146,17 @@ files:
|
|
125
146
|
- fixtures/dummy/public/favicon.ico
|
126
147
|
- fixtures/layout.rb
|
127
148
|
- fixtures/page.rb
|
128
|
-
- fixtures/
|
149
|
+
- fixtures/rails_helper.rb
|
150
|
+
- fixtures/standard_element.rb
|
129
151
|
- fixtures/view_helper.rb
|
152
|
+
- fixtures/void_element.rb
|
130
153
|
- lib/generators/phlex/collection/USAGE
|
131
154
|
- lib/generators/phlex/collection/collection_generator.rb
|
132
155
|
- lib/generators/phlex/collection/templates/collection.rb.erb
|
156
|
+
- lib/generators/phlex/controller/USAGE
|
157
|
+
- lib/generators/phlex/controller/controller_generator.rb
|
158
|
+
- lib/generators/phlex/controller/templates/controller.rb.erb
|
159
|
+
- lib/generators/phlex/controller/templates/view.rb.erb
|
133
160
|
- lib/generators/phlex/layout/USAGE
|
134
161
|
- lib/generators/phlex/layout/layout_generator.rb
|
135
162
|
- lib/generators/phlex/layout/templates/layout.rb.erb
|
@@ -147,26 +174,47 @@ files:
|
|
147
174
|
- lib/phlex.rb
|
148
175
|
- lib/phlex/block.rb
|
149
176
|
- lib/phlex/buffered.rb
|
177
|
+
- lib/phlex/callable.rb
|
150
178
|
- lib/phlex/collection.rb
|
151
179
|
- lib/phlex/compiler.rb
|
180
|
+
- lib/phlex/compiler/elements.rb
|
152
181
|
- lib/phlex/compiler/formatter.rb
|
153
|
-
- lib/phlex/compiler/generators/
|
154
|
-
- lib/phlex/compiler/generators/
|
155
|
-
- lib/phlex/compiler/
|
156
|
-
- lib/phlex/compiler/
|
157
|
-
- lib/phlex/compiler/
|
158
|
-
- lib/phlex/compiler/
|
159
|
-
- lib/phlex/compiler/
|
182
|
+
- lib/phlex/compiler/generators/content.rb
|
183
|
+
- lib/phlex/compiler/generators/element.rb
|
184
|
+
- lib/phlex/compiler/nodes/base.rb
|
185
|
+
- lib/phlex/compiler/nodes/call.rb
|
186
|
+
- lib/phlex/compiler/nodes/command.rb
|
187
|
+
- lib/phlex/compiler/nodes/fcall.rb
|
188
|
+
- lib/phlex/compiler/nodes/method_add_block.rb
|
189
|
+
- lib/phlex/compiler/nodes/vcall.rb
|
190
|
+
- lib/phlex/compiler/optimizer.rb
|
191
|
+
- lib/phlex/compiler/visitors/base.rb
|
160
192
|
- lib/phlex/compiler/visitors/file.rb
|
193
|
+
- lib/phlex/compiler/visitors/stable_scope.rb
|
194
|
+
- lib/phlex/compiler/visitors/statements.rb
|
195
|
+
- lib/phlex/compiler/visitors/view.rb
|
196
|
+
- lib/phlex/compiler/visitors/view_method.rb
|
161
197
|
- lib/phlex/configuration.rb
|
198
|
+
- lib/phlex/elements.rb
|
162
199
|
- lib/phlex/engine.rb
|
200
|
+
- lib/phlex/helpers.rb
|
163
201
|
- lib/phlex/html.rb
|
202
|
+
- lib/phlex/html/callbacks.rb
|
203
|
+
- lib/phlex/markdown.rb
|
204
|
+
- lib/phlex/rails.rb
|
205
|
+
- lib/phlex/rails/form.rb
|
164
206
|
- lib/phlex/rails/helpers.rb
|
165
207
|
- lib/phlex/rails/layout.rb
|
166
208
|
- lib/phlex/renderable.rb
|
167
209
|
- lib/phlex/table.rb
|
210
|
+
- lib/phlex/testing/capybara.rb
|
211
|
+
- lib/phlex/testing/nokogiri.rb
|
212
|
+
- lib/phlex/testing/rails.rb
|
213
|
+
- lib/phlex/testing/view_helper.rb
|
214
|
+
- lib/phlex/translation.rb
|
215
|
+
- lib/phlex/turbo/frame.rb
|
216
|
+
- lib/phlex/turbo/stream.rb
|
168
217
|
- lib/phlex/version.rb
|
169
|
-
- lib/phlex/view.rb
|
170
218
|
- lib/tasks/phlex_tasks.rake
|
171
219
|
- package-lock.json
|
172
220
|
- package.json
|
@@ -197,7 +245,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
197
245
|
- !ruby/object:Gem::Version
|
198
246
|
version: '0'
|
199
247
|
requirements: []
|
200
|
-
rubygems_version: 3.3.
|
248
|
+
rubygems_version: 3.3.25
|
201
249
|
signing_key:
|
202
250
|
specification_version: 4
|
203
251
|
summary: A framework for building views with a Ruby DSL.
|
data/.rspec
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
--require spec_helper
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Fixtures
|
4
|
-
module Compilation
|
5
|
-
module VCall
|
6
|
-
class WithStandardElement < Phlex::View
|
7
|
-
def template
|
8
|
-
div
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
class WithVoidElement < Phlex::View
|
13
|
-
def template
|
14
|
-
img
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
class WithAnotherMethodCall < Phlex::View
|
19
|
-
def template
|
20
|
-
article
|
21
|
-
some_other_method
|
22
|
-
article
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class WithRedefinedTagMethod < Phlex::View
|
27
|
-
def template
|
28
|
-
title
|
29
|
-
article
|
30
|
-
end
|
31
|
-
|
32
|
-
def title
|
33
|
-
h1
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlex
|
4
|
-
class Compiler
|
5
|
-
module Generators
|
6
|
-
class StandardElement
|
7
|
-
def initialize(formatter, method_name:, arguments: nil)
|
8
|
-
@formatter = formatter
|
9
|
-
@method_name = method_name
|
10
|
-
end
|
11
|
-
|
12
|
-
def call
|
13
|
-
@formatter.append do |f|
|
14
|
-
f.text "<"
|
15
|
-
f.text tag
|
16
|
-
f.text ">"
|
17
|
-
|
18
|
-
f.text "</"
|
19
|
-
f.text tag
|
20
|
-
f.text ">"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def tag
|
25
|
-
HTML::STANDARD_ELEMENTS[@method_name]
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlex
|
4
|
-
class Compiler
|
5
|
-
module Generators
|
6
|
-
class VoidElement
|
7
|
-
def initialize(formatter, method_name:, arguments: nil)
|
8
|
-
@formatter = formatter
|
9
|
-
@method_name = method_name
|
10
|
-
@arguments = arguments
|
11
|
-
end
|
12
|
-
|
13
|
-
def call
|
14
|
-
@formatter.append do |f|
|
15
|
-
f.text "<"
|
16
|
-
f.text tag
|
17
|
-
f.text " />"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def tag
|
24
|
-
HTML::VOID_ELEMENTS[@method_name]
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlex
|
4
|
-
class Compiler
|
5
|
-
module Optimizers
|
6
|
-
class BaseOptimizer
|
7
|
-
def initialize(node, compiler:)
|
8
|
-
@node = node
|
9
|
-
@compiler = compiler
|
10
|
-
end
|
11
|
-
|
12
|
-
def call
|
13
|
-
if standard_element?
|
14
|
-
@node.extend(self.class::StandardElement)
|
15
|
-
elsif void_element?
|
16
|
-
@node.extend(self.class::VoidElement)
|
17
|
-
else
|
18
|
-
false
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def standard_element?
|
25
|
-
HTML::STANDARD_ELEMENTS[name] && !@compiler.redefined?(name)
|
26
|
-
end
|
27
|
-
|
28
|
-
def void_element?
|
29
|
-
HTML::VOID_ELEMENTS[name] && !@compiler.redefined?(name)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlex
|
4
|
-
class Compiler
|
5
|
-
module Optimizers
|
6
|
-
class VCall < BaseOptimizer
|
7
|
-
module StandardElement
|
8
|
-
def format(formatter)
|
9
|
-
Generators::StandardElement.new(formatter,
|
10
|
-
method_name: value.value.to_sym).call
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
module VoidElement
|
15
|
-
def format(formatter)
|
16
|
-
Generators::VoidElement.new(formatter,
|
17
|
-
method_name: value.value.to_sym).call
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def name
|
24
|
-
@node.value.value.to_sym
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlex
|
4
|
-
class Compiler
|
5
|
-
module Visitors
|
6
|
-
class BaseVisitor < SyntaxTree::Visitor
|
7
|
-
def initialize(compiler = nil)
|
8
|
-
@compiler = compiler
|
9
|
-
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
def format(node)
|
14
|
-
Formatter.format("", node)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlex
|
4
|
-
class Compiler
|
5
|
-
module Visitors
|
6
|
-
class Component < BaseVisitor
|
7
|
-
visit_method def visit_def(node)
|
8
|
-
visitor = Visitors::ComponentMethod.new(@compiler)
|
9
|
-
visitor.visit_all(node.child_nodes)
|
10
|
-
|
11
|
-
if visitor.optimized_something?
|
12
|
-
@compiler.redefine(
|
13
|
-
format(node)
|
14
|
-
)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
visit_method def visit_class(node)
|
19
|
-
nil
|
20
|
-
end
|
21
|
-
|
22
|
-
visit_method def visit_module(node)
|
23
|
-
nil
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlex
|
4
|
-
class Compiler
|
5
|
-
module Visitors
|
6
|
-
class ComponentMethod < BaseVisitor
|
7
|
-
def optimized_something?
|
8
|
-
!!@optimized_something
|
9
|
-
end
|
10
|
-
|
11
|
-
visit_method def visit_vcall(node)
|
12
|
-
@optimized_something = Optimizers::VCall.new(node,
|
13
|
-
compiler: @compiler).call
|
14
|
-
|
15
|
-
super
|
16
|
-
end
|
17
|
-
|
18
|
-
visit_method def visit_class(node)
|
19
|
-
nil
|
20
|
-
end
|
21
|
-
|
22
|
-
visit_method def visit_module(node)
|
23
|
-
nil
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
data/lib/phlex/view.rb
DELETED
@@ -1,229 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3.0")
|
4
|
-
using Overrides::Symbol::Name
|
5
|
-
end
|
6
|
-
|
7
|
-
module Phlex
|
8
|
-
class View
|
9
|
-
extend HTML
|
10
|
-
include Renderable
|
11
|
-
|
12
|
-
class << self
|
13
|
-
attr_accessor :rendered_at_least_once
|
14
|
-
|
15
|
-
def compile
|
16
|
-
return if @compiled
|
17
|
-
return unless name
|
18
|
-
return if name.start_with? "#"
|
19
|
-
|
20
|
-
Compiler.new(self).call
|
21
|
-
|
22
|
-
@compiled = true
|
23
|
-
end
|
24
|
-
|
25
|
-
def compiled?
|
26
|
-
!!@compiled
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def call(buffer = +"", view_context: nil, parent: nil, &block)
|
31
|
-
raise "The same view instance shouldn't be rendered twice" if rendered?
|
32
|
-
|
33
|
-
@_rendered = true
|
34
|
-
@_target = buffer
|
35
|
-
@_view_context = view_context
|
36
|
-
@_parent = parent
|
37
|
-
@output_buffer = self
|
38
|
-
|
39
|
-
template(&block)
|
40
|
-
|
41
|
-
self.class.rendered_at_least_once ||= true
|
42
|
-
|
43
|
-
buffer
|
44
|
-
end
|
45
|
-
|
46
|
-
def rendered?
|
47
|
-
@_rendered ||= false
|
48
|
-
end
|
49
|
-
|
50
|
-
HTML::STANDARD_ELEMENTS.each do |method_name, tag|
|
51
|
-
register_element(method_name, tag: tag)
|
52
|
-
end
|
53
|
-
|
54
|
-
HTML::VOID_ELEMENTS.each do |method_name, tag|
|
55
|
-
register_void_element(method_name, tag: tag)
|
56
|
-
end
|
57
|
-
|
58
|
-
def yield_content(&block)
|
59
|
-
return unless block_given?
|
60
|
-
|
61
|
-
original_length = @_target.length
|
62
|
-
output = yield(self)
|
63
|
-
unchanged = (original_length == @_target.length)
|
64
|
-
|
65
|
-
if unchanged
|
66
|
-
case output
|
67
|
-
when String, Symbol, Integer, Float
|
68
|
-
text(output)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
nil
|
73
|
-
end
|
74
|
-
|
75
|
-
def text(content)
|
76
|
-
@_target << case content
|
77
|
-
when String then CGI.escape_html(content)
|
78
|
-
when Symbol then CGI.escape_html(content.name)
|
79
|
-
else CGI.escape_html(content.to_s)
|
80
|
-
end
|
81
|
-
|
82
|
-
nil
|
83
|
-
end
|
84
|
-
|
85
|
-
def whitespace
|
86
|
-
@_target << " "
|
87
|
-
nil
|
88
|
-
end
|
89
|
-
|
90
|
-
def comment(content = "")
|
91
|
-
@_target << "<!-- " << CGI.escape_html(content.to_s) << " -->"
|
92
|
-
nil
|
93
|
-
end
|
94
|
-
|
95
|
-
def doctype
|
96
|
-
@_target << HTML::DOCTYPE
|
97
|
-
nil
|
98
|
-
end
|
99
|
-
|
100
|
-
def raw(content = nil, &block)
|
101
|
-
@_target << (content || instance_exec(&block))
|
102
|
-
nil
|
103
|
-
end
|
104
|
-
|
105
|
-
def html_safe?
|
106
|
-
true
|
107
|
-
end
|
108
|
-
|
109
|
-
def safe_append=(value)
|
110
|
-
return unless value
|
111
|
-
|
112
|
-
@_target << case value
|
113
|
-
when String then value
|
114
|
-
when Symbol then value.name
|
115
|
-
else value.to_s
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
def append=(value)
|
120
|
-
return unless value
|
121
|
-
|
122
|
-
if value.html_safe?
|
123
|
-
self.safe_append = value
|
124
|
-
else
|
125
|
-
@_target << case value
|
126
|
-
when String then CGI.escape_html(value)
|
127
|
-
when Symbol then CGI.escape_html(value.name)
|
128
|
-
else CGI.escape_html(value.to_s)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def capture(&block)
|
134
|
-
return unless block_given?
|
135
|
-
|
136
|
-
original_buffer = @_target
|
137
|
-
new_buffer = +""
|
138
|
-
@_target = new_buffer
|
139
|
-
|
140
|
-
yield
|
141
|
-
|
142
|
-
@_target = original_buffer
|
143
|
-
new_buffer.html_safe
|
144
|
-
end
|
145
|
-
|
146
|
-
def classes(*tokens, **conditional_tokens)
|
147
|
-
tokens = self.tokens(*tokens, **conditional_tokens)
|
148
|
-
|
149
|
-
if tokens.present?
|
150
|
-
{ class: tokens }
|
151
|
-
else
|
152
|
-
{}
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
def tokens(*tokens, **conditional_tokens)
|
157
|
-
conditional_tokens.each do |condition, token|
|
158
|
-
case condition
|
159
|
-
when Symbol then next unless send(condition)
|
160
|
-
when Proc then next unless condition.call
|
161
|
-
else raise ArgumentError,
|
162
|
-
"The class condition must be a Symbol or a Proc."
|
163
|
-
end
|
164
|
-
|
165
|
-
case token
|
166
|
-
when Symbol then tokens << token.name
|
167
|
-
when String then tokens << token
|
168
|
-
when Array then tokens.concat(token)
|
169
|
-
else raise ArgumentError,
|
170
|
-
"Conditional classes must be Symbols, Strings, or Arrays of Symbols or Strings."
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
tokens.compact.join(" ")
|
175
|
-
end
|
176
|
-
|
177
|
-
def helpers
|
178
|
-
@_view_context
|
179
|
-
end
|
180
|
-
|
181
|
-
def _attributes(attributes, buffer: +"")
|
182
|
-
if attributes[:href]&.start_with?(/\s*javascript/)
|
183
|
-
attributes[:href] = attributes[:href].sub(/^\s*(javascript:)+/, "")
|
184
|
-
end
|
185
|
-
|
186
|
-
_build_attributes(attributes, buffer: buffer)
|
187
|
-
|
188
|
-
unless self.class.rendered_at_least_once
|
189
|
-
Phlex::ATTRIBUTE_CACHE[attributes.hash] = buffer.freeze
|
190
|
-
end
|
191
|
-
|
192
|
-
buffer
|
193
|
-
end
|
194
|
-
|
195
|
-
def _build_attributes(attributes, buffer:)
|
196
|
-
attributes.each do |k, v|
|
197
|
-
next unless v
|
198
|
-
|
199
|
-
name = case k
|
200
|
-
when String
|
201
|
-
k
|
202
|
-
when Symbol
|
203
|
-
k.name.tr("_", "-")
|
204
|
-
else
|
205
|
-
k.to_s
|
206
|
-
end
|
207
|
-
|
208
|
-
if HTML::EVENT_ATTRIBUTES[name] || name.match?(/[<>&"']/)
|
209
|
-
raise ArgumentError, "Unsafe attribute name detected: #{k}."
|
210
|
-
end
|
211
|
-
|
212
|
-
case v
|
213
|
-
when true
|
214
|
-
buffer << " " << name
|
215
|
-
when String
|
216
|
-
buffer << " " << name << '="' << CGI.escape_html(v) << '"'
|
217
|
-
when Symbol
|
218
|
-
buffer << " " << name << '="' << CGI.escape_html(v.name) << '"'
|
219
|
-
when Hash
|
220
|
-
_build_attributes(v.transform_keys { "#{k}-#{_1.name.tr('_', '-')}" }, buffer: buffer)
|
221
|
-
else
|
222
|
-
buffer << " " << name << '="' << CGI.escape_html(v.to_s) << '"'
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
buffer
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|