heartml 1.0.0.beta17 → 1.0.0.beta18

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 472d4b41b5c7e6b3642f760e372a526cfcd616aa46ac73e1293937035fd5b91f
4
- data.tar.gz: c96192107e486944439b83976b6ce79f846fdae544b3a0ae7cfcceecaab7f538
3
+ metadata.gz: 6b5bbe4c65f744b46c84b6fb6949994e9ebe78301f6e73fcb0ce91590d37a128
4
+ data.tar.gz: acfe3bf54d39db1737d5a46a86c9aabfd06437c2287b13bbe1b59634049acdae
5
5
  SHA512:
6
- metadata.gz: 2940a6ecd8eebd9b24a7dd1f30da984569aa11c9b5f77e679847a5668e5717e257aa121546e2e59338625a0464631207158c3d79dff6b92a2186a05edcf2d760
7
- data.tar.gz: 956b7f57627c4dc972985e3ba37095bc50329f7b8a4cf6b1519a3e77c216588ac43da9392304814fc031d0efd0357d4941d94de57fa12f6257f8f1d08ec74654
6
+ metadata.gz: ddca7cfd38b3ddb634a3791cfbf4fb0425a24f222f58139a5d5f67388503f0afb0654a1c663f600b1fe1eeb64affe71a9d60f9ea047001486baf580e38cdedc3
7
+ data.tar.gz: 0ae6a4dd6e06c6e3bf6fb4ec9eafe482d76fea77b346a6493f96a7f6b39cad06a7e2774b8c8457cca438c58914bf1ce86d91f53bf17fbb0e9aea225fc7895edc
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.0.0.beta18] — 2024-11-27
6
+
7
+ - Simplifications and improvements to server directive syntax and CSS handling [#1]
8
+
5
9
  ## [1.0.0.beta17] — 2024-10-27
6
10
 
7
11
  - Add `.` effect shortcut for `@textContent = .`
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- heartml (1.0.0.beta17)
4
+ heartml (1.0.0.beta18)
5
5
  concurrent-ruby (~> 1.2)
6
6
  nokolexbor (>= 0.4.2)
7
7
 
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # Heartml: Ruby (WIP)
1
+ # Heartml: Ruby Web Components (WIP)
2
2
 
3
- Server-rendered web components in Ruby using a SFC (Single-File Component) format loosely based on [HTML Modules](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md). Logic on the server-side is analogous to client-side logic provided by the Heartml web component library written in JavaScript.
3
+ Server-rendered custom elements in Ruby using a SFC (Single-File Component) format loosely based on [HTML Modules](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md). Logic on the server-side is analogous to client-side logic provided by the [Heartml JavaScript library](https://github.com/heartml/heartml).
4
4
 
5
- Great for pairing with [esbuild-plugin-html-modules](https://github.com/hotmodule/esbuild-plugin-html-modules) for a full-stack component rendering pipeline.
5
+ Great for pairing with [esbuild-plugin-html-modules](https://github.com/whitefusionhq/esbuild-plugin-html-modules) for a full-stack component rendering pipeline.
6
6
 
7
7
  ## Installation
8
8
 
@@ -58,6 +58,16 @@ module Heartml
58
58
  directive :attribute, ->(_, node, name, value) {
59
59
  node[name] = value if name.match?(%r{^aria[A-Z-]}) || value
60
60
  }
61
+
62
+ directive :appendUnsafe, ->(_, node, value) {
63
+ node.swap(value.is_a?(Nokolexbor::Node) ? value : value.to_s)
64
+ }
65
+
66
+ directive :append, ->(_, node, value) {
67
+ span = node.document.create_element("span")
68
+ span.content = value.to_s
69
+ node.swap(span.inner_html)
70
+ }
61
71
  end
62
72
  end
63
73
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Heartml
4
4
  # @return [String]
5
- VERSION = "1.0.0.beta17"
5
+ VERSION = "1.0.0.beta18"
6
6
  end
data/lib/heartml.rb CHANGED
@@ -52,9 +52,7 @@ module Heartml
52
52
  def self.included(klass)
53
53
  klass.extend ClassMethods
54
54
 
55
- klass.attribute_binding "server-children", :_server_children, only: :template
56
- klass.attribute_binding "server-content", :_server_content, only: :template
57
- klass.attribute_binding "server-unsafe-eval", :_server_unsafe_eval
55
+ klass.attribute_binding "hl-content", :_server_content, only: :template
58
56
 
59
57
  # Don't stomp on a superclass's `content` method
60
58
  has_content_method = begin
@@ -82,8 +80,6 @@ module Heartml
82
80
 
83
81
  def html_file_extensions = %w[module.html mod.html heartml].freeze
84
82
 
85
- def processed_css_extension = "css-local"
86
-
87
83
  # @param tag_name [String]
88
84
  # @param heart_module [String] if not provided, a class method called `source_location` must be
89
85
  # available with the absolute path of the Ruby file
@@ -194,13 +190,20 @@ module Heartml
194
190
 
195
191
  tmpl_el = doc.css("> template").find do |node|
196
192
  node.attributes.empty? ||
197
- (node.attributes.count == 1 && node.attributes.any? { |k| k[0].start_with?("data-") })
193
+ (node.attributes.count == 1 && node.attributes.any? { |k| k[0] == "data-ssr-only" })
198
194
  end
199
195
 
200
- unless tmpl_el
196
+ if tmpl_el
197
+ # Hoist light DOM children templates, if need be
198
+ doc.css("> template[hl-content]").each do |node|
199
+ tmpl_el.children[0] << node
200
+ end
201
+ else
202
+ # No top-level template, so we create one
201
203
  tmpl_el = doc.document.create_element("template")
202
204
  immediate_children = doc.css("> :not(style):not(script)")
203
205
  tmpl_el.children[0] << immediate_children
206
+ tmpl_el.children[0] << doc.css("> style[server-effect]")
204
207
  doc.prepend_child(tmpl_el)
205
208
  end
206
209
 
@@ -210,26 +213,8 @@ module Heartml
210
213
  # Set attributes on the custom element
211
214
  attributes.each { |k, v| doc[k.to_s.tr("_", "-")] = value_to_attribute(v) if v }
212
215
 
213
- # Look for external and internal styles
214
- output_styles = ""
215
- external_styles = doc.css("link[rel=stylesheet]")
216
- external_styles.each do |external_style|
217
- next unless external_style["server-process"]
218
-
219
- output_styles += File.read(File.expand_path(external_style["href"], File.dirname(self.class.heart_module)))
220
- external_style.remove
221
- rescue StandardError => e
222
- raise e.class, e.message.lines.first,
223
- ["#{self.class.heart_module}:#{external_style.line}", *e.backtrace]
224
- end
225
- sidecar_file = "#{File.join(
226
- File.dirname(self.class.heart_module), File.basename(self.class.heart_module, ".*")
227
- )}.#{self.class.processed_css_extension}"
228
- output_styles += if File.exist?(sidecar_file)
229
- File.read(sidecar_file)
230
- else
231
- doc.css("> style:not([scope])").map(&:content).join
232
- end
216
+ # Look for internal styles
217
+ output_styles = doc.css("> style:not([scope])").map(&:content).join
233
218
 
234
219
  # Now remove all nodes *except* the template
235
220
  doc.children.each do |node|
@@ -248,10 +233,11 @@ module Heartml
248
233
  # Guess what? We can reuse the same template tag! =)
249
234
  tmpl_el["shadowrootmode"] = "open"
250
235
  tmpl_el.children[0] << style_tag if style_tag
236
+ child_content.at_css("hl-slot")&.swap(content) if @_replaced_content.is_a?(Nokolexbor::Node) && content
251
237
  doc << child_content if child_content
252
238
  else
253
239
  tmpl_el.children[0] << style_tag if style_tag
254
- tmpl_el.children[0].at_css("slot:not([name])")&.swap(child_content) if child_content
240
+ tmpl_el.children[0].at_css("hl-slot")&.swap(child_content) if child_content
255
241
  tmpl_el.children[0].children.each do |node|
256
242
  doc << node
257
243
  end
@@ -376,28 +362,10 @@ module Heartml
376
362
  @_context_locals = previous_context
377
363
  end
378
364
 
379
- def _server_children(attribute:, node:) # rubocop:disable Lint/UnusedMethodArgument
365
+ def _server_content(attribute:, node:) # rubocop:disable Lint/UnusedMethodArgument
380
366
  self.replaced_content = node.children[0]
381
367
  node.remove
382
368
  end
383
-
384
- def _server_unsafe_eval(attribute:, node:)
385
- node_name = node.name
386
- correct_node = node_name == "template" ? node.children[0] : node
387
- result = node_or_string(evaluate_attribute_expression(attribute, correct_node.inner_html))
388
-
389
- if node_name == "template"
390
- node.swap(result)
391
- else
392
- node.inner_html = result
393
- attribute.parent.delete(attribute.name)
394
- end
395
- end
396
-
397
- def _server_content(attribute:, node:)
398
- result = evaluate_attribute_expression(attribute, "content")
399
- node.swap(result)
400
- end
401
369
  end
402
370
 
403
371
  require_relative "heartml/template_renderer"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heartml
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta17
4
+ version: 1.0.0.beta18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jared White
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-27 00:00:00.000000000 Z
11
+ date: 2024-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby