1 /*
2  * Copyright (C) 2018 Alexander Borisov
3  *
4  * Author: Alexander Borisov <borisov@lexbor.com>
5  */
6 
7 #include "lexbor/html/interfaces/title_element.h"
8 #include "lexbor/html/interfaces/document.h"
9 #include "lexbor/dom/interfaces/text.h"
10 
11 
12 lxb_html_title_element_t *
lxb_html_title_element_interface_create(lxb_html_document_t * document)13 lxb_html_title_element_interface_create(lxb_html_document_t *document)
14 {
15     lxb_html_title_element_t *element;
16 
17     element = lexbor_mraw_calloc(document->dom_document.mraw,
18                                  sizeof(lxb_html_title_element_t));
19     if (element == NULL) {
20         return NULL;
21     }
22 
23     lxb_dom_node_t *node = lxb_dom_interface_node(element);
24 
25     node->owner_document = lxb_html_document_original_ref(document);
26     node->type = LXB_DOM_NODE_TYPE_ELEMENT;
27 
28     return element;
29 }
30 
31 lxb_html_title_element_t *
lxb_html_title_element_interface_destroy(lxb_html_title_element_t * title)32 lxb_html_title_element_interface_destroy(lxb_html_title_element_t *title)
33 {
34     lexbor_str_t *text;
35     lxb_dom_document_t *doc = lxb_dom_interface_node(title)->owner_document;
36 
37     text = title->strict_text;
38 
39     (void) lxb_dom_node_interface_destroy(lxb_dom_interface_node(title));
40 
41     if (text != NULL) {
42         lexbor_str_destroy(text, doc->text, false);
43         lxb_dom_document_destroy_struct(doc, text);
44     }
45 
46     return NULL;
47 }
48 
49 const lxb_char_t *
lxb_html_title_element_text(lxb_html_title_element_t * title,size_t * len)50 lxb_html_title_element_text(lxb_html_title_element_t *title, size_t *len)
51 {
52     if (lxb_dom_interface_node(title)->first_child == NULL) {
53         goto failed;
54     }
55 
56     if (lxb_dom_interface_node(title)->first_child->type != LXB_DOM_NODE_TYPE_TEXT) {
57         goto failed;
58     }
59 
60     lxb_dom_text_t *text;
61 
62     text = lxb_dom_interface_text(lxb_dom_interface_node(title)->first_child);
63 
64     if (len != NULL) {
65         *len = text->char_data.data.length;
66     }
67 
68     return text->char_data.data.data;
69 
70 failed:
71 
72     if (len != NULL) {
73         *len = 0;
74     }
75 
76     return NULL;
77 }
78 
79 const lxb_char_t *
lxb_html_title_element_strict_text(lxb_html_title_element_t * title,size_t * len)80 lxb_html_title_element_strict_text(lxb_html_title_element_t *title, size_t *len)
81 {
82     const lxb_char_t *text;
83     size_t text_len;
84 
85     lxb_dom_document_t *doc = lxb_dom_interface_node(title)->owner_document;
86 
87     text = lxb_html_title_element_text(title, &text_len);
88     if (text == NULL) {
89         goto failed;
90     }
91 
92     if (title->strict_text != NULL) {
93         if (title->strict_text->length < text_len) {
94             const lxb_char_t *data;
95 
96             data = lexbor_str_realloc(title->strict_text,
97                                       doc->text, (text_len + 1));
98             if (data == NULL) {
99                 goto failed;
100             }
101         }
102     }
103     else {
104         title->strict_text = lxb_dom_document_create_struct(doc,
105                                                             sizeof(lexbor_str_t));
106         if (title->strict_text == NULL) {
107             goto failed;
108         }
109 
110         lexbor_str_init(title->strict_text, doc->text, text_len);
111         if (title->strict_text->data == NULL) {
112             title->strict_text = lxb_dom_document_destroy_struct(doc,
113                                                                  title->strict_text);
114             goto failed;
115         }
116     }
117 
118     memcpy(title->strict_text->data, text, sizeof(lxb_char_t) * text_len);
119 
120     title->strict_text->data[text_len] = 0x00;
121     title->strict_text->length = text_len;
122 
123     lexbor_str_strip_collapse_whitespace(title->strict_text);
124 
125     if (len != NULL) {
126         *len = title->strict_text->length;
127     }
128 
129     return title->strict_text->data;
130 
131 failed:
132 
133     if (len != NULL) {
134         *len = 0;
135     }
136 
137     return NULL;
138 }
139