moxml 0.5.105 → 0.5.106
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/moxml/adapter/base.rb +8 -0
- data/lib/moxml/adapter/leptris.rb +17 -0
- data/lib/moxml/document.rb +15 -0
- data/lib/moxml/element.rb +11 -2
- data/lib/moxml/version.rb +1 -1
- data/spec/moxml/at_search_spec.rb +27 -0
- 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: 28a815d79bd0bc2f356a01f0a4f5337e111ab6bce63f7e8c2f7247efac096b4c
|
|
4
|
+
data.tar.gz: b0a75eb438464fe9327fdb0420f14be0e8b19fea4252fe8abc995e295a6c6449
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 33363ebc463f8e46fbd955ad3adb8f43b01775c27cc72ddaf356e62761e9a7b1917c1c15de36716806a1c306c111368fa0705ec1e37a11fd386f6183c274f291
|
|
7
|
+
data.tar.gz: aef109c340cdcb4f30a76f87ef05e2568091e01c3dcf815fa2c945ff1cc49a961a0c36e1541f32873cca0226af2bd43a019c7cdac0c5f89b195558c2090a621a
|
data/lib/moxml/adapter/base.rb
CHANGED
|
@@ -175,6 +175,14 @@ module Moxml
|
|
|
175
175
|
node
|
|
176
176
|
end
|
|
177
177
|
|
|
178
|
+
# Cross-document root adoption: adapters whose engine deep-copies
|
|
179
|
+
# a foreign root into the target document natively answer the
|
|
180
|
+
# installed native here (leptris >= 1.9.292, engine #1495);
|
|
181
|
+
# nil keeps the Ruby splice.
|
|
182
|
+
def adopt_root(_doc, _element)
|
|
183
|
+
nil
|
|
184
|
+
end
|
|
185
|
+
|
|
178
186
|
# Element-only children: adapters whose engine carries the
|
|
179
187
|
# face override (leptris C filter, nokogiri native); the
|
|
180
188
|
# default type-filters the native child list so non-element
|
|
@@ -1437,6 +1437,23 @@ module Moxml
|
|
|
1437
1437
|
end
|
|
1438
1438
|
end
|
|
1439
1439
|
|
|
1440
|
+
NATIVE_ROOT_ADOPT =
|
|
1441
|
+
NATIVE_READ_LAYER &&
|
|
1442
|
+
Gem::Version.new(::Leptris::VERSION) >= Gem::Version.new("1.9.292.0")
|
|
1443
|
+
|
|
1444
|
+
# The engine deep-copies the foreign subtree into the target
|
|
1445
|
+
# document's pool (leptris#1495) and the binding memoizes the
|
|
1446
|
+
# INSTALLED handle — a fresh pointer distinct from the consumed
|
|
1447
|
+
# source. Answer the installed binding element; callers re-point
|
|
1448
|
+
# wrappers at it.
|
|
1449
|
+
def adopt_root(doc, element)
|
|
1450
|
+
return nil unless NATIVE_ROOT_ADOPT
|
|
1451
|
+
|
|
1452
|
+
binding_doc = to_binding(doc)
|
|
1453
|
+
binding_doc.root = to_binding(element)
|
|
1454
|
+
binding_doc.root
|
|
1455
|
+
end
|
|
1456
|
+
|
|
1440
1457
|
# Element-only children through the engine-level filter: the
|
|
1441
1458
|
# C face mints element-kind natives directly (klass-children),
|
|
1442
1459
|
# so interleaved text/comment nodes cost nothing. Entity
|
data/lib/moxml/document.rb
CHANGED
|
@@ -29,6 +29,21 @@ module Moxml
|
|
|
29
29
|
(owner.is_a?(Document) && owner.root.equal?(element))
|
|
30
30
|
if owner.is_a?(Document) && attached &&
|
|
31
31
|
!owner.equal?(self) && element.context.equal?(context)
|
|
32
|
+
installed = adapter.adopt_root(@native, element.native)
|
|
33
|
+
if installed
|
|
34
|
+
# The engine deep-copies the foreign subtree into this
|
|
35
|
+
# document's pool (leptris >= 1.9.292, engine #1495) and the
|
|
36
|
+
# binding memoizes the INSTALLED handle — a fresh pointer.
|
|
37
|
+
# Re-point the source wrapper so later writes reach the live
|
|
38
|
+
# tree, and recompute its scope-derived memos.
|
|
39
|
+
unless installed.equal?(element.native)
|
|
40
|
+
element.refresh_native!(Moxml::Node.wrap(installed, context).native)
|
|
41
|
+
element.invalidate_namespace_cache!
|
|
42
|
+
end
|
|
43
|
+
context.bump_children_generation
|
|
44
|
+
invalidate_children_cache!
|
|
45
|
+
return
|
|
46
|
+
end
|
|
32
47
|
# libleptris refuses a root owned by another document (the
|
|
33
48
|
# engine's set_root ownership check), while Nokogiri adopts.
|
|
34
49
|
# Cross-document CHILD attaches are supported, so build the
|
data/lib/moxml/element.rb
CHANGED
|
@@ -360,9 +360,18 @@ module Moxml
|
|
|
360
360
|
|
|
361
361
|
alias content= text=
|
|
362
362
|
|
|
363
|
+
# Generation-gated memo (the #321 shape): the native read
|
|
364
|
+
# allocates a fresh String per call and hydration walks re-read
|
|
365
|
+
# the same wrappers — 122k births over 10 passes of 2,000
|
|
366
|
+
# elements before this memo, 5 after. All inner-text writers are
|
|
367
|
+
# children mutations, which bump the children generation.
|
|
363
368
|
def inner_text
|
|
364
|
-
|
|
365
|
-
|
|
369
|
+
@inner_text = nil if @inner_text_gen != context.children_generation
|
|
370
|
+
@inner_text_gen = context.children_generation
|
|
371
|
+
@inner_text ||= begin
|
|
372
|
+
text = raw_inner_text
|
|
373
|
+
entity_bearing? ? adapter.restore_entities(text) : text
|
|
374
|
+
end
|
|
366
375
|
end
|
|
367
376
|
|
|
368
377
|
# Returns inner text without entity marker restoration.
|
data/lib/moxml/version.rb
CHANGED
|
@@ -312,6 +312,22 @@ RSpec.describe "Nokogiri-compatible node sugar" do
|
|
|
312
312
|
end
|
|
313
313
|
end
|
|
314
314
|
|
|
315
|
+
describe "Document#root= native adoption re-points the source wrapper" do
|
|
316
|
+
it "writes through the original wrapper reach the installed tree" do
|
|
317
|
+
ctx = Moxml.new(:leptris)
|
|
318
|
+
other = ctx.parse('<r xmlns="urn:x" a="1"><p>hi<b>t</b></p></r>')
|
|
319
|
+
doc = ctx.create_document
|
|
320
|
+
src_root = other.root
|
|
321
|
+
doc.root = src_root
|
|
322
|
+
# the engine deep-copies; the wrapper now addresses the installed
|
|
323
|
+
# handle — a later write must serialize into the new document
|
|
324
|
+
src_root["a"] = "2"
|
|
325
|
+
expect(doc.to_xml(indent: 0)).to include('a="2"')
|
|
326
|
+
expect(doc.root["a"]).to eq("2")
|
|
327
|
+
expect(doc.root.namespace_uri.to_s).to eq("urn:x")
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
315
331
|
describe "Document#root= with a foreign root" do
|
|
316
332
|
it "adopts the subtree from another document" do
|
|
317
333
|
doc = Moxml.parse("<old><x/></old>")
|
|
@@ -409,6 +425,17 @@ RSpec.describe "Nokogiri-compatible node sugar" do
|
|
|
409
425
|
expect(a.text).to eq("w")
|
|
410
426
|
end
|
|
411
427
|
|
|
428
|
+
it "Element#inner_text memoizes and invalidates on child mutations" do
|
|
429
|
+
doc = Moxml.parse("<r><a>x<b>y</b>z</a></r>")
|
|
430
|
+
a = doc.at("//a")
|
|
431
|
+
first = a.inner_text
|
|
432
|
+
expect(a.inner_text).to equal(first)
|
|
433
|
+
a.add_child(doc.create_element("c"))
|
|
434
|
+
expect(a.inner_text).not_to equal(first)
|
|
435
|
+
a.text = "plain"
|
|
436
|
+
expect(a.inner_text).to eq("plain")
|
|
437
|
+
end
|
|
438
|
+
|
|
412
439
|
it "Attribute#value memoizes and invalidates on value=" do
|
|
413
440
|
doc = Moxml.parse(%(<r a="1"/>))
|
|
414
441
|
attr = doc.root.attributes.first
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: moxml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.106
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: |
|
|
14
14
|
Moxml is a unified XML manipulation library that provides a common API
|