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 2012 Daniel Silverstone <dsilvers@netsurf-browser.org>
6 */
7
8 #include <assert.h>
9 #include <stdlib.h>
10
11 #include <dom/html/html_text_area_element.h>
12
13 #include "html/html_document.h"
14 #include "html/html_text_area_element.h"
15
16 #include "core/node.h"
17 #include "core/attr.h"
18 #include "utils/utils.h"
19
20 static struct dom_element_protected_vtable _protect_vtable = {
21 {
22 DOM_NODE_PROTECT_VTABLE_HTML_TEXT_AREA_ELEMENT
23 },
24 DOM_HTML_TEXT_AREA_ELEMENT_PROTECT_VTABLE
25 };
26
27 /**
28 * Create a dom_html_text_area_element object
29 *
30 * \param params The html element creation parameters
31 * \param ele The returned element object
32 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
33 */
_dom_html_text_area_element_create(struct dom_html_element_create_params * params,struct dom_html_text_area_element ** ele)34 dom_exception _dom_html_text_area_element_create(
35 struct dom_html_element_create_params *params,
36 struct dom_html_text_area_element **ele)
37 {
38 struct dom_node_internal *node;
39
40 *ele = malloc(sizeof(dom_html_text_area_element));
41 if (*ele == NULL)
42 return DOM_NO_MEM_ERR;
43
44 /* Set up vtables */
45 node = (struct dom_node_internal *) *ele;
46 node->base.vtable = &_dom_html_element_vtable;
47 node->vtable = &_protect_vtable;
48
49 return _dom_html_text_area_element_initialise(params, *ele);
50 }
51
52 /**
53 * Initialise a dom_html_text_area_element object
54 *
55 * \param params The html element creation parameters
56 * \param ele The dom_html_text_area_element object
57 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
58 */
_dom_html_text_area_element_initialise(struct dom_html_element_create_params * params,struct dom_html_text_area_element * ele)59 dom_exception _dom_html_text_area_element_initialise(
60 struct dom_html_element_create_params *params,
61 struct dom_html_text_area_element *ele)
62 {
63 ele->form = NULL;
64 ele->default_value = NULL;
65 ele->default_value_set = false;
66 ele->value = NULL;
67 ele->value_set = false;
68
69 return _dom_html_element_initialise(params, &ele->base);
70 }
71
72 /**
73 * Finalise a dom_html_text_area_element object
74 *
75 * \param ele The dom_html_text_area_element object
76 */
_dom_html_text_area_element_finalise(struct dom_html_text_area_element * ele)77 void _dom_html_text_area_element_finalise(struct dom_html_text_area_element *ele)
78 {
79 if (ele->default_value != NULL) {
80 dom_string_unref(ele->default_value);
81 ele->default_value = NULL;
82 ele->default_value_set = false;
83 }
84
85 if (ele->value != NULL) {
86 dom_string_unref(ele->value);
87 ele->value = NULL;
88 ele->value_set = false;
89 }
90
91 _dom_html_element_finalise(&ele->base);
92 }
93
94 /**
95 * Destroy a dom_html_text_area_element object
96 *
97 * \param ele The dom_html_text_area_element object
98 */
_dom_html_text_area_element_destroy(struct dom_html_text_area_element * ele)99 void _dom_html_text_area_element_destroy(struct dom_html_text_area_element *ele)
100 {
101 _dom_html_text_area_element_finalise(ele);
102 free(ele);
103 }
104
105 /*-----------------------------------------------------------------------*/
106 /* Public APIs */
107
108 /**
109 * Get the disabled property
110 *
111 * \param ele The dom_html_text_area_element object
112 * \param disabled The returned status
113 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
114 */
dom_html_text_area_element_get_disabled(dom_html_text_area_element * ele,bool * disabled)115 dom_exception dom_html_text_area_element_get_disabled(dom_html_text_area_element *ele,
116 bool *disabled)
117 {
118 return dom_html_element_get_bool_property(&ele->base, "disabled",
119 SLEN("disabled"), disabled);
120 }
121
122 /**
123 * Set the disabled property
124 *
125 * \param ele The dom_html_text_area_element object
126 * \param disabled The status
127 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
128 */
dom_html_text_area_element_set_disabled(dom_html_text_area_element * ele,bool disabled)129 dom_exception dom_html_text_area_element_set_disabled(dom_html_text_area_element *ele,
130 bool disabled)
131 {
132 return dom_html_element_set_bool_property(&ele->base, "disabled",
133 SLEN("disabled"), disabled);
134 }
135
136 /**
137 * Get the readOnly property
138 *
139 * \param ele The dom_html_text_area_element object
140 * \param disabled The returned status
141 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
142 */
dom_html_text_area_element_get_read_only(dom_html_text_area_element * ele,bool * read_only)143 dom_exception dom_html_text_area_element_get_read_only(dom_html_text_area_element *ele,
144 bool *read_only)
145 {
146 return dom_html_element_get_bool_property(&ele->base, "readonly",
147 SLEN("readonly"), read_only);
148 }
149
150 /**
151 * Set the readOnly property
152 *
153 * \param ele The dom_html_text_area_element object
154 * \param disabled The status
155 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
156 */
dom_html_text_area_element_set_read_only(dom_html_text_area_element * ele,bool read_only)157 dom_exception dom_html_text_area_element_set_read_only(dom_html_text_area_element *ele,
158 bool read_only)
159 {
160 return dom_html_element_set_bool_property(&ele->base, "readonly",
161 SLEN("readonly"), read_only);
162 }
163
164 /**
165 * Get the defaultValue property
166 *
167 * \param ele The dom_html_text_area_element object
168 * \param disabled The returned status
169 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
170 */
dom_html_text_area_element_get_default_value(dom_html_text_area_element * ele,dom_string ** default_value)171 dom_exception dom_html_text_area_element_get_default_value(
172 dom_html_text_area_element *ele, dom_string **default_value)
173 {
174 dom_exception err;
175
176 if (ele->default_value_set == false) {
177 err = dom_node_get_text_content((dom_node *)ele,
178 &ele->default_value);
179 if (err == DOM_NO_ERR) {
180 ele->default_value_set = true;
181 }
182 }
183
184 *default_value = ele->default_value;
185
186 if (*default_value != NULL)
187 dom_string_ref(*default_value);
188
189 return DOM_NO_ERR;
190 }
191
192 /**
193 * Set the defaultValue property
194 *
195 * \param ele The dom_html_text_area_element object
196 * \param disabled The status
197 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
198 */
dom_html_text_area_element_set_default_value(dom_html_text_area_element * ele,dom_string * default_value)199 dom_exception dom_html_text_area_element_set_default_value(
200 dom_html_text_area_element *ele, dom_string *default_value)
201 {
202 if (ele->default_value != NULL)
203 dom_string_unref(ele->default_value);
204
205 ele->default_value = default_value;
206 ele->default_value_set = true;
207
208 if (ele->default_value != NULL)
209 dom_string_ref(ele->default_value);
210
211 return DOM_NO_ERR;
212 }
213
214 /**
215 * Get the value property
216 *
217 * \param ele The dom_html_text_area_element object
218 * \param disabled The returned status
219 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
220 */
dom_html_text_area_element_get_value(dom_html_text_area_element * ele,dom_string ** value)221 dom_exception dom_html_text_area_element_get_value(
222 dom_html_text_area_element *ele, dom_string **value)
223 {
224 dom_exception err;
225
226 if (ele->value_set == false) {
227 err = dom_node_get_text_content((dom_node *)ele,
228 &ele->value);
229 if (err == DOM_NO_ERR) {
230 ele->default_value_set = true;
231 if (ele->default_value_set == false) {
232 ele->default_value_set = true;
233 ele->default_value = ele->value;
234 dom_string_ref(ele->default_value);
235 }
236 }
237 }
238
239 *value = ele->value;
240
241 if (*value != NULL)
242 dom_string_ref(*value);
243
244 return DOM_NO_ERR;
245 }
246
247 /**
248 * Set the value property
249 *
250 * \param ele The dom_html_text_area_element object
251 * \param disabled The status
252 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
253 */
dom_html_text_area_element_set_value(dom_html_text_area_element * ele,dom_string * value)254 dom_exception dom_html_text_area_element_set_value(
255 dom_html_text_area_element *ele, dom_string *value)
256 {
257 dom_exception err;
258
259 if (ele->default_value_set == false) {
260 err = dom_node_get_text_content((dom_node *)ele,
261 &ele->default_value);
262 if (err == DOM_NO_ERR) {
263 ele->default_value_set = true;
264 }
265 }
266
267 if (ele->value != NULL)
268 dom_string_unref(ele->value);
269
270 ele->value = value;
271 ele->value_set = true;
272
273 if (ele->value != NULL)
274 dom_string_ref(ele->value);
275
276 return dom_node_set_text_content((dom_node *)ele, ele->value);
277 }
278
279 /*------------------------------------------------------------------------*/
280 /* The protected virtual functions */
281
282 /* The virtual function used to parse attribute value, see src/core/element.c
283 * for detail */
_dom_html_text_area_element_parse_attribute(dom_element * ele,dom_string * name,dom_string * value,dom_string ** parsed)284 dom_exception _dom_html_text_area_element_parse_attribute(dom_element *ele,
285 dom_string *name, dom_string *value,
286 dom_string **parsed)
287 {
288 UNUSED(ele);
289 UNUSED(name);
290
291 dom_string_ref(value);
292 *parsed = value;
293
294 return DOM_NO_ERR;
295 }
296
297 /* The virtual destroy function, see src/core/node.c for detail */
_dom_virtual_html_text_area_element_destroy(dom_node_internal * node)298 void _dom_virtual_html_text_area_element_destroy(dom_node_internal *node)
299 {
300 _dom_html_text_area_element_destroy((struct dom_html_text_area_element *) node);
301 }
302
303 /* The virtual copy function, see src/core/node.c for detail */
_dom_html_text_area_element_copy(dom_node_internal * old,dom_node_internal ** copy)304 dom_exception _dom_html_text_area_element_copy(
305 dom_node_internal *old, dom_node_internal **copy)
306 {
307 dom_html_text_area_element *new_node;
308 dom_exception err;
309
310 new_node = malloc(sizeof(dom_html_text_area_element));
311 if (new_node == NULL)
312 return DOM_NO_MEM_ERR;
313
314 err = dom_html_text_area_element_copy_internal(old, new_node);
315 if (err != DOM_NO_ERR) {
316 free(new_node);
317 return err;
318 }
319
320 *copy = (dom_node_internal *) new_node;
321
322 return DOM_NO_ERR;
323 }
324
_dom_html_text_area_element_copy_internal(dom_html_text_area_element * old,dom_html_text_area_element * new)325 dom_exception _dom_html_text_area_element_copy_internal(
326 dom_html_text_area_element *old,
327 dom_html_text_area_element *new)
328 {
329 dom_exception err;
330
331 err = dom_html_element_copy_internal(old, new);
332 if (err != DOM_NO_ERR) {
333 return err;
334 }
335
336 /* TODO: We don't seem to keep a ref to form element, so just
337 * copy the pointer for now. */
338 new->form = old->form;
339
340 new->default_value = dom_string_ref(old->default_value);
341 new->default_value_set = old->default_value_set;
342 new->value = dom_string_ref(old->value);
343 new->value_set = old->value_set;
344
345 return DOM_NO_ERR;
346 }
347
348 /*-----------------------------------------------------------------------*/
349 /* API functions */
350
351 #define SIMPLE_GET(attr) \
352 dom_exception dom_html_text_area_element_get_##attr( \
353 dom_html_text_area_element *element, \
354 dom_string **attr) \
355 { \
356 dom_exception ret; \
357 dom_string *_memo_##attr; \
358 \
359 _memo_##attr = \
360 ((struct dom_html_document *) \
361 ((struct dom_node_internal *)element)->owner)->\
362 memoised[hds_##attr]; \
363 \
364 ret = dom_element_get_attribute(element, _memo_##attr, attr); \
365 \
366 return ret; \
367 }
368 #define SIMPLE_SET(attr) \
369 dom_exception dom_html_text_area_element_set_##attr( \
370 dom_html_text_area_element *element, \
371 dom_string *attr) \
372 { \
373 dom_exception ret; \
374 dom_string *_memo_##attr; \
375 \
376 _memo_##attr = \
377 ((struct dom_html_document *) \
378 ((struct dom_node_internal *)element)->owner)->\
379 memoised[hds_##attr]; \
380 \
381 ret = dom_element_set_attribute(element, _memo_##attr, attr); \
382 \
383 return ret; \
384 }
385
386 #define SIMPLE_GET_SET(attr) SIMPLE_GET(attr) SIMPLE_SET(attr)
387
388 SIMPLE_GET_SET(access_key);
389 SIMPLE_GET_SET(name);
390
dom_html_text_area_element_get_type(dom_html_text_area_element * text_area,dom_string ** type)391 dom_exception dom_html_text_area_element_get_type(
392 dom_html_text_area_element *text_area, dom_string **type)
393 {
394 dom_html_document *html = (dom_html_document *)
395 ((dom_node_internal *)text_area)->owner;
396
397 *type = html->memoised[hds_textarea];
398 dom_string_ref(*type);
399
400 return DOM_NO_ERR;
401 }
402
dom_html_text_area_element_get_tab_index(dom_html_text_area_element * text_area,int32_t * tab_index)403 dom_exception dom_html_text_area_element_get_tab_index(
404 dom_html_text_area_element *text_area, int32_t *tab_index)
405 {
406 return dom_html_element_get_int32_t_property(&text_area->base, "tabindex",
407 SLEN("tabindex"), tab_index);
408 }
409
dom_html_text_area_element_set_tab_index(dom_html_text_area_element * text_area,uint32_t tab_index)410 dom_exception dom_html_text_area_element_set_tab_index(
411 dom_html_text_area_element *text_area, uint32_t tab_index)
412 {
413 return dom_html_element_set_int32_t_property(&text_area->base, "tabindex",
414 SLEN("tabindex"), tab_index);
415 }
416
dom_html_text_area_element_get_cols(dom_html_text_area_element * text_area,int32_t * cols)417 dom_exception dom_html_text_area_element_get_cols(
418 dom_html_text_area_element *text_area, int32_t *cols)
419 {
420 return dom_html_element_get_int32_t_property(&text_area->base, "cols",
421 SLEN("cols"), cols);
422 }
423
dom_html_text_area_element_set_cols(dom_html_text_area_element * text_area,uint32_t cols)424 dom_exception dom_html_text_area_element_set_cols(
425 dom_html_text_area_element *text_area, uint32_t cols)
426 {
427 return dom_html_element_set_int32_t_property(&text_area->base, "cols",
428 SLEN("cols"), cols);
429 }
430
dom_html_text_area_element_get_rows(dom_html_text_area_element * text_area,int32_t * rows)431 dom_exception dom_html_text_area_element_get_rows(
432 dom_html_text_area_element *text_area, int32_t *rows)
433 {
434 return dom_html_element_get_int32_t_property(&text_area->base, "rows",
435 SLEN("rows"), rows);
436 }
437
dom_html_text_area_element_set_rows(dom_html_text_area_element * text_area,uint32_t rows)438 dom_exception dom_html_text_area_element_set_rows(
439 dom_html_text_area_element *text_area, uint32_t rows)
440 {
441 return dom_html_element_set_int32_t_property(&text_area->base, "rows",
442 SLEN("rows"), rows);
443 }
444
dom_html_text_area_element_get_form(dom_html_text_area_element * text_area,dom_html_form_element ** form)445 dom_exception dom_html_text_area_element_get_form(
446 dom_html_text_area_element *text_area, dom_html_form_element **form)
447 {
448 *form = text_area->form;
449
450 if (*form != NULL)
451 dom_node_ref(*form);
452
453 return DOM_NO_ERR;
454 }
455
_dom_html_text_area_element_set_form(dom_html_text_area_element * text_area,dom_html_form_element * form)456 dom_exception _dom_html_text_area_element_set_form(
457 dom_html_text_area_element *text_area, dom_html_form_element *form)
458 {
459 text_area->form = form;
460
461 return DOM_NO_ERR;
462 }
463
464 /**
465 * Blur this control
466 *
467 * \param ele The form object
468 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
469 */
dom_html_text_area_element_blur(dom_html_text_area_element * ele)470 dom_exception dom_html_text_area_element_blur(dom_html_text_area_element *ele)
471 {
472 struct dom_html_document *doc =
473 (dom_html_document *) dom_node_get_owner(ele);
474 bool success = false;
475 assert(doc != NULL);
476
477 /* This event does not bubble & is Non-cancellable. Mentioned in w3 specs. More research is needed to prove why. */
478 return _dom_dispatch_generic_event((dom_document *) doc,
479 (dom_event_target *) ele,
480 doc->memoised[hds_blur], false,
481 false, &success);
482 }
483
484 /**
485 * Focus this control
486 *
487 * \param ele The form object
488 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
489 */
dom_html_text_area_element_focus(dom_html_text_area_element * ele)490 dom_exception dom_html_text_area_element_focus(dom_html_text_area_element *ele)
491 {
492 struct dom_html_document *doc =
493 (dom_html_document *) dom_node_get_owner(ele);
494 bool success = false;
495 assert(doc != NULL);
496
497 /* This event does not bubble & is Non-cancellable. Mentioned in w3 specs. More research is needed to prove why. */
498 return _dom_dispatch_generic_event((dom_document *)doc,
499 (dom_event_target *) ele,
500 doc->memoised[hds_focus], false,
501 false, &success);
502 }
503
504 /**
505 * Select this control
506 *
507 * \param ele The form object
508 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
509 */
dom_html_text_area_element_select(dom_html_text_area_element * ele)510 dom_exception dom_html_text_area_element_select(dom_html_text_area_element *ele)
511 {
512 struct dom_html_document *doc =
513 (dom_html_document *) dom_node_get_owner(ele);
514 bool success = false;
515 assert(doc != NULL);
516
517 /* This event bubbles & is non-cancelable. Mentioned in w3 specs. More research is needed to prove why. */
518 return _dom_dispatch_generic_event((dom_document *)doc,
519 (dom_event_target *) ele,
520 doc->memoised[hds_select], true,
521 false, &success);
522 }
523