Gitweb links:
...log
http://git.netsurf-browser.org/netsurf.git/shortlog/f4e50b45c834b644caa6a82bd044faa82f6f4860
...commit
http://git.netsurf-browser.org/netsurf.git/commit/f4e50b45c834b644caa6a82bd044faa82f6f4860
...tree
http://git.netsurf-browser.org/netsurf.git/tree/f4e50b45c834b644caa6a82bd044faa82f6f4860
The branch, master has been updated
via f4e50b45c834b644caa6a82bd044faa82f6f4860 (commit)
via 68b9417a6bc8344f68f8a8206d2f2781079bd713 (commit)
via 3c7538a9f906e38e78be0300049f9e49839d7fd7 (commit)
from a8596a80aeb70acb05aba29f654df24210f50c19 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=f4e50b45c834b644caa6a82bd044faa82f6f4860
commit f4e50b45c834b644caa6a82bd044faa82f6f4860
Author: Vincent Sanders <[email protected]>
Commit: Vincent Sanders <[email protected]>
make free text search content handler agnostic
diff --git a/content/content_protected.h b/content/content_protected.h
index 26f4380..667f5ba 100644
--- a/content/content_protected.h
+++ b/content/content_protected.h
@@ -44,6 +44,9 @@ struct content;
struct redraw_context;
struct rect;
struct browser_window_features;
+struct textsearch_context;
+struct box;
+struct selection;
typedef struct content_handler content_handler;
@@ -98,6 +101,21 @@ struct content_handler {
bool (*exec)(struct content *c, const char *src, size_t srclen);
bool (*saw_insecure_objects)(struct content *c);
+ /**
+ * content specific free text search find
+ */
+ nserror (*textsearch_find)(struct content *c, struct textsearch_context
*context, const char *pattern, int p_len, bool case_sens);
+
+ /**
+ * get bounds of free text search match
+ */
+ nserror (*textsearch_bounds)(struct content *c, unsigned start_idx,
unsigned end_idx, struct box *start_ptr, struct box *end_ptr, struct rect
*bounds_out);
+
+ /**
+ * create a selection object
+ */
+ nserror (*create_selection)(struct content *c, struct selection
**sel_out);
+
/**
* handler dependant content sensitive internal data interface.
*/
diff --git a/content/handlers/html/html.c b/content/handlers/html/html.c
index 88098eb..23d6078 100644
--- a/content/handlers/html/html.c
+++ b/content/handlers/html/html.c
@@ -2179,6 +2179,153 @@ static void html_fini(void)
html_css_fini();
}
+/**
+ * Finds all occurrences of a given string in an html box
+ *
+ * \param pattern the string pattern to search for
+ * \param p_len pattern length
+ * \param cur pointer to the current box
+ * \param case_sens whether to perform a case sensitive search
+ * \param context The search context to add the entry to.
+ * \return true on success, false on memory allocation failure
+ */
+static nserror
+find_occurrences_html_box(const char *pattern,
+ int p_len,
+ struct box *cur,
+ bool case_sens,
+ struct textsearch_context *context)
+{
+ struct box *a;
+ nserror res = NSERROR_OK;
+
+ /* ignore this box, if there's no visible text */
+ if (!cur->object && cur->text) {
+ const char *text = cur->text;
+ unsigned length = cur->length;
+
+ while (length > 0) {
+ unsigned match_length;
+ unsigned match_offset;
+ const char *new_text;
+ const char *pos;
+
+ pos = content_textsearch_find_pattern(text,
+ length,
+ pattern,
+ p_len,
+ case_sens,
+ &match_length);
+ if (!pos)
+ break;
+
+ /* found string in box => add to list */
+ match_offset = pos - cur->text;
+
+ res = content_textsearch_add_match(context,
+ cur->byte_offset + match_offset,
+ cur->byte_offset + match_offset +
match_length,
+ cur,
+ cur);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ new_text = pos + match_length;
+ length -= (new_text - text);
+ text = new_text;
+ }
+ }
+
+ /* and recurse */
+ for (a = cur->children; a; a = a->next) {
+ res = find_occurrences_html_box(pattern,
+ p_len,
+ a,
+ case_sens,
+ context);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+ }
+
+ return res;
+}
+
+/**
+ * Finds all occurrences of a given string in the html box tree
+ *
+ * \param pattern the string pattern to search for
+ * \param p_len pattern length
+ * \param c The content to search
+ * \param csens whether to perform a case sensitive search
+ * \param context The search context to add the entry to.
+ * \return true on success, false on memory allocation failure
+ */
+static nserror
+html_textsearch_find(struct content *c,
+ struct textsearch_context *context,
+ const char *pattern,
+ int p_len,
+ bool csens)
+{
+ html_content *html = (html_content *)c;
+
+ if (html->layout == NULL) {
+ return NSERROR_INVALID;
+ }
+
+ return find_occurrences_html_box(pattern,
+ p_len,
+ html->layout,
+ csens,
+ context);
+}
+
+
+static nserror
+html_textsearch_bounds(struct content *c,
+ unsigned start_idx,
+ unsigned end_idx,
+ struct box *start_box,
+ struct box *end_box,
+ struct rect *bounds)
+{
+ /* get box position and jump to it */
+ box_coords(start_box, &bounds->x0, &bounds->y0);
+ /* \todo: move x0 in by correct idx */
+ box_coords(end_box, &bounds->x1, &bounds->y1);
+ /* \todo: move x1 in by correct idx */
+ bounds->x1 += end_box->width;
+ bounds->y1 += end_box->height;
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * create a selection object suitable for this content
+ */
+static 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, &html->len_ctx);
+
+ *sel_out = sel;
+ return NSERROR_OK;
+}
+
+
+/**
+ * HTML content handler function table
+ */
static const content_handler html_content_handler = {
.fini = html_fini,
.create = html_create,
@@ -2205,6 +2352,9 @@ static const content_handler html_content_handler = {
.type = html_content_type,
.exec = html_exec,
.saw_insecure_objects = html_saw_insecure_objects,
+ .textsearch_find = html_textsearch_find,
+ .textsearch_bounds = html_textsearch_bounds,
+ .create_selection = html_create_selection,
.no_share = true,
};
diff --git a/content/handlers/text/textplain.c
b/content/handlers/text/textplain.c
index 750c5eb..a233d82 100644
--- a/content/handlers/text/textplain.c
+++ b/content/handlers/text/textplain.c
@@ -1212,6 +1212,107 @@ textplain_coord_from_offset(const char *text, size_t
offset, size_t length)
return x;
}
+/**
+ * Finds all occurrences of a given string in a textplain content
+ *
+ * \param c the content to be searched
+ * \param context The search context to add the entry to.
+ * \param pattern the string pattern to search for
+ * \param p_len pattern length
+ * \param case_sens whether to perform a case sensitive search
+ * \return NSERROR_OK on success else error code on faliure
+ */
+static nserror
+textplain_textsearch_find(struct content *c,
+ struct textsearch_context *context,
+ const char *pattern,
+ int p_len,
+ bool case_sens)
+{
+ int nlines = textplain_line_count(c);
+ int line;
+ nserror res = NSERROR_OK;
+
+ for(line = 0; line < nlines; line++) {
+ size_t offset, length;
+ const char *text;
+
+ text = textplain_get_line(c, line, &offset, &length);
+ if (text) {
+ while (length > 0) {
+ unsigned match_length;
+ size_t start_idx;
+ const char *new_text;
+ const char *pos;
+
+ pos = content_textsearch_find_pattern(
+ text,
+ length,
+ pattern,
+ p_len,
+ case_sens,
+ &match_length);
+ if (!pos)
+ break;
+
+ /* found string in line => add to list */
+ start_idx = offset + (pos - text);
+ res = content_textsearch_add_match(context,
+ start_idx,
+ start_idx + match_length,
+ NULL,
+ NULL);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ new_text = pos + match_length;
+ offset += (new_text - text);
+ length -= (new_text - text);
+ text = new_text;
+ }
+ }
+ }
+
+ return res;
+}
+
+
+/**
+ * get bounds of a free text search match
+ */
+static nserror
+textplain_textsearch_bounds(struct content *c,
+ unsigned start_idx,
+ unsigned end_idx,
+ struct box *start_box,
+ struct box *end_box,
+ struct rect *bounds)
+{
+ textplain_coords_from_range(c, start_idx, end_idx, bounds);
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * create a selection object suitable for this content
+ */
+static nserror
+textplain_create_selection(struct content *c, struct selection **sel_out)
+{
+ struct selection *sel;
+ sel = selection_create(c, false);
+ if (sel == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ selection_init(sel, NULL, NULL);
+
+ *sel_out = sel;
+ return NSERROR_OK;
+}
+
/**
* plain text content handler table
@@ -1232,6 +1333,9 @@ static const content_handler textplain_content_handler = {
.get_selection = textplain_get_selection,
.clone = textplain_clone,
.type = textplain_content_type,
+ .textsearch_find = textplain_textsearch_find,
+ .textsearch_bounds = textplain_textsearch_bounds,
+ .create_selection = textplain_create_selection,
.no_share = true,
};
diff --git a/content/textsearch.c b/content/textsearch.c
index 7db0714..145c8c4 100644
--- a/content/textsearch.c
+++ b/content/textsearch.c
@@ -24,23 +24,17 @@
*/
#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
#include "utils/errors.h"
#include "utils/utils.h"
-#include "content/content.h"
-#include "content/hlcache.h"
-#include "desktop/selection.h"
+#include "netsurf/types.h"
#include "netsurf/search.h"
-#include "netsurf/content_type.h"
+#include "desktop/selection.h"
#include "desktop/gui_internal.h"
-#include "text/textplain.h"
-#include "html/box.h"
-#include "html/box_inspect.h"
-#include "html/private.h"
-
+#include "content/content.h"
+#include "content/content_protected.h"
+#include "content/hlcache.h"
#include "content/textsearch.h"
@@ -68,12 +62,9 @@ struct textsearch_context {
char *string;
bool prev_case_sens;
bool newsearch;
- bool is_html;
};
-
-
/**
* Release the memory used by the list of matches,
* deleting selection objects too
@@ -105,24 +96,14 @@ static void free_matches(struct textsearch_context
*textsearch)
}
-/**
- * Find the first occurrence of 'match' in 'string' and return its index
- *
- * \param string the string to be searched (unterminated)
- * \param s_len length of the string to be searched
- * \param pattern the pattern for which we are searching (unterminated)
- * \param p_len length of pattern
- * \param case_sens true iff case sensitive match required
- * \param m_len accepts length of match in bytes
- * \return pointer to first match, NULL if none
- */
-static const char *
-find_pattern(const char *string,
- int s_len,
- const char *pattern,
- int p_len,
- bool case_sens,
- unsigned int *m_len)
+/* Exported function documented in content/textsearch.h */
+const char *
+content_textsearch_find_pattern(const char *string,
+ int s_len,
+ const char *pattern,
+ int p_len,
+ bool case_sens,
+ unsigned int *m_len)
{
struct { const char *ss, *s, *p; bool first; } context[16];
const char *ep = pattern + p_len;
@@ -226,29 +207,26 @@ find_pattern(const char *string,
}
-/**
- * Add a new entry to the list of matches
- *
- * \param start_idx Offset of match start within textual representation
- * \param end_idx Offset of match end
- * \param context The search context to add the entry to.
- * \return Pointer to added entry, NULL iff failed.
- */
-static struct list_entry *
-add_entry(unsigned start_idx,
- unsigned end_idx,
- struct textsearch_context *context)
+/* Exported function documented in content/textsearch.h */
+nserror
+content_textsearch_add_match(struct textsearch_context *context,
+ unsigned start_idx,
+ unsigned end_idx,
+ struct box *start_box,
+ struct box *end_box)
{
struct list_entry *entry;
/* found string in box => add to list */
entry = calloc(1, sizeof(*entry));
- if (!entry) {
- return NULL;
+ if (entry == NULL) {
+ return NSERROR_NOMEM;
}
entry->start_idx = start_idx;
entry->end_idx = end_idx;
+ entry->start_box = start_box;
+ entry->end_box = end_box;
entry->sel = NULL;
entry->next = NULL;
@@ -262,168 +240,7 @@ add_entry(unsigned start_idx,
context->found->prev = entry;
- return entry;
-}
-
-
-/**
- * Finds all occurrences of a given string in an html box
- *
- * \param pattern the string pattern to search for
- * \param p_len pattern length
- * \param cur pointer to the current box
- * \param case_sens whether to perform a case sensitive search
- * \param context The search context to add the entry to.
- * \return true on success, false on memory allocation failure
- */
-static bool
-find_occurrences_html_box(const char *pattern,
- int p_len,
- struct box *cur,
- bool case_sens,
- struct textsearch_context *context)
-{
- struct box *a;
-
- /* ignore this box, if there's no visible text */
- if (!cur->object && cur->text) {
- const char *text = cur->text;
- unsigned length = cur->length;
-
- while (length > 0) {
- struct list_entry *entry;
- unsigned match_length;
- unsigned match_offset;
- const char *new_text;
- const char *pos;
-
- pos = find_pattern(text,
- length,
- pattern,
- p_len,
- case_sens,
- &match_length);
- if (!pos)
- break;
-
- /* found string in box => add to list */
- match_offset = pos - cur->text;
-
- entry = add_entry(cur->byte_offset + match_offset,
- cur->byte_offset + match_offset +
match_length,
- context);
- if (!entry)
- return false;
-
- entry->start_box = cur;
- entry->end_box = cur;
-
- new_text = pos + match_length;
- length -= (new_text - text);
- text = new_text;
- }
- }
-
- /* and recurse */
- for (a = cur->children; a; a = a->next) {
- if (!find_occurrences_html_box(pattern,
- p_len,
- a,
- case_sens,
- context))
- return false;
- }
-
- return true;
-}
-
-/**
- * Finds all occurrences of a given string in the html box tree
- *
- * \param pattern the string pattern to search for
- * \param p_len pattern length
- * \param c The content to search
- * \param csens whether to perform a case sensitive search
- * \param context The search context to add the entry to.
- * \return true on success, false on memory allocation failure
- */
-static bool
-find_occurrences_html(const char *pattern,
- int p_len,
- struct content *c,
- bool csens,
- struct textsearch_context *context)
-{
- html_content *html = (html_content *)c;
-
- if (html->layout == NULL) {
- return false;
- }
-
- return find_occurrences_html_box(pattern,
- p_len,
- html->layout,
- csens,
- context);
-}
-
-/**
- * Finds all occurrences of a given string in a textplain content
- *
- * \param pattern the string pattern to search for
- * \param p_len pattern length
- * \param c the content to be searched
- * \param case_sens whether to perform a case sensitive search
- * \param context The search context to add the entry to.
- * \return true on success, false on memory allocation failure
- */
-static bool
-find_occurrences_text(const char *pattern,
- int p_len,
- struct content *c,
- bool case_sens,
- struct textsearch_context *context)
-{
- int nlines = textplain_line_count(c);
- int line;
-
- for(line = 0; line < nlines; line++) {
- size_t offset, length;
- const char *text;
-
- text = textplain_get_line(c, line, &offset, &length);
- if (text) {
- while (length > 0) {
- struct list_entry *entry;
- unsigned match_length;
- size_t start_idx;
- const char *new_text;
- const char *pos;
-
- pos = find_pattern(text, length,
- pattern, p_len,
- case_sens,
- &match_length);
- if (!pos)
- break;
-
- /* found string in line => add to list */
- start_idx = offset + (pos - text);
- entry = add_entry(start_idx,
- start_idx + match_length,
- context);
- if (!entry)
- return false;
-
- new_text = pos + match_length;
- offset += (new_text - text);
- length -= (new_text - text);
- text = new_text;
- }
- }
- }
-
- return true;
+ return NSERROR_OK;
}
@@ -434,6 +251,7 @@ find_occurrences_text(const char *pattern,
static void search_show_all(bool all, struct textsearch_context *context)
{
struct list_entry *a;
+ nserror res;
for (a = context->found->next; a; a = a->next) {
bool add = true;
@@ -445,26 +263,15 @@ static void search_show_all(bool all, struct
textsearch_context *context)
a->sel = NULL;
}
}
- if (add && !a->sel) {
- if (context->is_html == true) {
- html_content *html = (html_content *)context->c;
- a->sel = selection_create(context->c, true);
- if (!a->sel)
- continue;
-
- selection_init(a->sel, html->layout,
- &html->len_ctx);
- } else {
- a->sel = selection_create(context->c, false);
- if (!a->sel)
- continue;
+ if (add && !a->sel) {
- selection_init(a->sel, NULL, NULL);
+ res = context->c->handler->create_selection(context->c,
+ &a->sel);
+ if (res == NSERROR_OK) {
+ selection_set_start(a->sel, a->start_idx);
+ selection_set_end(a->sel, a->end_idx);
}
-
- selection_set_start(a->sel, a->start_idx);
- selection_set_end(a->sel, a->end_idx);
}
}
}
@@ -478,7 +285,7 @@ static void search_show_all(bool all, struct
textsearch_context *context)
* \param context The search context to add the entry to.
* \param flags flags to control the search.
*/
-static void
+static nserror
search_text(const char *string,
int string_len,
struct textsearch_context *context,
@@ -487,22 +294,24 @@ search_text(const char *string,
struct rect bounds;
union content_msg_data msg_data;
bool case_sensitive, forwards, showall;
+ nserror res = NSERROR_OK;
case_sensitive = ((flags & SEARCH_FLAG_CASE_SENSITIVE) != 0) ?
true : false;
forwards = ((flags & SEARCH_FLAG_FORWARDS) != 0) ? true : false;
showall = ((flags & SEARCH_FLAG_SHOWALL) != 0) ? true : false;
- if (context->c == NULL)
- return;
+ if (context->c == NULL) {
+ return res;
+ }
/* check if we need to start a new search or continue an old one */
if ((context->newsearch) ||
(context->prev_case_sens != case_sensitive)) {
- bool res;
- if (context->string != NULL)
+ if (context->string != NULL) {
free(context->string);
+ }
context->current = NULL;
free_matches(context);
@@ -515,19 +324,18 @@ search_text(const char *string,
guit->search->hourglass(true, context->gui_p);
- if (context->is_html == true) {
- res = find_occurrences_html(string, string_len,
- context->c, case_sensitive, context);
- } else {
- res = find_occurrences_text(string, string_len,
- context->c, case_sensitive, context);
- }
+ /* call content find handler */
+ res = context->c->handler->textsearch_find(context->c,
+ context,
+ string,
+ string_len,
+ case_sensitive);
guit->search->hourglass(false, context->gui_p);
- if (!res) {
+ if (res != NSERROR_OK) {
free_matches(context);
- return;
+ return res;
}
context->prev_case_sens = case_sensitive;
@@ -558,29 +366,28 @@ search_text(const char *string,
(context->current->next != NULL),
context->gui_p);
- if (context->current == NULL)
- return;
-
- if (context->is_html == true) {
- /* get box position and jump to it */
- box_coords(context->current->start_box, &bounds.x0, &bounds.y0);
- /* \todo: move x0 in by correct idx */
- box_coords(context->current->end_box, &bounds.x1, &bounds.y1);
- /* \todo: move x1 in by correct idx */
- bounds.x1 += context->current->end_box->width;
- bounds.y1 += context->current->end_box->height;
- } else {
- textplain_coords_from_range(context->c,
- context->current->start_idx,
- context->current->end_idx, &bounds);
+ if (context->current == NULL) {
+ return res;
}
- msg_data.scroll.area = true;
- msg_data.scroll.x0 = bounds.x0;
- msg_data.scroll.y0 = bounds.y0;
- msg_data.scroll.x1 = bounds.x1;
- msg_data.scroll.y1 = bounds.y1;
- content_broadcast(context->c, CONTENT_MSG_SCROLL, &msg_data);
+ /* call content match bounds handler */
+ res = context->c->handler->textsearch_bounds(context->c,
+
context->current->start_idx,
+ context->current->end_idx,
+
+
context->current->start_box,
+ context->current->end_box,
+ &bounds);
+ if (res == NSERROR_OK) {
+ msg_data.scroll.area = true;
+ msg_data.scroll.x0 = bounds.x0;
+ msg_data.scroll.y0 = bounds.y0;
+ msg_data.scroll.x1 = bounds.x1;
+ msg_data.scroll.y1 = bounds.y1;
+ content_broadcast(context->c, CONTENT_MSG_SCROLL, &msg_data);
+ }
+
+ return res;
}
@@ -600,6 +407,7 @@ content_textsearch_step(struct textsearch_context
*textsearch,
{
int string_len;
int i = 0;
+ nserror res = NSERROR_OK;
assert(textsearch != NULL);
@@ -612,7 +420,7 @@ content_textsearch_step(struct textsearch_context
*textsearch,
}
if (i < string_len) {
- search_text(string, string_len, textsearch, flags);
+ res = search_text(string, string_len, textsearch, flags);
} else {
union content_msg_data msg_data;
free_matches(textsearch);
@@ -627,7 +435,7 @@ content_textsearch_step(struct textsearch_context
*textsearch,
content_broadcast(textsearch->c, CONTENT_MSG_SCROLL, &msg_data);
}
- return NSERROR_OK;
+ return res;
}
@@ -675,12 +483,18 @@ content_textsearch_create(struct content *c,
struct list_entry *search_head;
content_type type;
- type = c->handler->type();
-
- if (type != CONTENT_HTML && type != CONTENT_TEXTPLAIN) {
+ if ((c->handler->textsearch_find == NULL) ||
+ (c->handler->textsearch_bounds == NULL) ||
+ (c->handler->create_selection == NULL)){
+ /*
+ * content has no free text find handler so searching
+ * is unsupported.
+ */
return NSERROR_NOT_IMPLEMENTED;
}
+ type = c->handler->type();
+
context = malloc(sizeof(struct textsearch_context));
if (context == NULL) {
return NSERROR_NOMEM;
@@ -706,7 +520,6 @@ content_textsearch_create(struct content *c,
context->prev_case_sens = false;
context->newsearch = true;
context->c = c;
- context->is_html = (type == CONTENT_HTML) ? true : false;
context->gui_p = gui_data;
*textsearch_out = context;
diff --git a/content/textsearch.h b/content/textsearch.h
index c0a1acf..e30ebc4 100644
--- a/content/textsearch.h
+++ b/content/textsearch.h
@@ -28,7 +28,7 @@
struct textsearch_context;
struct content;
-
+struct box;
/**
* Ends the search process, invalidating all state freeing the list of
@@ -54,4 +54,29 @@ bool content_textsearch_ishighlighted(struct
textsearch_context *textsearch,
unsigned *start_idx,
unsigned *end_idx);
+/**
+ * Find the first occurrence of 'match' in 'string' and return its index
+ *
+ * \param string the string to be searched (unterminated)
+ * \param s_len length of the string to be searched
+ * \param pattern the pattern for which we are searching (unterminated)
+ * \param p_len length of pattern
+ * \param case_sens true iff case sensitive match required
+ * \param m_len accepts length of match in bytes
+ * \return pointer to first match, NULL if none
+ */
+const char *content_textsearch_find_pattern(const char *string, int s_len,
const char *pattern, int p_len, bool case_sens, unsigned int *m_len);
+
+/**
+ * Add a new entry to the list of matches
+ *
+ * \param context The search context to add the entry to.
+ * \param start_idx Offset of match start within textual representation
+ * \param end_idx Offset of match end
+ * \param start A pointer for the start
+ * \param end A pointer for the end
+ * \return NSERROR_OK on sucess else error code on faliure
+ */
+nserror content_textsearch_add_match(struct textsearch_context *context,
unsigned start_idx, unsigned end_idx, struct box *start_ptr, struct box
*end_ptr);
+
#endif
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=68b9417a6bc8344f68f8a8206d2f2781079bd713
commit 68b9417a6bc8344f68f8a8206d2f2781079bd713
Author: Vincent Sanders <[email protected]>
Commit: Vincent Sanders <[email protected]>
consolodate the textsearch code into a single module
diff --git a/content/content.c b/content/content.c
index 34602d6..bc3f484 100644
--- a/content/content.c
+++ b/content/content.c
@@ -917,87 +917,6 @@ 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 */
-nserror
-content_textsearch(struct hlcache_handle *h,
- void *context,
- search_flags_t flags,
- const char *string)
-{
- struct content *c = hlcache_handle_get_content(h);
- nserror res;
-
- 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 */
-nserror content_textsearch_clear(struct hlcache_handle *h)
-{
- struct content *c = hlcache_handle_get_content(h);
- assert(c != 0);
-
- return(content_textsearch__clear(c));
-}
-
-
/* exported interface documented in content/content.h */
nserror
content_debug_dump(struct hlcache_handle *h, FILE *f, enum content_debug op)
diff --git a/content/textsearch.c b/content/textsearch.c
index c535948..7db0714 100644
--- a/content/textsearch.c
+++ b/content/textsearch.c
@@ -30,6 +30,7 @@
#include "utils/errors.h"
#include "utils/utils.h"
#include "content/content.h"
+#include "content/hlcache.h"
#include "desktop/selection.h"
#include "netsurf/search.h"
#include "netsurf/content_type.h"
@@ -583,8 +584,16 @@ search_text(const char *string,
}
-/* Exported function documented in context/textsearch.h */
-nserror
+/**
+ * Begins/continues the search process
+ *
+ * \note that this may be called many times for a single search.
+ *
+ * \param context The search context in use.
+ * \param flags The flags forward/back etc
+ * \param string The string to match
+ */
+static nserror
content_textsearch_step(struct textsearch_context *textsearch,
search_flags_t flags,
const char *string)
@@ -649,7 +658,15 @@ content_textsearch_ishighlighted(struct textsearch_context
*textsearch,
/* Exported function documented in content/textsearch.h */
-nserror
+/**
+ * create a search_context
+ *
+ * \param c The content the search_context is connected to
+ * \param context A context pointer passed to the provider routines.
+ * \param search_out A pointer to recive the new text search context
+ * \return NSERROR_OK on success and \a search_out updated else error code
+ */
+static nserror
content_textsearch_create(struct content *c,
void *gui_data,
struct textsearch_context **textsearch_out)
@@ -716,3 +733,83 @@ nserror content_textsearch_destroy(struct
textsearch_context *textsearch)
return NSERROR_OK;
}
+
+/**
+ * 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/textsearch.h */
+nserror
+content_textsearch(struct hlcache_handle *h,
+ void *context,
+ search_flags_t flags,
+ const char *string)
+{
+ struct content *c = hlcache_handle_get_content(h);
+ nserror res;
+
+ 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/textsearch.h */
+nserror content_textsearch_clear(struct hlcache_handle *h)
+{
+ struct content *c = hlcache_handle_get_content(h);
+ assert(c != 0);
+
+ return(content_textsearch__clear(c));
+}
diff --git a/content/textsearch.h b/content/textsearch.h
index f94bcdb..c0a1acf 100644
--- a/content/textsearch.h
+++ b/content/textsearch.h
@@ -24,34 +24,11 @@
#ifndef NETSURF_CONTENT_SEARCH_H
#define NETSURF_CONTENT_SEARCH_H
-#include <ctype.h>
-#include <string.h>
-
#include "desktop/search.h"
struct textsearch_context;
struct content;
-/**
- * create a search_context
- *
- * \param c The content the search_context is connected to
- * \param context A context pointer passed to the provider routines.
- * \param search_out A pointer to recive the new text search context
- * \return NSERROR_OK on success and \a search_out updated else error code
- */
-nserror content_textsearch_create(struct content *c, void *context, struct
textsearch_context **textsearch_out);
-
-/**
- * Begins/continues the search process
- *
- * \note that this may be called many times for a single search.
- *
- * \param context The search context in use.
- * \param flags The flags forward/back etc
- * \param string The string to match
- */
-nserror content_textsearch_step(struct textsearch_context *textsearch,
search_flags_t flags, const char *string);
/**
* Ends the search process, invalidating all state freeing the list of
diff --git a/desktop/search.c b/desktop/search.c
index df77a8f..d4abfed 100644
--- a/desktop/search.c
+++ b/desktop/search.c
@@ -23,6 +23,8 @@
* Free text search (core)
*/
+#include <stdbool.h>
+
#include "utils/errors.h"
#include "content/content.h"
#include "netsurf/types.h"
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=3c7538a9f906e38e78be0300049f9e49839d7fd7
commit 3c7538a9f906e38e78be0300049f9e49839d7fd7
Author: Vincent Sanders <[email protected]>
Commit: Vincent Sanders <[email protected]>
hoist common text search out of content handlers
diff --git a/content/content.c b/content/content.c
index 6532587..34602d6 100644
--- a/content/content.c
+++ b/content/content.c
@@ -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));
}
diff --git a/content/content.h b/content/content.h
index 2b16c52..f68af53 100644
--- a/content/content.h
+++ b/content/content.h
@@ -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);
/**
diff --git a/content/content_protected.h b/content/content_protected.h
index 314a0a9..26f4380 100644
--- a/content/content_protected.h
+++ b/content/content_protected.h
@@ -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[];
diff --git a/content/handlers/html/html.c b/content/handlers/html/html.c
index a3d4264..88098eb 100644
--- a/content/handlers/html/html.c
+++ b/content/handlers/html/html.c
@@ -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,
diff --git a/content/handlers/html/interaction.c
b/content/handlers/html/interaction.c
index 8ae5144..f2eae70 100644
--- a/content/handlers/html/interaction.c
+++ b/content/handlers/html/interaction.c
@@ -1599,82 +1599,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.
*/
void html_overflow_scroll_callback(void *client_data,
diff --git a/content/handlers/html/private.h b/content/handlers/html/private.h
index 1367c62..dde61c2 100644
--- a/content/handlers/html/private.h
+++ b/content/handlers/html/private.h
@@ -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;
/**
diff --git a/content/handlers/html/redraw.c b/content/handlers/html/redraw.c
index f9fb6b4..aa99782 100644
--- a/content/handlers/html/redraw.c
+++ b/content/handlers/html/redraw.c
@@ -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;
diff --git a/content/handlers/text/textplain.c
b/content/handlers/text/textplain.c
index e8c3831..750c5eb 100644
--- a/content/handlers/text/textplain.c
+++ b/content/handlers/text/textplain.c
@@ -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,
diff --git a/desktop/search.c b/desktop/search.c
index c4b5b35..df77a8f 100644
--- a/desktop/search.c
+++ b/desktop/search.c
@@ -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);
}
}
-----------------------------------------------------------------------
Summary of changes:
content/content.c | 38 +--
content/content.h | 11 +-
content/content_protected.h | 29 ++-
content/handlers/html/html.c | 158 ++++++++++++-
content/handlers/html/interaction.c | 76 ------
content/handlers/html/private.h | 5 -
content/handlers/html/redraw.c | 23 +-
content/handlers/text/textplain.c | 193 ++++++++-------
content/textsearch.c | 446 ++++++++++++++---------------------
content/textsearch.h | 50 ++--
desktop/search.c | 6 +-
11 files changed, 524 insertions(+), 511 deletions(-)
diff --git a/content/content.c b/content/content.c
index 6532587..bc3f484 100644
--- a/content/content.c
+++ b/content/content.c
@@ -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,34 +917,6 @@ content_drop_file_at_point(struct hlcache_handle *h,
}
-/* exported interface, documented in content/content.h */
-void
-content_search(struct hlcache_handle *h,
- void *context,
- search_flags_t flags,
- const char *string)
-{
- struct content *c = hlcache_handle_get_content(h);
- assert(c != 0);
-
- if (c->handler->search != NULL) {
- c->handler->search(c, context, flags, string);
- }
-}
-
-
-/* exported interface, documented in content/content.h */
-void content_search_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);
- }
-}
-
-
/* exported interface documented in content/content.h */
nserror
content_debug_dump(struct hlcache_handle *h, FILE *f, enum content_debug op)
diff --git a/content/content.h b/content/content.h
index 2b16c52..f68af53 100644
--- a/content/content.h
+++ b/content/content.h
@@ -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);
/**
diff --git a/content/content_protected.h b/content/content_protected.h
index 314a0a9..667f5ba 100644
--- a/content/content_protected.h
+++ b/content/content_protected.h
@@ -44,6 +44,9 @@ struct content;
struct redraw_context;
struct rect;
struct browser_window_features;
+struct textsearch_context;
+struct box;
+struct selection;
typedef struct content_handler content_handler;
@@ -87,9 +90,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);
@@ -101,6 +101,21 @@ struct content_handler {
bool (*exec)(struct content *c, const char *src, size_t srclen);
bool (*saw_insecure_objects)(struct content *c);
+ /**
+ * content specific free text search find
+ */
+ nserror (*textsearch_find)(struct content *c, struct textsearch_context
*context, const char *pattern, int p_len, bool case_sens);
+
+ /**
+ * get bounds of free text search match
+ */
+ nserror (*textsearch_bounds)(struct content *c, unsigned start_idx,
unsigned end_idx, struct box *start_ptr, struct box *end_ptr, struct rect
*bounds_out);
+
+ /**
+ * create a selection object
+ */
+ nserror (*create_selection)(struct content *c, struct selection
**sel_out);
+
/**
* handler dependant content sensitive internal data interface.
*/
@@ -237,6 +252,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[];
diff --git a/content/handlers/html/html.c b/content/handlers/html/html.c
index a3d4264..23d6078 100644
--- a/content/handlers/html/html.c
+++ b/content/handlers/html/html.c
@@ -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;
@@ -2185,6 +2179,153 @@ static void html_fini(void)
html_css_fini();
}
+/**
+ * Finds all occurrences of a given string in an html box
+ *
+ * \param pattern the string pattern to search for
+ * \param p_len pattern length
+ * \param cur pointer to the current box
+ * \param case_sens whether to perform a case sensitive search
+ * \param context The search context to add the entry to.
+ * \return true on success, false on memory allocation failure
+ */
+static nserror
+find_occurrences_html_box(const char *pattern,
+ int p_len,
+ struct box *cur,
+ bool case_sens,
+ struct textsearch_context *context)
+{
+ struct box *a;
+ nserror res = NSERROR_OK;
+
+ /* ignore this box, if there's no visible text */
+ if (!cur->object && cur->text) {
+ const char *text = cur->text;
+ unsigned length = cur->length;
+
+ while (length > 0) {
+ unsigned match_length;
+ unsigned match_offset;
+ const char *new_text;
+ const char *pos;
+
+ pos = content_textsearch_find_pattern(text,
+ length,
+ pattern,
+ p_len,
+ case_sens,
+ &match_length);
+ if (!pos)
+ break;
+
+ /* found string in box => add to list */
+ match_offset = pos - cur->text;
+
+ res = content_textsearch_add_match(context,
+ cur->byte_offset + match_offset,
+ cur->byte_offset + match_offset +
match_length,
+ cur,
+ cur);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ new_text = pos + match_length;
+ length -= (new_text - text);
+ text = new_text;
+ }
+ }
+
+ /* and recurse */
+ for (a = cur->children; a; a = a->next) {
+ res = find_occurrences_html_box(pattern,
+ p_len,
+ a,
+ case_sens,
+ context);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+ }
+
+ return res;
+}
+
+/**
+ * Finds all occurrences of a given string in the html box tree
+ *
+ * \param pattern the string pattern to search for
+ * \param p_len pattern length
+ * \param c The content to search
+ * \param csens whether to perform a case sensitive search
+ * \param context The search context to add the entry to.
+ * \return true on success, false on memory allocation failure
+ */
+static nserror
+html_textsearch_find(struct content *c,
+ struct textsearch_context *context,
+ const char *pattern,
+ int p_len,
+ bool csens)
+{
+ html_content *html = (html_content *)c;
+
+ if (html->layout == NULL) {
+ return NSERROR_INVALID;
+ }
+
+ return find_occurrences_html_box(pattern,
+ p_len,
+ html->layout,
+ csens,
+ context);
+}
+
+
+static nserror
+html_textsearch_bounds(struct content *c,
+ unsigned start_idx,
+ unsigned end_idx,
+ struct box *start_box,
+ struct box *end_box,
+ struct rect *bounds)
+{
+ /* get box position and jump to it */
+ box_coords(start_box, &bounds->x0, &bounds->y0);
+ /* \todo: move x0 in by correct idx */
+ box_coords(end_box, &bounds->x1, &bounds->y1);
+ /* \todo: move x1 in by correct idx */
+ bounds->x1 += end_box->width;
+ bounds->y1 += end_box->height;
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * create a selection object suitable for this content
+ */
+static 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, &html->len_ctx);
+
+ *sel_out = sel;
+ return NSERROR_OK;
+}
+
+
+/**
+ * HTML content handler function table
+ */
static const content_handler html_content_handler = {
.fini = html_fini,
.create = html_create,
@@ -2204,8 +2345,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,
@@ -2213,6 +2352,9 @@ static const content_handler html_content_handler = {
.type = html_content_type,
.exec = html_exec,
.saw_insecure_objects = html_saw_insecure_objects,
+ .textsearch_find = html_textsearch_find,
+ .textsearch_bounds = html_textsearch_bounds,
+ .create_selection = html_create_selection,
.no_share = true,
};
diff --git a/content/handlers/html/interaction.c
b/content/handlers/html/interaction.c
index 8ae5144..f2eae70 100644
--- a/content/handlers/html/interaction.c
+++ b/content/handlers/html/interaction.c
@@ -1599,82 +1599,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.
*/
void html_overflow_scroll_callback(void *client_data,
diff --git a/content/handlers/html/private.h b/content/handlers/html/private.h
index 1367c62..dde61c2 100644
--- a/content/handlers/html/private.h
+++ b/content/handlers/html/private.h
@@ -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;
/**
diff --git a/content/handlers/html/redraw.c b/content/handlers/html/redraw.c
index f9fb6b4..aa99782 100644
--- a/content/handlers/html/redraw.c
+++ b/content/handlers/html/redraw.c
@@ -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;
diff --git a/content/handlers/text/textplain.c
b/content/handlers/text/textplain.c
index e8c3831..a233d82 100644
--- a/content/handlers/text/textplain.c
+++ b/content/handlers/text/textplain.c
@@ -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;
@@ -1291,6 +1212,107 @@ textplain_coord_from_offset(const char *text, size_t
offset, size_t length)
return x;
}
+/**
+ * Finds all occurrences of a given string in a textplain content
+ *
+ * \param c the content to be searched
+ * \param context The search context to add the entry to.
+ * \param pattern the string pattern to search for
+ * \param p_len pattern length
+ * \param case_sens whether to perform a case sensitive search
+ * \return NSERROR_OK on success else error code on faliure
+ */
+static nserror
+textplain_textsearch_find(struct content *c,
+ struct textsearch_context *context,
+ const char *pattern,
+ int p_len,
+ bool case_sens)
+{
+ int nlines = textplain_line_count(c);
+ int line;
+ nserror res = NSERROR_OK;
+
+ for(line = 0; line < nlines; line++) {
+ size_t offset, length;
+ const char *text;
+
+ text = textplain_get_line(c, line, &offset, &length);
+ if (text) {
+ while (length > 0) {
+ unsigned match_length;
+ size_t start_idx;
+ const char *new_text;
+ const char *pos;
+
+ pos = content_textsearch_find_pattern(
+ text,
+ length,
+ pattern,
+ p_len,
+ case_sens,
+ &match_length);
+ if (!pos)
+ break;
+
+ /* found string in line => add to list */
+ start_idx = offset + (pos - text);
+ res = content_textsearch_add_match(context,
+ start_idx,
+ start_idx + match_length,
+ NULL,
+ NULL);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ new_text = pos + match_length;
+ offset += (new_text - text);
+ length -= (new_text - text);
+ text = new_text;
+ }
+ }
+ }
+
+ return res;
+}
+
+
+/**
+ * get bounds of a free text search match
+ */
+static nserror
+textplain_textsearch_bounds(struct content *c,
+ unsigned start_idx,
+ unsigned end_idx,
+ struct box *start_box,
+ struct box *end_box,
+ struct rect *bounds)
+{
+ textplain_coords_from_range(c, start_idx, end_idx, bounds);
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * create a selection object suitable for this content
+ */
+static nserror
+textplain_create_selection(struct content *c, struct selection **sel_out)
+{
+ struct selection *sel;
+ sel = selection_create(c, false);
+ if (sel == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ selection_init(sel, NULL, NULL);
+
+ *sel_out = sel;
+ return NSERROR_OK;
+}
+
/**
* plain text content handler table
@@ -1305,14 +1327,15 @@ 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,
.get_selection = textplain_get_selection,
.clone = textplain_clone,
.type = textplain_content_type,
+ .textsearch_find = textplain_textsearch_find,
+ .textsearch_bounds = textplain_textsearch_bounds,
+ .create_selection = textplain_create_selection,
.no_share = true,
};
diff --git a/content/textsearch.c b/content/textsearch.c
index c535948..145c8c4 100644
--- a/content/textsearch.c
+++ b/content/textsearch.c
@@ -24,22 +24,17 @@
*/
#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
#include "utils/errors.h"
#include "utils/utils.h"
-#include "content/content.h"
-#include "desktop/selection.h"
+#include "netsurf/types.h"
#include "netsurf/search.h"
-#include "netsurf/content_type.h"
+#include "desktop/selection.h"
#include "desktop/gui_internal.h"
-#include "text/textplain.h"
-#include "html/box.h"
-#include "html/box_inspect.h"
-#include "html/private.h"
-
+#include "content/content.h"
+#include "content/content_protected.h"
+#include "content/hlcache.h"
#include "content/textsearch.h"
@@ -67,12 +62,9 @@ struct textsearch_context {
char *string;
bool prev_case_sens;
bool newsearch;
- bool is_html;
};
-
-
/**
* Release the memory used by the list of matches,
* deleting selection objects too
@@ -104,24 +96,14 @@ static void free_matches(struct textsearch_context
*textsearch)
}
-/**
- * Find the first occurrence of 'match' in 'string' and return its index
- *
- * \param string the string to be searched (unterminated)
- * \param s_len length of the string to be searched
- * \param pattern the pattern for which we are searching (unterminated)
- * \param p_len length of pattern
- * \param case_sens true iff case sensitive match required
- * \param m_len accepts length of match in bytes
- * \return pointer to first match, NULL if none
- */
-static const char *
-find_pattern(const char *string,
- int s_len,
- const char *pattern,
- int p_len,
- bool case_sens,
- unsigned int *m_len)
+/* Exported function documented in content/textsearch.h */
+const char *
+content_textsearch_find_pattern(const char *string,
+ int s_len,
+ const char *pattern,
+ int p_len,
+ bool case_sens,
+ unsigned int *m_len)
{
struct { const char *ss, *s, *p; bool first; } context[16];
const char *ep = pattern + p_len;
@@ -225,29 +207,26 @@ find_pattern(const char *string,
}
-/**
- * Add a new entry to the list of matches
- *
- * \param start_idx Offset of match start within textual representation
- * \param end_idx Offset of match end
- * \param context The search context to add the entry to.
- * \return Pointer to added entry, NULL iff failed.
- */
-static struct list_entry *
-add_entry(unsigned start_idx,
- unsigned end_idx,
- struct textsearch_context *context)
+/* Exported function documented in content/textsearch.h */
+nserror
+content_textsearch_add_match(struct textsearch_context *context,
+ unsigned start_idx,
+ unsigned end_idx,
+ struct box *start_box,
+ struct box *end_box)
{
struct list_entry *entry;
/* found string in box => add to list */
entry = calloc(1, sizeof(*entry));
- if (!entry) {
- return NULL;
+ if (entry == NULL) {
+ return NSERROR_NOMEM;
}
entry->start_idx = start_idx;
entry->end_idx = end_idx;
+ entry->start_box = start_box;
+ entry->end_box = end_box;
entry->sel = NULL;
entry->next = NULL;
@@ -261,168 +240,7 @@ add_entry(unsigned start_idx,
context->found->prev = entry;
- return entry;
-}
-
-
-/**
- * Finds all occurrences of a given string in an html box
- *
- * \param pattern the string pattern to search for
- * \param p_len pattern length
- * \param cur pointer to the current box
- * \param case_sens whether to perform a case sensitive search
- * \param context The search context to add the entry to.
- * \return true on success, false on memory allocation failure
- */
-static bool
-find_occurrences_html_box(const char *pattern,
- int p_len,
- struct box *cur,
- bool case_sens,
- struct textsearch_context *context)
-{
- struct box *a;
-
- /* ignore this box, if there's no visible text */
- if (!cur->object && cur->text) {
- const char *text = cur->text;
- unsigned length = cur->length;
-
- while (length > 0) {
- struct list_entry *entry;
- unsigned match_length;
- unsigned match_offset;
- const char *new_text;
- const char *pos;
-
- pos = find_pattern(text,
- length,
- pattern,
- p_len,
- case_sens,
- &match_length);
- if (!pos)
- break;
-
- /* found string in box => add to list */
- match_offset = pos - cur->text;
-
- entry = add_entry(cur->byte_offset + match_offset,
- cur->byte_offset + match_offset +
match_length,
- context);
- if (!entry)
- return false;
-
- entry->start_box = cur;
- entry->end_box = cur;
-
- new_text = pos + match_length;
- length -= (new_text - text);
- text = new_text;
- }
- }
-
- /* and recurse */
- for (a = cur->children; a; a = a->next) {
- if (!find_occurrences_html_box(pattern,
- p_len,
- a,
- case_sens,
- context))
- return false;
- }
-
- return true;
-}
-
-/**
- * Finds all occurrences of a given string in the html box tree
- *
- * \param pattern the string pattern to search for
- * \param p_len pattern length
- * \param c The content to search
- * \param csens whether to perform a case sensitive search
- * \param context The search context to add the entry to.
- * \return true on success, false on memory allocation failure
- */
-static bool
-find_occurrences_html(const char *pattern,
- int p_len,
- struct content *c,
- bool csens,
- struct textsearch_context *context)
-{
- html_content *html = (html_content *)c;
-
- if (html->layout == NULL) {
- return false;
- }
-
- return find_occurrences_html_box(pattern,
- p_len,
- html->layout,
- csens,
- context);
-}
-
-/**
- * Finds all occurrences of a given string in a textplain content
- *
- * \param pattern the string pattern to search for
- * \param p_len pattern length
- * \param c the content to be searched
- * \param case_sens whether to perform a case sensitive search
- * \param context The search context to add the entry to.
- * \return true on success, false on memory allocation failure
- */
-static bool
-find_occurrences_text(const char *pattern,
- int p_len,
- struct content *c,
- bool case_sens,
- struct textsearch_context *context)
-{
- int nlines = textplain_line_count(c);
- int line;
-
- for(line = 0; line < nlines; line++) {
- size_t offset, length;
- const char *text;
-
- text = textplain_get_line(c, line, &offset, &length);
- if (text) {
- while (length > 0) {
- struct list_entry *entry;
- unsigned match_length;
- size_t start_idx;
- const char *new_text;
- const char *pos;
-
- pos = find_pattern(text, length,
- pattern, p_len,
- case_sens,
- &match_length);
- if (!pos)
- break;
-
- /* found string in line => add to list */
- start_idx = offset + (pos - text);
- entry = add_entry(start_idx,
- start_idx + match_length,
- context);
- if (!entry)
- return false;
-
- new_text = pos + match_length;
- offset += (new_text - text);
- length -= (new_text - text);
- text = new_text;
- }
- }
- }
-
- return true;
+ return NSERROR_OK;
}
@@ -433,6 +251,7 @@ find_occurrences_text(const char *pattern,
static void search_show_all(bool all, struct textsearch_context *context)
{
struct list_entry *a;
+ nserror res;
for (a = context->found->next; a; a = a->next) {
bool add = true;
@@ -444,26 +263,15 @@ static void search_show_all(bool all, struct
textsearch_context *context)
a->sel = NULL;
}
}
- if (add && !a->sel) {
- if (context->is_html == true) {
- html_content *html = (html_content *)context->c;
- a->sel = selection_create(context->c, true);
- if (!a->sel)
- continue;
-
- selection_init(a->sel, html->layout,
- &html->len_ctx);
- } else {
- a->sel = selection_create(context->c, false);
- if (!a->sel)
- continue;
+ if (add && !a->sel) {
- selection_init(a->sel, NULL, NULL);
+ res = context->c->handler->create_selection(context->c,
+ &a->sel);
+ if (res == NSERROR_OK) {
+ selection_set_start(a->sel, a->start_idx);
+ selection_set_end(a->sel, a->end_idx);
}
-
- selection_set_start(a->sel, a->start_idx);
- selection_set_end(a->sel, a->end_idx);
}
}
}
@@ -477,7 +285,7 @@ static void search_show_all(bool all, struct
textsearch_context *context)
* \param context The search context to add the entry to.
* \param flags flags to control the search.
*/
-static void
+static nserror
search_text(const char *string,
int string_len,
struct textsearch_context *context,
@@ -486,22 +294,24 @@ search_text(const char *string,
struct rect bounds;
union content_msg_data msg_data;
bool case_sensitive, forwards, showall;
+ nserror res = NSERROR_OK;
case_sensitive = ((flags & SEARCH_FLAG_CASE_SENSITIVE) != 0) ?
true : false;
forwards = ((flags & SEARCH_FLAG_FORWARDS) != 0) ? true : false;
showall = ((flags & SEARCH_FLAG_SHOWALL) != 0) ? true : false;
- if (context->c == NULL)
- return;
+ if (context->c == NULL) {
+ return res;
+ }
/* check if we need to start a new search or continue an old one */
if ((context->newsearch) ||
(context->prev_case_sens != case_sensitive)) {
- bool res;
- if (context->string != NULL)
+ if (context->string != NULL) {
free(context->string);
+ }
context->current = NULL;
free_matches(context);
@@ -514,19 +324,18 @@ search_text(const char *string,
guit->search->hourglass(true, context->gui_p);
- if (context->is_html == true) {
- res = find_occurrences_html(string, string_len,
- context->c, case_sensitive, context);
- } else {
- res = find_occurrences_text(string, string_len,
- context->c, case_sensitive, context);
- }
+ /* call content find handler */
+ res = context->c->handler->textsearch_find(context->c,
+ context,
+ string,
+ string_len,
+ case_sensitive);
guit->search->hourglass(false, context->gui_p);
- if (!res) {
+ if (res != NSERROR_OK) {
free_matches(context);
- return;
+ return res;
}
context->prev_case_sens = case_sensitive;
@@ -557,40 +366,48 @@ search_text(const char *string,
(context->current->next != NULL),
context->gui_p);
- if (context->current == NULL)
- return;
-
- if (context->is_html == true) {
- /* get box position and jump to it */
- box_coords(context->current->start_box, &bounds.x0, &bounds.y0);
- /* \todo: move x0 in by correct idx */
- box_coords(context->current->end_box, &bounds.x1, &bounds.y1);
- /* \todo: move x1 in by correct idx */
- bounds.x1 += context->current->end_box->width;
- bounds.y1 += context->current->end_box->height;
- } else {
- textplain_coords_from_range(context->c,
- context->current->start_idx,
- context->current->end_idx, &bounds);
+ if (context->current == NULL) {
+ return res;
}
- msg_data.scroll.area = true;
- msg_data.scroll.x0 = bounds.x0;
- msg_data.scroll.y0 = bounds.y0;
- msg_data.scroll.x1 = bounds.x1;
- msg_data.scroll.y1 = bounds.y1;
- content_broadcast(context->c, CONTENT_MSG_SCROLL, &msg_data);
+ /* call content match bounds handler */
+ res = context->c->handler->textsearch_bounds(context->c,
+
context->current->start_idx,
+ context->current->end_idx,
+
+
context->current->start_box,
+ context->current->end_box,
+ &bounds);
+ if (res == NSERROR_OK) {
+ msg_data.scroll.area = true;
+ msg_data.scroll.x0 = bounds.x0;
+ msg_data.scroll.y0 = bounds.y0;
+ msg_data.scroll.x1 = bounds.x1;
+ msg_data.scroll.y1 = bounds.y1;
+ content_broadcast(context->c, CONTENT_MSG_SCROLL, &msg_data);
+ }
+
+ return res;
}
-/* Exported function documented in context/textsearch.h */
-nserror
+/**
+ * Begins/continues the search process
+ *
+ * \note that this may be called many times for a single search.
+ *
+ * \param context The search context in use.
+ * \param flags The flags forward/back etc
+ * \param string The string to match
+ */
+static nserror
content_textsearch_step(struct textsearch_context *textsearch,
search_flags_t flags,
const char *string)
{
int string_len;
int i = 0;
+ nserror res = NSERROR_OK;
assert(textsearch != NULL);
@@ -603,7 +420,7 @@ content_textsearch_step(struct textsearch_context
*textsearch,
}
if (i < string_len) {
- search_text(string, string_len, textsearch, flags);
+ res = search_text(string, string_len, textsearch, flags);
} else {
union content_msg_data msg_data;
free_matches(textsearch);
@@ -618,7 +435,7 @@ content_textsearch_step(struct textsearch_context
*textsearch,
content_broadcast(textsearch->c, CONTENT_MSG_SCROLL, &msg_data);
}
- return NSERROR_OK;
+ return res;
}
@@ -649,7 +466,15 @@ content_textsearch_ishighlighted(struct textsearch_context
*textsearch,
/* Exported function documented in content/textsearch.h */
-nserror
+/**
+ * create a search_context
+ *
+ * \param c The content the search_context is connected to
+ * \param context A context pointer passed to the provider routines.
+ * \param search_out A pointer to recive the new text search context
+ * \return NSERROR_OK on success and \a search_out updated else error code
+ */
+static nserror
content_textsearch_create(struct content *c,
void *gui_data,
struct textsearch_context **textsearch_out)
@@ -658,12 +483,18 @@ content_textsearch_create(struct content *c,
struct list_entry *search_head;
content_type type;
- type = c->handler->type();
-
- if (type != CONTENT_HTML && type != CONTENT_TEXTPLAIN) {
+ if ((c->handler->textsearch_find == NULL) ||
+ (c->handler->textsearch_bounds == NULL) ||
+ (c->handler->create_selection == NULL)){
+ /*
+ * content has no free text find handler so searching
+ * is unsupported.
+ */
return NSERROR_NOT_IMPLEMENTED;
}
+ type = c->handler->type();
+
context = malloc(sizeof(struct textsearch_context));
if (context == NULL) {
return NSERROR_NOMEM;
@@ -689,7 +520,6 @@ content_textsearch_create(struct content *c,
context->prev_case_sens = false;
context->newsearch = true;
context->c = c;
- context->is_html = (type == CONTENT_HTML) ? true : false;
context->gui_p = gui_data;
*textsearch_out = context;
@@ -716,3 +546,83 @@ nserror content_textsearch_destroy(struct
textsearch_context *textsearch)
return NSERROR_OK;
}
+
+/**
+ * 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/textsearch.h */
+nserror
+content_textsearch(struct hlcache_handle *h,
+ void *context,
+ search_flags_t flags,
+ const char *string)
+{
+ struct content *c = hlcache_handle_get_content(h);
+ nserror res;
+
+ 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/textsearch.h */
+nserror content_textsearch_clear(struct hlcache_handle *h)
+{
+ struct content *c = hlcache_handle_get_content(h);
+ assert(c != 0);
+
+ return(content_textsearch__clear(c));
+}
diff --git a/content/textsearch.h b/content/textsearch.h
index f94bcdb..e30ebc4 100644
--- a/content/textsearch.h
+++ b/content/textsearch.h
@@ -24,34 +24,11 @@
#ifndef NETSURF_CONTENT_SEARCH_H
#define NETSURF_CONTENT_SEARCH_H
-#include <ctype.h>
-#include <string.h>
-
#include "desktop/search.h"
struct textsearch_context;
struct content;
-
-/**
- * create a search_context
- *
- * \param c The content the search_context is connected to
- * \param context A context pointer passed to the provider routines.
- * \param search_out A pointer to recive the new text search context
- * \return NSERROR_OK on success and \a search_out updated else error code
- */
-nserror content_textsearch_create(struct content *c, void *context, struct
textsearch_context **textsearch_out);
-
-/**
- * Begins/continues the search process
- *
- * \note that this may be called many times for a single search.
- *
- * \param context The search context in use.
- * \param flags The flags forward/back etc
- * \param string The string to match
- */
-nserror content_textsearch_step(struct textsearch_context *textsearch,
search_flags_t flags, const char *string);
+struct box;
/**
* Ends the search process, invalidating all state freeing the list of
@@ -77,4 +54,29 @@ bool content_textsearch_ishighlighted(struct
textsearch_context *textsearch,
unsigned *start_idx,
unsigned *end_idx);
+/**
+ * Find the first occurrence of 'match' in 'string' and return its index
+ *
+ * \param string the string to be searched (unterminated)
+ * \param s_len length of the string to be searched
+ * \param pattern the pattern for which we are searching (unterminated)
+ * \param p_len length of pattern
+ * \param case_sens true iff case sensitive match required
+ * \param m_len accepts length of match in bytes
+ * \return pointer to first match, NULL if none
+ */
+const char *content_textsearch_find_pattern(const char *string, int s_len,
const char *pattern, int p_len, bool case_sens, unsigned int *m_len);
+
+/**
+ * Add a new entry to the list of matches
+ *
+ * \param context The search context to add the entry to.
+ * \param start_idx Offset of match start within textual representation
+ * \param end_idx Offset of match end
+ * \param start A pointer for the start
+ * \param end A pointer for the end
+ * \return NSERROR_OK on sucess else error code on faliure
+ */
+nserror content_textsearch_add_match(struct textsearch_context *context,
unsigned start_idx, unsigned end_idx, struct box *start_ptr, struct box
*end_ptr);
+
#endif
diff --git a/desktop/search.c b/desktop/search.c
index c4b5b35..d4abfed 100644
--- a/desktop/search.c
+++ b/desktop/search.c
@@ -23,6 +23,8 @@
* Free text search (core)
*/
+#include <stdbool.h>
+
#include "utils/errors.h"
#include "content/content.h"
#include "netsurf/types.h"
@@ -37,7 +39,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 +48,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);
}
}
--
NetSurf Browser
_______________________________________________
netsurf-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]