hoist common text search out of content handlers

This commit is contained in:
Vincent Sanders 2020-05-12 21:09:41 +01:00
parent a8596a80ae
commit 3c7538a9f9
9 changed files with 111 additions and 203 deletions

View File

@ -36,6 +36,7 @@
#include "desktop/gui_internal.h"
#include "content/content_protected.h"
#include "content/textsearch.h"
#include "content/content_debug.h"
#include "content/hlcache.h"
#include "content/urldb.h"
@ -236,6 +237,9 @@ content__init(struct content *c,
c->total_size = 0;
c->http_code = 0;
c->textsearch.string = NULL;
c->textsearch.context = NULL;
content_set_status(c, messages_get("Loading"));
/* Finally, claim low-level cache events */
@ -824,6 +828,12 @@ nserror content_close(hlcache_handle *h)
NSLOG(netsurf, INFO, "content %p %s", c,
nsurl_access_log(llcache_handle_get_url(c->llcache)));
if (c->textsearch.context != NULL) {
content_textsearch_destroy(c->textsearch.context);
c->textsearch.context = NULL;
}
if (c->handler->close != NULL) {
res = c->handler->close(c);
} else {
@ -907,31 +917,84 @@ content_drop_file_at_point(struct hlcache_handle *h,
}
/**
* Terminate a search.
*
* \param c content to clear
*/
static nserror content_textsearch__clear(struct content *c)
{
free(c->textsearch.string);
c->textsearch.string = NULL;
if (c->textsearch.context != NULL) {
content_textsearch_destroy(c->textsearch.context);
c->textsearch.context = NULL;
}
return NSERROR_OK;
}
/* exported interface, documented in content/content.h */
void
content_search(struct hlcache_handle *h,
void *context,
search_flags_t flags,
const char *string)
nserror
content_textsearch(struct hlcache_handle *h,
void *context,
search_flags_t flags,
const char *string)
{
struct content *c = hlcache_handle_get_content(h);
assert(c != 0);
nserror res;
if (c->handler->search != NULL) {
c->handler->search(c, context, flags, string);
assert(c != NULL);
if (string != NULL &&
c->textsearch.string != NULL &&
c->textsearch.context != NULL &&
strcmp(string, c->textsearch.string) == 0) {
/* Continue prev. search */
content_textsearch_step(c->textsearch.context, flags, string);
} else if (string != NULL) {
/* New search */
free(c->textsearch.string);
c->textsearch.string = strdup(string);
if (c->textsearch.string == NULL) {
return NSERROR_NOMEM;
}
if (c->textsearch.context != NULL) {
content_textsearch_destroy(c->textsearch.context);
c->textsearch.context = NULL;
}
res = content_textsearch_create(c,
context,
&c->textsearch.context);
if (res != NSERROR_OK) {
return res;
}
content_textsearch_step(c->textsearch.context, flags, string);
} else {
/* Clear search */
content_textsearch__clear(c);
free(c->textsearch.string);
c->textsearch.string = NULL;
}
return NSERROR_OK;
}
/* exported interface, documented in content/content.h */
void content_search_clear(struct hlcache_handle *h)
nserror content_textsearch_clear(struct hlcache_handle *h)
{
struct content *c = hlcache_handle_get_content(h);
assert(c != 0);
if (c->handler->search_clear != NULL) {
c->handler->search_clear(c);
}
return(content_textsearch__clear(c));
}

View File

@ -378,19 +378,22 @@ bool content_drop_file_at_point(struct hlcache_handle *h,
int x, int y, char *file);
/**
* Search a content
* Free text search a content
*
* \param[in] h Handle to content to search.
* \param[in] context The context passed to gui table search handlers
* \param[in] flags The flags that control the search
* \param[in] The string being searched for.
* \retun NSERROR_OK on success else error code on faliure
*/
void content_search(struct hlcache_handle *h, void *context,
search_flags_t flags, const char *string);
nserror content_textsearch(struct hlcache_handle *h, void *context, search_flags_t flags, const char *string);
/**
* Clear a search
*
* \param[in] h Handle to content to clear search from.
*/
void content_search_clear(struct hlcache_handle *h);
nserror content_textsearch_clear(struct hlcache_handle *h);
/**

View File

@ -87,9 +87,6 @@ struct content_handler {
int scrx, int scry);
bool (*drop_file_at_point)(struct content *c, int x, int y,
char *file);
void (*search)(struct content *c, void *context, search_flags_t flags,
const char *string);
void (*search_clear)(struct content *c);
nserror (*debug_dump)(struct content *c, FILE *f, enum content_debug op);
nserror (*debug)(struct content *c, enum content_debug op);
nserror (*clone)(const struct content *old, struct content **newc);
@ -237,6 +234,14 @@ struct content {
* HTTP status code, 0 if not HTTP.
*/
long http_code;
/**
* Free text search state
*/
struct {
char *string;
struct textsearch_context *context;
} textsearch;
};
extern const char * const content_type_name[];

View File

@ -481,8 +481,6 @@ html_create_html_data(html_content *c, const http_parameter *params)
c->selection_owner.none = true;
c->focus_type = HTML_FOCUS_SELF;
c->focus_owner.self = true;
c->search = NULL;
c->search_string = NULL;
c->scripts_count = 0;
c->scripts = NULL;
c->jsthread = NULL;
@ -1326,10 +1324,6 @@ static nserror html_close(struct content *c)
selection_clear(&htmlc->sel, false);
if (htmlc->search != NULL) {
content_textsearch_destroy(htmlc->search);
}
/* clear the html content reference to the browser window */
htmlc->bw = NULL;
@ -2204,8 +2198,6 @@ static const content_handler html_content_handler = {
.get_contextual_content = html_get_contextual_content,
.scroll_at_point = html_scroll_at_point,
.drop_file_at_point = html_drop_file_at_point,
.search = html_search,
.search_clear = html_search_clear,
.debug_dump = html_debug_dump,
.debug = html_debug,
.clone = html_clone,

View File

@ -1598,82 +1598,6 @@ bool html_keypress(struct content *c, uint32_t key)
}
/**
* Handle search.
*
* \param c content of type HTML
* \param fe_ctx front end private data
* \param flags search flags
* \param string search string
*/
void
html_search(struct content *c,
void *fe_ctx,
search_flags_t flags,
const char *string)
{
html_content *html = (html_content *)c;
nserror res;
assert(c != NULL);
if ((string != NULL) &&
(html->search_string != NULL) &&
(strcmp(string, html->search_string) == 0) &&
(html->search != NULL)) {
/* Continue prev. search */
content_textsearch_step(html->search, flags, string);
} else if (string != NULL) {
/* New search */
free(html->search_string);
html->search_string = strdup(string);
if (html->search_string == NULL)
return;
if (html->search != NULL) {
content_textsearch_destroy(html->search);
html->search = NULL;
}
res = content_textsearch_create(c, fe_ctx, &html->search);
if (res != NSERROR_OK) {
return;
}
content_textsearch_step(html->search, flags, string);
} else {
/* Clear search */
html_search_clear(c);
free(html->search_string);
html->search_string = NULL;
}
}
/**
* Terminate a text search.
*
* \param c content of type HTML
*/
void html_search_clear(struct content *c)
{
html_content *html = (html_content *)c;
assert(c != NULL);
free(html->search_string);
html->search_string = NULL;
if (html->search != NULL) {
content_textsearch_destroy(html->search);
}
html->search = NULL;
}
/**
* Callback for in-page scrollbars.
*/

View File

@ -210,11 +210,6 @@ typedef struct html_content {
*/
struct form_control *visible_select_menu;
/** Context for free text search, or NULL if none */
struct textsearch_context *search;
/** Search string or NULL */
char *search_string;
} html_content;
/**

View File

@ -167,7 +167,6 @@ text_redraw(const char *utf8_text,
bool excluded,
struct content *c,
const struct selection *sel,
struct textsearch_context *search,
const struct redraw_context *ctx)
{
bool highlighted = false;
@ -195,8 +194,8 @@ text_redraw(const char *utf8_text,
/* what about the current search operation, if any? */
if (!highlighted &&
(search != NULL) &&
content_textsearch_ishighlighted(search,
(c->textsearch.context != NULL) &&
content_textsearch_ishighlighted(c->textsearch.context,
offset,
offset + len,
&start_idx,
@ -1138,11 +1137,19 @@ static bool html_redraw_text_box(const html_content *html, struct box *box,
font_plot_style_from_css(&html->len_ctx, box->style, &fstyle);
fstyle.background = current_background_color;
if (!text_redraw(box->text, box->length, box->byte_offset,
box->space, &fstyle, x, y,
clip, box->height, scale, excluded,
(struct content *)html, &html->sel,
html->search, ctx))
if (!text_redraw(box->text,
box->length,
box->byte_offset,
box->space,
&fstyle,
x, y,
clip,
box->height,
scale,
excluded,
(struct content *)html,
&html->sel,
ctx))
return false;
return true;

View File

@ -70,10 +70,6 @@ typedef struct textplain_content {
struct selection sel; /** Selection state */
/** Context for free text search, or NULL if none */
struct textsearch_context *search;
/** Current search string, or NULL if none */
char *search_string;
} textplain_content;
@ -738,77 +734,6 @@ static bool textplain_keypress(struct content *c, uint32_t key)
}
/**
* Terminate a search.
*
* \param c content of type text
*/
static void textplain_search_clear(struct content *c)
{
textplain_content *text = (textplain_content *) c;
assert(c != NULL);
free(text->search_string);
text->search_string = NULL;
if (text->search != NULL) {
content_textsearch_destroy(text->search);
}
text->search = NULL;
}
/**
* Handle search.
*
* \param c content of type text
* \param gui_data front end private data
* \param flags search flags
* \param string search string
*/
static void textplain_search(struct content *c, void *gui_data,
search_flags_t flags, const char *string)
{
textplain_content *text = (textplain_content *) c;
nserror res;
assert(c != NULL);
if (string != NULL &&
text->search_string != NULL &&
strcmp(string, text->search_string) == 0 &&
text->search != NULL) {
/* Continue prev. search */
content_textsearch_step(text->search, flags, string);
} else if (string != NULL) {
/* New search */
free(text->search_string);
text->search_string = strdup(string);
if (text->search_string == NULL)
return;
if (text->search != NULL) {
content_textsearch_destroy(text->search);
text->search = NULL;
}
res = content_textsearch_create(c, gui_data, &text->search);
if (res != NSERROR_OK) {
return;
}
content_textsearch_step(text->search, flags, string);
} else {
/* Clear search */
textplain_search_clear(c);
free(text->search_string);
text->search_string = NULL;
}
}
/**
@ -868,8 +793,8 @@ text_draw(const char *utf8_text,
/* what about the current search operation, if any? */
if (!highlighted &&
(text->search != NULL) &&
content_textsearch_ishighlighted(text->search,
(text->base.textsearch.context != NULL) &&
content_textsearch_ishighlighted(text->base.textsearch.context,
offset,
offset + len,
&start_idx,
@ -1164,10 +1089,10 @@ textplain_redraw(struct content *c,
}
if (!highlighted &&
(text->search != NULL)) {
(c->textsearch.context != NULL)) {
unsigned start_idx, end_idx;
if (content_textsearch_ishighlighted(
text->search,
c->textsearch.context,
tab_ofst,
tab_ofst + 1,
&start_idx,
@ -1227,10 +1152,6 @@ static nserror textplain_close(struct content *c)
{
textplain_content *text = (textplain_content *) c;
if (text->search != NULL) {
content_textsearch_destroy(text->search);
}
text->bw = NULL;
return NSERROR_OK;
@ -1305,8 +1226,6 @@ static const content_handler textplain_content_handler = {
.mouse_track = textplain_mouse_track,
.mouse_action = textplain_mouse_action,
.keypress = textplain_keypress,
.search = textplain_search,
.search_clear = textplain_search_clear,
.redraw = textplain_redraw,
.open = textplain_open,
.close = textplain_close,

View File

@ -37,7 +37,7 @@ void browser_window_search(struct browser_window *bw, void *context,
{
if ((bw != NULL) &&
(bw->current_content != NULL)) {
content_search(bw->current_content, context, flags, string);
content_textsearch(bw->current_content, context, flags, string);
}
}
@ -46,6 +46,6 @@ void browser_window_search_clear(struct browser_window *bw)
{
if ((bw != NULL) &&
(bw->current_content != NULL)) {
content_search_clear(bw->current_content);
content_textsearch_clear(bw->current_content);
}
}