phlex 0.5.3 → 1.0.0.rc2

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 (134) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -20
  3. data/config/sus.rb +0 -5
  4. data/lib/phlex/buffered.rb +2 -0
  5. data/lib/phlex/collection.rb +2 -0
  6. data/lib/phlex/elements.rb +1 -5
  7. data/lib/phlex/experimental.rb +10 -0
  8. data/lib/phlex/helpers.rb +23 -10
  9. data/lib/phlex/html.rb +72 -86
  10. data/lib/phlex/table.rb +1 -0
  11. data/lib/phlex/turbo/frame.rb +2 -0
  12. data/lib/phlex/turbo/stream.rb +2 -0
  13. data/lib/phlex/version.rb +1 -1
  14. data/lib/phlex.rb +2 -19
  15. metadata +6 -166
  16. data/Procfile.dev +0 -3
  17. data/Rakefile +0 -8
  18. data/config.ru +0 -9
  19. data/docs/assets/application.css +0 -32
  20. data/docs/assets/logo.png +0 -0
  21. data/docs/build.rb +0 -30
  22. data/docs/components/callout.rb +0 -9
  23. data/docs/components/code_block.rb +0 -26
  24. data/docs/components/code_span.rb +0 -9
  25. data/docs/components/example.rb +0 -32
  26. data/docs/components/heading.rb +0 -9
  27. data/docs/components/layout.rb +0 -91
  28. data/docs/components/markdown.rb +0 -25
  29. data/docs/components/nav/item.rb +0 -33
  30. data/docs/components/nav.rb +0 -6
  31. data/docs/components/tabs/tab.rb +0 -28
  32. data/docs/components/tabs.rb +0 -30
  33. data/docs/components/title.rb +0 -9
  34. data/docs/page_builder.rb +0 -39
  35. data/docs/pages/application_page.rb +0 -7
  36. data/docs/pages/helpers.rb +0 -97
  37. data/docs/pages/index.rb +0 -27
  38. data/docs/pages/library/collections.rb +0 -83
  39. data/docs/pages/rails/getting_started.rb +0 -57
  40. data/docs/pages/rails/helpers.rb +0 -55
  41. data/docs/pages/rails/layouts.rb +0 -61
  42. data/docs/pages/rails/migrating.rb +0 -37
  43. data/docs/pages/rails/rendering_views.rb +0 -35
  44. data/docs/pages/rails_integration.rb +0 -58
  45. data/docs/pages/templates.rb +0 -144
  46. data/docs/pages/testing/capybara.rb +0 -48
  47. data/docs/pages/testing/getting_started.rb +0 -44
  48. data/docs/pages/testing/nokogiri.rb +0 -83
  49. data/docs/pages/testing/rails.rb +0 -17
  50. data/docs/pages/translations.rb +0 -81
  51. data/docs/pages/views.rb +0 -184
  52. data/fixtures/compiler_test_helpers.rb +0 -19
  53. data/fixtures/content.rb +0 -60
  54. data/fixtures/dummy/app/assets/config/manifest.js +0 -0
  55. data/fixtures/dummy/app/components/comment_component.html.erb +0 -14
  56. data/fixtures/dummy/app/components/comment_component.rb +0 -8
  57. data/fixtures/dummy/app/components/reaction_component.html.erb +0 -3
  58. data/fixtures/dummy/app/components/reaction_component.rb +0 -7
  59. data/fixtures/dummy/app/controllers/articles_controller.rb +0 -4
  60. data/fixtures/dummy/app/controllers/comments_controller.rb +0 -4
  61. data/fixtures/dummy/app/views/application_view.rb +0 -8
  62. data/fixtures/dummy/app/views/articles/form.rb +0 -15
  63. data/fixtures/dummy/app/views/articles/index.html.erb +0 -14
  64. data/fixtures/dummy/app/views/articles/new.html.erb +0 -1
  65. data/fixtures/dummy/app/views/card.rb +0 -15
  66. data/fixtures/dummy/app/views/comments/comment.rb +0 -25
  67. data/fixtures/dummy/app/views/comments/index.html.erb +0 -3
  68. data/fixtures/dummy/app/views/comments/reaction.rb +0 -17
  69. data/fixtures/dummy/app/views/comments/show.html.erb +0 -3
  70. data/fixtures/dummy/app/views/heading.rb +0 -9
  71. data/fixtures/dummy/config/database.yml +0 -3
  72. data/fixtures/dummy/config/routes.rb +0 -5
  73. data/fixtures/dummy/config/storage.yml +0 -3
  74. data/fixtures/dummy/db/schema.rb +0 -6
  75. data/fixtures/dummy/log/.gitignore +0 -1
  76. data/fixtures/dummy/public/favicon.ico +0 -0
  77. data/fixtures/rails_helper.rb +0 -11
  78. data/fixtures/standard_element.rb +0 -87
  79. data/fixtures/void_element.rb +0 -31
  80. data/lib/generators/phlex/collection/USAGE +0 -8
  81. data/lib/generators/phlex/collection/collection_generator.rb +0 -13
  82. data/lib/generators/phlex/collection/templates/collection.rb.erb +0 -16
  83. data/lib/generators/phlex/controller/USAGE +0 -10
  84. data/lib/generators/phlex/controller/controller_generator.rb +0 -54
  85. data/lib/generators/phlex/controller/templates/controller.rb.erb +0 -10
  86. data/lib/generators/phlex/controller/templates/view.rb.erb +0 -14
  87. data/lib/generators/phlex/layout/USAGE +0 -8
  88. data/lib/generators/phlex/layout/layout_generator.rb +0 -13
  89. data/lib/generators/phlex/layout/templates/layout.rb.erb +0 -31
  90. data/lib/generators/phlex/page/USAGE +0 -8
  91. data/lib/generators/phlex/page/page_generator.rb +0 -13
  92. data/lib/generators/phlex/page/templates/page.rb.erb +0 -13
  93. data/lib/generators/phlex/table/USAGE +0 -8
  94. data/lib/generators/phlex/table/table_generator.rb +0 -14
  95. data/lib/generators/phlex/table/templates/table.rb.erb +0 -11
  96. data/lib/generators/phlex/view/USAGE +0 -8
  97. data/lib/generators/phlex/view/templates/view.rb.erb +0 -14
  98. data/lib/generators/phlex/view/view_generator.rb +0 -21
  99. data/lib/install/phlex.rb +0 -39
  100. data/lib/phlex/block.rb +0 -16
  101. data/lib/phlex/compiler/elements.rb +0 -49
  102. data/lib/phlex/compiler/formatter.rb +0 -91
  103. data/lib/phlex/compiler/generators/content.rb +0 -103
  104. data/lib/phlex/compiler/generators/element.rb +0 -61
  105. data/lib/phlex/compiler/nodes/base.rb +0 -19
  106. data/lib/phlex/compiler/nodes/call.rb +0 -9
  107. data/lib/phlex/compiler/nodes/command.rb +0 -13
  108. data/lib/phlex/compiler/nodes/fcall.rb +0 -18
  109. data/lib/phlex/compiler/nodes/method_add_block.rb +0 -33
  110. data/lib/phlex/compiler/nodes/vcall.rb +0 -9
  111. data/lib/phlex/compiler/optimizer.rb +0 -66
  112. data/lib/phlex/compiler/visitors/base.rb +0 -15
  113. data/lib/phlex/compiler/visitors/file.rb +0 -29
  114. data/lib/phlex/compiler/visitors/stable_scope.rb +0 -28
  115. data/lib/phlex/compiler/visitors/statements.rb +0 -36
  116. data/lib/phlex/compiler/visitors/view.rb +0 -19
  117. data/lib/phlex/compiler/visitors/view_method.rb +0 -59
  118. data/lib/phlex/compiler.rb +0 -70
  119. data/lib/phlex/html/callbacks.rb +0 -11
  120. data/lib/phlex/markdown.rb +0 -76
  121. data/lib/phlex/rails/engine.rb +0 -10
  122. data/lib/phlex/rails/form.rb +0 -67
  123. data/lib/phlex/rails/helpers.rb +0 -118
  124. data/lib/phlex/rails/layout.rb +0 -15
  125. data/lib/phlex/rails.rb +0 -11
  126. data/lib/phlex/renderable.rb +0 -47
  127. data/lib/phlex/testing/capybara.rb +0 -25
  128. data/lib/phlex/testing/nokogiri.rb +0 -24
  129. data/lib/phlex/testing/rails.rb +0 -19
  130. data/lib/phlex/translation.rb +0 -23
  131. data/lib/tasks/phlex_tasks.rake +0 -11
  132. data/package-lock.json +0 -1195
  133. data/package.json +0 -5
  134. data/tailwind.config.js +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1bd2b79d18bf802486addb4c486e3200b260248245a4ade7f1d0e3f4e56ecdab
