phlex 0.3.2 → 0.5.0

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.

Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +8 -0
  3. data/.rubocop.yml +21 -5
  4. data/Gemfile +26 -12
  5. data/Procfile.dev +3 -0
  6. data/README.md +1 -1
  7. data/Rakefile +3 -5
  8. data/SECURITY.md +1 -1
  9. data/bench.rb +7 -0
  10. data/config/sus.rb +15 -0
  11. data/docs/assets/application.css +6 -0
  12. data/docs/build.rb +17 -10
  13. data/docs/components/callout.rb +1 -1
  14. data/docs/components/code_block.rb +2 -2
  15. data/docs/components/code_span.rb +9 -0
  16. data/docs/components/example.rb +5 -5
  17. data/docs/components/heading.rb +2 -2
  18. data/docs/components/layout.rb +62 -17
  19. data/docs/components/markdown.rb +14 -15
  20. data/docs/components/nav/item.rb +33 -0
  21. data/docs/components/nav.rb +6 -0
  22. data/docs/components/tabs/tab.rb +4 -2
  23. data/docs/components/tabs.rb +1 -1
  24. data/docs/components/title.rb +2 -2
  25. data/docs/page_builder.rb +3 -0
  26. data/docs/pages/application_page.rb +1 -1
  27. data/docs/pages/helpers.rb +97 -0
  28. data/docs/pages/index.rb +6 -17
  29. data/docs/pages/library/collections.rb +83 -0
  30. data/docs/pages/rails/getting_started.rb +53 -0
  31. data/docs/pages/rails/helpers.rb +55 -0
  32. data/docs/pages/rails/layouts.rb +61 -0
  33. data/docs/pages/rails/migrating.rb +37 -0
  34. data/docs/pages/rails/rendering_views.rb +35 -0
  35. data/docs/pages/templates.rb +53 -151
  36. data/docs/pages/testing/capybara.rb +48 -0
  37. data/docs/pages/testing/getting_started.rb +44 -0
  38. data/docs/pages/testing/nokogiri.rb +83 -0
  39. data/docs/pages/testing/rails.rb +17 -0
  40. data/docs/pages/translations.rb +81 -0
  41. data/docs/pages/views.rb +87 -78
  42. data/fixtures/compiler_test_helpers.rb +19 -0
  43. data/fixtures/content.rb +60 -0
  44. data/fixtures/dummy/app/components/comment_component.html.erb +14 -0
  45. data/fixtures/dummy/app/components/comment_component.rb +8 -0
  46. data/fixtures/dummy/app/components/reaction_component.html.erb +3 -0
  47. data/fixtures/dummy/app/components/reaction_component.rb +7 -0
  48. data/fixtures/dummy/app/controllers/comments_controller.rb +4 -0
  49. data/fixtures/dummy/app/views/application_view.rb +8 -0
  50. data/fixtures/dummy/app/views/articles/form.rb +3 -1
  51. data/fixtures/dummy/app/views/card.rb +4 -2
  52. data/fixtures/dummy/app/views/comments/comment.rb +25 -0
  53. data/fixtures/dummy/app/views/comments/index.html.erb +3 -0
  54. data/fixtures/dummy/app/views/comments/reaction.rb +17 -0
  55. data/fixtures/dummy/app/views/comments/show.html.erb +3 -0
  56. data/fixtures/dummy/app/views/heading.rb +1 -1
  57. data/fixtures/layout.rb +5 -5
  58. data/fixtures/page.rb +18 -24
  59. data/fixtures/{test_helper.rb → rails_helper.rb} +3 -7
  60. data/fixtures/standard_element.rb +87 -0
  61. data/fixtures/view_helper.rb +1 -1
  62. data/fixtures/void_element.rb +31 -0
  63. data/lib/generators/phlex/collection/USAGE +8 -0
  64. data/lib/generators/phlex/collection/collection_generator.rb +13 -0
  65. data/lib/generators/phlex/collection/templates/collection.rb.erb +16 -0
  66. data/lib/generators/phlex/controller/USAGE +10 -0
  67. data/lib/generators/phlex/controller/controller_generator.rb +54 -0
  68. data/lib/generators/phlex/controller/templates/controller.rb.erb +10 -0
  69. data/lib/generators/phlex/controller/templates/view.rb.erb +14 -0
  70. data/lib/generators/phlex/layout/USAGE +8 -0
  71. data/lib/generators/phlex/layout/layout_generator.rb +13 -0
  72. data/lib/generators/phlex/layout/templates/layout.rb.erb +31 -0
  73. data/lib/generators/phlex/page/USAGE +8 -0
  74. data/lib/generators/phlex/page/page_generator.rb +13 -0
  75. data/lib/generators/phlex/page/templates/page.rb.erb +13 -0
  76. data/lib/generators/phlex/table/USAGE +8 -0
  77. data/lib/generators/phlex/table/table_generator.rb +14 -0
  78. data/lib/generators/phlex/table/templates/table.rb.erb +11 -0
  79. data/lib/generators/phlex/view/templates/view.rb.erb +7 -1
  80. data/lib/generators/phlex/view/view_generator.rb +9 -1
  81. data/lib/install/phlex.rb +10 -1
  82. data/lib/phlex/block.rb +2 -4
  83. data/lib/phlex/buffered.rb +6 -8
  84. data/lib/phlex/callable.rb +9 -0
  85. data/lib/phlex/collection.rb +33 -0
  86. data/lib/phlex/compiler/elements.rb +49 -0
  87. data/lib/phlex/compiler/generators/content.rb +103 -0
  88. data/lib/phlex/compiler/generators/element.rb +61 -0
  89. data/lib/phlex/compiler/nodes/base.rb +19 -0
  90. data/lib/phlex/compiler/nodes/call.rb +9 -0
  91. data/lib/phlex/compiler/nodes/command.rb +13 -0
  92. data/lib/phlex/compiler/nodes/fcall.rb +18 -0
  93. data/lib/phlex/compiler/nodes/method_add_block.rb +33 -0
  94. data/lib/phlex/compiler/nodes/vcall.rb +9 -0
  95. data/lib/phlex/compiler/optimizer.rb +66 -0
  96. data/lib/phlex/compiler/visitors/base.rb +15 -0
  97. data/lib/phlex/compiler/visitors/file.rb +23 -11
  98. data/lib/phlex/compiler/visitors/stable_scope.rb +28 -0
  99. data/lib/phlex/compiler/visitors/statements.rb +36 -0
  100. data/lib/phlex/compiler/visitors/view.rb +19 -0
  101. data/lib/phlex/compiler/visitors/view_method.rb +59 -0
  102. data/lib/phlex/compiler.rb +23 -3
  103. data/lib/phlex/elements.rb +57 -0
  104. data/lib/phlex/engine.rb +0 -3
  105. data/lib/phlex/helpers.rb +59 -0
  106. data/lib/phlex/html/callbacks.rb +11 -0
  107. data/lib/phlex/html.rb +209 -54
  108. data/lib/phlex/markdown.rb +76 -0
  109. data/lib/phlex/rails/form.rb +67 -0
  110. data/lib/phlex/rails/helpers.rb +118 -0
  111. data/lib/phlex/rails/layout.rb +15 -0
  112. data/lib/phlex/rails.rb +10 -0
  113. data/lib/phlex/renderable.rb +9 -3
  114. data/lib/phlex/table.rb +104 -0
  115. data/lib/phlex/testing/capybara.rb +25 -0
  116. data/lib/phlex/testing/nokogiri.rb +24 -0
  117. data/lib/phlex/testing/rails.rb +19 -0
  118. data/lib/phlex/testing/view_helper.rb +15 -0
  119. data/lib/phlex/translation.rb +23 -0
  120. data/lib/phlex/turbo/frame.rb +21 -0
  121. data/lib/phlex/turbo/stream.rb +18 -0
  122. data/lib/phlex/version.rb +1 -1
  123. data/lib/phlex.rb +22 -24
  124. metadata +112 -15
  125. data/.rspec +0 -1
  126. data/fixtures/compilation/vcall.rb +0 -38
  127. data/lib/phlex/compiler/generators/standard_element.rb +0 -30
  128. data/lib/phlex/compiler/generators/void_element.rb +0 -29
  129. data/lib/phlex/compiler/optimizers/base_optimizer.rb +0 -34
  130. data/lib/phlex/compiler/optimizers/vcall.rb +0 -29
  131. data/lib/phlex/compiler/visitors/base_visitor.rb +0 -19
  132. data/lib/phlex/compiler/visitors/component.rb +0 -28
  133. data/lib/phlex/compiler/visitors/component_method.rb +0 -28
  134. data/lib/phlex/rails/tag_helpers.rb +0 -29
  135. data/lib/phlex/view.rb +0 -223
