htx 0.0.8 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b83c07872c223b61b939883d9f2f6bc45a1cecc380c4b21701d04a606e7ae381
4
- data.tar.gz: bfbf43071b20b13be3895bf4e358617765f39f276ed1d37c91c93f09c024b48a
3
+ metadata.gz: 83c2b45f8852d11b5faa35989c0552a4135c3270d20aaaa2af8d170e696ad840
4
+ data.tar.gz: dcbbb3aac2484f55b445a029c9916e282dc75b93197f630b40227110aba02c28
5
5
  SHA512:
6
- metadata.gz: 0dc4f9f8fad2b18266ca93a562fa1565361b330744e8f02134341c1a5982f0821a9b008975adcff7840626d85f05bca223dd433705799c227217584dab1f970c
7
- data.tar.gz: 58756df107105643831511c4faff3f7ccdc96fdcd318d7f65833cb642b4c08be60ab2e2f9cc6ffb999a9980a63a8a15a9b0b8b94c0aab8a4f8447ee61909c5a4
6
+ metadata.gz: 8a26b13b0f0cdddf7d9338f1876c23e59adaef4abd2d706cae4a984bd74ca207465e93d6c1d1f0877adf5f27999ddbfd59d93c703ffe098ea7cfc239bc8f391d
7
+ data.tar.gz: e6ace0fd8c2289e1b2062e6f9e976e017b3e639cfd0eb0777bf5e4bd9ded53d8774c843cfcb1cc55a1c491d0fe6d4f81e337455897ec471bebc0d333db202ba5
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2019-2022 Nate Pickens
1
+ Copyright 2019-2023 Nate Pickens
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4
4
  documentation files (the "Software"), to deal in the Software without restriction, including without
data/README.md CHANGED
@@ -29,7 +29,7 @@ template = File.read(File.join('some/asset/dir', path))
29
29
 
30
30
  HTX.compile(path, template)
31
31
 
32
- # window['/components/crew.htx'] = function(htx) {
32
+ # globalThis['/components/crew.htx'] = function(htx) {
33
33
  # // ...
34
34
  # }
35
35
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.8
1
+ 0.1.0
data/lib/htx/template.rb CHANGED
@@ -17,7 +17,6 @@ module HTX
17
17
  'svg' => 'http://www.w3.org/2000/svg',
18
18
  }.freeze
19
19
 
20
- INDENT_VALID = /^( +|\t+)$/.freeze
21
20
  INDENT_GUESS = /^( +|\t+)(?=\S)/.freeze
22
21
  INDENT_REGEX = /\n(?=[^\n])/.freeze
23
22
 
@@ -32,17 +31,14 @@ module HTX
32
31
  NON_WHITESPACE = /\S/.freeze
33
32
 
34
33
  ##
35
- # Returns false. In the near future when support for the <:> tag has been dropped (in favor of
36
- # <htx-content>), will return true if Nokogiri's HTML5 parser is available. To use it now, monkey patch
37
- # this method to return true.
34
+ # Returns true if Nokogiri's HTML5 parser is available.
38
35
  #
39
36
  def self.html5_parser?
40
- false # !!defined?(Nokogiri::HTML5)
37
+ defined?(Nokogiri::HTML5)
41
38
  end
42
39
 
43
40
  ##
44
- # Returns Nokogiri's HTML5 parser if available and enabled, and Nokogiri's regular HTML parser
45
- # otherwise.
41
+ # Returns Nokogiri's HTML5 parser if available or Nokogiri's default HTML (4) parser otherwise.
46
42
  #
47
43
  def self.nokogiri_parser
48
44
  html5_parser? ? Nokogiri::HTML5 : Nokogiri::HTML
@@ -62,24 +58,11 @@ module HTX
62
58
  ##
63
59
  # Compiles the HTX template.
64
60
  #
65
- # * +assign_to+ - JavaScript object to assign the template function to (default: <tt>window</tt>).
66
- # * +indent+ - DEPRECATED. Indentation amount (number) or string (must be only spaces or tabs but not
67
- # both) to use for indentation of compiled output (default: indentation of first indented line of
68
- # uncompiled template).
69
- #
70
- def compile(assign_to: nil, indent: (indent_omitted = true; nil))
71
- @assign_to = assign_to || 'window'
72
- @indent =
73
- if indent.kind_of?(Numeric)
74
- ' ' * indent
75
- elsif indent && !indent.match?(INDENT_VALID)
76
- raise("Invalid indent value #{indent.inspect}: only spaces and tabs (but not both) are allowed")
77
- else
78
- indent || @content[INDENT_GUESS] || INDENT_DEFAULT
79
- end
80
-
81
- warn('The indent: option for HTX template compilation is deprecated.') unless indent_omitted
82
-
61
+ # * +assign_to+ - JavaScript object to assign the template function to (default: +globalThis+).
62
+ #
63
+ def compile(assign_to: nil)
64
+ @assign_to = assign_to || 'globalThis'
65
+ @base_indent = @indent = @content[INDENT_GUESS] || INDENT_DEFAULT
83
66
  @static_key = 0