4
- data.tar.gz: c27f8e8d3b6ab1d63ab28cd472873cbae295641e252c757230f684b79b17eb75
3
+ metadata.gz: 72f6baa9bd23ce981517a40897f2bb63a1cbd60fbc87bb127883e8eeb36cc302
4
+ data.tar.gz: 5abc8c59a81cdff51f5da9250a28d9cc42308b467aa662b155fb1d28eca4a1c2
5
5
  SHA512:
6
- metadata.gz: 140f1b74b07334bb469020e940955dd319f9622d372841d260f8fe283278259cae4e8f4f3f875815e6bbee56b4f6b9e49fcdd42f6dcb7e8e9eb3ef83bb0487f1
7
- data.tar.gz: 8124ba9fe2bc9adaa9aadcb1d23c3942ffab886cfe0c74993515abb36d07ba07a4198cfaa4550375fa8de81d3701cd8994947bc2bf5703f17cfec86573bd2481
6
+ metadata.gz: 8db8f9df3da1f218bd2029ea22414ea53a910de8b1810d71c70a0e9022a1353dd69557c91eb1ffee5355733c0d8d6878aae9379a75ee0eaa76d05c6ee20abb8e
7
+ data.tar.gz: 8027722c6fd1592c86f5fa6150814206a007c12a810985c72231195dcb0089aa34fd91a5addbeb9c14a8137a5a2f3fe984c07f554ee6504a4b4c25d6dd216046
data/Gemfile CHANGED
@@ -5,32 +5,14 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
5
5
 
