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.com>
  6.  */
  7.  
  8. #include <assert.h>
  9. #include <stdlib.h>
  10.  
  11. #include <dom/html/html_form_element.h>
  12.  
  13. #include "html/html_form_element.h"
  14. #include "html/html_button_element.h"
  15.  
  16. #include "html/html_collection.h"
  17. #include "html/html_document.h"
  18.  
  19. #include "core/node.h"
  20. #include "utils/utils.h"
  21.  
  22. static struct dom_element_protected_vtable _protect_vtable = {
  23.         {
  24.                 DOM_NODE_PROTECT_VTABLE_HTML_FORM_ELEMENT
  25.         },
  26.         DOM_HTML_FORM_ELEMENT_PROTECT_VTABLE
  27. };
  28.  
  29. static bool _dom_is_form_control(struct dom_node_internal *node, void *ctx);
  30.  
  31. /**
  32.  * Create a dom_html_form_element object
  33.  *
  34.  * \param doc  The document object
  35.  * \param ele  The returned element object
  36.  * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
  37.  */
  38. dom_exception _dom_html_form_element_create(struct dom_html_document *doc,
  39.                 dom_string *namespace, dom_string *prefix,
  40.                 struct dom_html_form_element **ele)
  41. {
  42.         struct dom_node_internal *node;
  43.  
  44.         *ele = malloc(sizeof(dom_html_form_element));
  45.         if (*ele == NULL)
  46.                 return DOM_NO_MEM_ERR;
  47.        
  48.         /* Set up vtables */
  49.         node = (struct dom_node_internal *) *ele;
  50.         node->base.vtable = &_dom_html_element_vtable;
  51.         node->vtable = &_protect_vtable;
  52.  
  53.         return _dom_html_form_element_initialise(doc, namespace, prefix, *ele);
  54. }
  55.  
  56. /**
  57.  * Initialise a dom_html_form_element object
  58.  *
  59.  * \param doc  The document object
  60.  * \param ele  The dom_html_form_element object
  61.  * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
  62.  */
  63. dom_exception _dom_html_form_element_initialise(struct dom_html_document *doc,
  64.                 dom_string *namespace, dom_string *prefix,
  65.                 struct dom_html_form_element *ele)
  66. {
  67.         dom_exception err;
  68.  
  69.         err = _dom_html_element_initialise(doc, &ele->base,
  70.                                            doc->memoised[hds_FORM],
  71.                                            namespace, prefix);
  72.        
  73.         ele->col = NULL;
  74.  
  75.         return err;
  76. }
  77.  
  78. /**
  79.  * Finalise a dom_html_form_element object
  80.  *
  81.  * \param ele  The dom_html_form_element object
  82.  */
  83. void _dom_html_form_element_finalise(struct dom_html_form_element *ele)
  84. {
  85.         _dom_html_element_finalise(&ele->base);
  86. }
  87.  
  88. /**
  89.  * Destroy a dom_html_form_element object
  90.  *
  91.  * \param ele  The dom_html_form_element object
  92.  */
  93. void _dom_html_form_element_destroy(struct dom_html_form_element *ele)
  94. {
  95.         _dom_html_form_element_finalise(ele);
  96.         free(ele);
  97. }
  98.  
  99. /*------------------------------------------------------------------------*/
  100. /* The protected virtual functions */
  101.  
  102. /* The virtual function used to parse attribute value, see src/core/element.c
  103.  * for detail */
  104. dom_exception _dom_html_form_element_parse_attribute(dom_element *ele,
  105.                 dom_string *name, dom_string *value,
  106.                 dom_string **parsed)
  107. {
  108.         UNUSED(ele);
  109.         UNUSED(name);
  110.  
  111.         dom_string_ref(value);
  112.         *parsed = value;
  113.  
  114.         return DOM_NO_ERR;
  115. }
  116.  
  117. /* The virtual destroy function, see src/core/node.c for detail */
  118. void _dom_virtual_html_form_element_destroy(dom_node_internal *node)
  119. {
  120.         _dom_html_form_element_destroy((struct dom_html_form_element *) node);
  121. }
  122.  
  123. /* The virtual copy function, see src/core/node.c for detail */
  124. dom_exception _dom_html_form_element_copy(dom_node_internal *old,
  125.                 dom_node_internal **copy)
  126. {
  127.         return _dom_html_element_copy(old, copy);
  128. }
  129.  
  130. /*-----------------------------------------------------------------------*/
  131. /* Public APIs */
  132.  
  133. /**
  134.  * Get the form controls under this form element
  135.  *
  136.  * \param ele  The form object
  137.  * \param col  The collection of form controls
  138.  * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
  139.  */
  140. dom_exception dom_html_form_element_get_elements(dom_html_form_element *ele,
  141.                 struct dom_html_collection **col)
  142. {
  143.         dom_exception err;
  144.  
  145.         if (ele->col == NULL) {
  146.                 dom_html_document *doc = (dom_html_document *) dom_node_get_owner(ele);
  147.                 assert(doc != NULL);
  148.                 err = _dom_html_collection_create(doc,
  149.                                 (dom_node_internal *) doc,
  150.                                 _dom_is_form_control, ele, col);
  151.                 if (err != DOM_NO_ERR)
  152.                         return err;
  153.  
  154.                 ele->col = *col;
  155.         }
  156.  
  157.         *col = ele->col;
  158.         dom_html_collection_ref(*col);
  159.  
  160.         return DOM_NO_ERR;
  161. }
  162.  
  163. /**
  164.  * Get the number of form controls under this form element
  165.  *
  166.  * \param ele  The form object
  167.  * \param len  The number of controls
  168.  * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
  169.  */
  170. dom_exception dom_html_form_element_get_length(dom_html_form_element *ele,
  171.                 uint32_t *len)
  172. {
  173.         dom_exception err;
  174.  
  175.         if (ele->col == NULL) {
  176.                 dom_html_document *doc = (dom_html_document *) dom_node_get_owner(ele);
  177.                 assert(doc != NULL);
  178.                 err = _dom_html_collection_create(doc,
  179.                                 (dom_node_internal *) doc,
  180.                                 _dom_is_form_control, ele, &ele->col);
  181.                 if (err != DOM_NO_ERR)
  182.                         return err;
  183.         }
  184.  
  185.         return dom_html_collection_get_length(ele->col, len);
  186. }
  187.  
  188. #define SIMPLE_GET_SET(attr)                                            \
  189.         dom_exception dom_html_form_element_get_##attr(                 \
  190.                 dom_html_form_element *element,                         \
  191.                 dom_string **attr)                                      \
  192.         {                                                               \
  193.                 dom_exception ret;                                      \
  194.                 dom_string *_memo_##attr;                               \
  195.                                                                         \
  196.                 _memo_##attr =                                          \
  197.                         ((struct dom_html_document *)                   \
  198.                          ((struct dom_node_internal *)element)->owner)->\
  199.                         memoised[hds_##attr];                           \
  200.                                                                         \
  201.                 ret = dom_element_get_attribute(element, _memo_##attr, attr); \
  202.                                                                         \
  203.                 return ret;                                             \
  204.         }                                                               \
  205.                                                                         \
  206.         dom_exception dom_html_form_element_set_##attr(                 \
  207.                 dom_html_form_element *element,                         \
  208.                 dom_string *attr)                                       \
  209.         {                                                               \
  210.                 dom_exception ret;                                      \
  211.                 dom_string *_memo_##attr;                               \
  212.                                                                         \
  213.                 _memo_##attr =                                          \
  214.                         ((struct dom_html_document *)                   \
  215.                          ((struct dom_node_internal *)element)->owner)->\
  216.                         memoised[hds_##attr];                           \
  217.                                                                         \
  218.                 ret = dom_element_set_attribute(element, _memo_##attr, attr); \
  219.                                                                         \
  220.                 return ret;                                             \
  221.         }
  222.  
  223. SIMPLE_GET_SET(accept_charset)
  224. SIMPLE_GET_SET(action)
  225. SIMPLE_GET_SET(enctype)
  226. SIMPLE_GET_SET(method)
  227. SIMPLE_GET_SET(target)
  228.  
  229.  
  230. /**
  231.  * Submit this form
  232.  *
  233.  * \param ele  The form object
  234.  * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
  235.  */
  236. dom_exception dom_html_form_element_submit(dom_html_form_element *ele)
  237. {
  238.         struct dom_html_document *doc =
  239.                 (dom_html_document *) dom_node_get_owner(ele);
  240.         bool success = false;
  241.         assert(doc != NULL);
  242.  
  243.         /* Dispatch an event and let the default action handler to deal with
  244.          * the submit action, and a 'submit' event is bubbling and cancelable
  245.          */
  246.         return _dom_dispatch_generic_event((dom_document *)doc,
  247.                                            (dom_event_target *) ele,
  248.                                            doc->memoised[hds_submit], true,
  249.                                            true, &success);
  250. }
  251.  
  252. /**
  253.  * Reset this form
  254.  *
  255.  * \param ele  The form object
  256.  * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
  257.  */
  258. dom_exception dom_html_form_element_reset(dom_html_form_element *ele)
  259. {
  260.         struct dom_html_document *doc =
  261.                 (dom_html_document *) dom_node_get_owner(ele);
  262.         bool success = false;
  263.         assert(doc != NULL);
  264.  
  265.         /* Dispatch an event and let the default action handler to deal with
  266.          * the reset action, and a 'reset' event is bubbling and cancelable
  267.          */
  268.         return _dom_dispatch_generic_event((dom_document *) doc,
  269.                                            (dom_event_target *) ele,
  270.                                            doc->memoised[hds_reset], true,
  271.                                            true, &success);
  272. }
  273.  
  274. /*-----------------------------------------------------------------------*/
  275. /* Internal functions */
  276.  
  277. /* Callback function to test whether certain node is a form control, see
  278.  * src/html/html_collection.h for detail. */
  279. static bool _dom_is_form_control(struct dom_node_internal *node, void *ctx)
  280. {
  281.         struct dom_html_document *doc =
  282.                 (struct dom_html_document *)(node->owner);
  283.         struct dom_html_form_element *form = ctx, *form2;
  284.  
  285.        
  286.         assert(node->type == DOM_ELEMENT_NODE);
  287.  
  288.         /* Form controls are INPUT TEXTAREA SELECT and BUTTON */
  289.         if (dom_string_caseless_isequal(node->name,
  290.                                         doc->memoised[hds_INPUT]))
  291.                 return true;
  292.         if (dom_string_caseless_isequal(node->name,
  293.                                         doc->memoised[hds_TEXTAREA]))
  294.                 return true;
  295.         if (dom_string_caseless_isequal(node->name,
  296.                                         doc->memoised[hds_SELECT]))
  297.                 return true;
  298.         if (dom_string_caseless_isequal(node->name,
  299.                                         doc->memoised[hds_BUTTON])) {
  300.                 dom_html_button_element *button =
  301.                         (dom_html_button_element *) node;
  302.                 dom_exception err =
  303.                         dom_html_button_element_get_form(button, &form2);
  304.                 if (err == DOM_NO_ERR) {
  305.                         return form == form2;
  306.                 }
  307.                 /* Couldn't get the form, assume it's not ours. */
  308.                 return false;
  309.         }
  310.  
  311.         return false;
  312. }
  313.  
  314.