data/lib/phlex/view.rb DELETED
@@ -1,223 +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)
101
- @_target << content
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
- { class: self.tokens(*tokens, **conditional_tokens) }
148
- end
149
-
150
- def tokens(*tokens, **conditional_tokens)
151
- conditional_tokens.each do |condition, token|
152
- case condition
153
- when Symbol then next unless send(condition)
154
- when Proc then next unless condition.call
155
- else raise ArgumentError,
156
- "The class condition must be a Symbol or a Proc."
157
- end
158
-
159
- case token
160
- when Symbol then tokens << token.name
161
- when String then tokens << token
162
- when Array then tokens.concat(t)
163
- else raise ArgumentError,
164
- "Conditional classes must be Symbols, Strings, or Arrays of Symbols or Strings."
165
- end
166
- end
167
-
168
- tokens.compact.join(" ")
169
- end
170
-
171
- def helpers
172
- @_view_context
173
- end
174
-
175
- def _attributes(attributes, buffer: +"")
176
- if attributes[:href]&.start_with?(/\s*javascript/)
177
- attributes[:href] = attributes[:href].sub(/^\s*(javascript:)+/, "")
178
- end
179
-
180
- _build_attributes(attributes, buffer: buffer)
181
-
182
- unless self.class.rendered_at_least_once
183
- Phlex::ATTRIBUTE_CACHE[attributes.hash] = buffer.freeze
184
- end
185
-
186
- buffer
187
- end
188
-
189
- def _build_attributes(attributes, buffer:)
190
- attributes.each do |k, v|
191
- next unless v
192
-
193
- name = case k
194
- when String
195
- k
196
- when Symbol
197
- k.name.tr("_", "-")
198
- else
199
- k.to_s
200
- end
201
-
202
- if HTML::EVENT_ATTRIBUTES[name] || name.match?(/[<>&"']/)
203
- raise ArgumentError, "Unsafe attribute name detected: #{k}."
204
- end
205
-
206
- case v
207
- when true
208
- buffer << " " << name
209
- when String
210
- buffer << " " << name << '="' << CGI.escape_html(v) << '"'
211
- when Symbol
212
- buffer << " " << name << '="' << CGI.escape_html(v.name) << '"'
213
- when Hash
214
- _build_attributes(v.transform_keys { "#{k}-#{_1.name.tr('_', '-')}" }, buffer: buffer)
215
- else
216
- buffer << " " << name << '="' << CGI.escape_html(v.to_s) << '"'
217
- end
218
- end
219
-
220
- buffer
221
- end
222
- end
223
- end