6
6
  gemspec
7
7
 
8
- gem "benchmark-ips"
9
- gem "benchmark-memory"
10
- gem "capybara"
11
- gem "rails"
12
8
  gem "rubocop"
13
- gem "solargraph"
14
9
  gem "sus"
15
10
  gem "syntax_suggest"
16
11
  gem "zeitwerk"
12
+ gem "benchmark-ips"
13
+ gem "erb"
17
14
 
18
15
  group :test do
19
16
  gem "i18n"
20
17
  gem "memory_profiler"
21
- gem "covered"
22
- end
23
-
24
- group :rails do
25
- gem "combustion"
26
- end
27
-
28
- group :docs do
29
- gem "filewatcher"
30
- gem "htmlbeautifier"
31
- gem "redcarpet"
32
- gem "markly"
33
- gem "webrick"
34
- gem "rouge"
35
- gem "kramdown"
36
18
  end
data/config/sus.rb CHANGED
@@ -1,15 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "covered/sus"
4
- include Covered::Sus
5
-
6
3
  require "phlex"
7
4
  require "bundler"
8
- require "view_component"
9
5
 
10
6
  Bundler.require :test
11
7
 
12
8
  require_relative "../fixtures/view_helper"
13
- require_relative "../fixtures/compiler_test_helpers"
14
9
 
15
10
  Zeitwerk::Loader.eager_load_all
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "delegate"
4
+
3
5
  module Phlex
