[gxml] Fixed GNode implementations of DomNode for insert, replace, append and remove nodes
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gxml] Fixed GNode implementations of DomNode for insert, replace, append and remove nodes
- Date: Wed, 20 Jul 2016 00:13:52 +0000 (UTC)
commit abe8023eba87908aec0a9e2c7a8068eb298f48f2
Author: Daniel Espinosa <esodan gmail com>
Date: Tue Jul 19 19:12:27 2016 -0500
Fixed GNode implementations of DomNode for insert, replace, append and remove nodes
* Added Unit Tests
gxml/DomNode.vala | 8 +++---
gxml/GXmlNode.vala | 64 +++++++++++++++++++++++++++++++++++++------
test/DomGDocumentTest.vala | 54 +++++++++++++++++++++++++++++++++++-
3 files changed, 111 insertions(+), 15 deletions(-)
---
diff --git a/gxml/DomNode.vala b/gxml/DomNode.vala
index 0652f75..54355f4 100644
--- a/gxml/DomNode.vala
+++ b/gxml/DomNode.vala
@@ -76,10 +76,10 @@ public interface GXml.DomNode : GLib.Object, GXml.DomEventTarget {
public abstract string? lookup_namespace_uri (string? prefix);
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 insert_before (DomNode node, DomNode? child) throws GLib.Error;
+ public abstract DomNode append_child (DomNode node) throws GLib.Error;
+ public abstract DomNode replace_child (DomNode node, DomNode child) throws GLib.Error;
+ public abstract DomNode remove_child (DomNode child) throws GLib.Error;
}
public errordomain GXml.DomError {
diff --git a/gxml/GXmlNode.vala b/gxml/GXmlNode.vala
index 12891cf..cb11953 100644
--- a/gxml/GXmlNode.vala
+++ b/gxml/GXmlNode.vala
@@ -284,22 +284,68 @@ public abstract class GXml.GNode : Object,
return false;
}
- public DomNode insert_before (DomNode node, DomNode? child) {
- int i = children_nodes.index_of (child as GXml.Node);
- children_nodes.insert (i, (node as GXml.Node));
- return node;
- }
- public DomNode append_child (DomNode node) {
+ public DomNode insert_before (DomNode node, DomNode? child) throws GLib.Error {
+ if (!(node is GXml.GNode))
+ throw new DomError.INVALID_NODE_TYPE_ERROR (_("Invalid atemp to add invalid node type"));
+ if (child != null && !this.contains (child))
+ throw new DomError.NOT_FOUND_ERROR (_("Can't find child to insert node before"));
+ if (!(this is DomDocument
+ || this is DomElement
+ || this is DomDocumentFragment))
+ throw new DomError.HIERARCHY_REQUEST_ERROR (_("Invalid atemp to insert a node"));
+ if (!(node is DomDocumentFragment
+ || node is DomDocumentType
+ || node is DomElement
+ || node is DomText
+ || node is DomProcessingInstruction
+ || node is DomComment))
+ throw new DomError.HIERARCHY_REQUEST_ERROR (_("Invalid atemp to insert an invalid node type"));
+ if ((node is DomText && this is DomDocument)
+ || (node is DomDocumentType && !(this is DomDocument)))
+ throw new DomError.HIERARCHY_REQUEST_ERROR (_("Invalid atemp to insert a document's type or text node
to a invalid parent"));
+ //FIXME: We should follow steps for DOM4 observers in https://www.w3.org/TR/dom/#concept-node-pre-insert
+ if (child != null) {
+ int i = this.children_nodes.index_of (child as GXml.Node);
+ children_nodes.insert (i, (node as GXml.Node));
+ return node;
+ }
children_nodes.add ((node as GXml.Node));
return node;
}
- public DomNode replace_child (DomNode node, DomNode child) {
+ public DomNode append_child (DomNode node) throws GLib.Error {
+ return insert_before (node, null);
+ }
+ public DomNode replace_child (DomNode node, DomNode child) throws GLib.Error {
+ if (!(node is GXml.GNode))
+ throw new DomError.INVALID_NODE_TYPE_ERROR (_("Invalid atemp to add invalid node type"));
+ if (child == null || !this.contains (child))
+ throw new DomError.NOT_FOUND_ERROR (_("Can't find child node to replace or child have a different
parent"));
+ if (!(this is DomDocument
+ || this is DomElement
+ || this is DomDocumentFragment))
+ throw new DomError.HIERARCHY_REQUEST_ERROR (_("Invalid atemp to insert a node"));
+ if (!(node is DomDocumentFragment
+ || node is DomDocumentType
+ || node is DomElement
+ || node is DomText
+ || node is DomProcessingInstruction
+ || node is DomComment))
+ throw new DomError.HIERARCHY_REQUEST_ERROR (_("Invalid atemp to insert an invalid node type"));
+ if ((node is DomText && this is DomDocument)
+ || (node is DomDocumentType && !(this is DomDocument)))
+ throw new DomError.HIERARCHY_REQUEST_ERROR (_("Invalid atemp to insert a document's type or text node
to a invalid parent"));
+ //FIXME: Checks for HierarchyRequestError for https://www.w3.org/TR/dom/#concept-node-replace
int i = children_nodes.index_of ((child as GXml.Node));
children_nodes.remove_at (i);
- children_nodes.insert (i, (node as GXml.Node));
+ if (i < children_nodes.size)
+ children_nodes.insert (i, (node as GXml.Node));
+ if (i >= children_nodes.size)
+ child_nodes.add (node);
return child;
}
- public DomNode remove_child (DomNode child) {
+ public DomNode remove_child (DomNode child) throws GLib.Error {
+ if (!this.contains (child))
+ throw new DomError.NOT_FOUND_ERROR (_("Can't find child node to remove or child have a different
parent"));
int i = children_nodes.index_of ((child as GXml.Node));
return (DomNode) children_nodes.remove_at (i);
}
diff --git a/test/DomGDocumentTest.vala b/test/DomGDocumentTest.vala
index 611e06d..80952ce 100644
--- a/test/DomGDocumentTest.vala
+++ b/test/DomGDocumentTest.vala
@@ -119,7 +119,8 @@ static const string HTMLDOC ="
assert (lc[1].get_attribute ("class") == "black block");
});
Test.add_func ("/gxml/dom/node", () => {
- GLib.message ("Doc: "+HTMLDOC);
+ try {
+ Test.message ("Doc: "+HTMLDOC);
GDocument doc = new GDocument.from_string (HTMLDOC);
assert (doc is DomDocument);
assert (doc.document_element.children.size == 1);
@@ -191,10 +192,59 @@ static const string HTMLDOC ="
assert (!ng.is_default_namespace ("gxml:http://git.gnome.org/browse/gxml"));
var ng2 = doc.create_element_ns ("http://live.gnome.org/GXml", "OtherNode");
b.child_nodes.add (ng2);
- GLib.message ("BODY:"+(b as GXml.Node).to_string ());
assert (ng2.lookup_prefix ("http://live.gnome.org/GXml") == null);
assert (ng2.lookup_namespace_uri (null) == "http://live.gnome.org/GXml");
assert (ng2.is_default_namespace ("http://live.gnome.org/GXml"));
+ var pn = doc.create_element ("p") as DomElement;
+ pn.set_attribute ("id", "insertedp01");
+ var p = doc.document_element.children[0];
+ assert (p.node_name == "body");
+ var cp0 = p.children[0];
+ assert (cp0.node_name == "p");
+ assert (cp0.get_attribute ("class") == "black");
+ assert (p.contains (cp0));
+ assert (cp0.parent_node.contains (cp0));
+ p.insert_before (pn, cp0);
+ var ppn = p.children[0];
+ assert (ppn.node_name == "p");
+ assert (ppn.has_attribute ("id"));
+ assert (ppn.get_attribute ("id") == "insertedp01");
+ var pn2 = doc.create_element ("p") as DomElement;
+ pn2.set_attribute ("id", "newp");
+ p.append_child (pn2);
+ assert (p.children.length == 7);
+ assert (p.children[6] is DomElement);
+ assert (p.children[6].node_name == "p");
+ assert (p.children[6].get_attribute ("id") == "newp");
+ var pn3 = doc.create_element ("p") as DomElement;
+ pn3.set_attribute ("id", "newp1");
+ pn3.set_attribute ("class", "black");
+ p.replace_child (pn3, pn2);
+ assert (p.children.length == 7);
+ assert (p.children[6] is DomElement);
+ assert (p.children[6].node_name == "p");
+ assert (p.children[6].get_attribute ("id") == "newp1");
+ assert (p.children[6].get_attribute ("class") == "black");
+ var pn4 = doc.create_element ("p") as DomElement;
+ pn4.set_attribute ("id", "newp2");
+ pn4.set_attribute ("class", "black");
+ p.replace_child (pn4, p.child_nodes[0]);
+ GLib.message ("BODY:"+(p as GXml.Node).to_string ());
+ assert (p.children.length == 7);
+ assert (p.children[0] is DomElement);
+ assert (p.children[0].node_name == "p");
+ assert (p.children[0].get_attribute ("id") == "newp2");
+ assert (p.children[0].get_attribute ("class") == "black");
+ p.remove_child (p.children[0]);
+ assert (p.children.length == 6);
+ assert (p.children[0] is DomElement);
+ assert (p.children[0].node_name == "p");
+ assert (!p.has_attribute ("id"));
+ assert (p.children[0].get_attribute ("class") == "black");
+ } catch (GLib.Error e) {
+ GLib.message ("Error: "+e.message);
+ assert_not_reached ();
+ }
});
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]