lib/moxml/element.rb in moxml-0.1.0 vs lib/moxml/element.rb in moxml-0.1.1
- old
+ new
@@ -1,145 +1,107 @@
+# frozen_string_literal: true
+
+require_relative "attribute"
+require_relative "namespace"
+
module Moxml
class Element < Node
- def initialize(name_or_native = nil)
- case name_or_native
- when String
- super(adapter.create_element(nil, name_or_native))
- else
- super(name_or_native)
- end
- end
-
def name
- adapter.node_name(native)
+ adapter.node_name(@native)
end
- def attributes
- adapter.attributes(native).transform_values { |attr| Attribute.new(attr) }
+ def name=(value)
+ adapter.set_node_name(@native, value)
end
def []=(name, value)
- adapter.set_attribute(native, name, value)
+ adapter.set_attribute(@native, name, normalize_xml_value(value))
end
def [](name)
- attr = adapter.get_attribute(native, name)
- attr.nil? ? nil : Attribute.new(attr)
+ adapter.get_attribute_value(@native, name)
end
- def add_child(node)
- adapter.add_child(native, node.native)
- self
+ def attribute(name)
+ native_attr = adapter.get_attribute(@native, name)
+ native_attr && Attribute.new(native_attr, context)
end
- def namespace
- ns = adapter.namespace(native)
- ns.nil? ? nil : Namespace.new(ns)
+ def attributes
+ adapter.attributes(@native).map do |attr|
+ Attribute.new(attr, context)
+ end
end
- def namespace=(ns)
- adapter.set_namespace(native, ns&.native)
+ def remove_attribute(name)
+ adapter.remove_attribute(@native, name)
self
end
- def namespaces
- adapter.namespaces(native).transform_values { |ns| Namespace.new(ns) }
+ def add_namespace(prefix, uri)
+ validate_uri(uri)
+ adapter.create_native_namespace(@native, prefix, uri)
+ self
+ rescue ValidationError => e
+ raise Moxml::NamespaceError, e.message
end
+ alias add_namespace_definition add_namespace
- def css(selector)
- NodeSet.new(adapter.css(native, selector))
+ # it's NOT the same as namespaces.first
+ def namespace
+ ns = adapter.namespace(@native)
+ ns && Namespace.new(ns, context)
end
- def xpath(expression, namespaces = {})
- NodeSet.new(adapter.xpath(native, expression, namespaces))
+ # it does NOT change the list of namespace definitions
+ def namespace=(ns_or_hash)
+ if ns_or_hash.is_a?(Hash)
+ adapter.set_namespace(
+ @native,
+ adapter.create_namespace(@native, *ns_or_hash.to_a.first)
+ )
+ else
+ adapter.set_namespace(@native, ns_or_hash&.native)
+ end
end
- def at_css(selector)
- node = adapter.at_css(native, selector)
- node.nil? ? nil : wrap_node(node)
+ def namespaces
+ adapter.namespace_definitions(@native).map do |ns|
+ Namespace.new(ns, context)
+ end
end
+ alias namespace_definitions namespaces
- def at_xpath(expression, namespaces = {})
- node = adapter.at_xpath(native, expression, namespaces)
- node.nil? ? nil : wrap_node(node)
+ def text
+ adapter.text_content(@native)
end
- def blank?
- text.strip.empty? && children.empty?
+ def text=(content)
+ adapter.set_text_content(@native, normalize_xml_value(content))
end
- def value
- text.strip
+ def inner_html
+ adapter.inner_html(@native)
end
- def value=(val)
- self.text = val.to_s
+ def inner_html=(html)
+ doc = context.parse("<root>#{html}</root>")
+ adapter.replace_children(@native, doc.root.children.map(&:native))
end
- def matches?(selector)
- adapter.matches?(native, selector)
- end
-
- def ancestors
- NodeSet.new(adapter.ancestors(native))
- end
-
- def descendants
- NodeSet.new(adapter.descendants(native))
- end
-
- def previous_elements
- NodeSet.new(adapter.previous_elements(native))
- end
-
- def next_elements
- NodeSet.new(adapter.next_elements(native))
- end
-
- def inner_text
- adapter.inner_text(native)
- end
-
- def inner_text=(text)
- adapter.set_inner_text(native, text)
+ # Fluent interface methods
+ def with_attribute(name, value)
+ self[name] = value
self
end
- def key?(name)
- adapter.has_attribute?(native, name)
- end
-
- alias has_attribute? key?
-
- def classes
- (self["class"] || "").split(/\s+/)
- end
-
- def add_class(*names)
- self["class"] = (classes + names).uniq.join(" ")
+ def with_namespace(prefix, uri)
+ add_namespace(prefix, uri)
self
end
- def remove_class(*names)
- self["class"] = (classes - names).join(" ")
+ def with_text(content)
+ self.text = content
self
- end
-
- def toggle_class(name)
- if classes.include?(name)
- remove_class(name)
- else
- add_class(name)
- end
- end
-
- def has_class?(name)
- classes.include?(name)
- end
-
- private
-
- def create_native_node
- adapter.create_element(nil, "")
end
end
end