moxml 0.5.68 → 0.5.69

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c7ec66b00a34ed3918ab24c9b8bcc494e487927f99ad7557909ddf7e6701f8e3
4
- data.tar.gz: f0ee8feffee4bbf33c403dd5e1f6d3b44c7b8dee5efa7410bab490d3de0157a7
3
+ metadata.gz: d107d95a6e6c40031e9ea519397fe43ecbb08bf991ea5308bb72cc1510df0525
4
+ data.tar.gz: 574d6d7b1b5b211a87992b772358c0bfd96cdf0133c5cd2a2ac6547115139f02
5
5
  SHA512:
6
- metadata.gz: aa0d67f8dec259694dae78abd1a009710beecf97b785297092bef801b53ebe14f9bf980d9ac671d3be0cd8f003773e8556bcfb8ba85eeb5830ff5fd779703042
7
- data.tar.gz: 4e18e8625fae38b9b1857489b3e8d04649c6930b1ace17be78a3863c42a33e2402a329be95e78fb3804fb7d2207d1bbf6d4f22588b868e8291cf156337b87b5a
6
+ metadata.gz: fc99001a56408820af4db232e682b4a5723eb1ef36545909b38144973c3b1583cca7966f89c08ee9b6d6c450bd034fc90bf53300f35e041b8f394154c18e80d7
7
+ data.tar.gz: 15cae743eca3abed5bcf07d4ea264974602b247b9b7edfee018ccf73b0dc4732bb2420779ee8cb90b7a6d7055fe274a51ec5d2509fab9536c056df1d9339a1cf
@@ -23,11 +23,13 @@ module Moxml
23
23
  def assemble_document_children(doc)
24
24
  children = []
25
25
 
26
- native_doctype = doc.doctype
27
- children << native_doctype if native_doctype
28
-
29
- doctype_wrapper = attachments.get(doc, :doctype)
30
- children << doctype_wrapper if doctype_wrapper
26
+ # Attached DOCTYPEs (NATIVE_DOC_PARTS) list the STORED
27
+ # native the same object the attaching wrapper was
28
+ # refreshed onto — so wrapper identity holds; doc.doctype
29
+ # mints a fresh DocType per call and would fork wrappers.
30
+ doctype_native = attachments.get(doc, :doctype)
31
+ doctype_native = doc.doctype unless doctype_native.is_a?(::Leptris::XML::DocType)
32
+ children << doctype_native if doctype_native
31
33
 
32
34
  # The libxml2-model document node lists prolog PIs/comments,
33
35
  # the root, and epilog PIs/comments in document order — the
@@ -55,10 +57,25 @@ module Moxml
55
57
  when CustomizedLeptris::Declaration
56
58
  child.parent_doc = doc
57
59
  attachments.set(doc, :declaration, child)
60
+ mirror_declaration_native(doc, child) if NATIVE_DOC_PARTS
58
61
  when CustomizedLeptris::Doctype
62
+ if NATIVE_DOC_PARTS
63
+ dt = doc.set_doctype(child.name,
64
+ public_id: child.external_id,
65
+ system_id: child.system_id)
66
+ attachments.set(doc, :doctype, dt)
67
+ return dt
68
+ end
59
69
  child.parent_doc = doc
60
70
  attachments.set(doc, :doctype, child)
61
71
  when ::Leptris::XML::DocType
72
+ if NATIVE_DOC_PARTS
73
+ dt = doc.set_doctype(child.root_name,
74
+ public_id: child.public_id,
75
+ system_id: child.system_id)
76
+ attachments.set(doc, :doctype, dt)
77
+ return dt
78
+ end
62
79
  raise Moxml::DocumentStructureError.new(
63
80
  "libleptris does not support attaching a native DocType to a document",
64
81
  )
@@ -112,7 +129,7 @@ module Moxml
112
129
  end
113
130
 
114
131
  doctype = attachments.get(doc, :doctype)
115
- parts << doctype.to_xml << "\n" if doctype
132
+ parts << doctype.to_xml << "\n" if doctype.is_a?(CustomizedLeptris::Doctype)
116
133
 
117
134
  native = native_doctype_xml(doc)
118
135
  parts << native << "\n" if native
@@ -304,6 +321,40 @@ module Moxml
304
321
  attachments.get(native, :had_source_declaration) ? true : false
305
322
  end
306
323
 