84
67
  @close_count = 0
85
68
  @whitespace_buff = nil
@@ -158,14 +141,35 @@ module HTX
158
141
  # * +node+ - Nokogiri node to process.
159
142
  #
160
143
  def process_fragment_node(node)
161
- append("#{@assign_to}['#{@name}'] = function(htx) {")
162
- @whitespace_buff = "\n"
144
+ append(
145
+ <<~JS
146
+ #{@assign_to}['#{@name}'] = ((HTX) => {
147
+ #{@indent}function render($rndr) {
148
+ JS
149
+ )
150
+
151
+ @indent = @base_indent * 2
163
152
 
164
153
  node.children.each do |child|
165
154
  process(child)
166
155
  end
167
156
 
168
- append("\n}\n",)
157
+ append("\n\n#{@indent}return $rndr.rootNode")
158
+
159
+ @indent = @base_indent
160
+
161
+ append(
162
+ +<<~JS
163
+
164
+ #{@indent}}
165
+
166
+ #{@indent}return function Template(context) {
167
+ #{@indent * 2}this.render = render.bind(context, new HTX.Renderer)
168
+ #{@indent}}
169
+ })(globalThis.HTX ||= {});
170
+ JS
171
+ )
172
+
169
173
  flush
170
174
  end
171
175
 
@@ -173,21 +177,16 @@ module HTX
173
177
  # Processes an element node.
174
178
  #
175
179
  # * +node+ - Nokogiri node to process.
176
- # * +xmlns+ - True if node is the descendent of a node with an xmlns attribute.
180
+ # * +xmlns+ - True if node is the descendant of a node with an xmlns attribute.
177
181
  #
178
182
  def process_element_node(node, xmlns: false)
179
183
  children = node.children
180
184
  childless = children.empty? || (children.size == 1 && self.class.formatting_node?(children.first))
181
185
  dynamic_key = self.class.attribute_value(node.attr(DYNAMIC_KEY_ATTR))
182
- attributes = self.class.process_attributes(node)
186
+ attributes = self.class.process_attributes(node, xmlns: xmlns)
183
187
  xmlns ||= !!self.class.namespace(node)
184
188
 
185
189
  if self.class.htx_content_node?(node)
186
- if node.name != CONTENT_TAG
187
- warn("#{@name}:#{node.line}: The <#{node.name}> tag has been deprecated. Use <#{CONTENT_TAG}> "\
188
- "for identical functionality.")
189
- end
190
-
191
190
  if attributes.size > 0
192
191
  raise(MalformedTemplateError.new("<#{node.name}> tags may not have attributes other than "\
193
192
  "#{DYNAMIC_KEY_ATTR}", @name, node))
@@ -263,13 +262,13 @@ module HTX
263
262
  # * +text+ - String to append to the compiled template string.
264
263
  #
265
264
  def append(text)
266
- return @compiled if text.nil? || text.empty?
265
+ return if text.nil? || text.empty?
267
266
 
268
267
  if @close_count > 0
269
268
  close_count = @close_count
270
269
  @close_count = 0
271
270
 
272
- append("htx.close(#{close_count unless close_count == 1})")
271
+ append("$rndr.close(#{close_count unless close_count == 1})")
273
272
  end
274
273
 
275
274
  if @whitespace_buff
@@ -286,8 +285,6 @@ module HTX
286
285
 
287
286
  flush if text.match?(NON_WHITESPACE)
288
287
  @statement_buff << text
289
-
290
- @compiled
291
288
  end
292
289
 
293
290
  ##
@@ -302,7 +299,7 @@ module HTX
302
299
  args << 0 unless args.last.kind_of?(Integer)
303
300
  args[-1] |= (@static_key += 1) << FLAG_BITS
304
301
 
305
- append("htx.node(#{args.join(', ')})")
302
+ append("$rndr.node(#{args.join(', ')})")
306
303
  end
307
304
 
308
305
  ##
