p2 2.10 → 2.12
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/CHANGELOG.md +8 -0
- data/lib/p2/compiler.rb +85 -30
- data/lib/p2/template.rb +20 -5
- data/lib/p2/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c26b9c214f11c471fb039fba72fdde0b98f8d7c85864ec9db271a295f2e078fa
|
4
|
+
data.tar.gz: 52dc0929deb222d22e496cf451ee927f5047403e1b687f1588e2dccc74f59135
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb6032e2a12263ca0ff29cf00b677d1aa88dbd2becf57e662d09c857ecc39e4670af18b1b6493e548b83a4e73d010822b3cca4b07b4ed372e5b63d566bd11861
|
7
|
+
data.tar.gz: cbdbaf04e4beb275463b38ee453b93dac751a74166f3264a41269177f869a04a2082999dc4f2adca03ef85b075d5726fbc0300bb5ffa9d27041bddaf146b87f3
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
# 2.12 2025-09-11
|
2
|
+
|
3
|
+
- Add support for injecting location attributes into HTML tags (for debug purposes)
|
4
|
+
|
5
|
+
# 2.11 2025-09-11
|
6
|
+
|
7
|
+
- Add mode param to `P2::Template` wrapper class
|
8
|
+
|
1
9
|
# 2.10 2025-09-11
|
2
10
|
|
3
11
|
- Add support for rendering XML, implement `Proc#render_xml`
|
data/lib/p2/compiler.rb
CHANGED
@@ -10,6 +10,12 @@ module P2
|
|
10
10
|
# A Compiler converts a template into an optimized form that generates HTML
|
11
11
|
# efficiently.
|
12
12
|
class Compiler < Sirop::Sourcifier
|
13
|
+
@@html_atts_injector = nil
|
14
|
+
|
15
|
+
def self.html_atts_injector=(proc)
|
16
|
+
@@html_atts_injector = proc
|
17
|
+
end
|
18
|
+
|
13
19
|
# Compiles the given proc, returning the generated source map and the
|
14
20
|
# generated optimized source code.
|
15
21
|
#
|
@@ -80,12 +86,12 @@ module P2
|
|
80
86
|
# @param orig_ast [Prism::Node] template AST
|
81
87
|
# @return [self]
|
82
88
|
def with_source_map(orig_proc, orig_ast)
|
83
|
-
fn =
|
89
|
+
@fn = orig_proc.source_location.first
|
84
90
|
@orig_proc = orig_proc
|
85
91
|
@orig_proc_fn = orig_proc.source_location.first
|
86
92
|
@source_map = {
|
87
93
|
source_fn: orig_proc.source_location.first,
|
88
|
-
compiled_fn:
|
94
|
+
compiled_fn: Compiler.source_location_to_fn(orig_proc.source_location)
|
89
95
|
}
|
90
96
|
@source_map_line_ofs = 2
|
91
97
|
self
|
@@ -155,7 +161,7 @@ module P2
|
|
155
161
|
|
156
162
|
# adjust_whitespace(node.location)
|
157
163
|
is_void = is_void_element?(tag)
|
158
|
-
emit_html(node.tag_location, format_html_tag_open(tag, node.attributes))
|
164
|
+
emit_html(node.tag_location, format_html_tag_open(node.tag_location, tag, node.attributes))
|
159
165
|
return if is_void
|
160
166
|
|
161
167
|
case node.block
|
@@ -456,13 +462,14 @@ module P2
|
|
456
462
|
|
457
463
|
# Formats an open tag with optional attributes.
|
458
464
|
#
|
465
|
+
# @param loc [Prism::Location] tag location
|
459
466
|
# @param tag [String, Symbol] HTML tag
|
460
467
|
# @param attributes [Hash, nil] attributes
|
461
468
|
# @return [String] HTML
|
462
|
-
def format_html_tag_open(tag, attributes)
|
469
|
+
def format_html_tag_open(loc, tag, attributes)
|
463
470
|
tag = convert_tag(tag)
|
464
|
-
if attributes && attributes&.elements.size > 0
|
465
|
-
"<#{tag} #{format_html_attributes(attributes)}>"
|
471
|
+
if attributes && attributes&.elements.size > 0 || @@html_atts_injector
|
472
|
+
"<#{tag} #{format_html_attributes(loc, attributes)}>"
|
466
473
|
else
|
467
474
|
"<#{tag}>"
|
468
475
|
end
|
@@ -551,37 +558,85 @@ module P2
|
|
551
558
|
|
552
559
|
# Formats HTML attributes from the given node.
|
553
560
|
#
|
554
|
-
# @param
|
561
|
+
# @param loc [Prism::Location] tag location
|
562
|
+
# @param node [Prism::Node] attributes node
|
555
563
|
# @return [String] HTML
|
556
|
-
def format_html_attributes(node)
|
557
|
-
elements = node
|
558
|
-
|
559
|
-
|
560
|
-
!is_static_node?(it.key) || !is_static_node?(it.value)
|
564
|
+
def format_html_attributes(loc, node)
|
565
|
+
elements = node&.elements || []
|
566
|
+
if elements.any? { is_dynamic_attribute?(it) }
|
567
|
+
return format_html_dynamic_attributes(loc, node)
|
561
568
|
end
|
562
569
|
|
563
|
-
|
570
|
+
injected_atts = format_injected_attributes(loc)
|
571
|
+
parts = elements.map { format_attribute(it.key, it.value) }
|
572
|
+
(injected_atts + parts).compact.join(' ')
|
573
|
+
end
|
574
|
+
|
575
|
+
# Formats dynamic HTML attributes from the given node.
|
576
|
+
#
|
577
|
+
# @param loc [Prism::Location] tag location
|
578
|
+
# @param node [Prism::Node] attributes node
|
579
|
+
# @return [String] HTML
|
580
|
+
def format_html_dynamic_attributes(loc, node)
|
581
|
+
injected_atts = compute_injected_attributes(loc)
|
582
|
+
if injected_atts.empty?
|
583
|
+
return interpolated("P2.format_tag_attrs(#{format_code(node)})")
|
584
|
+
else
|
585
|
+
return interpolated("P2.format_tag_attrs(#{injected_atts.inspect}.merge(#{format_code(node)}))")
|
586
|
+
end
|
587
|
+
end
|
564
588
|
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
589
|
+
# Returns true if the given node is a dynamic node.
|
590
|
+
#
|
591
|
+
# @param node [Prism::Node] attributes node
|
592
|
+
# @return [bool] is node dynamic
|
593
|
+
def is_dynamic_attribute?(node)
|
594
|
+
node.is_a?(Prism::AssocSplatNode) || !is_static_node?(node.key) || !is_static_node?(node.value)
|
595
|
+
end
|
596
|
+
|
597
|
+
# Computes injected attributes for the given tag location.
|
598
|
+
#
|
599
|
+
# @param loc [Prism::Location] tag location
|
600
|
+
# @return [Hash] injected attributes hash
|
601
|
+
def compute_injected_attributes(loc)
|
602
|
+
return {} if (@mode == :xml) || !@@html_atts_injector
|
603
|
+
|
604
|
+
loc = loc_start(loc)
|
605
|
+
@@html_atts_injector&.(@fn, loc[0], loc[1] + 1)
|
606
|
+
end
|
607
|
+
|
608
|
+
# Computes injected attributes for the given tag location.
|
609
|
+
#
|
610
|
+
# @param loc [Prism::Location] tag location
|
611
|
+
# @return [Array<String>] array of attribute strings
|
612
|
+
def format_injected_attributes(loc)
|
613
|
+
atts = compute_injected_attributes(loc)
|
614
|
+
atts.map { |k, v| format_attribute(k, v) }
|
615
|
+
end
|
616
|
+
|
617
|
+
# Formats a tag attribute with the given key and value. A nil, or false
|
618
|
+
# value will return nil.
|
619
|
+
#
|
620
|
+
# @param key [any] attribute key
|
621
|
+
# @param value [any] attribute value
|
622
|
+
# @return [String, nil] formatted attribute
|
623
|
+
def format_attribute(key, value)
|
624
|
+
case value
|
625
|
+
when Prism::TrueNode
|
626
|
+
format_literal(key)
|
627
|
+
when Prism::FalseNode, Prism::NilNode
|
628
|
+
nil
|
629
|
+
when String
|
630
|
+
"#{P2.underscores_to_dashes(key)}=\\\"#{value}\\\""
|
631
|
+
else
|
632
|
+
key = format_literal(key)
|
633
|
+
if is_static_node?(value)
|
634
|
+
value = format_literal(value)
|
635
|
+
"#{P2.underscores_to_dashes(key)}=\\\"#{value}\\\""
|
573
636
|
else
|
574
|
-
|
575
|
-
if is_static_node?(value)
|
576
|
-
value = format_literal(value)
|
577
|
-
"#{P2.underscores_to_dashes(k)}=\\\"#{value}\\\""
|
578
|
-
else
|
579
|
-
"#{P2.underscores_to_dashes(k)}=\\\"#\{#{format_code(value)}}\\\""
|
580
|
-
end
|
637
|
+
"#{P2.underscores_to_dashes(key)}=\\\"#\{#{format_code(value)}}\\\""
|
581
638
|
end
|
582
639
|
end
|
583
|
-
|
584
|
-
parts.compact.join(' ')
|
585
640
|
end
|
586
641
|
|
587
642
|
# Emits HTML into the pending HTML buffer.
|
data/lib/p2/template.rb
CHANGED
@@ -4,10 +4,25 @@ module P2
|
|
4
4
|
# Template wrapper class. This class can be used to distinguish between P2
|
5
5
|
# templates and other kinds of procs.
|
6
6
|
class Template
|
7
|
-
attr_reader :proc
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def
|
7
|
+
attr_reader :proc, :mode
|
8
|
+
|
9
|
+
# @param proc [Proc] template proc
|
10
|
+
# @param mode [Symbol] mode (:html, :xml)
|
11
|
+
def initialize(proc, mode: :html)
|
12
|
+
@proc = proc
|
13
|
+
@mode = mode
|
14
|
+
end
|
15
|
+
|
16
|
+
def render(*, **, &)
|
17
|
+
(mode == :xml) ? @proc.render_xml(*, **, &) : @proc.render(*, **, &)
|
18
|
+
end
|
19
|
+
|
20
|
+
def apply(*, **, &)
|
21
|
+
Template.new(@proc.apply(*, **, &), mode: @mode)
|
22
|
+
end
|
23
|
+
|
24
|
+
def compiled_proc
|
25
|
+
@proc.compiled_proc(mode: @mode)
|
26
|
+
end
|
12
27
|
end
|
13
28
|
end
|
data/lib/p2/version.rb
CHANGED