[gxml] DOM4: Step 1: Implement DomNode by GNode
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gxml] DOM4: Step 1: Implement DomNode by GNode
- Date: Mon, 18 Jul 2016 05:44:32 +0000 (UTC)
commit 5a720864171bbdfa05958b4d774c6310bc996a1f
Author: Daniel Espinosa <esodan gmail com>
Date: Fri May 6 22:20:19 2016 -0500
DOM4: Step 1: Implement DomNode by GNode
* DomNode API addaptions for node_type() and compare_document_position()
* Implementing DomNode by GNode
* Implementing GListChildren.insert() and .remove_at() to implement
DomNode.insert_before() and others
gxml/DomNode.vala | 29 ++++---
gxml/GXmlListChildren.vala | 22 ++++-
gxml/GXmlNode.vala | 182 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 215 insertions(+), 18 deletions(-)
---
diff --git a/gxml/DomNode.vala b/gxml/DomNode.vala
index b11a79c..c012582 100644
--- a/gxml/DomNode.vala
+++ b/gxml/DomNode.vala
@@ -33,12 +33,12 @@ public interface GXml.DomNode : GLib.Object, GXml.DomEventTarget {
public const ushort DOCUMENT_TYPE_NODE = 10;
public const ushort DOCUMENT_FRAGMENT_NODE = 11;
public const ushort NOTATION_NODE = 12; // historical
- public abstract ushort node_type { get; }
+ public abstract GXml.NodeType node_type { get; }
public abstract string node_name { get; }
- public abstract string? baseURI { get; }
+ public abstract string? base_uri { get; }
- public abstract Document? owner_document { get; }
+ public abstract DomDocument? owner_document { get; }
public abstract DomNode? parent_node { get; }
public abstract DomElement? parent_element { get; }
public abstract DomNodeList child_nodes { get; }
@@ -56,23 +56,26 @@ public interface GXml.DomNode : GLib.Object, GXml.DomEventTarget {
public abstract DomNode clone_node (bool deep = false);
public abstract bool is_equal_node (DomNode? node);
- public const ushort DOCUMENT_POSITION_DISCONNECTED = 0x01;
- public const ushort DOCUMENT_POSITION_PRECEDING = 0x02;
- public const ushort DOCUMENT_POSITION_FOLLOWING = 0x04;
- public const ushort DOCUMENT_POSITION_CONTAINS = 0x08;
- public const ushort DOCUMENT_POSITION_CONTAINED_BY = 0x10;
- public const ushort DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
- public abstract ushort compare_document_position (DomNode other);
+ [Flags]
+ public enum DocumenPosition {
+ DISCONNECTED,
+ PRECEDING,
+ FOLLOWING,
+ CONTAINS,
+ CONTAINED_BY,
+ IMPLEMENTATION_SPECIFIC
+ }
+ public abstract DocumenPosition compare_document_position (DomNode other);
public abstract bool contains (DomNode? other);
- public abstract string? lookup_prefix(string? namespace);
+ public abstract string? lookup_prefix (string? nspace);
public abstract string? lookup_namespace_uri (string? prefix);
- public abstract bool is_default_namespace(string? namespace);
+ public abstract bool is_default_namespace (string? nspace);
public abstract DomNode insert_before (DomNode node, DomNode? child);
public abstract DomNode append_child (DomNode node);
public abstract DomNode replace_child (DomNode node, DomNode child);
- public abstract DomNode remove_child(DomNode child);
+ public abstract DomNode remove_child (DomNode child);
}
public errordomain GXml.DomError {
diff --git a/gxml/GXmlListChildren.vala b/gxml/GXmlListChildren.vala
index 072b879..c864cad 100644
--- a/gxml/GXmlListChildren.vala
+++ b/gxml/GXmlListChildren.vala
@@ -25,7 +25,7 @@ using Gee;
/**
* A {@link Gee.AbstractBidirList} implementation to access {@link Xml.Node} collection
*/
-public class GXml.GListChildren : AbstractBidirList<GXml.Node>
+public class GXml.GListChildren : AbstractBidirList<GXml.Node>, DomNodeList
{
private GXml.GDocument _doc;
private Xml.Node *_node;
@@ -65,14 +65,23 @@ public class GXml.GListChildren : AbstractBidirList<GXml.Node>
return -1;
}
/**
- * This method is ignored by default.
+ * Insert @item before @index
*/
- public override void insert (int index, GXml.Node item) {}
+ public override void insert (int index, GXml.Node item) {
+ var n = @get (index);
+ if (n == null) return;
+ n.get_internal_node ()->add_prev_sibling (item.get_internal_node ());
+ }
public override Gee.ListIterator<GXml.Node> list_iterator () { return new Iterator (_doc, _node); }
/**
- * This method is ignored by default.
+ * Removes a node at @index
*/
- public override GXml.Node remove_at (int index) { return null; }
+ public override GXml.Node remove_at (int index) {
+ var n = @get (index);
+ if (n == null) return null;
+ n.get_internal_node ()->unlink_node ();
+ return n;
+ }
/**
* This method is ignored by default.
*/
@@ -240,5 +249,8 @@ public class GXml.GListChildren : AbstractBidirList<GXml.Node>
return true;
}
}
+ // DomNodeList implementation
+ public DomNode? item (ulong index) { return (DomNode) @get ((int) index); }
+ public ulong length { get { return (ulong) size; } }
}
diff --git a/gxml/GXmlNode.vala b/gxml/GXmlNode.vala
index c219553..e7ed183 100644
--- a/gxml/GXmlNode.vala
+++ b/gxml/GXmlNode.vala
@@ -104,5 +104,187 @@ public abstract class GXml.GNode : Object, GXml.Node
}
return null;
}
+ // DomNode Implementation
+ public string node_name { get { return name; } }
+
+ protected string _base_uri = null;
+ public string? base_uri { get { return _base_uri; } }
+
+ public DomDocument? owner_document { get { return document; } }
+ public DomNode? parent_node { get { return parent; } }
+ public DomElement? parent_element {
+ get {
+ if (parent is DomElement) return parent;
+ return null;
+ }
+ }
+ public DomNodeList child_nodes { get { return children; } }
+ public DomNode? first_child { get { return children.itirator ().first (); } }
+ public DomNode? last_child { get { return children.itirator ().last (); } }
+ public DomNode? previous_sibling {
+ get {
+ if (_node == null) return null;
+ if (_node->prev == null) return null;
+ return GNode.to_gnode (_doc, _node->prev);
+ }
+ }
+ public DomNode? next_sibling {
+ get {
+ if (_node == null) return null;
+ if (_node->next == null) return null;
+ return GNode.to_gnode (_doc, _node->next);
+ }
+ }
+
+ public string? node_value { get { return @value; } set { this.@value = value; } }
+ public string? text_content {
+ get {
+ string t = null;
+ if (this is GXml.Text) return this.@value;
+ if (this is GXml.ProcessingInstruction) return this.@value;
+ if (this is GXml.Comment) return this.@value;
+ if (this is GXml.Document || this is GXml.Element) {
+ foreach (GXml.Node n in children) {
+ if (n is GXml.Text) {
+ if (t == null) t = n.value;
+ else t += n.value;
+ }
+ }
+ }
+ return t;
+ }
+ set {
+ if (this is GXml.Document || this is GXml.Element) {
+ var t = this.document.create_text (value);
+ this.document.add (t);
+ }
+ if (!(this is GXml.Text || this is GXml.Comment || this is GXml.ProcessingInstruction)) return;
+ this.@value = value;
+ }
+ }
+
+ public bool has_child_nodes () { return (children.size > 0); }
+ public void normalize () {
+ GXml.Text t = null;
+ int[] r = {};
+ for (int i = 0; i < children.size; i++) {
+ var n = children.get (i);
+ if (n is GXml.DomText) {
+ if ((t as GXml.DomText).length == 0) {
+ r += i;
+ continue;
+ }
+ if (t == null) {
+ t = n;
+ continue;
+ } else {
+ t.@value += n.value;
+ }
+ }
+ }
+ foreach (int j in r) {
+ children.remove_at (j);
+ }
+ }
+
+ public DomNode clone_node (bool deep = false) {
+ Xml.Node *n = null;
+ if (deep)
+ n = _node->copy_node (2);
+ else
+ n = _node->copy_prop_list (_node->properties);
+ if (n == null) return null;
+ return Node.to_gnode (_doc, n);
+ }
+ public bool is_equal_node (DomNode? node) {
+ if (node == null) return false;
+ if (this.children.size != node.children.size) return false;
+ foreach (Attribute a in attrs.values) {
+ if (!node.attrs.has_key (a.name)) return false;
+ if (a.value != node.attrs.get (a.name).value) return false;
+ }
+ for (int i=0; i < children.size; i++) {
+ if (!children[i].is_equal_node (node.children[i])) return false;
+ }
+ }
+
+ public DocumenPosition compare_document_position (DomNode other) {
+ if (this == other) return (DocumenPosition) 0;
+ if (this.document != (other as GXml.Node).document)
+ return DocumenPosition.DISCONNECTED & DocumenPosition.IMPLEMENTATION_SPECIFIC
+ & (this > other) ? DocumentPosition.PRECEDING : DocumentPosition.FOLLOWING;
+ if (other.parent == this)
+ return DocumenPosition.CONTAINS & DocumenPosition.PRECEDING;
+ if (this.parent == other)
+ return DocumenPosition.CONTAINED_BY & DocumenPosition.FOLLOWING;
+ if (other < this) return DocumenPosition.PRECEDING;
+ return DocumenPosition.FOLLOWING;
+ }
+ public bool contains (DomNode? other) {
+ if (other == null) return false;
+ if (other == this) return true;
+ if (other.parent == this) return true;
+ return false;
+ }
+
+ public string? lookup_prefix (string? nspace) {
+ if (parent == null) return null;
+ if (this is GXml.DocumentType || this is GXml.DocumentFragment) return null;
+ if (this is GXml.Document)
+ if ((this as GXml.Document).root != null)
+ return (document.root as DomNode).lookup_prefix (nspace);
+ else
+ return null;
+ if (this is GXml.Element) {
+ if (namespaces.size > 0) {
+ var ns = namespaces[0];
+ if (ns.prefix == nspace) return ns.uri;
+ else return null;
+ }
+ }
+ return this.parent.lookup_prefix (nspace);
+ }
+ public string? lookup_namespace_uri (string? prefix) {
+ if (prefix == null) return null;
+ if (this is GXml.DocumentType || this is GXml.DocumentFragment) return null;
+ if (this is GXml.Document)
+ if ((this as GXml.Document).root != null)
+ return (document.root as DomNode).lookup_namespace_uri (prefix);
+ else
+ return null;
+ if (this is GXml.Element) {
+ if (namespaces.size > 0) {
+ var ns = namespaces[0];
+ if (ns.prefix == nspace) return ns.uri;
+ else return null;
+ }
+ }
+ return this.parent.lookup_namespace_uri (prefix);
+ }
+ public bool is_default_namespace (string? nspace) {
+ if (nspace == null) return false;
+ var ns = lookup_namespace_uri (null);
+ if (ns == nspace) return true;
+ return false;
+ }
+
+ public DomNode insert_before (DomNode node, DomNode? child) {
+ int i = children.index_of (child);
+ children.insert (i, node);
+ return node;
+ }
+ public DomNode append_child (DomNode node) {
+ children.add (node);
+ return node;
+ }
+ public DomNode replace_child (DomNode node, DomNode child) {
+ int i = children.index_of (child);
+ children.remove_at (i);
+ children.insert (node, i);
+ }
+ public DomNode remove_child (DomNode child) {
+ int i = children.index_of (child);
+ return children.remove_at (i);
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]