4
6
  class Buffered < SimpleDelegator
5
7
  def initialize(object, buffer:)
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Phlex
4
4
  module Collection
5
+ include Experimental
6
+
5
7
  def initialize(collection: nil, item: nil)
6
8
  unless collection || item
7
9
  raise ArgumentError, "You must pass a collection or an item as a keyword argument."
@@ -10,11 +10,7 @@ module Phlex
10
10
  class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
11
11
  # frozen_string_literal: true
12
12
 
13
- def #{element}(content = nil, **attributes, &block)
14
- if content
15
- raise ArgumentError, %(👋 You can no longer pass content to #{element} as a positional argument.\n Instead, you can pass it as a block, e.g. #{element} { "Hello" })
16
- end
17
-
13
+ def #{element}(**attributes, &block)
18
14
  if attributes.length > 0
19
15
  if block_given?
20
16
  @_target << "<#{tag}" << (Phlex::ATTRIBUTE_CACHE[attributes.hash] || _attributes(**attributes)) << ">"
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlex
4
+ module Experimental
5
+ def before_template
6
+ puts "Warning: #{self.class.name} is experimental and subject to change."
7
+ super
8
+ end
9
+ end
10
+ end
data/lib/phlex/helpers.rb CHANGED
@@ -7,23 +7,36 @@ end
7
7
  module Phlex::Helpers
8
8
  def tokens(*tokens, **conditional_tokens)
9
9
  conditional_tokens.each do |condition, token|
10
- case condition
11
- when Symbol then next unless send(condition)
12
- when Proc then next unless condition.call
13
- else raise ArgumentError,
14
- "The class condition must be a Symbol or a Proc."
10
+ truthy = case condition
11
+ when Symbol then send(condition)
12
+ when Proc then condition.call
13
+ else raise ArgumentError, "The class condition must be a Symbol or a Proc."
15
14
  end
16
15
 
17
- case token
18
- when Symbol then tokens << token.name
16
+ if truthy
17
+ case token
18
+ when Hash then _append_token(tokens, token[:then])
19
+ else _append_token(tokens, token)
20
+ end
21
+ else
22
+ case token
23
+ when Hash then _append_token(tokens, token[:else])
24
+ end
25
+ end
26
+ end
27
+
28
+ tokens.join(" ")
29
+ end
30
+
31
+ def _append_token(tokens, token)
32
+ case token
33
+ when nil then nil
19
34
  when String then tokens << token
35
+ when Symbol then tokens << token.name
20
36
  when Array then tokens.concat(token)
21
37
  else raise ArgumentError,
22
38
  "Conditional classes must be Symbols, Strings, or Arrays of Symbols or Strings."
23
- end
24
39
  end
25
-
26
- tokens.compact.join(" ")
27
40
  end
28
41
 
29
42
  def classes(*tokens, **conditional_tokens)
data/lib/phlex/html.rb CHANGED
@@ -128,25 +128,9 @@ module Phlex
128
128
 
129
129
  extend Elements
130
130
  include Helpers
131
- include Callable
132
- include Renderable
133
131
 
134
132
  class << self
135
133
  attr_accessor :rendered_at_least_once
136
-
137
- # def compile
138
- # return if @compiled
139
- # return unless name
140
- # return if name.start_with? "#"
141
- #
142
- # Compiler.new(self).call
143
- #
144
- # @compiled = true
145
- # end
146
- #
147
- # def compiled?
148
- # !!@compiled
149
- # end
150
134
  end
151
135
 
152
136
  def call(buffer = +"", view_context: nil, parent: nil, &block)
@@ -158,15 +142,30 @@ module Phlex
158
142
  @_target = buffer
159
143
  @_view_context = view_context
160
144
  @_parent = parent
161
- @output_buffer = self
162
145
 
163
- template(&block)
146
+ around_template { template { yield_content(&block) } }
164
147
 
165
148
  self.class.rendered_at_least_once ||= true
166
149
 
167
150
  buffer
168
151
  end
169
152
 
153
+ def render(renderable, *args, **kwargs, &block)
154
+ if renderable.is_a?(Phlex::HTML)
155
+ renderable.call(@_target, view_context: @_view_context, parent: self, &block)
156
+ elsif renderable.is_a?(Class) && renderable < Phlex::HTML
157
+ raise ArgumentError, "You tried to render the Phlex view class: #{renderable.name} but you probably meant to render an instance of that class instead."
158
+ else
159
+ raise ArgumentError, "You can't render a #{renderable}."
160
+ end
161
+
162
+ nil
163
+ end
164
+
165
+ def format
166
+ :html
167
+ end
168
+
170
169
  def rendered?
171
170
  @_rendered ||= false
172
171
  end
@@ -183,37 +182,18 @@ module Phlex
183
182
  register_void_element(method_name, tag: tag)
184
183
  end
185
184
 
186
- def yield_content(&block)
187
- return unless block_given?
188
-
189
- original_length = @_target.length
190
- output = yield(self)
191
- unchanged = (original_length == @_target.length)
192
-
193
- if unchanged
194
- case output
195
- when String, Symbol, Integer, Float
196
- text(output)
197
- end
198
- end
199
-
200
- nil
201
- end
202
-
203
185
  def text(content)
204
- @_target << _output(content)
186
+ @_target << ERB::Util.html_escape(
187
+ case content
188
+ when String then content
189
+ when Symbol then content.name
190
+ else content.to_s
191
+ end
192
+ )
205
193
 
206
194
  nil
207
195
  end
208
196
 
209
- def _output(content)
210
- case content
211
- when String then Hescape.escape_html(content)
212
- when Symbol then Hescape.escape_html(content.name)
213
- else Hescape.escape_html(content.to_s)
214
- end
215
- end
216
-
217
197
  def whitespace
218
198
  @_target << " "
219
199
 
@@ -225,8 +205,11 @@ module Phlex
225
205
  nil
226
206
  end
227
207
 
228
- def comment(content = "")
229
- @_target << "<!-- " << Hescape.escape_html(content.to_s) << " -->"
208
+ def comment(&block)
209
+ @_target << "<!-- "
210
+ yield_content(&block)
211
+ @_target << " -->"
212
+
230
213
  nil
231
214
  end
232
215
 
@@ -240,34 +223,6 @@ module Phlex
240
223
  nil
241
224
  end
242
225
 
243
- def html_safe?
244
- true
245
- end
246
-
247
- def safe_append=(value)
248
- return unless value
249
-
250
- @_target << case value
251
- when String then value
252
- when Symbol then value.name
253
- else value.to_s
254
- end
255
- end
256
-
257
- def append=(value)
258
- return unless value
259
-
260
- if value.html_safe?
261
- self.safe_append = value
262
- else
263
- @_target << case value
264
- when String then Hescape.escape_html(value)
265
- when Symbol then Hescape.escape_html(value.name)
266
- else Hescape.escape_html(value.to_s)
267
- end
268
- end
269
- end
270
-
271
226
  def capture(&block)
272
227
  return unless block_given?
273
228
 
@@ -279,11 +234,44 @@ module Phlex
279
234
 
280
235
  @_target = original_buffer
281
236
 
282
- new_buffer.html_safe
237
+ new_buffer
283
238
  end
284
239
 
285
- def helpers
286
- @_view_context
240
+ private
241
+
242
+ def around_template
243
+ before_template
244
+ yield
245
+ after_template
246
+ end
247
+
248
+ def before_template
249
+ nil
250
+ end
251
+
252
+ def after_template
253
+ nil
254
+ end
255
+
256
+ def yield_content(&block)
257
+ return unless block_given?
258
+
259
+ original_length = @_target.length
260
+ content = yield(self)
261
+ unchanged = (original_length == @_target.length)
262
+
263
+ if unchanged
264
+ case content
265
+ when String
266
+ @_target << ERB::Util.html_escape(content)
267
+ when Symbol
268
+ @_target << ERB::Util.html_escape(content.name)
269
+ when Integer, Float
270
+ @_target << ERB::Util.html_escape(content.to_s)
271
+ end
272
+ end
273
+
274
+ nil
287
275
  end
288
276
 
289
277
  def _attributes(**attributes)
@@ -306,14 +294,12 @@ module Phlex
306
294
  next unless v
307
295
 
308
296
  name = case k
309
- when String
310
- k
311
- when Symbol
312
- k.name.tr("_", "-")
313
- else
314
- k.to_s
297
+ when String then k
298
+ when Symbol then k.name.tr("_", "-")
299
+ else k.to_s
315
300
  end
316
301
 
302
+ # Detect unsafe attribute names. Attribute names are considered unsafe if they match an event attribute or include unsafe characters.
317
303
  if HTML::EVENT_ATTRIBUTES[name] || name.match?(/[<>&"']/)
318
304
  raise ArgumentError, "Unsafe attribute name detected: #{k}."
319
305
  end
@@ -322,13 +308,13 @@ module Phlex
322
308
  when true
323
309
  buffer << " " << name
324
310
  when String
325
- buffer << " " << name << '="' << Hescape.escape_html(v) << '"'
311
+ buffer << " " << name << '="' << ERB::Util.html_escape(v) << '"'
326
312
  when Symbol
327
- buffer << " " << name << '="' << Hescape.escape_html(v.name) << '"'
313
+ buffer << " " << name << '="' << ERB::Util.html_escape(v.name) << '"'
328
314
  when Hash
329
315
  _build_attributes(v.transform_keys { "#{k}-#{_1.name.tr('_', '-')}" }, buffer: buffer)
330
316
  else
331
- buffer << " " << name << '="' << Hescape.escape_html(v.to_s) << '"'
317
+ buffer << " " << name << '="' << ERB::Util.html_escape(v.to_s) << '"'
332
318
  end
333
319
  end
334
320
 
data/lib/phlex/table.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Phlex
4
4
  module Table
5
+ include Experimental
5
6
  include Collection
6
7
 
7
8
  module ClassMethods
@@ -3,6 +3,8 @@
3
3
  module Phlex
4
4
  module Turbo
5
5
  class Frame < Phlex::HTML
6
+ include Experimental
7
+
6
8
  register_element :turbo_frame
7
9
 
8
10
  def initialize(src:, loading:, disabled:, target:, autoscroll:)
@@ -3,6 +3,8 @@
3
3
  module Phlex
4
4
  module Turbo
5
5
  class Stream < Phlex::HTML
6
+ include Experimental
7
+
6
8
  register_element :turbo_stream
7
9
 
8
10
  def initialize(action:, **attributes)
data/lib/phlex/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Phlex
4
- VERSION = "0.5.3"
4
+ VERSION = "1.0.0.rc2"
5
5
  end
data/lib/phlex.rb CHANGED
@@ -1,23 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "hescape"
3
+ require "erb"
4
4
  require "zeitwerk"
5
- require "syntax_tree"
6
5
 
7
6
  module Phlex
8
7
  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.rb")
14
-
15
- loader.ignore("#{__dir__}/phlex/rails.rb")
16
- loader.ignore("#{__dir__}/phlex/rails")
17
-
18
8
  loader.inflector.inflect("html" => "HTML")
19
- loader.inflector.inflect("vcall" => "VCall")
20
- loader.inflector.inflect("fcall" => "FCall")
9
+ loader.ignore("#{__dir__}/phlex/testing")
21
10
  loader.setup
22
11
  end
23
12
 
@@ -25,12 +14,6 @@ module Phlex
25
14
  ArgumentError = Class.new(ArgumentError) { include Error }
26
15
  NameError = Class.new(NameError) { include Error }
27
16
 
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
-
34
17
  extend self
35
18
 
36
19
  ATTRIBUTE_CACHE = {}