Module: Moxml::Node

Constant Summary

Constants included from NodeBehavior

Moxml::NodeBehavior::TYPES

Constants included from XmlUtils

XmlUtils::VALID_ELEMENT_NAMES

Instance Attribute Summary

Attributes included from NodeBehavior

#context, #native, #parent_node

Class Method Summary collapse

Methods included from NodeBehavior

#==, #adapter, #add_child, #add_next_sibling, #add_previous_sibling, #after, #ancestors, #at_xpath, #before, #blank?, #children, #clear_native_memo!, #content, #descendants, #digest, #document, #dup, #each, #each_node, #entity_bearing?, #find, #find_all, #first_child, #following_siblings, #has_children?, #identifier, #initialize, #invalidate_namespace_cache!, #last_child, #line_number, #materialize, #materialize_fields, #namespace, #namespaces, #next_sibling, #outer_xml, #parent, #path, #preceding_siblings, #previous_sibling, #prime_contract, #refresh_native!, #remove, #replace, #source_position, #text, #to_xml, #xpath

Methods included from XmlUtils

#encode_entities, #normalize_xml_value, #validate_comment_content, #validate_declaration_encoding, #validate_declaration_standalone, #validate_declaration_version, #validate_element_name, #validate_entity_reference_name, #validate_pi_target, #validate_prefix, #validate_uri

Class Method Details

.adapter(context) ⇒ Object



608
609
610
# File 'lib/moxml/node.rb', line 608

def self.adapter(context)
  context.config.adapter
end

.contract_module(type) ⇒ Object

The contract module for a type — what an in-place extended native carries instead of a wrapper shell.



554
555
556
# File 'lib/moxml/node.rb', line 554

def self.contract_module(type)
  contract_modules[type]
end

.contract_modules ⇒ Object



558
559
560
561
562
563
564
565
566
567
568
569
570
571
# File 'lib/moxml/node.rb', line 558

def self.contract_modules
  @contract_modules ||= {
    element: Element,
    text: Text,
    cdata: Cdata,
    comment: Comment,
    processing_instruction: ProcessingInstruction,
    document: Document,
    declaration: Declaration,
    doctype: Doctype,
    attribute: Attribute,
    entity_reference: EntityReference,
  }.freeze
end

.node_type_map ⇒ Object

Instantiation shells per type — the contract constants (Element, Text, ...) are modules since issue #230, so wrappers mint through Wrappers::*.



537
538
539
540
541
542
543
544
545
546
547
548
549
550
# File 'lib/moxml/node.rb', line 537

def self.node_type_map
  @node_type_map ||= {
    element: Wrappers::Element,
    text: Wrappers::Text,
    cdata: Wrappers::Cdata,
    comment: Wrappers::Comment,
    processing_instruction: Wrappers::ProcessingInstruction,
    document: Wrappers::Document,
    declaration: Wrappers::Declaration,
    doctype: Wrappers::Doctype,
    attribute: Wrappers::Attribute,
    entity_reference: Wrappers::EntityReference,
  }.freeze
end

.wrap(node, context) ⇒ Object



573
574
575
# File 'lib/moxml/node.rb', line 573

def self.wrap(node, context)
  wrap_with(node, context, adapter(context))
end

.wrap_with(node, context, adapter) ⇒ Object

The wrap path with the adapter already resolved — walk entry points know the adapter (it is self); one config-chain hop saved per wrapped node.



580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
# File 'lib/moxml/node.rb', line 580

def self.wrap_with(node, context, adapter)
  return nil if node.nil?

  cached = context.wrapper_for(node)
  return cached if cached

  type = adapter.node_type(node)

  # Extend-in-place (issue #230): adapters whose natives can
  # carry the contract modules directly (leptris TypedData) mint
  # the native itself as the wrapper — @native is self. The
  # minted wrapper primes with ITSELF (not the input native):
  # adapter calls then receive the contract-bearing receiver,
  # which klass-propagating reads (#246) dispatch on — and the
  # input native keeps its registration so later wraps of the
  # same base object hit the cache instead of re-minting.
  if (extended = adapter.wrap_native(node, type, context))
    extended.prime_contract(extended, context, adapter, type)
    context.register_wrapper(node, extended)
    context.register_wrapper(extended, extended) unless extended.equal?(node)
    return extended
  end

  klass = node_type_map[type] || Wrappers::Node
  klass.new(node, context, adapter, type)
    .tap { |wrapper| context.register_wrapper(node, wrapper) }
end