Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * This file is part of libdom.
  3.  * Licensed under the MIT License,
  4.  *                http://www.opensource.org/licenses/mit-license.php
  5.  * Copyright 2009 Bo Yang <struggleyb.nku@gmail.com>
  6.  */
  7.  
  8. #include <assert.h>
  9. #include <stdlib.h>
  10.  
  11. #include <libwapcaplet/libwapcaplet.h>
  12.  
  13. #include "html/html_options_collection.h"
  14.  
  15. #include "core/node.h"
  16. #include "core/element.h"
  17. #include "core/string.h"
  18. #include "utils/utils.h"
  19.  
  20. /*-----------------------------------------------------------------------*/
  21. /* Constructor and destructor */
  22.  
  23. /**
  24.  * Create a dom_html_options_collection
  25.  *
  26.  * \param doc   The document
  27.  * \param root  The root element of the collection
  28.  * \param ic    The callback function used to determin whether certain node
  29.  *              beint32_ts to the collection
  30.  * \param col   The result collection object
  31.  * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
  32.  */
  33. dom_exception _dom_html_options_collection_create(struct dom_html_document *doc,
  34.                 struct dom_node_internal *root,
  35.                 dom_callback_is_in_collection ic,
  36.                 void *ctx,
  37.                 struct dom_html_options_collection **col)
  38. {
  39.         *col = malloc(sizeof(dom_html_options_collection));
  40.         if (*col == NULL)
  41.                 return DOM_NO_MEM_ERR;
  42.        
  43.         return _dom_html_options_collection_initialise(doc, *col, root,
  44.                                                        ic, ctx);
  45. }
  46.  
  47. /**
  48.  * Intialiase a dom_html_options_collection
  49.  *
  50.  * \param doc   The document
  51.  * \param col   The collection object to be initialised
  52.  * \param root  The root element of the collection
  53.  * \param ic    The callback function used to determin whether certain node
  54.  *              beint32_ts to the collection
  55.  * \return DOM_NO_ERR on success.
  56.  */
  57. dom_exception _dom_html_options_collection_initialise(struct dom_html_document *doc,
  58.                 struct dom_html_options_collection *col,
  59.                 struct dom_node_internal *root,
  60.                 dom_callback_is_in_collection ic, void *ctx)
  61. {
  62.         return _dom_html_collection_initialise(doc, &col->base, root, ic, ctx);
  63. }
  64.  
  65. /**
  66.  * Finalise a dom_html_options_collection object
  67.  *
  68.  * \param col  The dom_html_options_collection object
  69.  */
  70. void _dom_html_options_collection_finalise(struct dom_html_options_collection *col)
  71. {
  72.         _dom_html_collection_finalise(&col->base);
  73. }
  74.  
  75. /**
  76.  * Destroy a dom_html_options_collection object
  77.  * \param col  The dom_html_options_collection object
  78.  */
  79. void _dom_html_options_collection_destroy(struct dom_html_options_collection *col)
  80. {
  81.         _dom_html_options_collection_finalise(col);
  82.  
  83.         free(col);
  84. }
  85.  
  86.  
  87. /*-----------------------------------------------------------------------*/
  88. /* Public API */
  89.  
  90. /**
  91.  * Get the length of this dom_html_options_collection
  92.  *
  93.  * \param col  The dom_html_options_collection object
  94.  * \param len  The returned length of this collection
  95.  * \return DOM_NO_ERR on success.
  96.  */
  97. dom_exception dom_html_options_collection_get_length(dom_html_options_collection *col,
  98.                 uint32_t *len)
  99. {
  100.         return dom_html_collection_get_length(&col->base, len);
  101. }
  102.  
  103. /**
  104.  * Set the length of this dom_html_options_collection
  105.  *
  106.  * \param col  The dom_html_options_collection object
  107.  * \param len  The length of this collection to be set
  108.  * \return DOM_NO_ERR on success.
  109.  */
  110. dom_exception dom_html_options_collection_set_length(
  111.                 dom_html_options_collection *col, uint32_t len)
  112. {
  113.         UNUSED(col);
  114.         UNUSED(len);
  115.  
  116.         /* TODO: how to deal with this */
  117.         return DOM_NOT_SUPPORTED_ERR;
  118. }
  119.  
  120. /**
  121.  * Get the node with certain index
  122.  *
  123.  * \param col  The dom_html_options_collection object
  124.  * \param index  The index number based on zero
  125.  * \param node   The returned node object
  126.  * \return DOM_NO_ERR on success.
  127.  */
  128. dom_exception dom_html_options_collection_item(dom_html_options_collection *col,
  129.                 uint32_t index, struct dom_node **node)
  130. {
  131.         return dom_html_collection_item(&col->base, index, node);
  132. }
  133.  
  134. /**
  135.  * Get the node in the collection according name
  136.  *
  137.  * \param col   The collection
  138.  * \param name  The name of target node
  139.  * \param node  The returned node object
  140.  * \return DOM_NO_ERR on success.
  141.  */
  142. dom_exception dom_html_options_collection_named_item(dom_html_options_collection *col,
  143.                 dom_string *name, struct dom_node **node)
  144. {
  145.         struct dom_node_internal *n = col->base.root;
  146.         dom_string *kname;
  147.         dom_exception err;
  148.  
  149.         /* Search for an element with an appropriate ID */
  150.         err = dom_html_collection_named_item(&col->base, name, node);
  151.         if (err == DOM_NO_ERR && *node != NULL)
  152.                 return err;
  153.  
  154.         /* Didn't find one, so consider name attribute */
  155.         err = dom_string_create_interned((const uint8_t *) "name", SLEN("name"),
  156.                         &kname);
  157.         if (err != DOM_NO_ERR)
  158.                 return err;
  159.  
  160.         while (n != NULL) {
  161.                 if (n->type == DOM_ELEMENT_NODE &&
  162.                     col->base.ic(n, col->base.ctx) == true) {
  163.                         dom_string *nval = NULL;
  164.  
  165.                         err = dom_element_get_attribute(n, kname, &nval);
  166.                         if (err != DOM_NO_ERR) {
  167.                                 dom_string_unref(kname);
  168.                                 return err;
  169.                         }
  170.  
  171.                         if (nval != NULL && dom_string_isequal(name, nval)) {
  172.                                 *node = (struct dom_node *) n;
  173.                                 dom_node_ref(n);
  174.                                 dom_string_unref(nval);
  175.                                 dom_string_unref(kname);
  176.  
  177.                                 return DOM_NO_ERR;
  178.                         }
  179.  
  180.                         if (nval != NULL)
  181.                                 dom_string_unref(nval);
  182.                 }
  183.  
  184.                 /* Depth first iterating */
  185.                 if (n->first_child != NULL) {
  186.                         n = n->first_child;
  187.                 } else if (n->next != NULL) {
  188.                         n = n->next;
  189.                 } else {
  190.                         /* No children and siblings */
  191.                         struct dom_node_internal *parent = n->parent;
  192.  
  193.                         while (parent != col->base.root &&
  194.                                         n == parent->last_child) {
  195.                                 n = parent;
  196.                                 parent = parent->parent;
  197.                         }
  198.                        
  199.                         if (parent == col->base.root)
  200.                                 n = NULL;
  201.                         else
  202.                                 n = n->next;
  203.                 }
  204.         }
  205.  
  206.         dom_string_unref(kname);
  207.  
  208.         /* Not found the target node */
  209.         *node = NULL;
  210.  
  211.         return DOM_NO_ERR;
  212. }
  213.  
  214. /**
  215.  * Claim a reference on this collection
  216.  *
  217.  * \pram col  The collection object
  218.  */
  219. void dom_html_options_collection_ref(dom_html_options_collection *col)
  220. {
  221.         if (col == NULL)
  222.                 return;
  223.        
  224.         col->base.refcnt ++;
  225. }
  226.  
  227. /**
  228.  * Relese a reference on this collection
  229.  *
  230.  * \pram col  The collection object
  231.  */
  232. void dom_html_options_collection_unref(dom_html_options_collection *col)
  233. {
  234.         if (col == NULL)
  235.                 return;
  236.        
  237.         if (col->base.refcnt > 0)
  238.                 col->base.refcnt --;
  239.        
  240.         if (col->base.refcnt == 0)
  241.                 _dom_html_options_collection_destroy(col);
  242. }
  243.  
  244.