leptris 1.9.14 → 1.9.15
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 +17 -0
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/element.rb +11 -7
- data/lib/leptris/xml/node.rb +11 -2
- 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: c1b73d7abca12056f163aed086825140416384075955e593f11191156db475fc
|
|
4
|
+
data.tar.gz: ead9075339cfd0736ca79cbede18612702f4632c95d9d90a512f67b3e4c32ec7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 22ec81a95a094913096d9c0749c42a64274f7af9225c4128b51529c8160f6480d3f23476b548f7c766202be9744dee9a830eaa715dbeea77a42e4d374f61b6e5
|
|
7
|
+
data.tar.gz: 5e5408837f3ca2b4b54e4069a36798000b67d87fee9ed7021927b4e6c8b95d6a04a9f9d770fcd786763569d700182f87fc5b7df54c14462391c0420f69d108ed
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,23 @@ All notable changes to Leptris will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.9.15] - 2026-08-27
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **`Element#[]` serves bare names from the versioned attributes
|
|
13
|
+
hash on every document kind** (writable included): materializes
|
|
14
|
+
on demand, invalidates through the mutation gate. Qualified names
|
|
15
|
+
(with a colon) still route to the engine — they resolve through
|
|
16
|
+
in-scope declarations where the written prefix never matters,
|
|
17
|
+
which a written-name-keyed hash cannot answer. Writable
|
|
18
|
+
attribute loops reach readonly parity: 0.196 s -> 0.101 s (2x);
|
|
19
|
+
the readonly special-case branch is deleted. The qualified/bare
|
|
20
|
+
split is spec-pinned (cross-prefix match, undeclared-prefix nil).
|
|
21
|
+
- **`first_element_child` memoizes** with version invalidation
|
|
22
|
+
(structural mutations bump): 0.058 s -> 0.015 s (4x) on the
|
|
23
|
+
repeat loop.
|
|
24
|
+
|
|
8
25
|
## [1.9.14] - 2026-08-27
|
|
9
26
|
|
|
10
27
|
### Changed
|
data/lib/leptris/version.rb
CHANGED
data/lib/leptris/xml/element.rb
CHANGED
|
@@ -35,16 +35,20 @@ class Leptris::XML::Element < Leptris::XML::Node
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def [](key)
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
# BARE names serve from the versioned attributes hash (written
|
|
39
|
+
# name == the only legal key for a no-namespace attribute);
|
|
40
|
+
# materializes on demand, invalidates through the mutation gate
|
|
41
|
+
# (ADR 0003's 1.9.14 extension); a hash read cannot
|
|
42
|
+
# use-after-free. QUALIFIED names (with a colon) go to the
|
|
43
|
+
# engine: they resolve through in-scope declarations, where the
|
|
44
|
+
# written prefix never matters — the hash cannot answer them.
|
|
45
|
+
name = key.to_s
|
|
46
|
+
if @document && !name.include?(":")
|
|
47
|
+
cached = attributes[name]
|
|
44
48
|
return cached.nil? ? nil : cached.value
|
|
45
49
|
end
|
|
46
50
|
ensure_alive!
|
|
47
|
-
Leptris::XML::FFI.leptris_element_attribute(@c_ptr,
|
|
51
|
+
Leptris::XML::FFI.leptris_element_attribute(@c_ptr, name)
|
|
48
52
|
end
|
|
49
53
|
alias_method :attr, :[]
|
|
50
54
|
alias_method :get_attribute, :[]
|
data/lib/leptris/xml/node.rb
CHANGED
|
@@ -179,14 +179,23 @@ class Leptris::XML::Node
|
|
|
179
179
|
alias_method :previous, :previous_sibling
|
|
180
180
|
|
|
181
181
|
def first_element_child
|
|
182
|
+
return @first_element_child if memo_hit?(@first_element_child_version)
|
|
182
183
|
ensure_alive!
|
|
183
184
|
ptr = Leptris::XML::FFI.leptris_node_first_child(@c_ptr)
|
|
185
|
+
result = nil
|
|
184
186
|
until ptr.nil? || ptr.null?
|
|
185
187
|
node = Leptris::XML::Node.wrap(ptr, @document, parent: as_element_or_self)
|
|
186
|
-
|
|
188
|
+
if node.element?
|
|
189
|
+
result = node
|
|
190
|
+
break
|
|
191
|
+
end
|
|
187
192
|
ptr = Leptris::XML::FFI.leptris_node_next_sibling(ptr)
|
|
188
193
|
end
|
|
189
|
-
|
|
194
|
+
if @document
|
|
195
|
+
@first_element_child = result
|
|
196
|
+
@first_element_child_version = @document.version
|
|
197
|
+
end
|
|
198
|
+
result
|
|
190
199
|
end
|
|
191
200
|
|
|
192
201
|
def last_element_child
|