1 /* 2 * Copyright 2014 Vincent Sanders <vince@netsurf-browser.org> 3 * 4 * This file is part of NetSurf, http://www.netsurf-browser.org/ 5 * 6 * NetSurf is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; version 2 of the License. 9 * 10 * NetSurf is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 /** 20 * \file 21 * Interface to form handling functions internal to HTML content handler. 22 */ 23 24 #ifndef NETSURF_HTML_FORM_INTERNAL_H 25 #define NETSURF_HTML_FORM_INTERNAL_H 26 27 #include <stdbool.h> 28 29 #include "netsurf/form.h" 30 31 struct box; 32 struct form_control; 33 struct form_option; 34 struct form_select_menu; 35 struct form; 36 struct html_content; 37 struct dom_string; 38 struct content; 39 struct nsurl; 40 struct fetch_multipart_data; 41 struct redraw_context; 42 struct browser_window; 43 44 enum browser_mouse_state; 45 46 /** Type of a struct form_control. */ 47 typedef enum { 48 GADGET_HIDDEN, 49 GADGET_TEXTBOX, 50 GADGET_RADIO, 51 GADGET_CHECKBOX, 52 GADGET_SELECT, 53 GADGET_TEXTAREA, 54 GADGET_IMAGE, 55 GADGET_PASSWORD, 56 GADGET_SUBMIT, 57 GADGET_RESET, 58 GADGET_FILE, 59 GADGET_BUTTON 60 } form_control_type; 61 62 /** Data for textarea */ 63 struct form_textarea_data { 64 struct form_control *gadget; 65 }; 66 67 struct image_input_coords { 68 int x; 69 int y; 70 }; 71 72 /** Form control. */ 73 struct form_control { 74 void *node; /**< Corresponding DOM node */ 75 struct dom_string *node_value; /**< The last value sync'd with the DOM */ 76 bool syncing; /**< Set if a DOM sync is in-progress */ 77 struct html_content *html; /**< HTML content containing control */ 78 79 form_control_type type; /**< Type of control */ 80 81 struct form *form; /**< Containing form */ 82 83 char *name; /**< Control name */ 84 char *value; /**< Current value of control */ 85 char *initial_value; /**< Initial value of control */ 86 char *last_synced_value; /**< The last value sync'd to the DOM */ 87 bool disabled; /**< Whether control is disabled */ 88 89 struct box *box; /**< Box for control */ 90 91 unsigned int length; /**< Number of characters in control */ 92 unsigned int maxlength; /**< Maximum characters permitted */ 93 94 bool selected; /**< Whether control is selected */ 95 96 union { 97 struct { 98 int mx, my; 99 } image; 100 struct { 101 int num_items; 102 struct form_option *items, *last_item; 103 bool multiple; 104 int num_selected; 105 /** Currently selected item, if num_selected == 1. */ 106 struct form_option *current; 107 struct form_select_menu *menu; 108 } select; 109 struct { 110 struct textarea *ta; 111 struct dom_string *initial; 112 struct form_textarea_data data; 113 } text; /**< input type=text or textarea */ 114 } data; 115 116 struct form_control *prev; /**< Previous control in this form */ 117 struct form_control *next; /**< Next control in this form. */ 118 }; 119 120 /** Form submit method. */ 121 typedef enum { 122 method_GET, /**< GET, always url encoded. */ 123 method_POST_URLENC, /**< POST, url encoded. */ 124 method_POST_MULTIPART /**< POST, multipart/form-data. */ 125 } form_method; 126 127 /** HTML form. */ 128 struct form { 129 void *node; /**< Corresponding DOM node */ 130 131 char *action; /**< Absolute URL to submit to. */ 132 char *target; /**< Target to submit to. */ 133 form_method method; /**< Method and enctype. */ 134 char *accept_charsets; /**< Charset to submit form in */ 135 char *document_charset; /**< Charset of document containing form */ 136 struct form_control *controls; /**< Linked list of controls. */ 137 struct form_control *last_control; /**< Last control in list. */ 138 139 struct form *prev; /**< Previous form in doc. */ 140 }; 141 142 /** 143 * Called by the select menu when it wants an area to be redrawn. The 144 * coordinates are menu origin relative. 145 * 146 * \param client_data data which was passed to form_open_select_menu 147 * \param x X coordinate of redraw rectangle 148 * \param y Y coordinate of redraw rectangle 149 * \param width width of redraw rectangle 150 * \param height height of redraw rectangle 151 */ 152 typedef void(*select_menu_redraw_callback)(void *client_data, 153 int x, int y, int width, int height); 154 155 /** 156 * Create a struct form. 157 * 158 * \param node DOM node associated with form 159 * \param action URL to submit form to, or NULL for default 160 * \param target Target frame of form, or NULL for default 161 * \param method method and enctype 162 * \param charset acceptable encodings for form submission, or NULL 163 * \param doc_charset encoding of containing document, or NULL 164 * \return A new form or NULL on memory exhaustion 165 */ 166 struct form *form_new(void *node, const char *action, const char *target, 167 form_method method, const char *charset, 168 const char *doc_charset); 169 170 /** 171 * Free a form and any controls it owns. 172 * 173 * \note There may exist controls attached to box tree nodes which are not 174 * associated with any form. These will leak at present. Ideally, they will 175 * be cleaned up when the box tree is destroyed. As that currently happens 176 * via talloc, this won't happen. These controls are distinguishable, as their 177 * form field will be NULL. 178 * 179 * \param form The form to free 180 */ 181 void form_free(struct form *form); 182 183 184 /** 185 * Create a struct form_control. 186 * 187 * \param node Associated DOM node 188 * \param type control type 189 * \return a new structure, or NULL on memory exhaustion 190 */ 191 struct form_control *form_new_control(void *node, form_control_type type); 192 193 194 /** 195 * Add a control to the list of controls in a form. 196 * 197 * \param form The form to add the control to 198 * \param control The control to add 199 */ 200 void form_add_control(struct form *form, struct form_control *control); 201 202 203 /** 204 * Free a struct form_control. 205 * 206 * \param control structure to free 207 */ 208 void form_free_control(struct form_control *control); 209 210 211 /** 212 * Add an option to a form select control. 213 * 214 * \param control form control of type GADGET_SELECT 215 * \param value value of option, used directly (not copied) 216 * \param text text for option, used directly (not copied) 217 * \param selected this option is selected 218 * \param node the DOM node this option is associated with 219 * \return true on success, false on memory exhaustion 220 */ 221 bool form_add_option(struct form_control *control, char *value, char *text, 222 bool selected, void *node); 223 224 225 /** 226 * Open a select menu for a select form control, creating it if necessary. 227 * 228 * \param client_data data passed to the redraw callback 229 * \param control The select form control for which the menu is being opened 230 * \param redraw_callback The callback to redraw the select menu. 231 * \param c The content the select menu is opening for. 232 * \return NSERROR_OK on sucess else error code. 233 */ 234 nserror form_open_select_menu(void *client_data, 235 struct form_control *control, 236 select_menu_redraw_callback redraw_callback, 237 struct content *c); 238 239 240 /** 241 * Destroy a select menu and free allocated memory. 242 * 243 * \param control the select form control owning the select menu being 244 * destroyed. 245 */ 246 void form_free_select_menu(struct form_control *control); 247 248 249 /** 250 * Redraw an opened select menu. 251 * 252 * \param control the select menu being redrawn 253 * \param x the X coordinate to draw the menu at 254 * \param y the Y coordinate to draw the menu at 255 * \param scale current redraw scale 256 * \param clip clipping rectangle 257 * \param ctx current redraw context 258 * \return true on success, false otherwise 259 */ 260 bool form_redraw_select_menu(struct form_control *control, int x, int y, 261 float scale, const struct rect *clip, 262 const struct redraw_context *ctx); 263 264 265 /** 266 * Check whether a clipping rectangle is completely contained in the 267 * select menu. 268 * 269 * \param control the select menu to check the clipping rectangle for 270 * \param scale the current browser window scale 271 * \param clip the clipping rectangle 272 * \return true if inside false otherwise 273 */ 274 bool form_clip_inside_select_menu(struct form_control *control, float scale, 275 const struct rect *clip); 276 277 278 /** 279 * Handle mouse action for the currently opened select menu. 280 * 281 * \param control the select menu which received the mouse action 282 * \param mouse current mouse state 283 * \param x X coordinate of click 284 * \param y Y coordinate of click 285 * \return text for the browser status bar or NULL if the menu has to be closed 286 */ 287 const char *form_select_mouse_action(struct form_control *control, 288 enum browser_mouse_state mouse, int x, int y); 289 290 291 /** 292 * Handle mouse drag end for the currently opened select menu. 293 * 294 * \param control the select menu which received the mouse drag end 295 * \param mouse current mouse state 296 * \param x X coordinate of drag end 297 * \param y Y coordinate of drag end 298 */ 299 void form_select_mouse_drag_end(struct form_control *control, 300 enum browser_mouse_state mouse, int x, int y); 301 302 303 /** 304 * Get the dimensions of a select menu. 305 * 306 * \param control the select menu to get the dimensions of 307 * \param width gets updated to menu width 308 * \param height gets updated to menu height 309 */ 310 void form_select_get_dimensions(struct form_control *control, 311 int *width, int *height); 312 313 314 /** 315 * Callback for the core select menu. 316 */ 317 void form_select_menu_callback(void *client_data, 318 int x, int y, int width, int height); 319 320 321 /** 322 * Set a radio form control and clear the others in the group. 323 * 324 * \param radio form control of type GADGET_RADIO 325 */ 326 void form_radio_set(struct form_control *radio); 327 328 /** 329 * navigate browser window based on form submission. 330 * 331 * \param page_url content url 332 * \param target The browsing context in which the navigation will occour. 333 * \param form The form to submit. 334 * \param submit_button The control used to submit the form. 335 */ 336 nserror form_submit(struct nsurl *page_url, struct browser_window *target, 337 struct form *form, struct form_control *submit_button); 338 339 340 /** 341 * Update gadget value. 342 */ 343 void form_gadget_update_value(struct form_control *control, char *value); 344 345 346 /** 347 * Synchronise this gadget with its associated DOM node. 348 * 349 * If the DOM has changed and the gadget has not, the DOM's new value is 350 * imported into the gadget. If the gadget's value has changed and the DOM's 351 * has not, the gadget's value is pushed into the DOM. 352 * If both have changed, the gadget's value wins. 353 * 354 * \param control The form gadget to synchronise 355 * 356 * \note Currently this will only synchronise input gadgets (text/password) 357 */ 358 void form_gadget_sync_with_dom(struct form_control *control); 359 360 #endif 361