From b9bc34b8753d2b67f049ea1773dc0004a2d93eb9 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Tue, 12 Nov 2019 18:34:39 +0000 Subject: [PATCH] split out html interaction header elements and rename source --- content/handlers/html/Makefile | 2 +- content/handlers/html/box.c | 3 + content/handlers/html/html.c | 1 + content/handlers/html/html_internal.h | 20 +- .../{html_interaction.c => interaction.c} | 325 +++++++++++------- content/handlers/html/interaction.h | 77 +++++ 6 files changed, 279 insertions(+), 149 deletions(-) rename content/handlers/html/{html_interaction.c => interaction.c} (88%) create mode 100644 content/handlers/html/interaction.h diff --git a/content/handlers/html/Makefile b/content/handlers/html/Makefile index afefba27d..6b4c1e8ee 100644 --- a/content/handlers/html/Makefile +++ b/content/handlers/html/Makefile @@ -3,5 +3,5 @@ S_HTML := box.c box_construct.c box_normalise.c box_textarea.c \ font.c form.c imagemap.c layout.c search.c table.c \ html.c html_css.c html_css_fetcher.c html_script.c \ - html_interaction.c html_redraw.c html_redraw_border.c \ + interaction.c html_redraw.c html_redraw_border.c \ html_forms.c html_object.c diff --git a/content/handlers/html/box.c b/content/handlers/html/box.c index 475e86b47..94c74877f 100644 --- a/content/handlers/html/box.c +++ b/content/handlers/html/box.c @@ -33,6 +33,7 @@ #include "utils/nsoption.h" #include "utils/log.h" #include "utils/talloc.h" +#include "utils/nsurl.h" #include "netsurf/misc.h" #include "netsurf/content.h" #include "netsurf/mouse.h" @@ -40,10 +41,12 @@ #include "css/dump.h" #include "desktop/scrollbar.h" #include "desktop/gui_internal.h" +#include "desktop/search.h" #include "html/box.h" #include "html/form_internal.h" #include "html/html_internal.h" +#include "html/interaction.h" #define box_is_float(box) (box->type == BOX_FLOAT_LEFT || \ box->type == BOX_FLOAT_RIGHT) diff --git a/content/handlers/html/html.c b/content/handlers/html/html.c index 88c77fdd0..25633a875 100644 --- a/content/handlers/html/html.c +++ b/content/handlers/html/html.c @@ -57,6 +57,7 @@ #include "html/html.h" #include "html/html_save.h" #include "html/html_internal.h" +#include "html/interaction.h" #include "html/box.h" #include "html/form_internal.h" #include "html/imagemap.h" diff --git a/content/handlers/html/html_internal.h b/content/handlers/html/html_internal.h index fd6354a5a..388c1558d 100644 --- a/content/handlers/html/html_internal.h +++ b/content/handlers/html/html_internal.h @@ -31,8 +31,10 @@ #include "content/content_protected.h" #include "desktop/selection.h" + struct gui_layout_table; struct scrollbar_msg_data; +struct content_redraw_data; typedef enum { HTML_DRAG_NONE, /** No drag */ @@ -85,11 +87,6 @@ union html_focus_owner { struct box *content; }; -struct html_scrollbar_data { - struct content *c; - struct box *box; -}; - /** * Data specific to CONTENT_HTML. */ @@ -300,19 +297,6 @@ bool html_redraw_inline_borders(struct box *box, struct rect b, const struct rect *clip, float scale, bool first, bool last, const struct redraw_context *ctx); -/* in html/html_interaction.c */ -void html_mouse_track(struct content *c, struct browser_window *bw, - browser_mouse_state mouse, int x, int y); -void html_mouse_action(struct content *c, struct browser_window *bw, - browser_mouse_state mouse, int x, int y); -bool html_keypress(struct content *c, uint32_t key); -void html_overflow_scroll_callback(void *client_data, - struct scrollbar_msg_data *scrollbar_data); -void html_search(struct content *c, void *context, - search_flags_t flags, const char *string); -void html_search_clear(struct content *c); - - /* in html/html_script.c */ dom_hubbub_error html_process_script(void *ctx, dom_node *node); diff --git a/content/handlers/html/html_interaction.c b/content/handlers/html/interaction.c similarity index 88% rename from content/handlers/html/html_interaction.c rename to content/handlers/html/interaction.c index 4de15f872..f3f8b566f 100644 --- a/content/handlers/html/html_interaction.c +++ b/content/handlers/html/interaction.c @@ -55,6 +55,7 @@ #include "html/html_internal.h" #include "html/imagemap.h" #include "html/search.h" +#include "html/interaction.h" /** * Get pointer shape for given box @@ -220,22 +221,6 @@ static size_t html_selection_drag_end(struct html_content *html, } -/** - * Handle mouse tracking (including drags) in an HTML content window. - * - * \param c content of type html - * \param bw browser window - * \param mouse state of mouse buttons and modifier keys - * \param x coordinate of mouse - * \param y coordinate of mouse - */ - -void html_mouse_track(struct content *c, struct browser_window *bw, - browser_mouse_state mouse, int x, int y) -{ - html_mouse_action(c, bw, mouse, x, y); -} - /** * Helper for file gadgets to store their filename. * @@ -334,23 +319,200 @@ html_overflow_scroll_drag_end(struct scrollbar *scrollbar, /** - * Handle mouse clicks and movements in an HTML content window. + * handle html mouse action when select menu is open * - * \param c content of type html - * \param bw browser window - * \param mouse state of mouse buttons and modifier keys - * \param x coordinate of mouse - * \param y coordinate of mouse - * - * This function handles both hovering and clicking. It is important that the - * code path is identical (except that hovering doesn't carry out the action), - * so that the status bar reflects exactly what will happen. Having separate - * code paths opens the possibility that an attacker will make the status bar - * show some harmless action where clicking will be harmful. */ +static nserror +mouse_action_select_menu(html_content *html, + struct browser_window *bw, + browser_mouse_state mouse, + int x, int y) +{ + struct box *box; + int box_x = 0; + int box_y = 0; + const char *status; + int width, height; + struct hlcache_handle *bw_content; -void html_mouse_action(struct content *c, struct browser_window *bw, - browser_mouse_state mouse, int x, int y) + assert(html->visible_select_menu != NULL); + + box = html->visible_select_menu->box; + box_coords(box, &box_x, &box_y); + + box_x -= box->border[LEFT].width; + box_y += box->height + box->border[BOTTOM].width + + box->padding[BOTTOM] + box->padding[TOP]; + + status = form_select_mouse_action(html->visible_select_menu, + mouse, + x - box_x, + y - box_y); + if (status != NULL) { + /* set status if menu still open */ + union content_msg_data msg_data; + msg_data.explicit_status_text = status; + content_broadcast((struct content *)html, + CONTENT_MSG_STATUS, + &msg_data); + return NSERROR_OK; + } + + /* close menu and redraw where it was */ + form_select_get_dimensions(html->visible_select_menu, &width, &height); + + html->visible_select_menu = NULL; + + bw_content = browser_window_get_content(bw); + content_request_redraw(bw_content, + box_x, + box_y, + width, + height); + return NSERROR_OK; +} + + +/** + * handle html mouse action when a selection drag is being performed + * + */ +static nserror +mouse_action_drag_selection(html_content *html, + struct browser_window *bw, + browser_mouse_state mouse, + int x, int y) +{ + struct box *box; + int dir = -1; + int dx, dy; + size_t idx; + union html_drag_owner drag_owner; + int pixel_offset; + plot_font_style_t fstyle; + + if (!mouse) { + /* End of selection drag */ + if (selection_dragging_start(&html->sel)) { + dir = 1; + } + + idx = html_selection_drag_end(html, mouse, x, y, dir); + + if (idx != 0) { + selection_track(&html->sel, mouse, idx); + } + + drag_owner.no_owner = true; + html_set_drag_type(html, HTML_DRAG_NONE, drag_owner, NULL); + + return NSERROR_OK; + } + + if (selection_dragging_start(&html->sel)) { + dir = 1; + } + + box = box_pick_text_box(html, x, y, dir, &dx, &dy); + if (box != NULL) { + font_plot_style_from_css(&html->len_ctx, box->style, &fstyle); + + guit->layout->position(&fstyle, + box->text, + box->length, + dx, + &idx, + &pixel_offset); + + selection_track(&html->sel, mouse, box->byte_offset + idx); + } + return NSERROR_OK; +} + + +/** + * handle html mouse action when a scrollbar drag is being performed + * + */ +static nserror +mouse_action_drag_scrollbar(html_content *html, + struct browser_window *bw, + browser_mouse_state mouse, + int x, int y) +{ + struct scrollbar *scr; + struct html_scrollbar_data *data; + struct box *box; + int box_x = 0; + int box_y = 0; + const char *status; + int scroll_mouse_x = 0, scroll_mouse_y = 0; + scrollbar_mouse_status scrollbar_status; + + scr = html->drag_owner.scrollbar; + + if (!mouse) { + /* drag end: scrollbar */ + html_overflow_scroll_drag_end(scr, mouse, x, y); + } + + data = scrollbar_get_data(scr); + + box = data->box; + + box_coords(box, &box_x, &box_y); + + if (scrollbar_is_horizontal(scr)) { + scroll_mouse_x = x - box_x ; + scroll_mouse_y = y - (box_y + box->padding[TOP] + + box->height + box->padding[BOTTOM] - + SCROLLBAR_WIDTH); + scrollbar_status = scrollbar_mouse_action(scr, + mouse, + scroll_mouse_x, + scroll_mouse_y); + } else { + scroll_mouse_x = x - (box_x + box->padding[LEFT] + + box->width + box->padding[RIGHT] - + SCROLLBAR_WIDTH); + scroll_mouse_y = y - box_y; + + scrollbar_status = scrollbar_mouse_action(scr, + mouse, + scroll_mouse_x, + scroll_mouse_y); + } + status = scrollbar_mouse_status_to_message(scrollbar_status); + + if (status != NULL) { + union content_msg_data msg_data; + + msg_data.explicit_status_text = status; + content_broadcast((struct content *)html, + CONTENT_MSG_STATUS, + &msg_data); + } + + return NSERROR_OK; +} + + +/* exported interface documented in html/interaction.h */ +nserror html_mouse_track(struct content *c, + struct browser_window *bw, + browser_mouse_state mouse, + int x, int y) +{ + return html_mouse_action(c, bw, mouse, x, y); +} + + +/* exported interface documented in html/interaction.h */ +nserror +html_mouse_action(struct content *c, + struct browser_window *bw, + browser_mouse_state mouse, + int x, int y) { html_content *html = (html_content *) c; enum { ACTION_NONE, ACTION_SUBMIT, ACTION_GO } action = ACTION_NONE; @@ -383,7 +545,6 @@ void html_mouse_action(struct content *c, struct browser_window *bw, browser_drag_type drag_type = browser_window_get_drag_type(bw); union content_msg_data msg_data; struct dom_node *node = html->layout->node; /* Default to the */ - union html_drag_owner drag_owner; union html_selection_owner sel_owner; bool click = mouse & (BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_PRESS_2 | BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_CLICK_2 | @@ -399,112 +560,16 @@ void html_mouse_action(struct content *c, struct browser_window *bw, } if (html->visible_select_menu != NULL) { - box = html->visible_select_menu->box; - box_coords(box, &box_x, &box_y); - - box_x -= box->border[LEFT].width; - box_y += box->height + box->border[BOTTOM].width + - box->padding[BOTTOM] + box->padding[TOP]; - status = form_select_mouse_action(html->visible_select_menu, - mouse, x - box_x, y - box_y); - if (status != NULL) { - msg_data.explicit_status_text = status; - content_broadcast(c, CONTENT_MSG_STATUS, &msg_data); - } else { - int width, height; - struct hlcache_handle *bw_content; - form_select_get_dimensions(html->visible_select_menu, - &width, &height); - html->visible_select_menu = NULL; - bw_content = browser_window_get_content(bw); - content_request_redraw(bw_content,box_x, box_y, - width, height); - } - return; + return mouse_action_select_menu(html, bw, mouse, x, y); } if (html->drag_type == HTML_DRAG_SELECTION) { - /* Selection drag */ - struct box *box; - int dir = -1; - int dx, dy; - - if (!mouse) { - /* End of selection drag */ - int dir = -1; - size_t idx; - - if (selection_dragging_start(&html->sel)) - dir = 1; - - idx = html_selection_drag_end(html, mouse, x, y, dir); - - if (idx != 0) - selection_track(&html->sel, mouse, idx); - - drag_owner.no_owner = true; - html_set_drag_type(html, HTML_DRAG_NONE, - drag_owner, NULL); - return; - } - - if (selection_dragging_start(&html->sel)) - dir = 1; - - box = box_pick_text_box(html, x, y, dir, &dx, &dy); - - if (box != NULL) { - int pixel_offset; - size_t idx; - plot_font_style_t fstyle; - - font_plot_style_from_css(&html->len_ctx, - box->style, &fstyle); - - guit->layout->position(&fstyle, - box->text, box->length, - dx, &idx, &pixel_offset); - - selection_track(&html->sel, mouse, - box->byte_offset + idx); - } - return; + return mouse_action_drag_selection(html, bw, mouse, x, y); } if (html->drag_type == HTML_DRAG_SCROLLBAR) { - struct scrollbar *scr = html->drag_owner.scrollbar; - struct html_scrollbar_data *data = scrollbar_get_data(scr); + return mouse_action_drag_scrollbar(html, bw, mouse, x, y); - if (!mouse) { - /* drag end: scrollbar */ - html_overflow_scroll_drag_end(scr, mouse, x, y); - } - - box = data->box; - box_coords(box, &box_x, &box_y); - if (scrollbar_is_horizontal(scr)) { - scroll_mouse_x = x - box_x ; - scroll_mouse_y = y - (box_y + box->padding[TOP] + - box->height + box->padding[BOTTOM] - - SCROLLBAR_WIDTH); - status = scrollbar_mouse_status_to_message( - scrollbar_mouse_action(scr, mouse, - scroll_mouse_x, - scroll_mouse_y)); - } else { - scroll_mouse_x = x - (box_x + box->padding[LEFT] + - box->width + box->padding[RIGHT] - - SCROLLBAR_WIDTH); - scroll_mouse_y = y - box_y; - status = scrollbar_mouse_status_to_message( - scrollbar_mouse_action(scr, mouse, - scroll_mouse_x, - scroll_mouse_y)); - } - - msg_data.explicit_status_text = status; - content_broadcast(c, CONTENT_MSG_STATUS, &msg_data); - return; } if (html->drag_type == HTML_DRAG_TEXTAREA_SELECTION || diff --git a/content/handlers/html/interaction.h b/content/handlers/html/interaction.h new file mode 100644 index 000000000..c1339c01e --- /dev/null +++ b/content/handlers/html/interaction.h @@ -0,0 +1,77 @@ +/* + * Copyright 2004 James Bursa + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file + * HTML content user interaction handling + */ + +#ifndef NETSURF_HTML_INTERACTION_H +#define NETSURF_HTML_INTERACTION_H + +/** + * Context for scrollbar + */ +struct html_scrollbar_data { + struct content *c; + struct box *box; +}; + +/** + * Handle mouse tracking (including drags) in an HTML content window. + * + * \param c content of type html + * \param bw browser window + * \param mouse state of mouse buttons and modifier keys + * \param x coordinate of mouse + * \param y coordinate of mouse + */ +nserror html_mouse_track(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. + * + * This function handles both hovering and clicking. It is important that the + * code path is identical (except that hovering doesn't carry out the action), + * so that the status bar reflects exactly what will happen. Having separate + * code paths opens the possibility that an attacker will make the status bar + * show some harmless action where clicking will be harmful. + * + * \param c content of type html + * \param bw browser window + * \param mouse state of mouse buttons and modifier keys + * \param x x coordinate of mouse + * \param y y coordinate of mouse + * \return NSERROR_OK or appropriate error code. + */ +nserror html_mouse_action(struct content *c, struct browser_window *bw, + browser_mouse_state mouse, int x, int y); + +bool html_keypress(struct content *c, uint32_t key); + +void html_overflow_scroll_callback(void *client_data, + struct scrollbar_msg_data *scrollbar_data); + +void html_search(struct content *c, void *context, + search_flags_t flags, const char *string); + +void html_search_clear(struct content *c); + +#endif