[lasem] dom: store owner_document as node member.



commit 044b5b4a4e3a606d9af46d017d75d4d1393b32e6
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Tue Apr 2 21:34:27 2013 +0200

    dom: store owner_document as node member.
    
    It used to be retrieved by walking the tree from node to document,
    but it was not conforming to the DOM specification, where owner_document
    must be non null as soon as the element is created.

 src/lsmdomdocument.c |   20 +++++++++++++---
 src/lsmdomnode.c     |    9 +------
 src/lsmdomnode.h     |    2 +
 tests/dom.c          |   59 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 78 insertions(+), 12 deletions(-)
---
diff --git a/src/lsmdomdocument.c b/src/lsmdomdocument.c
index 31741cd..fdba500 100644
--- a/src/lsmdomdocument.c
+++ b/src/lsmdomdocument.c
@@ -80,20 +80,32 @@ LsmDomElement *
 lsm_dom_document_create_element (LsmDomDocument *document, const char *tag_name)
 {
        LsmDomDocumentClass *document_class;
+       LsmDomElement *element;
 
        g_return_val_if_fail (LSM_IS_DOM_DOCUMENT (document), NULL);
 
        document_class = LSM_DOM_DOCUMENT_GET_CLASS (document);
-       if (document_class->create_element != NULL)
-               return document_class->create_element (document, tag_name);
+       if (document_class->create_element == NULL)
+               return NULL;
 
-       return NULL;
+       element = document_class->create_element (document, tag_name);
+       if (element != NULL)
+               LSM_DOM_NODE (element)->owner_document = document;
+
+       return element;
 }
 
 static LsmDomText *
 lsm_dom_document_create_text_node_base (LsmDomDocument *document, const char *data)
 {
-       return LSM_DOM_TEXT (lsm_dom_text_new (data));
+       LsmDomText *text_node;
+
+       text_node = LSM_DOM_TEXT (lsm_dom_text_new (data));
+
+       if (text_node != NULL)
+               LSM_DOM_NODE (text_node)->owner_document = document;
+
+       return text_node;
 }
 
 /**
diff --git a/src/lsmdomnode.c b/src/lsmdomnode.c
index d9d61b8..51f5c9f 100644
--- a/src/lsmdomnode.c
+++ b/src/lsmdomnode.c
@@ -341,16 +341,9 @@ lsm_dom_node_get_attributes (LsmDomNode* self)
 LsmDomDocument *
 lsm_dom_node_get_owner_document (LsmDomNode* self)
 {
-       LsmDomNode *parent;
-
        g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
 
-       for (parent = self;
-            parent != NULL &&
-            !LSM_IS_DOM_DOCUMENT (parent);
-            parent = parent->parent_node);
-
-       return LSM_DOM_DOCUMENT (parent);
+       return self->owner_document;
 }
 
 /**
diff --git a/src/lsmdomnode.h b/src/lsmdomnode.h
index de1458c..221e200 100644
--- a/src/lsmdomnode.h
+++ b/src/lsmdomnode.h
@@ -56,6 +56,8 @@ typedef struct _LsmDomNodeClass LsmDomNodeClass;
 struct _LsmDomNode {
        GObject object;
 
+       LsmDomDocument  *owner_document;
+
        LsmDomNode      *next_sibling;
        LsmDomNode      *previous_sibling;
        LsmDomNode      *parent_node;
diff --git a/tests/dom.c b/tests/dom.c
index a33037e..82c4a30 100644
--- a/tests/dom.c
+++ b/tests/dom.c
@@ -2,6 +2,14 @@
 #include <lsmdom.h>
 
 static void
+_weak_ref_cb (void *data, GObject *object)
+{
+       int *counter = data;
+
+       (*counter)++;
+}
+
+static void
 create_document_test (void)
 {
        LsmDomDocument *document;
@@ -21,6 +29,49 @@ create_document_test (void)
        g_object_unref (document);
 }
 
+static void
+owner_document_test (void)
+{
+       LsmDomDocument *document;
+       LsmDomElement *element;
+       LsmDomElement *text_element;
+       LsmDomText *text;
+       int counter = 0;
+
+       document = lsm_dom_implementation_create_document (NULL, "svg");
+       g_assert (LSM_IS_DOM_DOCUMENT (document));
+       g_assert (lsm_dom_node_get_owner_document (LSM_DOM_NODE (document)) == NULL);
+
+       element = lsm_dom_document_create_element (document, "svg");
+       g_assert (LSM_IS_DOM_ELEMENT (element));
+       g_assert (lsm_dom_node_get_owner_document (LSM_DOM_NODE (element)) == document);
+
+       lsm_dom_node_append_child (LSM_DOM_NODE (document), LSM_DOM_NODE (element));
+       g_assert (lsm_dom_node_get_owner_document (LSM_DOM_NODE (element)) == document);
+
+       text_element = lsm_dom_document_create_element (document, "text");
+       g_assert (LSM_IS_DOM_ELEMENT (text_element));
+       g_assert (lsm_dom_node_get_owner_document (LSM_DOM_NODE (text_element)) == document);
+
+       lsm_dom_node_append_child (LSM_DOM_NODE (element), LSM_DOM_NODE (text_element));
+
+       text = lsm_dom_document_create_text_node (document, "");
+       g_assert (LSM_IS_DOM_TEXT (text));
+       g_assert (lsm_dom_node_get_owner_document (LSM_DOM_NODE (text)) == document);
+
+       lsm_dom_node_append_child (LSM_DOM_NODE (text_element), LSM_DOM_NODE (text));
+       g_assert (lsm_dom_node_get_owner_document (LSM_DOM_NODE (text)) == document);
+
+       g_object_weak_ref (G_OBJECT (document), _weak_ref_cb, &counter);
+       g_object_weak_ref (G_OBJECT (element), _weak_ref_cb, &counter);
+       g_object_weak_ref (G_OBJECT (text_element), _weak_ref_cb, &counter);
+       g_object_weak_ref (G_OBJECT (text), _weak_ref_cb, &counter);
+
+       g_object_unref (document);
+
+       g_assert_cmpint (counter, ==, 4);
+}
+
 #if 0 /* Unused code - remove? */
 static void
 create_element_test (void)
