module Rocx module Elements class BaseContainer < BaseElement attr_reader :children class << self def properties_tag(*args) @properties_tag = args.first if args.any? @properties_tag end def value_property(name) attr_reader name define_method "#{name}=" do |value| class_name = name.to_s.split("_").map(&:capitalize).join prop_class = Rocx::Properties.const_get class_name instance_variable_set "@#{name}", prop_class.new(value) end properties << name end def property(name) define_method "#{name}" do class_name = name.to_s.split("_").map(&:capitalize).join prop_class = Rocx::Properties.const_get class_name if instance_variable_get("@#{name}").nil? instance_variable_set "@#{name}", prop_class.new end instance_variable_get "@#{name}" end properties << name end def properties @properties ||= [] end end def initialize(**args) @children = [] super args end def <<(child) children << child end def to_xml(xml) (namespace ? xml[namespace] : xml).public_send(tag_name, xml_attributes) { property_xml(xml) children.each { |child| child.to_xml(xml) } } end protected def property_xml(xml) props = properties.map(&method(:send)).compact return if props.none?(&:render?) xml[namespace].public_send(properties_tag) { props.each { |prop| prop.to_xml(xml) } } end def properties self.class.properties end def properties_tag self.class.properties_tag end end end end