@@ -311,8 +308,6 @@ module HTX
311
308
  def flush
312
309
  @compiled << @statement_buff
313
310
  @statement_buff.clear
314
-
315
- @compiled
316
311
  end
317
312
 
318
313
  ##
@@ -340,7 +335,7 @@ module HTX
340
335
  # * +node+ - Nokogiri node to check.
341
336
  #
342
337
  def self.htx_content_node?(node)
343
- node && (node.name == CONTENT_TAG || node.name == 'htx-text' || node.name == ':')
338
+ node&.name == CONTENT_TAG
344
339
  end
345
340
 
346
341
  ##
@@ -348,10 +343,10 @@ module HTX
348
343
  #
349
344
  # * +node+ - Nokogiri node to process the attributes of.
350
345
  #
351
- def self.process_attributes(node)
346
+ def self.process_attributes(node, xmlns:)
352
347
  attributes = []
353
348
 
354
- if !node.attribute('xmlns') && (xmlns = namespace(node))
349
+ if !xmlns && !node.attribute('xmlns') && (xmlns = namespace(node))
355
350
  attributes.push(
356
351
  attribute_name('xmlns'),
357
352
  attribute_value(xmlns)
@@ -369,7 +364,9 @@ module HTX
369
364
  end
370
365
 
371
366
  ##
367
+ # Returns namespace URL of a Nokogiri node.
372
368
  #
369
+ # * +node+ - Nokogiri node to get the namespace of.
373
370
  #
374
371
  def self.namespace(node)
375
372
  node.namespace&.href || DEFAULT_XMLNS[node.name]
@@ -404,15 +401,10 @@ module HTX
404
401
  text ? TextParser.new(text, statement_allowed: false).parse : nil
405
402
  end
406
403
 
407
- # The Nokogiri HTML parser downcases all tag and attribute names, but SVG tags and attributes are case
408
- # sensitive and often mix cased. These maps are used to restore the correct case of such tags and
409
- # attributes.
410
- #
411
- # Note: Nokogiri's newer HTML5 parser resulting from the Nokogumbo merge fixes this issue, but it is
412
- # currently not available for JRuby. It also does not parse <:> as a tag, which is why it's been
413
- # deprecated in favor of <htx-content>. Once support for <:> has been completely removed, the HTML5
414
- # parser will be used for regular Ruby and this tag and attribute mapping hack reserved for JRuby (and
415
- # any other potential environments where the HTML5 parser is not available).
404
+ # The Nokogiri::HTML5 parser is used whenever possible, which correctly handles mix-cased SVG tag and
405
+ # attribute names. But when falling back to the Nokogiri::HTML parser (e.g. in JRuby environments where
406
+ # Nokogiri::HTML5 is not available), all tag and attribute names get downcased. These maps are used to
407
+ # restore the correct case.
416
408
 
417
409
  # Source: https://developer.mozilla.org/en-US/docs/Web/SVG/Element
418
410
  TAG_MAP = %w[
@@ -216,6 +216,8 @@ module HTX
216
216
  ##
217
217
  # Flushes buffer during parsing and performs statement detection if appropriate.
218
218
  #
219
+ # * +state+ - Last state that was parsed.
220
+ #
219
221
  def flush(state = nil)
220
222
  return if @buffer.empty?
221
223
 
data/lib/htx/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTX
4
- VERSION = '0.0.8'
4
+ VERSION = '0.1.0'
5
5
  end
data/lib/htx.rb CHANGED
@@ -21,18 +21,4 @@ module HTX
21
21
  def self.compile(name, content, options = EMPTY_HASH)
22
22
  Template.new(name, content).compile(**options)
23
23
  end
24
-
25
- ##
26
- # DEPRECATED. Use HTX::Template.new instead. HTX was formerly a class that would be instantiated for
27
- # compilation. This method allows HTX.new calls to continue working (but support will be removed in the
28
- # near future).
29
- #
30
- # * +name+ - Template name. Conventionally the path of the template file.
31
- # * +content+ - Template content.
32
- #
33
- def self.new(name, content)
34
- warn('HTX.new is deprecated. Please use HTX::Template.new instead.')
35
-
36
- Template.new(name, content)
37
- end
38
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: htx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nate Pickens
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-31 00:00:00.000000000 Z
11
+ date: 2023-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -96,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0'
98
98
  requirements: []
99
- rubygems_version: 3.2.32
99
+ rubygems_version: 3.4.6
100
100
  signing_key:
101
101
  specification_version: 4
102
102
  summary: A Ruby compiler for HTX templates.