@@ -85,6 +136,7 @@ node_list_test (void)
        LsmDomDocument *document;
        LsmDomElement *element;
        LsmDomNodeList *childs;
+       int counter = 0;
 
        document = lsm_dom_implementation_create_document (NULL, "svg");
        element = lsm_dom_document_create_element (document, "svg");
@@ -96,12 +148,18 @@ node_list_test (void)
        g_assert (lsm_dom_node_list_get_item (childs, 0) == LSM_DOM_NODE (element));
        g_assert (lsm_dom_node_list_get_item (childs, 1) == NULL);
 
+       g_object_weak_ref (G_OBJECT (document), _weak_ref_cb, &counter);
+       g_object_weak_ref (G_OBJECT (element), _weak_ref_cb, &counter);
+       g_object_weak_ref (G_OBJECT (childs), _weak_ref_cb, &counter);
+
        g_object_ref (childs);
        g_object_unref (document);
 
        g_assert (lsm_dom_node_list_get_length (childs) == 0);
 
        g_object_unref (childs);
+
+       g_assert_cmpint (counter, ==, 3);
 }
 
 static void
@@ -157,6 +215,7 @@ main (int argc, char *argv[])
        g_test_init (&argc, &argv, NULL);
 
        g_test_add_func ("/dom/create-document", create_document_test);
+       g_test_add_func ("/dom/owner-document", owner_document_test);
        g_test_add_func ("/dom/create-element", create_document_test);
        g_test_add_func ("/dom/add-remove-element", create_document_test);
        g_test_add_func ("/dom/node-list", node_list_test);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]