moxml 0.5.74 → 0.5.76

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: 9502f77654d0b09a3a8ab3b926702ee07e07009076fbeb4fd7013eb5b2b39499
4
- data.tar.gz: 21d7b7dc2742200d83ac2d89c1610857cb0bf90590ef260052ad287bcb427170
3
+ metadata.gz: 2df70c844d6a4b34a8b6088ab84555def6c66f73b6c975d4252f1337df9db206
4
+ data.tar.gz: 1ca3ee46f0c416f463eeea9d68954b17d9121c6816dc654c9d3e4ba420343e10
5
5
  SHA512:
6
- metadata.gz: ae16970a10ade16adfb8f186a6269db7c6e5f94374737eb82bee0e5fb3609719171fcb731db2f52b86948848c938cca984255f55dfaf4cfc854e384602c8e32a
7
- data.tar.gz: 3f2f44d095a8d0fc6ceb0e506e930a16ef2afaa82f817114fe3dafd609a917e8eac7dd4f2b247caa74a7da9b0642b035432cb2cdfd3f6359ac2d0b56b8e19a59
6
+ metadata.gz: 4c8288a741d4230ebe5f228ea2b7085ef74177b527bf661dd35395a27c41515150949fadfc15f267f0eec9d3ac74c3b779c942b62ad8c5ff4dcc8c85a0398e5b
7
+ data.tar.gz: a547141ac0046f1d1ece0e55eecba71e5c1ec124a91179a45d2e4e4a57d8cfe8a50422b24a91060267bafc04d4ce8cb1efcd507ebcdb5520959540697850bb9d
@@ -332,7 +332,9 @@ module Moxml
332
332
  root.is_a?(::Leptris::XML::Document)
333
333
 
334
334
  root.visit do |node, entering, depth|
335
- yield Moxml::Node.wrap(node, context) if entering && depth.positive?
335
+ if entering && depth.positive?
336
+ yield Moxml::Node.wrap_with(node, context, self)
337
+ end
336
338
  end
337
339
  end
338
340
 
@@ -1060,7 +1062,22 @@ module Moxml
1060
1062
  node.target
1061
1063
  end
1062
1064
 
1065
+ # Walk-minted binding nodes carry the engine's kind int in
1066
+ # @node_type (the visit callback primes it); one ivar read
1067
+ # replaces the class-case chain on the per-wrap hot path.
1068
+ VISIT_NODE_TYPES = %i[element text comment cdata
1069
+ processing_instruction doctype].freeze
1070
+
1063
1071
  def node_type(node)
1072
+ if node.is_a?(::Leptris::XML::Node) &&
1073
+ node.instance_variable_defined?(:@node_type)
1074
+ kind = node.instance_variable_get(:@node_type)
1075
+ if kind.is_a?(Integer)
1076
+ mapped = VISIT_NODE_TYPES[kind]
1077
+ return mapped if mapped
1078
+ end
1079
+ end
1080
+
1064
1081
  if NATIVE_READ_LAYER &&
1065
1082
  node.is_a?(::Leptris::XML::NativeNode)
1066
1083
  type = NN_NODE_TYPE.bind_call(node)
data/lib/moxml/node.rb CHANGED
@@ -38,9 +38,20 @@ module Moxml
38
38
 
39
39
  def refresh_native!(new_native)
40
40
  unless new_native.equal?(@native)
41
- context.unregister_wrapper(@native)
41
+ # Cache-stable binding nodes carry the wrapper in an ivar
42
+ # (see Node.wrap_with) — re-point it there; other natives
43
+ # ride the context map.
44
+ if @native.instance_variable_defined?(:@moxml_wrapper)
45
+ @native.instance_variable_set(:@moxml_wrapper, nil)
46
+ else
47
+ context.unregister_wrapper(@native)
48
+ end
42
49
  @native = new_native
43
- context.register_wrapper(new_native, self)
50
+ if new_native.instance_variable_defined?(:@c_address)
51
+ new_native.instance_variable_set(:@moxml_wrapper, self)
52
+ else
53
+ context.register_wrapper(new_native, self)
54
+ end
44
55
  clear_native_memo!
45
56
  end
46
57
  self
@@ -571,12 +582,28 @@ module Moxml
571
582
  end
572
583
 
573
584
  def self.wrap(node, context)
585
+ wrap_with(node, context, adapter(context))
586
+ end
587
+
588
+ # The wrap path with the adapter already resolved — walk entry
589
+ # points know the adapter (it is self); one config-chain hop
590
+ # saved per wrapped node.
591
+ def self.wrap_with(node, context, adapter)
574
592
  return nil if node.nil?
575
593
 
576
- cached = context.wrapper_for(node)
594
+ # Cache-stable binding nodes carry their wrapper directly
595
+ # (#312): the binding's document-owned cache hands the SAME
596
+ # node object for the engine node's whole lifetime, so an
597
+ # ivar is the identity map — one ivar read beats the WeakMap
598
+ # round trip, and the wrapper dies with the node (document
599
+ # scope) exactly like the binding's own wrappers.
600
+ cached = if node.instance_variable_defined?(:@moxml_wrapper)
601
+ node.instance_variable_get(:@moxml_wrapper)
602
+ else
603
+ context.wrapper_for(node)
604
+ end
577
605
  return cached if cached
578
606
 
579
- adapter = adapter(context)
580
607
  type = adapter.node_type(node)
581
608
 
582
609
  # Extend-in-place (issue #230): adapters whose natives can
@@ -595,8 +622,13 @@ module Moxml
595
622
  end
596
623
 
597
624
  klass = node_type_map[type] || Wrappers::Node
598
- klass.new(node, context, adapter, type)
599
- .tap { |wrapper| context.register_wrapper(node, wrapper) }
625
+ wrapper = klass.new(node, context, adapter, type)
626
+ if node.instance_variable_defined?(:@c_address)
627
+ node.instance_variable_set(:@moxml_wrapper, wrapper)
628
+ else
629
+ context.register_wrapper(node, wrapper)
630
+ end
631
+ wrapper
600
632
  end
601
633
 
602
634
  def self.adapter(context)
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.74"
4
+ VERSION = "0.5.76"
5
5
  end
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.74
4
+ version: 0.5.76
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-09-22 00:00:00.000000000 Z
11
+ date: 2026-09-23 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