324
+ # Write a created declaration through to the engine's
325
+ # document state (setters, libleptris 1.9.176 / #1094) so
326
+ # native reads and serialization see the same truth the
327
+ # facade does. Removal clears it (clear_declaration).
328
+ def mirror_declaration_native(doc, child)
329
+ # The engine setters reject empty values; the facade's
330
+ # minimal declarations may carry them (serializer formats
331
+ # what it gets). Mirror only non-empty parts — the wrapper
332
+ # remains the record for what the facade shows.
333
+ unless child.version.to_s.empty?
334
+ ::Leptris::XML::FFI.check_status(
335
+ ::Leptris::XML::FFI.leptris_document_set_version(
336
+ doc.c_ptr, child.version.to_s
337
+ ),
338
+ )
339
+ end
340
+ unless child.encoding.to_s.empty?
341
+ ::Leptris::XML::FFI.check_status(
342
+ ::Leptris::XML::FFI.leptris_document_set_encoding(
343
+ doc.c_ptr, child.encoding.to_s
344
+ ),
345
+ )
346
+ end
347
+ case child.standalone.to_s
348
+ when "yes" then sa = 1
349
+ when "no" then sa = 0
350
+ end
351
+ ::Leptris::XML::FFI.check_status(
352
+ ::Leptris::XML::FFI.leptris_document_set_standalone(
353
+ doc.c_ptr, sa || -1
354
+ ),
355
+ )
356
+ end
357
+
307
358
  def marker_text_for(parent, name)
308
359
  return nil unless parent.is_a?(::Leptris::XML::Element)
309
360
 
@@ -554,6 +554,16 @@ module Moxml
554
554
  (!defined?(::Leptris::XML::Native) ||
555
555
  ::Leptris::XML::Native.respond_to?(:plan_structs))
556
556
 
557
+ # leptris-ruby#275 (binding 1.9.204, the remove half of the
558
+ # document-level surfaces): remove_pi, clear_declaration,
559
+ # remove_doctype complete the set-only creation entries.
560
+ # Attached DOCTYPEs materialize as native nodes, document-PI
561
+ # removal works, and declaration state mirrors through.
562
+ NATIVE_DOC_PARTS =
563
+ Gem::Version.new(::Leptris::VERSION) >= Gem::Version.new("1.9.204.0") &&
564
+ ::Leptris::XML::Document.method_defined?(:remove_doctype) &&
565
+ ::Leptris::XML::Document.method_defined?(:clear_declaration)
566
+
557
567
  def self.plan_structs(native, spec)
558
568
  return nil unless NATIVE_PLAN_STRUCTS
559
569
 
@@ -957,6 +967,9 @@ module Moxml
957
967
  def remove_declaration(native_doc)
958
968
  attachments.delete(native_doc, :declaration)
959
969
  attachments.delete(native_doc, :had_source_declaration)
970
+ if NATIVE_DOC_PARTS && native_doc.is_a?(::Leptris::XML::Document)
971
+ native_doc.clear_declaration
972
+ end
960
973
  end
961
974
 
962
975
  def create_native_namespace(element, prefix, uri)
@@ -1499,6 +1512,15 @@ module Moxml
1499
1512
  attr
1500
1513
  end
1501
1514
 
1515
+ def actual_native(child_native, parent_native)
1516
+ if NATIVE_DOC_PARTS && child_native.is_a?(CustomizedLeptris::Doctype) &&
1517
+ parent_native.is_a?(::Leptris::XML::Document)
1518
+ attached = attachments.get(parent_native, :doctype)
1519
+ return attached if attached.is_a?(::Leptris::XML::DocType)
1520
+ end
1521
+ child_native
1522
+ end
1523
+
1502
1524
  def add_child(parent, child)
