From a8c540ea597fb17426c5458fa464f9c505c3bda8 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sat, 23 May 2020 22:00:00 +0100 Subject: move content specific selection end to content handlers --- content/content_protected.h | 9 ++++++ content/handlers/html/html.c | 5 ++-- content/handlers/html/textselection.c | 47 +++++++++++++++++++++++++++++-- content/handlers/html/textselection.h | 9 ++++++ content/handlers/text/textplain.c | 12 ++++++-- desktop/selection.c | 53 ++++------------------------------- desktop/selection.h | 6 ++-- 7 files changed, 84 insertions(+), 57 deletions(-) diff --git a/content/content_protected.h b/content/content_protected.h index 02bc8614d..b855c7701 100644 --- a/content/content_protected.h +++ b/content/content_protected.h @@ -130,6 +130,15 @@ struct content_handler { */ nserror (*textselection_copy)(struct content *c, unsigned start_idx, unsigned end_idx, struct selection_string *selstr); + /** + * get maximum index of text section. + * + * \param[in] c The content to measure + * \param[out] end_idx pointer to value to recive result + * \return NSERROR_OK and \a end_idx updated else error code + */ + nserror (*textselection_get_end)(struct content *c, unsigned *end_idx); + /** * create a selection object */ diff --git a/content/handlers/html/html.c b/content/handlers/html/html.c index 136c4eef2..2c471ae40 100644 --- a/content/handlers/html/html.c +++ b/content/handlers/html/html.c @@ -1056,7 +1056,7 @@ static void html_reformat(struct content *c, int width, int height) if (c->height < layout->y + layout->descendant_y1) c->height = layout->y + layout->descendant_y1; - selection_reinit(&htmlc->sel, htmlc->layout); + selection_reinit(&htmlc->sel); htmlc->reflowing = false; htmlc->had_initial_layout = true; @@ -1304,7 +1304,7 @@ html_open(struct content *c, html->drag_owner.no_owner = true; /* text selection */ - selection_init(&html->sel, html->layout); + selection_init(&html->sel); html->selection_type = HTML_SELECTION_NONE; html->selection_owner.none = true; @@ -2337,6 +2337,7 @@ static const content_handler html_content_handler = { .textsearch_bounds = html_textsearch_bounds, .textselection_redraw = html_textselection_redraw, .textselection_copy = html_textselection_copy, + .textselection_get_end = html_textselection_get_end, .create_selection = html_create_selection, .no_share = true, }; diff --git a/content/handlers/html/textselection.c b/content/handlers/html/textselection.c index 67fd25be3..06e28e11f 100644 --- a/content/handlers/html/textselection.c +++ b/content/handlers/html/textselection.c @@ -264,14 +264,13 @@ coords_from_range(struct box *box, nserror html_create_selection(struct content *c, struct selection **sel_out) { - html_content *html = (html_content *)c; struct selection *sel; sel = selection_create(c, true); if (sel == NULL) { return NSERROR_NOMEM; } - selection_init(sel, html->layout); + selection_init(sel); *sel_out = sel; return NSERROR_OK; @@ -528,3 +527,47 @@ html_textselection_copy(struct content *c, } return NSERROR_OK; } + + +/** + * Label each text box in the given box subtree with its position + * in a textual representation of the content. + * + * \param box The box at root of subtree + * \param idx current position within textual representation + * \return updated position + */ +static unsigned selection_label_subtree(struct box *box, unsigned idx) +{ + struct box *child = box->children; + + box->byte_offset = idx; + + if (box->text) { + idx += box->length + SPACE_LEN(box); + } + + while (child) { + if (child->list_marker) { + idx = selection_label_subtree(child->list_marker, idx); + } + + idx = selection_label_subtree(child, idx); + child = child->next; + } + + return idx; +} + +/* exported interface documented in html/textselection.h */ +nserror +html_textselection_get_end(struct content *c, unsigned *end_idx) +{ + html_content *html = (html_content *)c; + unsigned root_idx; + + root_idx = 0; + + *end_idx = selection_label_subtree(html->layout, root_idx); + return NSERROR_OK; +} diff --git a/content/handlers/html/textselection.h b/content/handlers/html/textselection.h index 4a866b0b2..95d7078c5 100644 --- a/content/handlers/html/textselection.h +++ b/content/handlers/html/textselection.h @@ -36,4 +36,13 @@ nserror html_textselection_redraw(struct content *c, unsigned start_idx, unsigne nserror html_textselection_copy(struct content *c, unsigned start_idx, unsigned end_idx, struct selection_string *selstr); +/** + * get maximum index of text section. + * + * \param[in] c The content to measure + * \param[out] end_idx pointer to value to recive result + * \return NSERROR_OK and \a end_idx updated else error code + */ +nserror html_textselection_get_end(struct content *c, unsigned *end_idx); + #endif diff --git a/content/handlers/text/textplain.c b/content/handlers/text/textplain.c index 5142291bb..1165bcf5d 100644 --- a/content/handlers/text/textplain.c +++ b/content/handlers/text/textplain.c @@ -1228,7 +1228,7 @@ textplain_open(struct content *c, text->bw = bw; /* text selection */ - selection_init(&text->sel, NULL); + selection_init(&text->sel); return NSERROR_OK; } @@ -1580,7 +1580,7 @@ textplain_create_selection(struct content *c, struct selection **sel_out) return NSERROR_NOMEM; } - selection_init(sel, NULL); + selection_init(sel); *sel_out = sel; return NSERROR_OK; @@ -1626,6 +1626,13 @@ textplain_textselection_copy(struct content *c, return NSERROR_OK; } +static nserror +textplain_textselection_get_end(struct content *c, unsigned *end_idx) +{ + *end_idx = textplain_size(c); + return NSERROR_OK; +} + /** * plain text content handler table */ @@ -1649,6 +1656,7 @@ static const content_handler textplain_content_handler = { .textsearch_bounds = textplain_textsearch_bounds, .textselection_redraw = textplain_textselection_redraw, .textselection_copy = textplain_textselection_copy, + .textselection_get_end = textplain_textselection_get_end, .create_selection = textplain_create_selection, .no_share = true, }; diff --git a/desktop/selection.c b/desktop/selection.c index 6839724f8..40edff885 100644 --- a/desktop/selection.c +++ b/desktop/selection.c @@ -67,35 +67,6 @@ struct selection_string { }; -/** - * Label each text box in the given box subtree with its position - * in a textual representation of the content. - * - * \param box The box at root of subtree - * \param idx current position within textual representation - * \return updated position - */ -static unsigned selection_label_subtree(struct box *box, unsigned idx) -{ - struct box *child = box->children; - - box->byte_offset = idx; - - if (box->text) { - idx += box->length + SPACE_LEN(box); - } - - while (child) { - if (child->list_marker) { - idx = selection_label_subtree(child->list_marker, idx); - } - - idx = selection_label_subtree(child, idx); - child = child->next; - } - - return idx; -} /** @@ -322,23 +293,12 @@ void selection_destroy(struct selection *s) /* exported interface documented in desktop/selection.h */ -void selection_reinit(struct selection *s, struct box *root) +void selection_reinit(struct selection *s) { - unsigned root_idx; - - assert(s); + s->max_idx = 0; - root_idx = 0; - - s->root = root; - if (root) { - s->max_idx = selection_label_subtree(root, root_idx); - } else { - if (s->is_html == false) { - s->max_idx = textplain_size(s->c); - } else { - s->max_idx = 0; - } + if (s->c->handler->textselection_get_end != NULL) { + s->c->handler->textselection_get_end(s->c, &s->max_idx); } if (s->defined) { @@ -354,8 +314,7 @@ void selection_reinit(struct selection *s, struct box *root) /* exported interface documented in desktop/selection.h */ -void -selection_init(struct selection *s, struct box *root) +void selection_init(struct selection *s) { if (s->defined) { selection_clear(s, true); @@ -366,7 +325,7 @@ selection_init(struct selection *s, struct box *root) s->end_idx = 0; s->drag_state = DRAG_NONE; - selection_reinit(s, root); + selection_reinit(s); } diff --git a/desktop/selection.h b/desktop/selection.h index cb9289ac7..e570d8311 100644 --- a/desktop/selection.h +++ b/desktop/selection.h @@ -108,9 +108,8 @@ void selection_destroy(struct selection *s); * Used from text and html content handlers * * \param s selection object - * \param root the root box for html document or NULL for text/plain */ -void selection_init(struct selection *s, struct box *root); +void selection_init(struct selection *s); /** * Initialise the selection object to use the given box subtree as its root, @@ -121,9 +120,8 @@ void selection_init(struct selection *s, struct box *root); * Used from html content handler * * \param s selection object - * \param root the root box for html document or NULL for text/plain */ -void selection_reinit(struct selection *s, struct box *root); +void selection_reinit(struct selection *s); /** * Clears the current selection, optionally causing the screen to be updated. -- cgit v1.2.3