phlex 2.4.0.beta2 → 2.4.1
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 +4 -4
- data/lib/phlex/compiler/method_compiler.rb +1 -1
- data/lib/phlex/compiler.rb +0 -2
- data/lib/phlex/fifo.rb +1 -1
- data/lib/phlex/html.rb +1 -1
- data/lib/phlex/kit.rb +2 -2
- data/lib/phlex/sgml/attributes.rb +38 -5
- data/lib/phlex/sgml.rb +3 -47
- data/lib/phlex/svg.rb +1 -1
- data/lib/phlex/version.rb +1 -1
- data/lib/ruby_lsp/phlex/addon.rb +2 -0
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: abdf62bcb21b9c00118dc8fa4f1c96d510caecc15eebf4539b5655c3ab94e057
|
|
4
|
+
data.tar.gz: e88808653a12b00adbb4980e07994b379bb871cabd4652c9e19bb76ef87dc0f0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f6568b33898b323c45e86405f3369816262195e4da70b9b94405779fd6728307b7c785ee53392bc1717ee2de26dad5029ec47b2f6753cb80ed4880a4cd15c97e
|
|
7
|
+
data.tar.gz: '09cdec83ffabbe16b7e2895f1964f1cc29217c89b93a1a7848c982ec1d0329d101ad165b165f0c98638daf9c0b5bc3072cf671661e41d139a9ffe5f5069f9055'
|
|
@@ -462,7 +462,7 @@ module Phlex::Compiler
|
|
|
462
462
|
when Refract::AssocNode
|
|
463
463
|
(Refract::StringNode === value.key || Refract::SymbolNode === value.key) && static_attribute_value_literal?(value.value)
|
|
464
464
|
when Refract::CallNode
|
|
465
|
-
if value in { receiver: Prism::ConstantReadNode[name: :Set]| Prism::ConstantPathNode[name: :Set, parent: nil], name: :[] }
|
|
465
|
+
if value in { receiver: Prism::ConstantReadNode[name: :Set] | Prism::ConstantPathNode[name: :Set, parent: nil], name: :[] }
|
|
466
466
|
value.arguments.arguments.all? { |n| static_token_value_literal?(n) }
|
|
467
467
|
else
|
|
468
468
|
false
|
data/lib/phlex/compiler.rb
CHANGED
data/lib/phlex/fifo.rb
CHANGED
data/lib/phlex/html.rb
CHANGED
|
@@ -55,7 +55,7 @@ class Phlex::HTML < Phlex::SGML
|
|
|
55
55
|
raise Phlex::ArgumentError.new("Expected the tag name to be a Symbol.")
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
if (tag = StandardElements.__registered_elements__[name]) || ((tag = name.name.tr("_", "-")).include?("-") && tag.match?(/\A[a-z0-9-]+\z/))
|
|
59
59
|
if attributes.length > 0 # with attributes
|
|
60
60
|
if block_given # with content block
|
|
61
61
|
buffer << "<#{tag}" << (Phlex::ATTRIBUTE_CACHE[attributes] ||= Phlex::SGML::Attributes.generate_attributes(attributes)) << ">"
|
data/lib/phlex/kit.rb
CHANGED
|
@@ -63,8 +63,8 @@ module Phlex::Kit
|
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
define_singleton_method(name) do |*args, **kwargs, &block|
|
|
66
|
-
component
|
|
67
|
-
if
|
|
66
|
+
component = Thread.current[:__phlex_component__]
|
|
67
|
+
if component
|
|
68
68
|
component.instance_exec do
|
|
69
69
|
constant = me.const_get(name)
|
|
70
70
|
render(constant.new(*args, **kwargs), &block)
|
|
@@ -4,7 +4,13 @@ module Phlex::SGML::Attributes
|
|
|
4
4
|
extend self
|
|
5
5
|
|
|
6
6
|
UNSAFE_ATTRIBUTES = Set.new(%w[srcdoc sandbox http-equiv]).freeze
|
|
7
|
-
REF_ATTRIBUTES = Set.new(%w[href src action formaction lowsrc dynsrc background ping]).freeze
|
|
7
|
+
REF_ATTRIBUTES = Set.new(%w[href src action formaction lowsrc dynsrc background ping xlinkhref]).freeze
|
|
8
|
+
NAMED_CHARACTER_REFERENCES = {
|
|
9
|
+
"colon" => ":",
|
|
10
|
+
"tab" => "\t",
|
|
11
|
+
"newline" => "\n",
|
|
12
|
+
}.freeze
|
|
13
|
+
UNSAFE_ATTRIBUTE_NAME_CHARS = %r([<>&"'/=\s\x00])
|
|
8
14
|
|
|
9
15
|
def generate_attributes(attributes, buffer = +"")
|
|
10
16
|
attributes.each do |k, v|
|
|
@@ -53,7 +59,11 @@ module Phlex::SGML::Attributes
|
|
|
53
59
|
when Phlex::SGML::SafeObject
|
|
54
60
|
v.to_s.gsub('"', """)
|
|
55
61
|
else
|
|
56
|
-
|
|
62
|
+
if v.respond_to?(:to_h)
|
|
63
|
+
generate_nested_attributes(v.to_h, "#{name}-", buffer)
|
|
64
|
+
else
|
|
65
|
+
raise Phlex::ArgumentError.new("Invalid attribute value for #{k}: #{v.inspect}.")
|
|
66
|
+
end
|
|
57
67
|
end
|
|
58
68
|
|
|
59
69
|
lower_name = name.downcase
|
|
@@ -64,7 +74,9 @@ module Phlex::SGML::Attributes
|
|
|
64
74
|
if value != true && REF_ATTRIBUTES.include?(normalized_name)
|
|
65
75
|
case value
|
|
66
76
|
when String
|
|
67
|
-
|
|
77
|
+
decoded_value = decode_html_character_references(value)
|
|
78
|
+
|
|
79
|
+
if decoded_value.downcase.delete("^a-z:").start_with?("javascript:")
|
|
68
80
|
# We just ignore these because they were likely not specified by the developer.
|
|
69
81
|
next
|
|
70
82
|
end
|
|
@@ -82,7 +94,7 @@ module Phlex::SGML::Attributes
|
|
|
82
94
|
end
|
|
83
95
|
end
|
|
84
96
|
|
|
85
|
-
if name.match?(
|
|
97
|
+
if name.match?(UNSAFE_ATTRIBUTE_NAME_CHARS)
|
|
86
98
|
raise Phlex::ArgumentError.new("Unsafe attribute name detected: #{k}.")
|
|
87
99
|
end
|
|
88
100
|
|
|
@@ -118,7 +130,7 @@ module Phlex::SGML::Attributes
|
|
|
118
130
|
else raise Phlex::ArgumentError.new("Attribute keys should be Strings or Symbols")
|
|
119
131
|
end
|
|
120
132
|
|
|
121
|
-
if name.match?(
|
|
133
|
+
if name.match?(UNSAFE_ATTRIBUTE_NAME_CHARS)
|
|
122
134
|
raise Phlex::ArgumentError.new("Unsafe attribute name detected: #{k}.")
|
|
123
135
|
end
|
|
124
136
|
end
|
|
@@ -156,6 +168,27 @@ module Phlex::SGML::Attributes
|
|
|
156
168
|
end
|
|
157
169
|
end
|
|
158
170
|
|
|
171
|
+
def decode_html_character_references(value)
|
|
172
|
+
value
|
|
173
|
+
.gsub(/&#x([0-9a-f]+);?/i) {
|
|
174
|
+
begin
|
|
175
|
+
[$1.to_i(16)].pack("U*")
|
|
176
|
+
rescue
|
|
177
|
+
""
|
|
178
|
+
end
|
|
179
|
+
}
|
|
180
|
+
.gsub(/&#(\d+);?/) {
|
|
181
|
+
begin
|
|
182
|
+
[$1.to_i].pack("U*")
|
|
183
|
+
rescue
|
|
184
|
+
""
|
|
185
|
+
end
|
|
186
|
+
}
|
|
187
|
+
.gsub(/&([a-z][a-z0-9]+);?/i) {
|
|
188
|
+
NAMED_CHARACTER_REFERENCES[$1.downcase] || ""
|
|
189
|
+
}
|
|
190
|
+
end
|
|
191
|
+
|
|
159
192
|
def generate_nested_tokens(tokens, sep = " ", gsub_from = nil, gsub_to = "")
|
|
160
193
|
buffer = +""
|
|
161
194
|
|
data/lib/phlex/sgml.rb
CHANGED
|
@@ -2,17 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
# **Standard Generalized Markup Language** for behaviour common to {HTML} and {SVG}.
|
|
4
4
|
class Phlex::SGML
|
|
5
|
-
ERBCompiler = ERB::Compiler.new("<>").tap do |compiler|
|
|
6
|
-
compiler.pre_cmd = [""]
|
|
7
|
-
compiler.put_cmd = "@_state.buffer.<<"
|
|
8
|
-
compiler.insert_cmd = "__implicit_output__"
|
|
9
|
-
compiler.post_cmd = ["nil"]
|
|
10
|
-
|
|
11
|
-
def compiler.add_insert_cmd(out, content)
|
|
12
|
-
out.push("#{@insert_cmd}((#{content}))")
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
5
|
include Phlex::Helpers
|
|
17
6
|
|
|
18
7
|
class << self
|
|
@@ -32,40 +21,6 @@ class Phlex::SGML
|
|
|
32
21
|
super
|
|
33
22
|
end
|
|
34
23
|
end
|
|
35
|
-
|
|
36
|
-
def erb(method_name, erb = nil, locals: nil, &block)
|
|
37
|
-
loc = caller_locations(1, 1)[0]
|
|
38
|
-
path = loc.path.delete_suffix(".rb")
|
|
39
|
-
file = loc.path
|
|
40
|
-
line = loc.lineno - 1
|
|
41
|
-
|
|
42
|
-
unless erb
|
|
43
|
-
method_path = "#{path}/#{method_name}.html.erb"
|
|
44
|
-
sidecar_path = "#{path}.html.erb"
|
|
45
|
-
|
|
46
|
-
if File.exist?(method_path)
|
|
47
|
-
erb = File.read(method_path)
|
|
48
|
-
file = method_path
|
|
49
|
-
line = 1
|
|
50
|
-
elsif method_name == :view_template && File.exist?(sidecar_path)
|
|
51
|
-
erb = File.read(sidecar_path)
|
|
52
|
-
file = sidecar_path
|
|
53
|
-
line = 1
|
|
54
|
-
else
|
|
55
|
-
raise Phlex::RuntimeError.new(<<~MESSAGE)
|
|
56
|
-
No ERB template found for #{method_name}
|
|
57
|
-
MESSAGE
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
code, _enc = ERBCompiler.compile(erb)
|
|
62
|
-
|
|
63
|
-
class_eval(<<~RUBY, file, line)
|
|
64
|
-
def #{method_name} #{locals}
|
|
65
|
-
#{code}
|
|
66
|
-
end
|
|
67
|
-
RUBY
|
|
68
|
-
end
|
|
69
24
|
end
|
|
70
25
|
|
|
71
26
|
def view_template
|
|
@@ -105,7 +60,8 @@ class Phlex::SGML
|
|
|
105
60
|
|
|
106
61
|
block ||= @_content_block
|
|
107
62
|
|
|
108
|
-
Thread.current[:__phlex_component__]
|
|
63
|
+
previous_phlex_component = Thread.current[:__phlex_component__]
|
|
64
|
+
Thread.current[:__phlex_component__] = self
|
|
109
65
|
|
|
110
66
|
state.around_render(self) do
|
|
111
67
|
before_template(&block)
|
|
@@ -127,7 +83,7 @@ class Phlex::SGML
|
|
|
127
83
|
after_template(&block)
|
|
128
84
|
end
|
|
129
85
|
ensure
|
|
130
|
-
Thread.current[:__phlex_component__] =
|
|
86
|
+
Thread.current[:__phlex_component__] = previous_phlex_component
|
|
131
87
|
end
|
|
132
88
|
|
|
133
89
|
def context
|
data/lib/phlex/svg.rb
CHANGED
|
@@ -41,7 +41,7 @@ class Phlex::SVG < Phlex::SGML
|
|
|
41
41
|
raise Phlex::ArgumentError.new("Expected the tag name to be a Symbol.")
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
if (tag = StandardElements.__registered_elements__[name]) || ((tag = name.name.tr("_", "-")).include?("-") && tag.match?(/\A[a-z0-9-]+\z/))
|
|
45
45
|
if attributes.length > 0 # with attributes
|
|
46
46
|
if block_given # with content block
|
|
47
47
|
buffer << "<#{tag}" << (Phlex::ATTRIBUTE_CACHE[attributes] ||= Phlex::SGML::Attributes.generate_attributes(attributes)) << ">"
|
data/lib/phlex/version.rb
CHANGED
data/lib/ruby_lsp/phlex/addon.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: phlex
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.4.
|
|
4
|
+
version: 2.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joel Drapper
|
|
8
8
|
- Will Cosgrove
|
|
9
|
+
autorequire:
|
|
9
10
|
bindir: bin
|
|
10
11
|
cert_chain: []
|
|
11
|
-
date:
|
|
12
|
+
date: 2026-02-06 00:00:00.000000000 Z
|
|
12
13
|
dependencies:
|
|
13
14
|
- !ruby/object:Gem::Dependency
|
|
14
15
|
name: zeitwerk
|
|
@@ -85,6 +86,7 @@ metadata:
|
|
|
85
86
|
changelog_uri: https://github.com/phlex-ruby/phlex/releases
|
|
86
87
|
funding_uri: https://github.com/sponsors/joeldrapper
|
|
87
88
|
rubygems_mfa_required: 'true'
|
|
89
|
+
post_install_message:
|
|
88
90
|
rdoc_options: []
|
|
89
91
|
require_paths:
|
|
90
92
|
- lib
|
|
@@ -99,7 +101,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
99
101
|
- !ruby/object:Gem::Version
|
|
100
102
|
version: '0'
|
|
101
103
|
requirements: []
|
|
102
|
-
rubygems_version: 3.
|
|
104
|
+
rubygems_version: 3.5.3
|
|
105
|
+
signing_key:
|
|
103
106
|
specification_version: 4
|
|
104
107
|
summary: Object-oriented views in Ruby.
|
|
105
108
|
test_files: []
|