1503
1525
  if NATIVE_READ_LAYER && !(NATIVE_MUTATIONS_COHERENT &&
1504
1526
  parent.is_a?(::Leptris::XML::NativeNode) &&
@@ -1591,14 +1613,33 @@ module Moxml
1591
1613
  remove_declaration(node.parent_doc) if node.parent_doc
1592
1614
  when CustomizedLeptris::Doctype
1593
1615
  attachments.delete(node.parent_doc, :doctype) if node.parent_doc
1616
+ when ::Leptris::XML::DocType
1617
+ if NATIVE_DOC_PARTS
1618
+ doc = node.document || doc_for(node)
1619
+ if doc
1620
+ doc.remove_doctype
1621
+ attachments.delete(doc, :doctype)
1622
+ end
1623
+ end
1594
1624
  when CustomizedLeptris::EntityReference
1595
1625
  marker_text_for(node.parent, node.name)&.unlink
1596
1626
  when CustomizedLeptris::DocumentPI
1597
- raise Moxml::NotImplementedError.new(
1598
- "libleptris has no document-level PI removal",
1599
- adapter: :leptris,
1600
- feature: :remove,
1601
- )
1627
+ if NATIVE_DOC_PARTS && node.parent_doc
1628
+ pis = node.parent_doc.processing_instructions
1629
+ index = pis.index do |target, data|
1630
+ target == node.target && data == node.data
1631
+ end
1632
+ if index
1633
+ node.parent_doc.remove_pi(index)
1634
+ node.parent_doc = nil
1635
+ end
1636
+ else
1637
+ raise Moxml::NotImplementedError.new(
1638
+ "libleptris has no document-level PI removal",
1639
+ adapter: :leptris,
1640
+ feature: :remove,
1641
+ )
1642
+ end
1602
1643
  else
1603
1644
  node.unlink
1604
1645
  end
data/lib/moxml/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Moxml
4
- VERSION = "0.5.68"
4
+ VERSION = "0.5.69"
5
5
  end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require "leptris"
5
+ rescue LoadError
6
+ return
7
+ end
8
+
9
+ require "moxml/adapter/leptris"
10
+
11
+ # leptris-ruby#275 (binding 1.9.204, the remove half): attached
12
+ # DOCTYPEs materialize as native nodes with wrapper identity, and
13
+ # document-PI removal / declaration clear work natively. Below the
14
+ # gate the legacy CustomizedLeptris paths keep the contract.
15
+ RSpec.describe Moxml::Adapter::Leptris do
16
+ around do |example|
17
+ Moxml.with_config(:leptris, true, "UTF-8") do
18
+ example.run
19
+ end
20
+ end
21
+
22
+ let(:ctx) { Moxml.new(:leptris) }
23
+ let(:gate) do
24
+ Moxml::Adapter::Leptris::NATIVE_DOC_PARTS
25
+ end
26
+
27
+ describe "created DOCTYPE as a native node" do
28
+ it "attaches, lists once with wrapper identity, serializes, and removes" do
29
+ skip "requires binding 1.9.204+ (leptris-ruby#275)" unless gate
30
+
31
+ doc = ctx.parse("<root/>")
32
+ doctype = doc.create_doctype("root", "-//X//DTD Y//EN", "y.dtd")
33
+ doc.add_child(doctype)
34
+
35
+ listed = doc.children.grep(Moxml::Doctype)
36
+ expect(listed.size).to eq(1)
37
+ expect(listed.first).to equal(doctype)
38
+ expect(doc.to_xml)
39
+ .to include(%(<!DOCTYPE root PUBLIC "-//X//DTD Y//EN" "y.dtd">))
40
+
41
+ doctype.remove
42
+ expect(doc.children).to all(be_a(Moxml::Element))
43
+ expect(doc.to_xml).not_to include("DOCTYPE")
44
+ end
45
+ end
46
+
47
+ describe "document-level PI removal" do
48
+ it "removes the PI from children and serialization" do
49
+ skip "requires binding 1.9.204+ (leptris-ruby#275)" unless gate
50
+
51
+ doc = ctx.parse("<root/>")
52
+ doc.add_child(doc.create_processing_instruction("before", "data"))
53
+ expect(doc.children.count { |c| c.is_a?(Moxml::ProcessingInstruction) })
54
+ .to eq(1)
55
+
56
+ doc.children
57
+ .find { |c| c.is_a?(Moxml::ProcessingInstruction) }
58
+ .remove
59
+ expect(doc.children.count { |c| c.is_a?(Moxml::ProcessingInstruction) })
60
+ .to eq(0)
61
+ expect(doc.to_xml).not_to include("<?before")
62
+ end
63
+ end
64
+
65
+ describe "declaration mirroring" do
66
+ it "writes created declarations through to engine state and clears on remove" do
67
+ skip "requires binding 1.9.204+ (leptris-ruby#275)" unless gate
68
+
69
+ doc = ctx.parse("<root/>")
70
+ declaration = doc.create_declaration("1.1", "UTF-8", "yes")
71
+ doc.add_child(declaration)
72
+
73
+ ffi = Leptris::XML::FFI
74
+ native = doc.native
75
+ expect(ffi.leptris_document_version(native.c_ptr)).to eq("1.1")
76
+ expect(ffi.leptris_document_standalone(native.c_ptr)).to eq(1)
77
+ expect(doc.to_xml).to include(%(version="1.1"))
78
+ expect(doc.to_xml).to include(%(standalone="yes"))
79
+
80
+ declaration.remove
81
+ expect(doc.to_xml).not_to include("version=")
82
+ end
83
+ end
84
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moxml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.68
4
+ version: 0.5.69
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -433,6 +433,7 @@ files:
433
433
  - spec/moxml/adapter/base_spec.rb
434
434
  - spec/moxml/adapter/entity_restoration_spec.rb
435
435
  - spec/moxml/adapter/headed_ox_spec.rb
436
+ - spec/moxml/adapter/leptris_doc_parts_spec.rb
436
437
  - spec/moxml/adapter/leptris_spec.rb
437
438
  - spec/moxml/adapter/libxml_internals_spec.rb
438
439
  - spec/moxml/adapter/libxml_spec.rb