leptris 1.9.13-aarch64-linux → 1.9.14-aarch64-linux
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 +23 -0
- data/docs/adr/0003-readonly-memoization-pattern.md +17 -1
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/cdata.rb +6 -3
- data/lib/leptris/xml/comment.rb +6 -3
- data/lib/leptris/xml/document.rb +22 -4
- data/lib/leptris/xml/element.rb +41 -17
- data/lib/leptris/xml/node.rb +36 -14
- data/lib/leptris/xml/node_set.rb +0 -1
- data/lib/leptris/xml/processing_instruction.rb +12 -6
- data/lib/leptris/xml/text.rb +6 -3
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c96f59841d0606a790ec372576cdb05f50bbc39c43cdf1188e7a4535068a7a8f
|
|
4
|
+
data.tar.gz: e3396a5ec39b5638f20a2254da0796f6330ca689f62e2fcad939850a42662f64
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a6cc9bb4c0ba7b0c39ced816d8435370947d6e051df16d1d03a899c5fbbdd1a7ba1e0c7e0a05f7879874a4b20c5db7b2f7b639138eb0137bbb1276e1288b7b59
|
|
7
|
+
data.tar.gz: 12846d96eec9f9a3d681bdb1bd9a2e29807a21575adc209851bdb4b3067f8c5999732faa9a4bdfad0af1ac6e55cdac6f52c832d886623f137c8b0aa867bc5ba2
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,29 @@ 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.14] - 2026-08-27
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **Writable documents memoize** — the versioned read cache. A
|
|
13
|
+
per-document mutation version advances at every mutation gate
|
|
14
|
+
(ensure_writable!, root=, add_pi); each memoized field carries
|
|
15
|
+
its own version stamp and recomputes after any bump. Readonly
|
|
16
|
+
semantics unchanged (their version never advances — memos
|
|
17
|
+
forever valid). Measured on writable documents: namespace
|
|
18
|
+
inspection 0.392 s -> 0.013 s (**31x**, readonly parity),
|
|
19
|
+
children 0.154 s -> 0.014 s (**11x**). The read-heavy
|
|
20
|
+
DOM-editing workload (parse, query repeatedly, mutate
|
|
21
|
+
occasionally) now performs like the readonly one between
|
|
22
|
+
mutations. Staleness is test-pinned: a mutation-invalidation
|
|
23
|
+
matrix covers content, attribute, structural, namespace, root=,
|
|
24
|
+
and PI mutations against every memoized read. The shared
|
|
25
|
+
node-level stamp variant was tried and rejected in favor of
|
|
26
|
+
per-field stamps (one field's recompute must not resurrect
|
|
27
|
+
another's stale memo). ADR 0003 extended.
|
|
28
|
+
- NodeSet#[] drops the Ruby-side bounds FFI (the C accessor
|
|
29
|
+
already returns NULL out of range).
|
|
30
|
+
|
|
8
31
|
## [1.9.13] - 2026-08-27
|
|
9
32
|
|
|
10
33
|
### Changed
|
|
@@ -1,4 +1,20 @@
|
|
|
1
|
-
# ADR 0003:
|
|
1
|
+
# ADR 0003: memoization stays hand-rolled; writable docs memoize via version stamps
|
|
2
|
+
|
|
3
|
+
## 2026-08-27 extension (leptris-ruby 1.9.14)
|
|
4
|
+
|
|
5
|
+
Writable documents now memoize too: Document carries a mutation
|
|
6
|
+
version advanced at every mutation gate (Node#ensure_writable!,
|
|
7
|
+
root=, add_pi), and each memoized field stores its OWN version
|
|
8
|
+
stamp (`return @x if memo_hit?(@x_version)`). A shared node-level
|
|
9
|
+
stamp was tried and rejected — one field's recompute resurrects
|
|
10
|
+
another field's stale memo. Readonly semantics are unchanged
|
|
11
|
+
(their version never advances). Round X's "version-stamp rejected:
|
|
12
|
+
the compare costs the read" was corrected: the compare is cheap
|
|
13
|
+
against multi-FFI reads.
|
|
14
|
+
|
|
15
|
+
The hand-rolled per-site pattern (below) still stands; only the
|
|
16
|
+
guard gained a version argument.
|
|
17
|
+
|
|
2
18
|
|
|
3
19
|
## Context
|
|
4
20
|
Every readonly-mode read repeats the same three lines:
|
data/lib/leptris/version.rb
CHANGED
data/lib/leptris/xml/cdata.rb
CHANGED
|
@@ -4,11 +4,14 @@ class Leptris::XML::CDATA < Leptris::XML::Text
|
|
|
4
4
|
def name; "#cdata-section"; end
|
|
5
5
|
|
|
6
6
|
def content
|
|
7
|
-
return @content if
|
|
7
|
+
return @content if memo_hit?(@content_version)
|
|
8
8
|
ensure_alive!
|
|
9
|
-
Leptris::XML::FFI.leptris_cdata_node_get_content(@c_ptr)
|
|
10
|
-
|
|
9
|
+
result = Leptris::XML::FFI.leptris_cdata_node_get_content(@c_ptr)
|
|
10
|
+
if @document
|
|
11
|
+
@content = result
|
|
12
|
+
@content_version = @document.version
|
|
11
13
|
end
|
|
14
|
+
result
|
|
12
15
|
end
|
|
13
16
|
|
|
14
17
|
def content=(new_content)
|
data/lib/leptris/xml/comment.rb
CHANGED
|
@@ -4,11 +4,14 @@ class Leptris::XML::Comment < Leptris::XML::Node
|
|
|
4
4
|
def name; "comment"; end
|
|
5
5
|
|
|
6
6
|
def content
|
|
7
|
-
return @content if
|
|
7
|
+
return @content if memo_hit?(@content_version)
|
|
8
8
|
ensure_alive!
|
|
9
|
-
Leptris::XML::FFI.leptris_comment_node_get_content(@c_ptr)
|
|
10
|
-
|
|
9
|
+
result = Leptris::XML::FFI.leptris_comment_node_get_content(@c_ptr)
|
|
10
|
+
if @document
|
|
11
|
+
@content = result
|
|
12
|
+
@content_version = @document.version
|
|
11
13
|
end
|
|
14
|
+
result
|
|
12
15
|
end
|
|
13
16
|
|
|
14
17
|
def content=(new_content)
|
data/lib/leptris/xml/document.rb
CHANGED
|
@@ -14,10 +14,27 @@ class Leptris::XML::Document
|
|
|
14
14
|
# `Document#free` was called explicitly and then GC ran.
|
|
15
15
|
Freed = Struct.new(:state) # state: :alive | :freed
|
|
16
16
|
|
|
17
|
+
# Mutation version: advanced by every data mutation (via
|
|
18
|
+
# Node#ensure_writable!, root=, add_pi). Node memos stamp the
|
|
19
|
+
# version they were computed under and recompute after any bump —
|
|
20
|
+
# the invalidation that makes WRITABLE-document memoization sound.
|
|
21
|
+
# Readonly documents never advance it, so their memos are forever
|
|
22
|
+
# valid (ADR 0003 semantics, unchanged).
|
|
23
|
+
def version
|
|
24
|
+
@version
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Called by the mutation gates (Node#ensure_writable!, root=,
|
|
28
|
+
# add_pi) — every memo stamped with an older version discards.
|
|
29
|
+
def advance_version
|
|
30
|
+
@version += 1
|
|
31
|
+
end
|
|
32
|
+
|
|
17
33
|
def initialize(c_ptr = nil, freed = Freed.new(:alive))
|
|
18
34
|
@c_ptr = c_ptr
|
|
19
35
|
@freed = freed
|
|
20
36
|
@readonly = false
|
|
37
|
+
@version = 0
|
|
21
38
|
# Per-document STRONG cache for Node wrappers, keyed on c_ptr
|
|
22
39
|
# address. Every wrapper is created through Node.wrap, which is the
|
|
23
40
|
# single construction path, so the same C node always yields the
|
|
@@ -142,6 +159,7 @@ class Leptris::XML::Document
|
|
|
142
159
|
raise Leptris::XML::UseAfterFreeError if @freed.state == :freed
|
|
143
160
|
Leptris::XML::FFI.check_status(
|
|
144
161
|
Leptris::XML::FFI.leptris_document_set_root(@c_ptr, element.c_ptr))
|
|
162
|
+
@version += 1
|
|
145
163
|
element
|
|
146
164
|
end
|
|
147
165
|
|
|
@@ -253,15 +271,14 @@ class Leptris::XML::Document
|
|
|
253
271
|
# Document-level processing instructions (not tree nodes):
|
|
254
272
|
# an array of [target, data] pairs in document order.
|
|
255
273
|
def processing_instructions
|
|
256
|
-
if
|
|
257
|
-
return @processing_instructions
|
|
258
|
-
end
|
|
274
|
+
return @processing_instructions if @pi_version == @version
|
|
259
275
|
count = Leptris::XML::FFI.leptris_document_pi_count(@c_ptr)
|
|
260
276
|
result = count.times.map do |i|
|
|
261
277
|
[Leptris::XML::FFI.leptris_document_pi_target(@c_ptr, i),
|
|
262
278
|
Leptris::XML::FFI.leptris_document_pi_data(@c_ptr, i)]
|
|
263
279
|
end
|
|
264
|
-
@processing_instructions = result
|
|
280
|
+
@processing_instructions = result
|
|
281
|
+
@pi_version = @version
|
|
265
282
|
result
|
|
266
283
|
end
|
|
267
284
|
|
|
@@ -270,6 +287,7 @@ class Leptris::XML::Document
|
|
|
270
287
|
witness = Leptris::XML::FFI.leptris_document_add_pi(
|
|
271
288
|
@c_ptr, target.to_s, data.to_s)
|
|
272
289
|
raise Leptris::XML::Error, "leptris_document_add_pi failed" if witness.null?
|
|
290
|
+
@version += 1
|
|
273
291
|
self
|
|
274
292
|
end
|
|
275
293
|
|
data/lib/leptris/xml/element.rb
CHANGED
|
@@ -17,11 +17,14 @@ class Leptris::XML::Element < Leptris::XML::Node
|
|
|
17
17
|
alias_method :node_name=, :name=
|
|
18
18
|
|
|
19
19
|
def content
|
|
20
|
-
return @content if
|
|
20
|
+
return @content if memo_hit?(@content_version)
|
|
21
21
|
ensure_alive!
|
|
22
|
-
Leptris::XML::FFI.leptris_element_text(@c_ptr)
|
|
23
|
-
|
|
22
|
+
result = Leptris::XML::FFI.leptris_element_text(@c_ptr)
|
|
23
|
+
if @document
|
|
24
|
+
@content = result
|
|
25
|
+
@content_version = @document.version
|
|
24
26
|
end
|
|
27
|
+
result
|
|
25
28
|
end
|
|
26
29
|
|
|
27
30
|
def content=(new_content)
|
|
@@ -104,31 +107,43 @@ class Leptris::XML::Element < Leptris::XML::Node
|
|
|
104
107
|
end
|
|
105
108
|
|
|
106
109
|
def keys
|
|
107
|
-
return @keys if
|
|
110
|
+
return @keys if memo_hit?(@keys_version)
|
|
108
111
|
result = each_attribute.to_a.map(&:name)
|
|
109
|
-
|
|
112
|
+
if @document
|
|
113
|
+
@keys = result
|
|
114
|
+
@keys_version = @document.version
|
|
115
|
+
end
|
|
110
116
|
result
|
|
111
117
|
end
|
|
112
118
|
|
|
113
119
|
def values
|
|
114
|
-
return @values if
|
|
120
|
+
return @values if memo_hit?(@values_version)
|
|
115
121
|
result = each_attribute.to_a.map(&:value)
|
|
116
|
-
|
|
122
|
+
if @document
|
|
123
|
+
@values = result
|
|
124
|
+
@values_version = @document.version
|
|
125
|
+
end
|
|
117
126
|
result
|
|
118
127
|
end
|
|
119
128
|
|
|
120
129
|
def attributes
|
|
121
|
-
return @attributes if
|
|
130
|
+
return @attributes if memo_hit?(@attributes_version)
|
|
122
131
|
result = {}
|
|
123
132
|
each_attribute { |attr| result[attr.name] = attr }
|
|
124
|
-
|
|
133
|
+
if @document
|
|
134
|
+
@attributes = result
|
|
135
|
+
@attributes_version = @document.version
|
|
136
|
+
end
|
|
125
137
|
result
|
|
126
138
|
end
|
|
127
139
|
|
|
128
140
|
def attribute_nodes
|
|
129
|
-
return @attribute_nodes if
|
|
141
|
+
return @attribute_nodes if memo_hit?(@attribute_nodes_version)
|
|
130
142
|
result = each_attribute.to_a
|
|
131
|
-
|
|
143
|
+
if @document
|
|
144
|
+
@attribute_nodes = result
|
|
145
|
+
@attribute_nodes_version = @document.version
|
|
146
|
+
end
|
|
132
147
|
result
|
|
133
148
|
end
|
|
134
149
|
|
|
@@ -247,7 +262,7 @@ class Leptris::XML::Element < Leptris::XML::Node
|
|
|
247
262
|
alias_method :<<, :add_child
|
|
248
263
|
|
|
249
264
|
def namespace
|
|
250
|
-
return @namespace if
|
|
265
|
+
return @namespace if memo_hit?(@namespace_version)
|
|
251
266
|
ensure_alive!
|
|
252
267
|
uri = Leptris::XML::FFI.leptris_element_namespace(@c_ptr)
|
|
253
268
|
result =
|
|
@@ -261,12 +276,15 @@ class Leptris::XML::Element < Leptris::XML::Node
|
|
|
261
276
|
prefix = nil if prefix.nil? || prefix.empty?
|
|
262
277
|
Leptris::XML::Namespace.new(self, uri, prefix: prefix)
|
|
263
278
|
end
|
|
264
|
-
|
|
279
|
+
if @document
|
|
280
|
+
@namespace = result
|
|
281
|
+
@namespace_version = @document.version
|
|
282
|
+
end
|
|
265
283
|
result
|
|
266
284
|
end
|
|
267
285
|
|
|
268
286
|
def namespace_definitions
|
|
269
|
-
return @namespace_definitions if
|
|
287
|
+
return @namespace_definitions if memo_hit?(@namespace_definitions_version)
|
|
270
288
|
ensure_alive!
|
|
271
289
|
count = Leptris::XML::FFI.leptris_element_namespace_count(@c_ptr)
|
|
272
290
|
result = count.times.map do |i|
|
|
@@ -274,12 +292,15 @@ class Leptris::XML::Element < Leptris::XML::Node
|
|
|
274
292
|
uri = Leptris::XML::FFI.leptris_element_namespace_decl_uri(@c_ptr, i)
|
|
275
293
|
Leptris::XML::Namespace.new(self, uri, prefix: prefix)
|
|
276
294
|
end
|
|
277
|
-
|
|
295
|
+
if @document
|
|
296
|
+
@namespace_definitions = result
|
|
297
|
+
@namespace_definitions_version = @document.version
|
|
298
|
+
end
|
|
278
299
|
result
|
|
279
300
|
end
|
|
280
301
|
|
|
281
302
|
def namespaces
|
|
282
|
-
return @namespaces if
|
|
303
|
+
return @namespaces if memo_hit?(@namespaces_version)
|
|
283
304
|
scopes = {}
|
|
284
305
|
node = self
|
|
285
306
|
while node.is_a?(Leptris::XML::Element)
|
|
@@ -289,7 +310,10 @@ class Leptris::XML::Element < Leptris::XML::Node
|
|
|
289
310
|
end
|
|
290
311
|
node = node.parent
|
|
291
312
|
end
|
|
292
|
-
|
|
313
|
+
if @document
|
|
314
|
+
@namespaces = scopes
|
|
315
|
+
@namespaces_version = @document.version
|
|
316
|
+
end
|
|
293
317
|
scopes
|
|
294
318
|
end
|
|
295
319
|
|
data/lib/leptris/xml/node.rb
CHANGED
|
@@ -101,13 +101,19 @@ class Leptris::XML::Node
|
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
# Raises ReadOnlyError when the owning document was marked readonly,
|
|
104
|
-
# UseAfterFreeError when it was freed.
|
|
104
|
+
# UseAfterFreeError when it was freed. Every node-level mutation
|
|
105
|
+
# passes through this gate, so it is where the document's mutation
|
|
106
|
+
# version advances — the invalidation behind writable-document
|
|
107
|
+
# memoization. Bumping before the C call is conservative: a failed
|
|
108
|
+
# mutation merely discards memos.
|
|
105
109
|
def ensure_writable!
|
|
106
110
|
ensure_alive!
|
|
107
111
|
if readonly_document?
|
|
108
112
|
raise Leptris::XML::ReadOnlyError,
|
|
109
113
|
"document is readonly — mutation attempted on #{inspect}"
|
|
110
114
|
end
|
|
115
|
+
@document.advance_version
|
|
116
|
+
nil
|
|
111
117
|
end
|
|
112
118
|
|
|
113
119
|
# Readonly is one-way, so caching TRUE is sound: once observed,
|
|
@@ -142,14 +148,17 @@ class Leptris::XML::Node
|
|
|
142
148
|
def children
|
|
143
149
|
# Immutable in readonly mode: the batch fetch plus wrapper
|
|
144
150
|
# construction is paid once.
|
|
145
|
-
return @children if
|
|
151
|
+
return @children if memo_hit?(@children_version)
|
|
146
152
|
ensure_alive!
|
|
147
153
|
parent = as_element_or_self
|
|
148
154
|
nodes = Leptris::XML::FFI.fetch_children(@c_ptr).map do |ptr|
|
|
149
155
|
Leptris::XML::Node.wrap(ptr, @document, parent: parent)
|
|
150
156
|
end
|
|
151
157
|
result = Leptris::XML::NodeSet.new(@document, nodes)
|
|
152
|
-
|
|
158
|
+
if @document
|
|
159
|
+
@children = result
|
|
160
|
+
@children_version = @document.version
|
|
161
|
+
end
|
|
153
162
|
result
|
|
154
163
|
end
|
|
155
164
|
|
|
@@ -185,9 +194,12 @@ class Leptris::XML::Node
|
|
|
185
194
|
end
|
|
186
195
|
|
|
187
196
|
def element_children
|
|
188
|
-
return @element_children if
|
|
197
|
+
return @element_children if memo_hit?(@element_children_version)
|
|
189
198
|
result = children.select(&:element?)
|
|
190
|
-
|
|
199
|
+
if @document
|
|
200
|
+
@element_children = result
|
|
201
|
+
@element_children_version = @document.version
|
|
202
|
+
end
|
|
191
203
|
result
|
|
192
204
|
end
|
|
193
205
|
alias_method :elements, :element_children
|
|
@@ -230,16 +242,19 @@ class Leptris::XML::Node
|
|
|
230
242
|
end
|
|
231
243
|
|
|
232
244
|
def path
|
|
233
|
-
return @path if
|
|
245
|
+
return @path if memo_hit?(@path_version)
|
|
234
246
|
ensure_alive!
|
|
235
247
|
str_ptr = Leptris::XML::FFI.leptris_node_get_xpath(@c_ptr)
|
|
236
248
|
result = str_ptr.null? ? nil : Leptris::XML::FFI.read_owned_string(str_ptr)
|
|
237
|
-
|
|
249
|
+
if @document
|
|
250
|
+
@path = result
|
|
251
|
+
@path_version = @document.version
|
|
252
|
+
end
|
|
238
253
|
result
|
|
239
254
|
end
|
|
240
255
|
|
|
241
256
|
def css_path
|
|
242
|
-
return @css_path if
|
|
257
|
+
return @css_path if memo_hit?(@css_path_version)
|
|
243
258
|
result =
|
|
244
259
|
if path.nil?
|
|
245
260
|
nil
|
|
@@ -249,7 +264,10 @@ class Leptris::XML::Node
|
|
|
249
264
|
part.gsub(/\[(\d+)\]/, ':nth-of-type(\1)')
|
|
250
265
|
end.join(" > ")
|
|
251
266
|
end
|
|
252
|
-
|
|
267
|
+
if @document
|
|
268
|
+
@css_path = result
|
|
269
|
+
@css_path_version = @document.version
|
|
270
|
+
end
|
|
253
271
|
result
|
|
254
272
|
end
|
|
255
273
|
|
|
@@ -274,11 +292,15 @@ class Leptris::XML::Node
|
|
|
274
292
|
|
|
275
293
|
protected
|
|
276
294
|
|
|
277
|
-
#
|
|
278
|
-
#
|
|
279
|
-
#
|
|
280
|
-
|
|
281
|
-
|
|
295
|
+
# A memo is valid while the document's mutation version has not
|
|
296
|
+
# advanced since that memo was stored. Each memoized field carries
|
|
297
|
+
# its OWN stamp — a shared node-level stamp would let one field's
|
|
298
|
+
# recompute resurrect another field's stale memo. Readonly
|
|
299
|
+
# documents never advance the version, so their memos are forever
|
|
300
|
+
# valid (ADR 0003 semantics); writable documents gain memos
|
|
301
|
+
# between mutations.
|
|
302
|
+
def memo_hit?(stamp)
|
|
303
|
+
@document && stamp == @document.version
|
|
282
304
|
end
|
|
283
305
|
|
|
284
306
|
def as_element_or_self
|
data/lib/leptris/xml/node_set.rb
CHANGED
|
@@ -60,7 +60,6 @@ class Leptris::XML::NodeSet
|
|
|
60
60
|
# inconsistently with an eager set.
|
|
61
61
|
return to_a[idx] if idx.negative?
|
|
62
62
|
if @result_ptr
|
|
63
|
-
return nil if idx < 0 || idx >= length
|
|
64
63
|
ptr = Leptris::XML::FFI.leptris_xpath_result_get_node(@result_ptr, idx)
|
|
65
64
|
return nil if ptr.null?
|
|
66
65
|
Leptris::XML::Node.wrap(ptr, @document)
|
|
@@ -2,20 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
class Leptris::XML::ProcessingInstruction < Leptris::XML::Node
|
|
4
4
|
def name
|
|
5
|
-
return @name if
|
|
5
|
+
return @name if memo_hit?(@name_version)
|
|
6
6
|
ensure_alive!
|
|
7
|
-
Leptris::XML::FFI.leptris_pi_node_get_target(@c_ptr)
|
|
8
|
-
|
|
7
|
+
result = Leptris::XML::FFI.leptris_pi_node_get_target(@c_ptr)
|
|
8
|
+
if @document
|
|
9
|
+
@name = result
|
|
10
|
+
@name_version = @document.version
|
|
9
11
|
end
|
|
12
|
+
result
|
|
10
13
|
end
|
|
11
14
|
alias_method :target, :name
|
|
12
15
|
|
|
13
16
|
def content
|
|
14
|
-
return @content if
|
|
17
|
+
return @content if memo_hit?(@content_version)
|
|
15
18
|
ensure_alive!
|
|
16
|
-
Leptris::XML::FFI.leptris_pi_node_get_data(@c_ptr).to_s
|
|
17
|
-
|
|
19
|
+
result = Leptris::XML::FFI.leptris_pi_node_get_data(@c_ptr).to_s
|
|
20
|
+
if @document
|
|
21
|
+
@content = result
|
|
22
|
+
@content_version = @document.version
|
|
18
23
|
end
|
|
24
|
+
result
|
|
19
25
|
end
|
|
20
26
|
|
|
21
27
|
def target=(new_target)
|
data/lib/leptris/xml/text.rb
CHANGED
|
@@ -4,11 +4,14 @@ class Leptris::XML::Text < Leptris::XML::Node
|
|
|
4
4
|
def name; "text"; end
|
|
5
5
|
|
|
6
6
|
def content
|
|
7
|
-
return @content if
|
|
7
|
+
return @content if memo_hit?(@content_version)
|
|
8
8
|
ensure_alive!
|
|
9
|
-
Leptris::XML::FFI.leptris_text_node_get_content(@c_ptr)
|
|
10
|
-
|
|
9
|
+
result = Leptris::XML::FFI.leptris_text_node_get_content(@c_ptr)
|
|
10
|
+
if @document
|
|
11
|
+
@content = result
|
|
12
|
+
@content_version = @document.version
|
|
11
13
|
end
|
|
14
|
+
result
|
|
12
15
|
end
|
|
13
16
|
|
|
14
17
|
def content=(new_content)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: leptris
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.9.
|
|
4
|
+
version: 1.9.14
|
|
5
5
|
platform: aarch64-linux
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ffi
|