NetSurf
html_interaction.c
Go to the documentation of this file.
1 /*
2  * Copyright 2006 James Bursa <bursa@users.sourceforge.net>
3  * Copyright 2006 Richard Wilson <info@tinct.net>
4  * Copyright 2008 Michael Drake <tlsa@netsurf-browser.org>
5  * Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
6  *
7  * This file is part of NetSurf, http://www.netsurf-browser.org/
8  *
9  * NetSurf is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; version 2 of the License.
12  *
13  * NetSurf is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 /**
23  * \file
24  * implementation of user interaction with a CONTENT_HTML.
25  */
26 
27 #include <assert.h>
28 #include <stdbool.h>
29 
30 #include <dom/dom.h>
31 
32 #include "utils/corestrings.h"
33 #include "utils/messages.h"
34 #include "utils/utils.h"
35 #include "utils/log.h"
36 #include "utils/nsoption.h"
37 #include "netsurf/content.h"
38 #include "netsurf/browser_window.h"
39 #include "netsurf/mouse.h"
40 #include "netsurf/misc.h"
41 #include "netsurf/layout.h"
42 #include "netsurf/keypress.h"
43 #include "content/hlcache.h"
44 #include "desktop/frames.h"
45 #include "desktop/scrollbar.h"
46 #include "desktop/selection.h"
47 #include "desktop/textarea.h"
48 #include "javascript/js.h"
49 #include "desktop/gui_internal.h"
50 
51 #include "html/box.h"
52 #include "html/box_textarea.h"
53 #include "html/font.h"
54 #include "html/form_internal.h"
55 #include "html/html_internal.h"
56 #include "html/imagemap.h"
57 #include "html/search.h"
58 
59 /**
60  * Get pointer shape for given box
61  *
62  * \param box box in question
63  * \param imagemap whether an imagemap applies to the box
64  */
65 
67 {
68  browser_pointer_shape pointer;
69  css_computed_style *style;
70  enum css_cursor_e cursor;
71  lwc_string **cursor_uris;
72 
73  if (box->type == BOX_FLOAT_LEFT || box->type == BOX_FLOAT_RIGHT)
74  style = box->children->style;
75  else
76  style = box->style;
77 
78  if (style == NULL)
80 
81  cursor = css_computed_cursor(style, &cursor_uris);
82 
83  switch (cursor) {
84  case CSS_CURSOR_AUTO:
85  if (box->href || (box->gadget &&
86  (box->gadget->type == GADGET_IMAGE ||
87  box->gadget->type == GADGET_SUBMIT)) ||
88  imagemap) {
89  /* link */
90  pointer = BROWSER_POINTER_POINT;
91  } else if (box->gadget &&
92  (box->gadget->type == GADGET_TEXTBOX ||
93  box->gadget->type == GADGET_PASSWORD ||
94  box->gadget->type == GADGET_TEXTAREA)) {
95  /* text input */
96  pointer = BROWSER_POINTER_CARET;
97  } else {
98  /* html content doesn't mind */
99  pointer = BROWSER_POINTER_AUTO;
100  }
101  break;
102  case CSS_CURSOR_CROSSHAIR:
103  pointer = BROWSER_POINTER_CROSS;
104  break;
105  case CSS_CURSOR_POINTER:
106  pointer = BROWSER_POINTER_POINT;
107  break;
108  case CSS_CURSOR_MOVE:
109  pointer = BROWSER_POINTER_MOVE;
110  break;
111  case CSS_CURSOR_E_RESIZE:
112  pointer = BROWSER_POINTER_RIGHT;
113  break;
114  case CSS_CURSOR_W_RESIZE:
115  pointer = BROWSER_POINTER_LEFT;
116  break;
117  case CSS_CURSOR_N_RESIZE:
118  pointer = BROWSER_POINTER_UP;
119  break;
120  case CSS_CURSOR_S_RESIZE:
121  pointer = BROWSER_POINTER_DOWN;
122  break;
123  case CSS_CURSOR_NE_RESIZE:
124  pointer = BROWSER_POINTER_RU;
125  break;
126  case CSS_CURSOR_SW_RESIZE:
127  pointer = BROWSER_POINTER_LD;
128  break;
129  case CSS_CURSOR_SE_RESIZE:
130  pointer = BROWSER_POINTER_RD;
131  break;
132  case CSS_CURSOR_NW_RESIZE:
133  pointer = BROWSER_POINTER_LU;
134  break;
135  case CSS_CURSOR_TEXT:
136  pointer = BROWSER_POINTER_CARET;
137  break;
138  case CSS_CURSOR_WAIT:
139  pointer = BROWSER_POINTER_WAIT;
140  break;
141  case CSS_CURSOR_PROGRESS:
142  pointer = BROWSER_POINTER_PROGRESS;
143  break;
144  case CSS_CURSOR_HELP:
145  pointer = BROWSER_POINTER_HELP;
146  break;
147  default:
148  pointer = BROWSER_POINTER_DEFAULT;
149  break;
150  }
151 
152  return pointer;
153 }
154 
155 
156 /**
157  * Start drag scrolling the contents of a box
158  *
159  * \param box the box to be scrolled
160  * \param x x ordinate of initial mouse position
161  * \param y y ordinate
162  */
163 
164 static void html_box_drag_start(struct box *box, int x, int y)
165 {
166  int box_x, box_y;
167  int scroll_mouse_x, scroll_mouse_y;
168 
169  box_coords(box, &box_x, &box_y);
170 
171  if (box->scroll_x != NULL) {
172  scroll_mouse_x = x - box_x ;
173  scroll_mouse_y = y - (box_y + box->padding[TOP] +
174  box->height + box->padding[BOTTOM] -
177  scroll_mouse_x, scroll_mouse_y);
178  } else if (box->scroll_y != NULL) {
179  scroll_mouse_x = x - (box_x + box->padding[LEFT] +
180  box->width + box->padding[RIGHT] -
182  scroll_mouse_y = y - box_y;
183 
185  scroll_mouse_x, scroll_mouse_y);
186  }
187 }
188 
189 
190 /**
191  * End overflow scroll scrollbar drags
192  *
193  * \param html html content
194  * \param mouse state of mouse buttons and modifier keys
195  * \param x coordinate of mouse
196  * \param y coordinate of mouse
197  * \param dir Direction of drag
198  */
200  browser_mouse_state mouse, int x, int y, int dir)
201 {
202  int pixel_offset;
203  struct box *box;
204  int dx, dy;
205  size_t idx = 0;
206 
207  box = box_pick_text_box(html, x, y, dir, &dx, &dy);
208  if (box) {
209  plot_font_style_t fstyle;
210 
211  font_plot_style_from_css(&html->len_ctx, box->style, &fstyle);
212 
213  guit->layout->position(&fstyle, box->text, box->length,
214  dx, &idx, &pixel_offset);
215 
216  idx += box->byte_offset;
217  }
218 
219  return idx;
220 }
221 
222 
223 /**
224  * Handle mouse tracking (including drags) in an HTML content window.
225  *
226  * \param c content of type html
227  * \param bw browser window
228  * \param mouse state of mouse buttons and modifier keys
229  * \param x coordinate of mouse
230  * \param y coordinate of mouse
231  */
232 
233 void html_mouse_track(struct content *c, struct browser_window *bw,
234  browser_mouse_state mouse, int x, int y)
235 {
236  html_mouse_action(c, bw, mouse, x, y);
237 }
238 
239 /**
240  * Helper for file gadgets to store their filename.
241  *
242  * Stores the filename unencoded on the dom node associated with the
243  * gadget.
244  *
245  * \todo Get rid of this crap eventually
246  *
247  * \param operation DOM operation
248  * \param key DOM node key being considerd
249  * \param _data The data assocated with the key
250  * \param src The source DOM node.
251  * \param dst The destination DOM node.
252  */
253 static void
254 html__image_coords_dom_user_data_handler(dom_node_operation operation,
255  dom_string *key,
256  void *_data,
257  struct dom_node *src,
258  struct dom_node *dst)
259 {
260  struct image_input_coords *oldcoords, *coords = _data, *newcoords;
261 
262  if (!dom_string_isequal(corestring_dom___ns_key_image_coords_node_data,
263  key) || coords == NULL) {
264  return;
265  }
266 
267  switch (operation) {
268  case DOM_NODE_CLONED:
269  newcoords = calloc(1, sizeof(*newcoords));
270  if (newcoords != NULL) {
271  *newcoords = *coords;
272  if (dom_node_set_user_data(dst,
273  corestring_dom___ns_key_image_coords_node_data,
274  newcoords,
276  &oldcoords) == DOM_NO_ERR) {
277  free(oldcoords);
278  }
279  }
280  break;
281 
282  case DOM_NODE_DELETED:
283  free(coords);
284  break;
285 
286  case DOM_NODE_RENAMED:
287  case DOM_NODE_IMPORTED:
288  case DOM_NODE_ADOPTED:
289  break;
290 
291  default:
292  NSLOG(netsurf, INFO, "User data operation not handled.");
293  assert(0);
294  }
295 }
296 
297 
298 /**
299  * End overflow scroll scrollbar drags
300  *
301  * \param scrollbar scrollbar widget
302  * \param mouse state of mouse buttons and modifier keys
303  * \param x coordinate of mouse
304  * \param y coordinate of mouse
305  */
306 static void
308  browser_mouse_state mouse,
309  int x, int y)
310 {
311  int scroll_mouse_x, scroll_mouse_y, box_x, box_y;
312  struct html_scrollbar_data *data = scrollbar_get_data(scrollbar);
313  struct box *box;
314 
315  box = data->box;
316  box_coords(box, &box_x, &box_y);
317 
318  if (scrollbar_is_horizontal(scrollbar)) {
319  scroll_mouse_x = x - box_x;
320  scroll_mouse_y = y - (box_y + box->padding[TOP] +
321  box->height + box->padding[BOTTOM] -
323  scrollbar_mouse_drag_end(scrollbar, mouse,
324  scroll_mouse_x, scroll_mouse_y);
325  } else {
326  scroll_mouse_x = x - (box_x + box->padding[LEFT] +
327  box->width + box->padding[RIGHT] -
329  scroll_mouse_y = y - box_y;
330  scrollbar_mouse_drag_end(scrollbar, mouse,
331  scroll_mouse_x, scroll_mouse_y);
332  }
333 }
334 
335 
336 /**
337  * Handle mouse clicks and movements in an HTML content window.
338  *
339  * \param c content of type html
340  * \param bw browser window
341  * \param mouse state of mouse buttons and modifier keys
342  * \param x coordinate of mouse
343  * \param y coordinate of mouse
344  *
345  * This function handles both hovering and clicking. It is important that the
346  * code path is identical (except that hovering doesn't carry out the action),
347  * so that the status bar reflects exactly what will happen. Having separate
348  * code paths opens the possibility that an attacker will make the status bar
349  * show some harmless action where clicking will be harmful.
350  */
351 
352 void html_mouse_action(struct content *c, struct browser_window *bw,
353  browser_mouse_state mouse, int x, int y)
354 {
355  html_content *html = (html_content *) c;
356  enum { ACTION_NONE, ACTION_SUBMIT, ACTION_GO } action = ACTION_NONE;
357  const char *title = 0;
358  nsurl *url = 0;
359  char *url_s = NULL;
360  size_t url_l = 0;
361  const char *target = 0;
362  char status_buffer[200];
363  const char *status = 0;
365  bool imagemap = false;
366  int box_x = 0, box_y = 0;
367  int gadget_box_x = 0, gadget_box_y = 0;
368  int html_object_pos_x = 0, html_object_pos_y = 0;
369  int text_box_x = 0;
370  struct box *url_box = 0;
371  struct box *gadget_box = 0;
372  struct box *text_box = 0;
373  struct box *box;
374  struct form_control *gadget = 0;
375  hlcache_handle *object = NULL;
376  struct box *html_object_box = NULL;
377  struct browser_window *iframe = NULL;
378  struct box *drag_candidate = NULL;
379  struct scrollbar *scrollbar = NULL;
380  plot_font_style_t fstyle;
381  int scroll_mouse_x = 0, scroll_mouse_y = 0;
382  int padding_left, padding_right, padding_top, padding_bottom;
384  union content_msg_data msg_data;
385  struct dom_node *node = html->layout->node; /* Default to the <HTML> */
386  union html_drag_owner drag_owner;
387  union html_selection_owner sel_owner;
388  bool click = mouse & (BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_PRESS_2 |
391 
392  nserror res = NSERROR_OK;
393 
394  if (drag_type != DRAGGING_NONE && !mouse &&
395  html->visible_select_menu != NULL) {
396  /* drag end: select menu */
398  mouse, x, y);
399  }
400 
401  if (html->visible_select_menu != NULL) {
402  box = html->visible_select_menu->box;
403  box_coords(box, &box_x, &box_y);
404 
405  box_x -= box->border[LEFT].width;
406  box_y += box->height + box->border[BOTTOM].width +
407  box->padding[BOTTOM] + box->padding[TOP];
409  mouse, x - box_x, y - box_y);
410  if (status != NULL) {
411  msg_data.explicit_status_text = status;
412  content_broadcast(c, CONTENT_MSG_STATUS, &msg_data);
413  } else {
414  int width, height;
415  struct hlcache_handle *bw_content;
417  &width, &height);
418  html->visible_select_menu = NULL;
419  bw_content = browser_window_get_content(bw);
420  content_request_redraw(bw_content,box_x, box_y,
421  width, height);
422  }
423  return;
424  }
425 
426  if (html->drag_type == HTML_DRAG_SELECTION) {
427  /* Selection drag */
428  struct box *box;
429  int dir = -1;
430  int dx, dy;
431 
432  if (!mouse) {
433  /* End of selection drag */
434  int dir = -1;
435  size_t idx;
436 
437  if (selection_dragging_start(&html->sel))
438  dir = 1;
439 
440  idx = html_selection_drag_end(html, mouse, x, y, dir);
441 
442  if (idx != 0)
443  selection_track(&html->sel, mouse, idx);
444 
445  drag_owner.no_owner = true;
447  drag_owner, NULL);
448  return;
449  }
450 
451  if (selection_dragging_start(&html->sel))
452  dir = 1;
453 
454  box = box_pick_text_box(html, x, y, dir, &dx, &dy);
455 
456  if (box != NULL) {
457  int pixel_offset;
458  size_t idx;
459  plot_font_style_t fstyle;
460 
462  box->style, &fstyle);
463 
464  guit->layout->position(&fstyle,
465  box->text, box->length,
466  dx, &idx, &pixel_offset);
467 
468  selection_track(&html->sel, mouse,
469  box->byte_offset + idx);
470  }
471  return;
472  }
473 
474  if (html->drag_type == HTML_DRAG_SCROLLBAR) {
475  struct scrollbar *scr = html->drag_owner.scrollbar;
476  struct html_scrollbar_data *data = scrollbar_get_data(scr);
477 
478  if (!mouse) {
479  /* drag end: scrollbar */
480  html_overflow_scroll_drag_end(scr, mouse, x, y);
481  }
482 
483  box = data->box;
484  box_coords(box, &box_x, &box_y);
485  if (scrollbar_is_horizontal(scr)) {
486  scroll_mouse_x = x - box_x ;
487  scroll_mouse_y = y - (box_y + box->padding[TOP] +
488  box->height + box->padding[BOTTOM] -
491  scrollbar_mouse_action(scr, mouse,
492  scroll_mouse_x,
493  scroll_mouse_y));
494  } else {
495  scroll_mouse_x = x - (box_x + box->padding[LEFT] +
496  box->width + box->padding[RIGHT] -
498  scroll_mouse_y = y - box_y;
500  scrollbar_mouse_action(scr, mouse,
501  scroll_mouse_x,
502  scroll_mouse_y));
503  }
504 
505  msg_data.explicit_status_text = status;
506  content_broadcast(c, CONTENT_MSG_STATUS, &msg_data);
507  return;
508  }
509 
512  box = html->drag_owner.textarea;
513  assert(box->gadget != NULL);
514  assert(box->gadget->type == GADGET_TEXTAREA ||
515  box->gadget->type == GADGET_PASSWORD ||
516  box->gadget->type == GADGET_TEXTBOX);
517 
518  box_coords(box, &box_x, &box_y);
519  textarea_mouse_action(box->gadget->data.text.ta, mouse,
520  x - box_x, y - box_y);
521 
522  /* TODO: Set appropriate statusbar message */
523  return;
524  }
525 
526  if (html->drag_type == HTML_DRAG_CONTENT_SELECTION ||
528  box = html->drag_owner.content;
529  assert(box->object != NULL);
530 
531  box_coords(box, &box_x, &box_y);
532  content_mouse_track(box->object, bw, mouse,
533  x - box_x, y - box_y);
534  return;
535  }
536 
537  if (html->drag_type == HTML_DRAG_CONTENT_SELECTION) {
538  box = html->drag_owner.content;
539  assert(box->object != NULL);
540 
541  box_coords(box, &box_x, &box_y);
542  content_mouse_track(box->object, bw, mouse,
543  x - box_x, y - box_y);
544  return;
545  }
546 
547  /* Content related drags handled by now */
548  assert(html->drag_type == HTML_DRAG_NONE);
549 
550  /* search the box tree for a link, imagemap, form control, or
551  * box with scrollbars
552  */
553 
554  box = html->layout;
555 
556  /* Consider the margins of the html page now */
557  box_x = box->margin[LEFT];
558  box_y = box->margin[TOP];
559 
560  /* descend through visible boxes setting more specific values for:
561  * box - deepest box at point
562  * html_object_box - html object
563  * html_object_pos_x - html object
564  * html_object_pos_y - html object
565  * object - non html object
566  * iframe - iframe
567  * url - href or imagemap
568  * target - href or imagemap or gadget
569  * url_box - href or imagemap
570  * imagemap - imagemap
571  * gadget - gadget
572  * gadget_box - gadget
573  * gadget_box_x - gadget
574  * gadget_box_y - gadget
575  * title - title
576  * pointer
577  *
578  * drag_candidate - first box with scroll
579  * padding_left - box with scroll
580  * padding_right
581  * padding_top
582  * padding_bottom
583  * scrollbar - inside padding box stops decent
584  * scroll_mouse_x - inside padding box stops decent
585  * scroll_mouse_y - inside padding box stops decent
586  *
587  * text_box - text box
588  * text_box_x - text_box
589  */
590  do {
591  if ((box->style != NULL) &&
592  (css_computed_visibility(box->style) ==
593  CSS_VISIBILITY_HIDDEN)) {
594  continue;
595  }
596 
597  if (box->node != NULL) {
598  node = box->node;
599  }
600 
601  if (box->object) {
602  if (content_get_type(box->object) == CONTENT_HTML) {
603  html_object_box = box;
604  html_object_pos_x = box_x;
605  html_object_pos_y = box_y;
606  } else {
607  object = box->object;
608  }
609  }
610 
611  if (box->iframe) {
612  iframe = box->iframe;
613  }
614 
615  if (box->href) {
616  url = box->href;
617  target = box->target;
618  url_box = box;
619  }
620 
621  if (box->usemap) {
622  url = imagemap_get(html, box->usemap,
623  box_x, box_y, x, y, &target);
624  if (url) {
625  imagemap = true;
626  url_box = box;
627  }
628  }
629 
630  if (box->gadget) {
631  gadget = box->gadget;
632  gadget_box = box;
633  gadget_box_x = box_x;
634  gadget_box_y = box_y;
635  if (gadget->form)
636  target = gadget->form->target;
637  }
638 
639  if (box->title) {
640  title = box->title;
641  }
642 
643  pointer = get_pointer_shape(box, false);
644 
645  if ((box->scroll_x != NULL) ||
646  (box->scroll_y != NULL)) {
647 
648  if (drag_candidate == NULL) {
649  drag_candidate = box;
650  }
651 
652  padding_left = box_x +
654  padding_right = padding_left + box->padding[LEFT] +
655  box->width + box->padding[RIGHT];
656  padding_top = box_y +
658  padding_bottom = padding_top + box->padding[TOP] +
659  box->height + box->padding[BOTTOM];
660 
661  if ((x > padding_left) &&
662  (x < padding_right) &&
663  (y > padding_top) &&
664  (y < padding_bottom)) {
665  /* mouse inside padding box */
666 
667  if ((box->scroll_y != NULL) &&
668  (x > (padding_right -
669  SCROLLBAR_WIDTH))) {
670  /* mouse above vertical box scroll */
671 
672  scrollbar = box->scroll_y;
673  scroll_mouse_x = x - (padding_right -
675  scroll_mouse_y = y - padding_top;
676  break;
677 
678  } else if ((box->scroll_x != NULL) &&
679  (y > (padding_bottom -
680  SCROLLBAR_WIDTH))) {
681  /* mouse above horizontal box scroll */
682 
683  scrollbar = box->scroll_x;
684  scroll_mouse_x = x - padding_left;
685  scroll_mouse_y = y - (padding_bottom -
687  break;
688  }
689  }
690  }
691 
692  if (box->text && !box->object) {
693  text_box = box;
694  text_box_x = box_x;
695  }
696  } while ((box = box_at_point(&html->len_ctx, box, x, y,
697  &box_x, &box_y)) != NULL);
698 
699  /* use of box_x, box_y, or content below this point is probably a
700  * mistake; they will refer to the last box returned by box_at_point */
701  assert(node != NULL);
702 
703  if (scrollbar) {
705  scrollbar_mouse_action(scrollbar, mouse,
706  scroll_mouse_x,
707  scroll_mouse_y));
708  pointer = BROWSER_POINTER_DEFAULT;
709  } else if (gadget) {
710  textarea_mouse_status ta_status;
711 
712  switch (gadget->type) {
713  case GADGET_SELECT:
714  status = messages_get("FormSelect");
715  pointer = BROWSER_POINTER_MENU;
716  if (mouse & BROWSER_MOUSE_CLICK_1 &&
717  nsoption_bool(core_select_menu)) {
718  html->visible_select_menu = gadget;
719  res = form_open_select_menu(c, gadget,
721  c);
722  if (res != NSERROR_OK) {
723  NSLOG(netsurf, ERROR,
724  "%s",
726  html->visible_select_menu = NULL;
727  }
728  pointer = BROWSER_POINTER_DEFAULT;
729  } else if (mouse & BROWSER_MOUSE_CLICK_1) {
730  msg_data.select_menu.gadget = gadget;
732  &msg_data);
733  }
734  break;
735  case GADGET_CHECKBOX:
736  status = messages_get("FormCheckbox");
737  if (mouse & BROWSER_MOUSE_CLICK_1) {
738  gadget->selected = !gadget->selected;
739  dom_html_input_element_set_checked(
740  (dom_html_input_element *)(gadget->node),
741  gadget->selected);
742  html__redraw_a_box(html, gadget_box);
743  }
744  break;
745  case GADGET_RADIO:
746  status = messages_get("FormRadio");
747  if (mouse & BROWSER_MOUSE_CLICK_1)
748  form_radio_set(gadget);
749  break;
750  case GADGET_IMAGE:
751  /* This falls through to SUBMIT */
752  if (mouse & BROWSER_MOUSE_CLICK_1) {
753  struct image_input_coords *coords, *oldcoords;
754  /** \todo Find a way to not ignore errors */
755  coords = calloc(1, sizeof(*coords));
756  if (coords == NULL) {
757  return;
758  }
759  coords->x = x - gadget_box_x;
760  coords->y = y - gadget_box_y;
761  if (dom_node_set_user_data(
762  gadget->node,
763  corestring_dom___ns_key_image_coords_node_data,
765  &oldcoords) != DOM_NO_ERR)
766  return;
767  free(oldcoords);
768  }
769  /* Fall through */
770  case GADGET_SUBMIT:
771  if (gadget->form) {
772  snprintf(status_buffer, sizeof status_buffer,
773  messages_get("FormSubmit"),
774  gadget->form->action);
775  status = status_buffer;
776  pointer = get_pointer_shape(gadget_box, false);
777  if (mouse & (BROWSER_MOUSE_CLICK_1 |
779  action = ACTION_SUBMIT;
780  } else {
781  status = messages_get("FormBadSubmit");
782  }
783  break;
784  case GADGET_TEXTBOX:
785  case GADGET_PASSWORD:
786  case GADGET_TEXTAREA:
787  if (gadget->type == GADGET_TEXTAREA)
788  status = messages_get("FormTextarea");
789  else
790  status = messages_get("FormTextbox");
791 
792  if (click && (html->selection_type !=
794  html->selection_owner.textarea !=
795  gadget_box)) {
796  sel_owner.none = true;
798  sel_owner, true);
799  }
800 
801  ta_status = textarea_mouse_action(gadget->data.text.ta,
802  mouse, x - gadget_box_x,
803  y - gadget_box_y);
804 
805  if (ta_status & TEXTAREA_MOUSE_EDITOR) {
806  pointer = get_pointer_shape(gadget_box, false);
807  } else {
808  pointer = BROWSER_POINTER_DEFAULT;
810  ta_status >> 3);
811  }
812  break;
813  case GADGET_HIDDEN:
814  /* not possible: no box generated */
815  break;
816  case GADGET_RESET:
817  status = messages_get("FormReset");
818  break;
819  case GADGET_FILE:
820  status = messages_get("FormFile");
821  if (mouse & BROWSER_MOUSE_CLICK_1) {
822  msg_data.gadget_click.gadget = gadget;
824  &msg_data);
825  }
826  break;
827  case GADGET_BUTTON:
828  /* This gadget cannot be activated */
829  status = messages_get("FormButton");
830  break;
831  }
832 
833  } else if (object && (mouse & BROWSER_MOUSE_MOD_2)) {
834 
835  if (mouse & BROWSER_MOUSE_DRAG_2) {
836  msg_data.dragsave.type = CONTENT_SAVE_NATIVE;
837  msg_data.dragsave.content = object;
839 
840  } else if (mouse & BROWSER_MOUSE_DRAG_1) {
841  msg_data.dragsave.type = CONTENT_SAVE_ORIG;
842  msg_data.dragsave.content = object;
844  }
845 
846  /* \todo should have a drag-saving object msg */
847 
848  } else if (iframe) {
849  int pos_x, pos_y;
850  float scale = browser_window_get_scale(bw);
851 
852  browser_window_get_position(iframe, false, &pos_x, &pos_y);
853 
854  if (mouse & BROWSER_MOUSE_CLICK_1 ||
855  mouse & BROWSER_MOUSE_CLICK_2) {
856  browser_window_mouse_click(iframe, mouse,
857  (x * scale) - pos_x,
858  (y * scale) - pos_y);
859  } else {
860  browser_window_mouse_track(iframe, mouse,
861  (x * scale) - pos_x,
862  (y * scale) - pos_y);
863  }
864  } else if (html_object_box) {
865 
866  if (click && (html->selection_type != HTML_SELECTION_CONTENT ||
867  html->selection_owner.content !=
868  html_object_box)) {
869  sel_owner.none = true;
871  sel_owner, true);
872  }
873  if (mouse & BROWSER_MOUSE_CLICK_1 ||
874  mouse & BROWSER_MOUSE_CLICK_2) {
875  content_mouse_action(html_object_box->object,
876  bw, mouse,
877  x - html_object_pos_x,
878  y - html_object_pos_y);
879  } else {
880  content_mouse_track(html_object_box->object,
881  bw, mouse,
882  x - html_object_pos_x,
883  y - html_object_pos_y);
884  }
885  } else if (url) {
886  if (nsoption_bool(display_decoded_idn) == true) {
887  res = nsurl_get_utf8(url, &url_s, &url_l);
888  if (res != NSERROR_OK) {
889  /* Unable to obtain a decoded IDN. This is not
890  * a fatal error. Ensure the string pointer
891  * is NULL so we use the encoded version.
892  */
893  url_s = NULL;
894  }
895  }
896 
897  if (title) {
898  snprintf(status_buffer, sizeof status_buffer, "%s: %s",
899  url_s ? url_s : nsurl_access(url), title);
900  } else {
901  snprintf(status_buffer, sizeof status_buffer, "%s",
902  url_s ? url_s : nsurl_access(url));
903  }
904 
905  status = status_buffer;
906 
907  if (url_s != NULL)
908  free(url_s);
909 
910  pointer = get_pointer_shape(url_box, imagemap);
911 
912  if (mouse & BROWSER_MOUSE_CLICK_1 &&
913  mouse & BROWSER_MOUSE_MOD_1) {
914  /* force download of link */
916  url,
917  content_get_url(c),
919  NULL,
920  NULL,
921  NULL);
922 
923  } else if (mouse & BROWSER_MOUSE_CLICK_2 &&
924  mouse & BROWSER_MOUSE_MOD_1) {
925  msg_data.savelink.url = url;
926  msg_data.savelink.title = title;
928 
929  } else if (mouse & (BROWSER_MOUSE_CLICK_1 |
931  action = ACTION_GO;
932  } else {
933  bool done = false;
934 
935  /* frame resizing */
936  if (browser_window_frame_resize_start(bw, mouse, x, y,
937  &pointer)) {
938  if (mouse & (BROWSER_MOUSE_DRAG_1 |
940  status = messages_get("FrameDrag");
941  }
942  done = true;
943  }
944 
945  /* if clicking in the main page, remove the selection from any
946  * text areas */
947  if (!done) {
948 
949  if (click && html->focus_type != HTML_FOCUS_SELF) {
950  union html_focus_owner fo;
951  fo.self = true;
953  true, 0, 0, 0, NULL);
954  }
955  if (click && html->selection_type !=
957  sel_owner.none = true;
959  sel_owner, true);
960  }
961 
962  if (text_box) {
963  int pixel_offset;
964  size_t idx;
965 
967  text_box->style, &fstyle);
968 
969  guit->layout->position(&fstyle,
970  text_box->text,
971  text_box->length,
972  x - text_box_x,
973  &idx,
974  &pixel_offset);
975 
976  if (selection_click(&html->sel, mouse,
977  text_box->byte_offset + idx)) {
978  /* key presses must be directed at the
979  * main browser window, paste text
980  * operations ignored */
981  html_drag_type drag_type;
982  union html_drag_owner drag_owner;
983 
984  if (selection_dragging(&html->sel)) {
985  drag_type = HTML_DRAG_SELECTION;
986  drag_owner.no_owner = true;
987  html_set_drag_type(html,
988  drag_type,
989  drag_owner,
990  NULL);
991  status = messages_get(
992  "Selecting");
993  }
994 
995  done = true;
996  }
997 
998  } else if (mouse & BROWSER_MOUSE_PRESS_1) {
999  sel_owner.none = true;
1000  selection_clear(&html->sel, true);
1001  }
1002 
1003  if (selection_defined(&html->sel)) {
1004  sel_owner.none = false;
1006  sel_owner, true);
1007  } else if (click && html->selection_type !=
1009  sel_owner.none = true;
1011  sel_owner, true);
1012  }
1013  }
1014 
1015  if (!done) {
1016  if (title)
1017  status = title;
1018 
1019  if (mouse & BROWSER_MOUSE_DRAG_1) {
1020  if (mouse & BROWSER_MOUSE_MOD_2) {
1021  msg_data.dragsave.type =
1022  CONTENT_SAVE_COMPLETE;
1023  msg_data.dragsave.content = NULL;
1026  &msg_data);
1027  } else {
1028  if (drag_candidate == NULL) {
1030  bw, x, y);
1031  } else {
1033  drag_candidate,
1034  x, y);
1035  }
1036  pointer = BROWSER_POINTER_MOVE;
1037  }
1038  }
1039  else if (mouse & BROWSER_MOUSE_DRAG_2) {
1040  if (mouse & BROWSER_MOUSE_MOD_2) {
1041  msg_data.dragsave.type =
1042  CONTENT_SAVE_SOURCE;
1043  msg_data.dragsave.content = NULL;
1046  &msg_data);
1047  } else {
1048  if (drag_candidate == NULL) {
1050  bw, x, y);
1051  } else {
1053  drag_candidate,
1054  x, y);
1055  }
1056  pointer = BROWSER_POINTER_MOVE;
1057  }
1058  }
1059  }
1060  if (mouse && mouse < BROWSER_MOUSE_MOD_1) {
1061  /* ensure key presses still act on the browser window */
1062  union html_focus_owner fo;
1063  fo.self = true;
1064  html_set_focus(html, HTML_FOCUS_SELF, fo,
1065  true, 0, 0, 0, NULL);
1066  }
1067  }
1068 
1069  if (!iframe && !html_object_box) {
1070  msg_data.explicit_status_text = status;
1071  content_broadcast(c, CONTENT_MSG_STATUS, &msg_data);
1072 
1073  msg_data.pointer = pointer;
1074  content_broadcast(c, CONTENT_MSG_POINTER, &msg_data);
1075  }
1076 
1077  /* fire dom click event */
1078  if (mouse & BROWSER_MOUSE_CLICK_1) {
1079  fire_dom_event(corestring_dom_click, node, true, true);
1080  }
1081 
1082  /* deferred actions that can cause this browser_window to be destroyed
1083  * and must therefore be done after set_status/pointer
1084  */
1085  switch (action) {
1086  case ACTION_SUBMIT:
1087  res = form_submit(content_get_url(c),
1088  browser_window_find_target(bw, target, mouse),
1089  gadget->form,
1090  gadget);
1091  break;
1092 
1093  case ACTION_GO:
1095  browser_window_find_target(bw, target, mouse),
1096  url,
1097  content_get_url(c),
1099  NULL,
1100  NULL,
1101  NULL);
1102  break;
1103 
1104  case ACTION_NONE:
1105  res = NSERROR_OK;
1106  break;
1107  }
1108 
1109  if (res != NSERROR_OK) {
1110  NSLOG(netsurf, ERROR, "%s", messages_get_errorcode(res));
1111  }
1112 
1113 }
1114 
1115 
1116 /**
1117  * Handle keypresses.
1118  *
1119  * \param c content of type HTML
1120  * \param key The UCS4 character codepoint
1121  * \return true if key handled, false otherwise
1122  */
1123 
1124 bool html_keypress(struct content *c, uint32_t key)
1125 {
1126  html_content *html = (html_content *) c;
1127  struct selection *sel = &html->sel;
1128 
1129  switch (html->focus_type) {
1130  case HTML_FOCUS_CONTENT:
1131  return content_keypress(html->focus_owner.content->object, key);
1132 
1133  case HTML_FOCUS_TEXTAREA:
1134  if (box_textarea_keypress(html, html->focus_owner.textarea, key) == NSERROR_OK) {
1135  return true;
1136  } else {
1137  return false;
1138  }
1139 
1140  default:
1141  /* Deal with it below */
1142  break;
1143  }
1144 
1145  switch (key) {
1146  case NS_KEY_COPY_SELECTION:
1148  return true;
1149 
1151  selection_clear(sel, true);
1152  return true;
1153 
1154  case NS_KEY_SELECT_ALL:
1155  selection_select_all(sel);
1156  return true;
1157 
1158  case NS_KEY_ESCAPE:
1159  if (selection_defined(sel)) {
1160  selection_clear(sel, true);
1161  return true;
1162  }
1163 
1164  /* if there's no selection, leave Escape for the caller */
1165  return false;
1166  }
1167 
1168  return false;
1169 }
1170 
1171 
1172 /**
1173  * Handle search.
1174  *
1175  * \param c content of type HTML
1176  * \param context front end private data
1177  * \param flags search flags
1178  * \param string search string
1179  */
1180 void
1182  void *context,
1183  search_flags_t flags,
1184  const char *string)
1185 {
1186  html_content *html = (html_content *)c;
1187 
1188  assert(c != NULL);
1189 
1190  if ((string != NULL) &&
1191  (html->search_string != NULL) &&
1192  (strcmp(string, html->search_string) == 0) &&
1193  (html->search != NULL)) {
1194  /* Continue prev. search */
1195  search_step(html->search, flags, string);
1196 
1197  } else if (string != NULL) {
1198  /* New search */
1199  free(html->search_string);
1200  html->search_string = strdup(string);
1201  if (html->search_string == NULL)
1202  return;
1203 
1204  if (html->search != NULL) {
1206  html->search = NULL;
1207  }
1208 
1209  html->search = search_create_context(c, CONTENT_HTML, context);
1210 
1211  if (html->search == NULL)
1212  return;
1213 
1214  search_step(html->search, flags, string);
1215 
1216  } else {
1217  /* Clear search */
1218  html_search_clear(c);
1219 
1220  free(html->search_string);
1221  html->search_string = NULL;
1222  }
1223 }
1224 
1225 
1226 /**
1227  * Terminate a search.
1228  *
1229  * \param c content of type HTML
1230  */
1232 {
1233  html_content *html = (html_content *)c;
1234 
1235  assert(c != NULL);
1236 
1237  free(html->search_string);
1238  html->search_string = NULL;
1239 
1240  if (html->search != NULL) {
1242  }
1243  html->search = NULL;
1244 }
1245 
1246 
1247 /**
1248  * Callback for in-page scrollbars.
1249  */
1250 void html_overflow_scroll_callback(void *client_data,
1251  struct scrollbar_msg_data *scrollbar_data)
1252 {
1253  struct html_scrollbar_data *data = client_data;
1254  html_content *html = (html_content *)data->c;
1255  struct box *box = data->box;
1256  union content_msg_data msg_data;
1257  html_drag_type drag_type;
1258  union html_drag_owner drag_owner;
1259 
1260  switch(scrollbar_data->msg) {
1261  case SCROLLBAR_MSG_MOVED:
1262 
1263  if (html->reflowing == true) {
1264  /* Can't redraw during layout, and it will
1265  * be redrawn after layout anyway. */
1266  break;
1267  }
1268 
1269  html__redraw_a_box(html, box);
1270  break;
1272  {
1273  struct rect rect = {
1274  .x0 = scrollbar_data->x0,
1275  .y0 = scrollbar_data->y0,
1276  .x1 = scrollbar_data->x1,
1277  .y1 = scrollbar_data->y1
1278  };
1279  drag_type = HTML_DRAG_SCROLLBAR;
1280  drag_owner.scrollbar = scrollbar_data->scrollbar;
1281  html_set_drag_type(html, drag_type, drag_owner, &rect);
1282  }
1283  break;
1285  drag_type = HTML_DRAG_NONE;
1286  drag_owner.no_owner = true;
1287  html_set_drag_type(html, drag_type, drag_owner, NULL);
1288 
1289  msg_data.pointer = BROWSER_POINTER_AUTO;
1290  content_broadcast(data->c, CONTENT_MSG_POINTER, &msg_data);
1291  break;
1292  }
1293 }
1294 
1295 
1296 /* Documented in html_internal.h */
1298  union html_drag_owner drag_owner, const struct rect *rect)
1299 {
1300  union content_msg_data msg_data;
1301 
1302  assert(html != NULL);
1303 
1304  html->drag_type = drag_type;
1305  html->drag_owner = drag_owner;
1306 
1307  switch (drag_type) {
1308  case HTML_DRAG_NONE:
1309  assert(drag_owner.no_owner == true);
1310  msg_data.drag.type = CONTENT_DRAG_NONE;
1311  break;
1312 
1313  case HTML_DRAG_SCROLLBAR:
1316  msg_data.drag.type = CONTENT_DRAG_SCROLL;
1317  break;
1318 
1319  case HTML_DRAG_SELECTION:
1320  assert(drag_owner.no_owner == true);
1321  /* Fall through */
1324  msg_data.drag.type = CONTENT_DRAG_SELECTION;
1325  break;
1326  }
1327  msg_data.drag.rect = rect;
1328 
1329  /* Inform of the content's drag status change */
1330  content_broadcast((struct content *)html, CONTENT_MSG_DRAG, &msg_data);
1331 }
1332 
1333 /* Documented in html_internal.h */
1335  union html_focus_owner focus_owner, bool hide_caret,
1336  int x, int y, int height, const struct rect *clip)
1337 {
1338  union content_msg_data msg_data;
1339  int x_off = 0;
1340  int y_off = 0;
1341  struct rect cr;
1342  bool textarea_lost_focus = html->focus_type == HTML_FOCUS_TEXTAREA &&
1343  focus_type != HTML_FOCUS_TEXTAREA;
1344 
1345  assert(html != NULL);
1346 
1347  switch (focus_type) {
1348  case HTML_FOCUS_SELF:
1349  assert(focus_owner.self == true);
1350  if (html->focus_type == HTML_FOCUS_SELF)
1351  /* Don't need to tell anyone anything */
1352  return;
1353  break;
1354 
1355  case HTML_FOCUS_CONTENT:
1356  box_coords(focus_owner.content, &x_off, &y_off);
1357  break;
1358 
1359  case HTML_FOCUS_TEXTAREA:
1360  box_coords(focus_owner.textarea, &x_off, &y_off);
1361  break;
1362  }
1363 
1364  html->focus_type = focus_type;
1365  html->focus_owner = focus_owner;
1366 
1367  if (textarea_lost_focus) {
1368  msg_data.caret.type = CONTENT_CARET_REMOVE;
1369  } else if (focus_type != HTML_FOCUS_SELF && hide_caret) {
1370  msg_data.caret.type = CONTENT_CARET_HIDE;
1371  } else {
1372  if (clip != NULL) {
1373  cr = *clip;
1374  cr.x0 += x_off;
1375  cr.y0 += y_off;
1376  cr.x1 += x_off;
1377  cr.y1 += y_off;
1378  }
1379 
1380  msg_data.caret.type = CONTENT_CARET_SET_POS;
1381  msg_data.caret.pos.x = x + x_off;
1382  msg_data.caret.pos.y = y + y_off;
1383  msg_data.caret.pos.height = height;
1384  msg_data.caret.pos.clip = (clip == NULL) ? NULL : &cr;
1385  }
1386 
1387  /* Inform of the content's drag status change */
1388  content_broadcast((struct content *)html, CONTENT_MSG_CARET, &msg_data);
1389 }
1390 
1391 /* Documented in html_internal.h */
1393  union html_selection_owner selection_owner, bool read_only)
1394 {
1395  union content_msg_data msg_data;
1396  struct box *box;
1397  bool changed = false;
1398  bool same_type = html->selection_type == selection_type;
1399 
1400  assert(html != NULL);
1401 
1402  if ((selection_type == HTML_SELECTION_NONE &&
1403  html->selection_type != HTML_SELECTION_NONE) ||
1404  (selection_type != HTML_SELECTION_NONE &&
1406  /* Existance of selection has changed, and we'll need to
1407  * inform our owner */
1408  changed = true;
1409 
1410  /* Clear any existing selection */
1411  if (html->selection_type != HTML_SELECTION_NONE) {
1412  switch (html->selection_type) {
1413  case HTML_SELECTION_SELF:
1414  if (same_type)
1415  break;
1416  selection_clear(&html->sel, true);
1417  break;
1419  if (same_type && html->selection_owner.textarea ==
1420  selection_owner.textarea)
1421  break;
1422  box = html->selection_owner.textarea;
1423  textarea_clear_selection(box->gadget->data.text.ta);
1424  break;
1426  if (same_type && html->selection_owner.content ==
1427  selection_owner.content)
1428  break;
1429  box = html->selection_owner.content;
1431  break;
1432  default:
1433  break;
1434  }
1435  }
1436 
1437  html->selection_type = selection_type;
1438  html->selection_owner = selection_owner;
1439 
1440  if (!changed)
1441  /* Don't need to report lack of change to owner */
1442  return;
1443 
1444  /* Prepare msg */
1445  switch (selection_type) {
1446  case HTML_SELECTION_NONE:
1447  assert(selection_owner.none == true);
1448  msg_data.selection.selection = false;
1449  break;
1450  case HTML_SELECTION_SELF:
1451  assert(selection_owner.none == false);
1452  /* fall through */
1455  msg_data.selection.selection = true;
1456  break;
1457  default:
1458  break;
1459  }
1460  msg_data.selection.read_only = read_only;
1461 
1462  /* Inform of the content's selection status change */
1464  &msg_data);
1465 }
struct form_control * gadget
Form control data, or 0 if not a form control.
Definition: box.h:260
void selection_clear(struct selection *s, bool redraw)
Clears the current selection, optionally causing the screen to be updated.
Definition: selection.c:888
Definition: box.h:143
const char * target
Link target, or 0.
Definition: box.h:223
const struct rect * rect
Definition: content.h:207
Focus is our own.
Definition: html_internal.h:74
void content_request_redraw(struct hlcache_handle *h, int x, int y, int width, int height)
Request a redraw of an area of a content.
Definition: content.c:511
Definition: box.h:143
struct box * content
Definition: html_internal.h:52
int y1
Bottom right.
Definition: types.h:42
this will form a new history node (don&#39;t set for back/reload/etc)
void html_overflow_scroll_callback(void *client_data, struct scrollbar_msg_data *scrollbar_data)
Callback for in-page scrollbars.
browser_drag_type
type of browser window drag in progess
void search_destroy_context(struct search_context *context)
Ends the search process, invalidating all state freeing the list of found boxes.
Definition: search.c:647
void selection_select_all(struct selection *s)
Selects all the text within the box subtree controlled by this selection object, updating the screen ...
Definition: selection.c:914
struct box_border border[4]
Border: TOP, RIGHT, BOTTOM, LEFT.
Definition: box.h:201
void html__redraw_a_box(struct html_content *html, struct box *box)
Redraw a box.
Definition: html.c:1636
browser_mouse_state
Mouse state.
Definition: mouse.h:43
char * action
Absolute URL to submit to.
void form_select_get_dimensions(struct form_control *control, int *width, int *height)
Get the dimensions of a select menu.
Definition: form.c:2064
struct content_msg_data::@109 savelink
CONTENT_MSG_SAVELINK - Save a URL.
struct nsurl * href
Link, or 0.
Definition: box.h:222
Localised message support (interface).
#define SCROLLBAR_WIDTH
Definition: scrollbar.h:32
void content_mouse_action(hlcache_handle *h, struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle mouse clicks and movements in a content window.
Definition: content.c:469
Not own; drag in textarea widget.
Definition: html_internal.h:42
Interface to form handling functions internal to HTML content handler.
Interface to platform-specific layout operation table.
struct form_textarea_data data
Public content interface.
A gadget has been clicked on (mainly for file)
Definition: content.h:85
int padding[4]
Padding: TOP, RIGHT, BOTTOM, LEFT.
Definition: box.h:200
nserror box_textarea_keypress(html_content *html, struct box *box, uint32_t key)
Handle form textarea keypress input.
Definition: box_textarea.c:41
struct form_control * visible_select_menu
Open core-handled form SELECT menu, or NULL if none currently open.
static void html_box_drag_start(struct box *box, int x, int y)
Start drag scrolling the contents of a box.
void scrollbar_start_content_drag(struct scrollbar *s, int x, int y)
Called when the content is being dragged to the scrollbars have to adjust.
Definition: scrollbar.c:991
const char * scrollbar_mouse_status_to_message(scrollbar_mouse_status status)
Get a status bar message from a scrollbar mouse input status.
Definition: scrollbar.c:899
html_drag_type drag_type
Current drag type.
size_t byte_offset
Definition: box.h:214
float browser_window_get_scale(struct browser_window *bw)
Gets the scale of a browser window.
struct scrollbar * scroll_x
Horizontal scroll.
Definition: box.h:203
char * target
Target to submit to.
#define selection_defined(s)
Definition: selection.h:75
Definition: box.h:143
Core mouse and pointer states.
struct content_msg_data::@111::@117 pos
With CONTENT_CARET_SET_POS.
Focus belongs to child content.
Definition: html_internal.h:75
Own; Text selection.
Definition: html_internal.h:40
Interface to platform-specific miscellaneous browser operation table.
struct content_msg_data::@111 caret
CONTENT_MSG_CARET - set caret position or, hide caret.
struct box * content
Definition: html_internal.h:85
static browser_pointer_shape get_pointer_shape(struct box *box, bool imagemap)
Get pointer shape for given box.
void html_search(struct content *c, void *context, search_flags_t flags, const char *string)
Handle search.
struct form * form
Containing form.
Definition: form_internal.h:81
button 1 clicked.
Definition: mouse.h:55
int x
Coordinate of left padding edge relative to parent box, or relative to ancestor that contains this bo...
Definition: box.h:173
struct search_context * search_create_context(struct content *c, content_type type, void *gui_data)
create a search_context
Definition: search.c:79
struct box * layout
Box tree, or NULL.
browser_pointer_shape
Mouse pointer type.
Definition: mouse.h:112
bool textarea_clear_selection(struct textarea *ta)
Clear any selection in the textarea.
Definition: textarea.c:3116
void html_mouse_track(struct content *c, struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle mouse tracking (including drags) in an HTML content window.
html_focus_type focus_type
Current input focus target type.
High-level resource cache interface.
int y
Coordinate of top padding edge, relative as for x.
Definition: box.h:175
struct scrollbar * scroll_y
Vertical scroll.
Definition: box.h:204
bool selection_copy_to_clipboard(struct selection *s)
Copy the selected contents to the clipboard.
Definition: selection.c:850
scrollbar message context data
Definition: scrollbar.h:58
union html_drag_owner drag_owner
Widget capturing all mouse events.
void * scrollbar_get_data(struct scrollbar *s)
Get the scrollbar&#39;s client data.
Definition: scrollbar.c:1014
#define selection_dragging(s)
Definition: selection.h:78
nserror form_open_select_menu(void *client_data, struct form_control *control, select_menu_redraw_callback callback, struct content *c)
Open a select menu for a select form control, creating it if necessary.
Definition: form.c:1490
const char * title
Definition: content.h:177
Caret movement / hiding.
Definition: content.h:82
Interface to key press operations.
Option reading and saving interface.
#define selection_dragging_start(s)
Definition: selection.h:81
int scrollbar_get_offset(struct scrollbar *s)
Get the current scroll offset to the visible part of the full area.
Definition: scrollbar.c:638
Allow URL to be saved.
Definition: content.h:79
void content_clear_selection(hlcache_handle *h)
Tell a content that any selection it has, or one of its objects has, must be cleared.
Definition: content.c:893
form_control_type type
Type of control.
Definition: form_internal.h:79
nserror
Enumeration of error codes.
Definition: errors.h:29
button 2 pressed
Definition: mouse.h:52
Hover: caret pointer.
Definition: textarea.h:133
nsurl * content_get_url(struct content *c)
Retrieve URL associated with content.
Definition: content.c:1114
struct hlcache_handle * browser_window_get_content(struct browser_window *bw)
Get a cache handle for the content within a browser window.
High-level cache handle.
Definition: hlcache.c:64
size_t length
Length of text.
Definition: box.h:217
struct hlcache_handle * content
if NULL, save the content generating the message
Definition: content.h:172
bool browser_window_frame_resize_start(struct browser_window *bw, browser_mouse_state mouse, int x, int y, browser_pointer_shape *pointer)
Definition: frames.c:961
struct form_control * gadget
Definition: content.h:211
struct content * c
Definition: html_internal.h:89
struct box * box_at_point(const nscss_len_ctx *len_ctx, struct box *box, const int x, const int y, int *box_x, int *box_y)
Find the boxes at a point.
Definition: box.c:691
void html_mouse_action(struct content *c, struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle mouse clicks and movements in an HTML content window.
void browser_window_get_position(struct browser_window *bw, bool root, int *pos_x, int *pos_y)
Get the position of the current browser window with respect to the root or parent browser window...
Useful interned string pointers (interface).
nserror form_submit(nsurl *page_url, struct browser_window *target, struct form *form, struct form_control *submit_button)
navigate browser window based on form submission.
Definition: form.c:2134
Corresponds to a single URL.
scrollbar_msg msg
Definition: scrollbar.h:60
struct dom_node * node
DOM node that generated this box or NULL.
Definition: box.h:276
Private data for text/html content.
html_selection_type
Definition: html_internal.h:57
2nd modifier key pressed (eg.
Definition: mouse.h:80
struct content_msg_data::@113 select_menu
CONTENT_MSG_SELECTMENU - Create select menu at pointer.
struct content_msg_data::@112 drag
CONTENT_MSG_DRAG - Drag start or end.
bool reflowing
Whether a layout (reflow) is in progress.
Selection in one of our textareas.
Definition: html_internal.h:60
struct nsurl * url
Definition: content.h:176
No error.
Definition: errors.h:30
Font style for plotting.
Definition: plot_style.h:111
html_selection_type selection_type
Current selection state.
textarea_mouse_status
Text area mouse input status flags.
Definition: textarea.h:130
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:115
browser_pointer_shape pointer
CONTENT_MSG_POINTER - Mouse pointer to set.
Definition: content.h:180
void browser_window_page_drag_start(struct browser_window *bw, int x, int y)
Start drag scrolling the contents of the browser window.
Internal font handling interfaces.
Single/Multi-line UTF-8 text area interface.
const char * form_select_mouse_action(struct form_control *control, browser_mouse_state mouse, int x, int y)
Handle mouse action for the currently opened select menu.
Definition: form.c:1923
Not own; drag in child content.
Definition: html_internal.h:44
Allow drag saving of content.
Definition: content.h:78
A selection made or cleared.
Definition: content.h:81
Selection in this html content.
Definition: html_internal.h:61
void html_set_drag_type(html_content *html, html_drag_type drag_type, union html_drag_owner drag_owner, const struct rect *rect)
Set our drag status, and inform whatever owns the content.
struct content_msg_data::@108 dragsave
CONTENT_MSG_DRAGSAVE - Drag save a content.
int x1
Definition: types.h:42
a scrollbar drag has started, all mouse events should be passed to the scrollbar regardless of the co...
Definition: scrollbar.h:47
Box tree construction and manipulation (interface).
char * search_string
Search string or NULL.
bool selection
false for selection cleared
Definition: content.h:183
int y0
Top left.
Definition: types.h:41
browser_drag_type browser_window_get_drag_type(struct browser_window *bw)
Get type of any current drag for a browser window.
struct content * c
Definition: selection.h:45
Focus belongs to textarea.
Definition: html_internal.h:76
int x
Carret x-coord.
Definition: content.h:133
Not own; drag in scrollbar widget.
Definition: html_internal.h:41
bool scrollbar_is_horizontal(struct scrollbar *s)
Check orientation of the scrollbar.
Definition: scrollbar.c:705
nserror browser_window_navigate(struct browser_window *bw, struct nsurl *url, struct nsurl *referrer, enum browser_window_nav_flags flags, char *post_urlenc, struct fetch_multipart_data *post_multipart, struct hlcache_handle *parent)
Start fetching a page in a browser window.
html_focus_type
Definition: html_internal.h:73
const char * title
Title, or 0.
Definition: box.h:224
button 1 pressed
Definition: mouse.h:50
For drags we don&#39;t own.
Definition: html_internal.h:50
void search_step(struct search_context *context, search_flags_t flags, const char *string)
Begins/continues the search process.
Definition: search.c:591
new status string
Definition: content.h:69
Interface to javascript engine functions.
start of button 2 drag
Definition: mouse.h:67
For directing input.
Definition: html_internal.h:82
void scrollbar_mouse_drag_end(struct scrollbar *s, browser_mouse_state mouse, int x, int y)
Handle end of mouse drags.
Definition: scrollbar.c:943
Definition: box.h:143
void form_select_mouse_drag_end(struct form_control *control, browser_mouse_state mouse, int x, int y)
Handle mouse drag end for the currently opened select menu.
Definition: form.c:1977
struct box * textarea
Definition: html_internal.h:84
A drag started or ended.
Definition: content.h:83
struct search_context * search
Context for free text search, or NULL if none.
Form control.
Definition: form_internal.h:73
void content_broadcast(struct content *c, content_msg msg, const union content_msg_data *data)
Send a message to all users.
Definition: content.c:786
struct box * box
Definition: html_internal.h:90
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Definition: messages.c:241
struct box * children
First child box, or 0.
Definition: box.h:232
search_flags_t
Definition: search.h:27
enum content_msg_data::@108::@115 type
nserror nsurl_get_utf8(const nsurl *url, char **url_s, size_t *url_l)
Get a UTF-8 string (for human readable IDNs) from a NetSurf URL object.
int height
Definition: gui.c:180
static void html_overflow_scroll_drag_end(struct scrollbar *scrollbar, browser_mouse_state mouse, int x, int y)
End overflow scroll scrollbar drags.
int width
border-width (pixels)
Definition: box.h:151
union html_focus_owner focus_owner
Current input focus target.
textarea_mouse_status textarea_mouse_action(struct textarea *ta, browser_mouse_state mouse, int x, int y)
Handles all kinds of mouse action.
Definition: textarea.c:2980
int height
Height of content box (excluding padding etc.).
Definition: box.h:178
Not own; drag in textarea widget.
Definition: html_internal.h:43
Frame and frameset creation and manipulation (interface).
box_type type
Type of box.
Definition: box.h:157
Rectangle coordinates.
Definition: types.h:40
struct rect rect
Rectangle coordinates.
union html_selection_owner selection_owner
Current selection owner.
void browser_window_mouse_click(struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle mouse clicks in a browser window.
nserror(* position)(const struct plot_font_style *fstyle, const char *string, size_t length, int x, size_t *char_offset, int *actual_x)
Find the position in a string where an x coordinate falls.
Definition: layout.h:63
bool fire_dom_event(dom_string *type, dom_node *target, bool bubbles, bool cancelable)
Construct an event and fire it at the DOM.
Definition: html.c:80
Scrollbar context.
Definition: scrollbar.c:43
char * text
Text, or 0 if none.
Definition: box.h:216
content_type content_get_type(struct hlcache_handle *h)
Retrieve computed type of content.
Definition: content.c:1124
scrollbar_mouse_status scrollbar_mouse_action(struct scrollbar *s, browser_mouse_state mouse, int x, int y)
Handle mouse actions other then drag ends.
Definition: scrollbar.c:779
int width
Width of content box (excluding padding etc.).
Definition: box.h:177
struct hlcache_handle * object
Object in this box (usually an image), or 0 if none.
Definition: box.h:269
Interface to HTML searching.
int y
Carret y-coord.
Definition: content.h:133
struct selection sel
HTML content&#39;s own text selection object.
int x0
Definition: types.h:41
bool selection_click(struct selection *s, browser_mouse_state mouse, unsigned idx)
Handles mouse clicks (including drag starts) in or near a selection.
Definition: selection.c:268
static void html__image_coords_dom_user_data_handler(dom_node_operation operation, dom_string *key, void *_data, struct dom_node *src, struct dom_node *dst)
Helper for file gadgets to store their filename.
Interface to a number of general purpose functionality.
Browser window creation and manipulation interface.
content is HTML
Definition: content_type.h:48
void box_coords(struct box *box, int *x, int *y)
Find the absolute coordinates of a box.
Definition: box.c:304
struct box * box
Box for control.
Definition: form_internal.h:89
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
int margin[4]
Margin: TOP, RIGHT, BOTTOM, LEFT.
Definition: box.h:199
Text selection within browser windows (interface).
const char * explicit_status_text
CONTENT_MSG_STATUS - Status message update.
Definition: content.h:142
void * node
Corresponding DOM node.
Definition: form_internal.h:74
struct box * content
Definition: html_internal.h:70
bool selected
Whether control is selected.
Definition: form_internal.h:94
struct box * textarea
Definition: html_internal.h:69
download rather than render the uri
nscss_len_ctx len_ctx
CSS length conversion context for document.
Browser window data.
nsurl * imagemap_get(struct html_content *c, const char *key, unsigned long x, unsigned long y, unsigned long click_x, unsigned long click_y, const char **target)
Retrieve url associated with imagemap entry.
Definition: imagemap.c:736
struct box * textarea
Definition: html_internal.h:54
struct box * box_pick_text_box(struct html_content *html, int x, int y, int dir, int *dx, int *dy)
Peform pick text on browser window contents to locate the box under the mouse pointer, or nearest in the given direction if the pointer is not over a text box.
Definition: box.c:898
the scroll value has changed
Definition: scrollbar.h:46
void browser_window_mouse_track(struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle non-click mouse action in a browser window.
void html_set_focus(html_content *html, html_focus_type focus_type, union html_focus_owner focus_owner, bool hide_caret, int x, int y, int height, const struct rect *clip)
Set our input focus, and inform whatever owns the content.
Wants a specific mouse pointer set.
Definition: content.h:80
Scrollbar widget interface.
void html_search_clear(struct content *c)
Terminate a search.
const char * messages_get_errorcode(nserror code)
lookup of a message by errorcode from the standard Messages hash.
Definition: messages.c:248
struct content_msg_data::@114 gadget_click
CONTENT_MSG_GADGETCLICK - User clicked on a form gadget.
void selection_track(struct selection *s, browser_mouse_state mouse, unsigned idx)
Handles movements related to the selection, eg.
Definition: selection.c:365
button 2 clicked.
Definition: mouse.h:57
void form_radio_set(struct form_control *radio)
Set a radio form control and clear the others in the group.
Definition: form.c:2099
struct browser_window * browser_window_find_target(struct browser_window *bw, const char *target, browser_mouse_state mouse)
Locate a browser window in the specified stack according.
Data specific to CONTENT_HTML.
Definition: html_internal.h:96
struct scrollbar * scrollbar
Definition: scrollbar.h:59
int width
Definition: gui.c:179
Create a select menu.
Definition: content.h:84
1st modifier key pressed (eg.
Definition: mouse.h:78
struct scrollbar * scrollbar
Definition: html_internal.h:53
void content_mouse_track(hlcache_handle *h, struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle mouse movements in a content window.
Definition: content.c:434
start of button 1 drag
Definition: mouse.h:65
struct html_content * html
HTML content containing control.
Definition: form_internal.h:77
static size_t html_selection_drag_end(struct html_content *html, browser_mouse_state mouse, int x, int y, int dir)
End overflow scroll scrollbar drags.
static nserror clip(const struct redraw_context *ctx, const struct rect *clip)
Sets a clip rectangle for subsequent plot operations.
Definition: plot.c:357
Interface to core interface table.
css_computed_style * style
Style for this box.
Definition: box.h:169
struct netsurf_table * guit
The global interface table.
Definition: gui_factory.c:46
void html_set_selection(html_content *html, html_selection_type selection_type, union html_selection_owner selection_owner, bool read_only)
Set our selection status, and inform whatever owns the content.
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
For getting at selections in this content or things in this content.
Definition: html_internal.h:67
bool content_keypress(struct hlcache_handle *h, uint32_t key)
Handle keypresses.
Definition: content.c:490
#define nsoption_bool(OPTION)
Get the value of a boolean option.
Definition: nsoption.h:270
void font_plot_style_from_css(const nscss_len_ctx *len_ctx, const css_computed_style *css, plot_font_style_t *fstyle)
Populate a font style using data from a computed CSS style.
Definition: font.c:135
Extra data for some content_msg messages.
Definition: content.h:102
html_drag_type
Definition: html_internal.h:37
struct browser_window * iframe
Iframe&#39;s browser_window, or NULL if none.
Definition: box.h:274
Box tree treeview box replacement (interface).
struct gui_layout_table * layout
Layout table.
Definition: gui_table.h:154
void form_select_menu_callback(void *client_data, int x, int y, int width, int height)
Callback for the core select menu.
Definition: form.c:2074
bool html_keypress(struct content *c, uint32_t key)
Handle keypresses.
char * usemap
Definition: box.h:262
Node in box tree.
Definition: box.h:155
cancel a scrollbar drag
Definition: scrollbar.h:52
Interface to HTML imagemap.