move free text search general interface to content.
needs additional cleanup to call content through handler table to perform searches.
This commit is contained in:
parent
e72ca36863
commit
a8596a80ae
|
@ -1,7 +1,16 @@
|
|||
# Content sources
|
||||
|
||||
S_CONTENT := content.c content_factory.c dirlist.c fetch.c hlcache.c \
|
||||
llcache.c mimesniff.c urldb.c no_backing_store.c
|
||||
S_CONTENT := \
|
||||
content.c \
|
||||
content_factory.c \
|
||||
dirlist.c \
|
||||
fetch.c \
|
||||
hlcache.c \
|
||||
llcache.c \
|
||||
mimesniff.c \
|
||||
textsearch.c \
|
||||
urldb.c \
|
||||
no_backing_store.c
|
||||
|
||||
# Make filesystem backing store available
|
||||
ifeq ($(NETSURF_FS_BACKING_STORE),YES)
|
||||
|
|
|
@ -20,5 +20,4 @@ S_HTML := box_construct.c \
|
|||
redraw.c \
|
||||
redraw_border.c \
|
||||
script.c \
|
||||
search.c \
|
||||
table.c
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "netsurf/misc.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "content/content_factory.h"
|
||||
#include "content/textsearch.h"
|
||||
#include "desktop/selection.h"
|
||||
#include "desktop/scrollbar.h"
|
||||
#include "desktop/textarea.h"
|
||||
|
@ -69,7 +70,6 @@
|
|||
#include "html/form_internal.h"
|
||||
#include "html/imagemap.h"
|
||||
#include "html/layout.h"
|
||||
#include "html/search.h"
|
||||
|
||||
#define CHUNK 4096
|
||||
|
||||
|
@ -1327,7 +1327,7 @@ static nserror html_close(struct content *c)
|
|||
selection_clear(&htmlc->sel, false);
|
||||
|
||||
if (htmlc->search != NULL) {
|
||||
search_destroy_context(htmlc->search);
|
||||
content_textsearch_destroy(htmlc->search);
|
||||
}
|
||||
|
||||
/* clear the html content reference to the browser window */
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "netsurf/layout.h"
|
||||
#include "netsurf/keypress.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "content/textsearch.h"
|
||||
#include "desktop/frames.h"
|
||||
#include "desktop/scrollbar.h"
|
||||
#include "desktop/selection.h"
|
||||
|
@ -55,7 +56,6 @@
|
|||
#include "html/form_internal.h"
|
||||
#include "html/private.h"
|
||||
#include "html/imagemap.h"
|
||||
#include "html/search.h"
|
||||
#include "html/interaction.h"
|
||||
|
||||
/**
|
||||
|
@ -1602,17 +1602,18 @@ bool html_keypress(struct content *c, uint32_t key)
|
|||
* Handle search.
|
||||
*
|
||||
* \param c content of type HTML
|
||||
* \param context front end private data
|
||||
* \param fe_ctx front end private data
|
||||
* \param flags search flags
|
||||
* \param string search string
|
||||
*/
|
||||
void
|
||||
html_search(struct content *c,
|
||||
void *context,
|
||||
void *fe_ctx,
|
||||
search_flags_t flags,
|
||||
const char *string)
|
||||
{
|
||||
html_content *html = (html_content *)c;
|
||||
nserror res;
|
||||
|
||||
assert(c != NULL);
|
||||
|
||||
|
@ -1621,7 +1622,7 @@ html_search(struct content *c,
|
|||
(strcmp(string, html->search_string) == 0) &&
|
||||
(html->search != NULL)) {
|
||||
/* Continue prev. search */
|
||||
search_step(html->search, flags, string);
|
||||
content_textsearch_step(html->search, flags, string);
|
||||
|
||||
} else if (string != NULL) {
|
||||
/* New search */
|
||||
|
@ -1631,16 +1632,16 @@ html_search(struct content *c,
|
|||
return;
|
||||
|
||||
if (html->search != NULL) {
|
||||
search_destroy_context(html->search);
|
||||
content_textsearch_destroy(html->search);
|
||||
html->search = NULL;
|
||||
}
|
||||
|
||||
html->search = search_create_context(c, CONTENT_HTML, context);
|
||||
|
||||
if (html->search == NULL)
|
||||
res = content_textsearch_create(c, fe_ctx, &html->search);
|
||||
if (res != NSERROR_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
search_step(html->search, flags, string);
|
||||
content_textsearch_step(html->search, flags, string);
|
||||
|
||||
} else {
|
||||
/* Clear search */
|
||||
|
@ -1653,9 +1654,9 @@ html_search(struct content *c,
|
|||
|
||||
|
||||
/**
|
||||
* Terminate a search.
|
||||
* Terminate a text search.
|
||||
*
|
||||
* \param c content of type HTML
|
||||
* \param c content of type HTML
|
||||
*/
|
||||
void html_search_clear(struct content *c)
|
||||
{
|
||||
|
@ -1667,7 +1668,7 @@ void html_search_clear(struct content *c)
|
|||
html->search_string = NULL;
|
||||
|
||||
if (html->search != NULL) {
|
||||
search_destroy_context(html->search);
|
||||
content_textsearch_destroy(html->search);
|
||||
}
|
||||
html->search = NULL;
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ typedef struct html_content {
|
|||
struct form_control *visible_select_menu;
|
||||
|
||||
/** Context for free text search, or NULL if none */
|
||||
struct search_context *search;
|
||||
struct textsearch_context *search;
|
||||
/** Search string or NULL */
|
||||
char *search_string;
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "netsurf/layout.h"
|
||||
#include "content/content.h"
|
||||
#include "content/content_protected.h"
|
||||
#include "content/textsearch.h"
|
||||
#include "css/utils.h"
|
||||
#include "desktop/selection.h"
|
||||
#include "desktop/print.h"
|
||||
|
@ -61,7 +62,6 @@
|
|||
#include "html/form_internal.h"
|
||||
#include "html/private.h"
|
||||
#include "html/layout.h"
|
||||
#include "html/search.h"
|
||||
|
||||
|
||||
bool html_redraw_debug = false;
|
||||
|
@ -167,7 +167,7 @@ text_redraw(const char *utf8_text,
|
|||
bool excluded,
|
||||
struct content *c,
|
||||
const struct selection *sel,
|
||||
struct search_context *search,
|
||||
struct textsearch_context *search,
|
||||
const struct redraw_context *ctx)
|
||||
{
|
||||
bool highlighted = false;
|
||||
|
@ -184,18 +184,23 @@ text_redraw(const char *utf8_text,
|
|||
unsigned end_idx;
|
||||
|
||||
/* first try the browser window's current selection */
|
||||
if (selection_defined(sel) && selection_highlighted(sel,
|
||||
offset, offset + len,
|
||||
&start_idx, &end_idx)) {
|
||||
if (selection_defined(sel) &&
|
||||
selection_highlighted(sel,
|
||||
offset,
|
||||
offset + len,
|
||||
&start_idx,
|
||||
&end_idx)) {
|
||||
highlighted = true;
|
||||
}
|
||||
|
||||
/* what about the current search operation, if any? */
|
||||
if (!highlighted && (search != NULL) &&
|
||||
search_term_highlighted(c,
|
||||
offset, offset + len,
|
||||
&start_idx, &end_idx,
|
||||
search)) {
|
||||
if (!highlighted &&
|
||||
(search != NULL) &&
|
||||
content_textsearch_ishighlighted(search,
|
||||
offset,
|
||||
offset + len,
|
||||
&start_idx,
|
||||
&end_idx)) {
|
||||
highlighted = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,10 +41,10 @@
|
|||
#include "content/content_protected.h"
|
||||
#include "content/content_factory.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "content/textsearch.h"
|
||||
#include "desktop/selection.h"
|
||||
#include "desktop/gui_internal.h"
|
||||
|
||||
#include "html/search.h"
|
||||
#include "text/textplain.h"
|
||||
|
||||
struct textplain_line {
|
||||
|
@ -71,7 +71,7 @@ typedef struct textplain_content {
|
|||
struct selection sel; /** Selection state */
|
||||
|
||||
/** Context for free text search, or NULL if none */
|
||||
struct search_context *search;
|
||||
struct textsearch_context *search;
|
||||
/** Current search string, or NULL if none */
|
||||
char *search_string;
|
||||
} textplain_content;
|
||||
|
@ -753,7 +753,7 @@ static void textplain_search_clear(struct content *c)
|
|||
text->search_string = NULL;
|
||||
|
||||
if (text->search != NULL) {
|
||||
search_destroy_context(text->search);
|
||||
content_textsearch_destroy(text->search);
|
||||
}
|
||||
text->search = NULL;
|
||||
}
|
||||
|
@ -771,14 +771,16 @@ 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 &&
|
||||
if (string != NULL &&
|
||||
text->search_string != NULL &&
|
||||
strcmp(string, text->search_string) == 0 &&
|
||||
text->search != NULL) {
|
||||
/* Continue prev. search */
|
||||
search_step(text->search, flags, string);
|
||||
content_textsearch_step(text->search, flags, string);
|
||||
|
||||
} else if (string != NULL) {
|
||||
/* New search */
|
||||
|
@ -788,17 +790,16 @@ static void textplain_search(struct content *c, void *gui_data,
|
|||
return;
|
||||
|
||||
if (text->search != NULL) {
|
||||
search_destroy_context(text->search);
|
||||
content_textsearch_destroy(text->search);
|
||||
text->search = NULL;
|
||||
}
|
||||
|
||||
text->search = search_create_context(c, CONTENT_TEXTPLAIN,
|
||||
gui_data);
|
||||
|
||||
if (text->search == NULL)
|
||||
res = content_textsearch_create(c, gui_data, &text->search);
|
||||
if (res != NSERROR_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
search_step(text->search, flags, string);
|
||||
content_textsearch_step(text->search, flags, string);
|
||||
|
||||
} else {
|
||||
/* Clear search */
|
||||
|
@ -839,7 +840,6 @@ text_draw(const char *utf8_text,
|
|||
float scale,
|
||||
textplain_content *text,
|
||||
const struct selection *sel,
|
||||
struct search_context *search,
|
||||
const struct redraw_context *ctx)
|
||||
{
|
||||
bool highlighted = false;
|
||||
|
@ -868,13 +868,12 @@ text_draw(const char *utf8_text,
|
|||
|
||||
/* what about the current search operation, if any? */
|
||||
if (!highlighted &&
|
||||
(search != NULL) &&
|
||||
search_term_highlighted((struct content *)text,
|
||||
offset,
|
||||
offset + len,
|
||||
&start_idx,
|
||||
&end_idx,
|
||||
search)) {
|
||||
(text->search != NULL) &&
|
||||
content_textsearch_ishighlighted(text->search,
|
||||
offset,
|
||||
offset + len,
|
||||
&start_idx,
|
||||
&end_idx)) {
|
||||
highlighted = true;
|
||||
}
|
||||
|
||||
|
@ -1125,7 +1124,6 @@ textplain_redraw(struct content *c,
|
|||
data->scale,
|
||||
text,
|
||||
&text->sel,
|
||||
text->search,
|
||||
ctx)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1165,15 +1163,17 @@ textplain_redraw(struct content *c,
|
|||
highlighted = true;
|
||||
}
|
||||
|
||||
if (!highlighted && (text->search != NULL)) {
|
||||
if (!highlighted &&
|
||||
(text->search != NULL)) {
|
||||
unsigned start_idx, end_idx;
|
||||
if (search_term_highlighted(c,
|
||||
tab_ofst,
|
||||
tab_ofst + 1,
|
||||
&start_idx,
|
||||
&end_idx,
|
||||
text->search))
|
||||
if (content_textsearch_ishighlighted(
|
||||
text->search,
|
||||
tab_ofst,
|
||||
tab_ofst + 1,
|
||||
&start_idx,
|
||||
&end_idx)) {
|
||||
highlighted = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (highlighted) {
|
||||
|
@ -1228,7 +1228,7 @@ static nserror textplain_close(struct content *c)
|
|||
textplain_content *text = (textplain_content *) c;
|
||||
|
||||
if (text->search != NULL) {
|
||||
search_destroy_context(text->search);
|
||||
content_textsearch_destroy(text->search);
|
||||
}
|
||||
|
||||
text->bw = NULL;
|
||||
|
|
|
@ -20,34 +20,27 @@
|
|||
|
||||
/**
|
||||
* \file
|
||||
* Free text search (core)
|
||||
* Free text search
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <dom/dom.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "utils/config.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/messages.h"
|
||||
#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/misc.h"
|
||||
#include "netsurf/content_type.h"
|
||||
#include "desktop/gui_internal.h"
|
||||
|
||||
#include "text/textplain.h"
|
||||
#include "html/box.h"
|
||||
#include "html/box_inspect.h"
|
||||
#include "html/html.h"
|
||||
#include "html/private.h"
|
||||
#include "html/search.h"
|
||||
|
||||
#ifndef NOF_ELEMENTS
|
||||
#define NOF_ELEMENTS(array) (sizeof(array)/sizeof(*(array)))
|
||||
#endif
|
||||
#include "content/textsearch.h"
|
||||
|
||||
|
||||
struct list_entry {
|
||||
|
@ -63,7 +56,10 @@ struct list_entry {
|
|||
struct list_entry *next;
|
||||
};
|
||||
|
||||
struct search_context {
|
||||
/**
|
||||
* The context for a free text search
|
||||
*/
|
||||
struct textsearch_context {
|
||||
void *gui_p;
|
||||
struct content *c;
|
||||
struct list_entry *found;
|
||||
|
@ -75,75 +71,35 @@ struct search_context {
|
|||
};
|
||||
|
||||
|
||||
/* Exported function documented in search.h */
|
||||
struct search_context *
|
||||
search_create_context(struct content *c, content_type type, void *gui_data)
|
||||
{
|
||||
struct search_context *context;
|
||||
struct list_entry *search_head;
|
||||
|
||||
if (type != CONTENT_HTML && type != CONTENT_TEXTPLAIN) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context = malloc(sizeof(struct search_context));
|
||||
if (context == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
search_head = malloc(sizeof(struct list_entry));
|
||||
if (search_head == NULL) {
|
||||
free(context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
search_head->start_idx = 0;
|
||||
search_head->end_idx = 0;
|
||||
search_head->start_box = NULL;
|
||||
search_head->end_box = NULL;
|
||||
search_head->sel = NULL;
|
||||
search_head->prev = NULL;
|
||||
search_head->next = NULL;
|
||||
|
||||
context->found = search_head;
|
||||
context->current = NULL;
|
||||
context->string = NULL;
|
||||
context->prev_case_sens = false;
|
||||
context->newsearch = true;
|
||||
context->c = c;
|
||||
context->is_html = (type == CONTENT_HTML) ? true : false;
|
||||
context->gui_p = gui_data;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Release the memory used by the list of matches,
|
||||
* deleting selection objects too
|
||||
*/
|
||||
|
||||
static void free_matches(struct search_context *context)
|
||||
static void free_matches(struct textsearch_context *textsearch)
|
||||
{
|
||||
struct list_entry *a;
|
||||
struct list_entry *b;
|
||||
struct list_entry *cur;
|
||||
struct list_entry *nxt;
|
||||
|
||||
a = context->found->next;
|
||||
cur = textsearch->found->next;
|
||||
|
||||
/* empty the list before clearing and deleting the
|
||||
* selections because the the clearing updates the
|
||||
* screen immediately, causing nested accesses to the list */
|
||||
/*
|
||||
* empty the list before clearing and deleting the selections
|
||||
* because the the clearing may update the toolkit immediately,
|
||||
* causing nested accesses to the list
|
||||
*/
|
||||
|
||||
context->found->prev = NULL;
|
||||
context->found->next = NULL;
|
||||
textsearch->found->prev = NULL;
|
||||
textsearch->found->next = NULL;
|
||||
|
||||
for (; a; a = b) {
|
||||
b = a->next;
|
||||
if (a->sel) {
|
||||
selection_clear(a->sel, true);
|
||||
selection_destroy(a->sel);
|
||||
for (; cur; cur = nxt) {
|
||||
nxt = cur->next;
|
||||
if (cur->sel) {
|
||||
selection_clear(cur->sel, true);
|
||||
selection_destroy(cur->sel);
|
||||
}
|
||||
free(a);
|
||||
free(cur);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,10 +115,13 @@ static void free_matches(struct search_context *context)
|
|||
* \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)
|
||||
static const char *
|
||||
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;
|
||||
|
@ -275,7 +234,9 @@ static const char *find_pattern(const char *string, int s_len,
|
|||
* \return Pointer to added entry, NULL iff failed.
|
||||
*/
|
||||
static struct list_entry *
|
||||
add_entry(unsigned start_idx, unsigned end_idx, struct search_context *context)
|
||||
add_entry(unsigned start_idx,
|
||||
unsigned end_idx,
|
||||
struct textsearch_context *context)
|
||||
{
|
||||
struct list_entry *entry;
|
||||
|
||||
|
@ -289,7 +250,7 @@ add_entry(unsigned start_idx, unsigned end_idx, struct search_context *context)
|
|||
entry->end_idx = end_idx;
|
||||
entry->sel = NULL;
|
||||
|
||||
entry->next = 0;
|
||||
entry->next = NULL;
|
||||
entry->prev = context->found->prev;
|
||||
|
||||
if (context->found->prev == NULL) {
|
||||
|
@ -305,7 +266,7 @@ add_entry(unsigned start_idx, unsigned end_idx, struct search_context *context)
|
|||
|
||||
|
||||
/**
|
||||
* Finds all occurrences of a given string in the html box tree
|
||||
* Finds all occurrences of a given string in an html box
|
||||
*
|
||||
* \param pattern the string pattern to search for
|
||||
* \param p_len pattern length
|
||||
|
@ -314,9 +275,12 @@ add_entry(unsigned start_idx, unsigned end_idx, struct search_context *context)
|
|||
* \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 box *cur, bool case_sens,
|
||||
struct search_context *context)
|
||||
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;
|
||||
|
||||
|
@ -330,9 +294,14 @@ static bool find_occurrences_html(const char *pattern, int p_len,
|
|||
unsigned match_length;
|
||||
unsigned match_offset;
|
||||
const char *new_text;
|
||||
const char *pos = find_pattern(text, length,
|
||||
pattern, p_len, case_sens,
|
||||
&match_length);
|
||||
const char *pos;
|
||||
|
||||
pos = find_pattern(text,
|
||||
length,
|
||||
pattern,
|
||||
p_len,
|
||||
case_sens,
|
||||
&match_length);
|
||||
if (!pos)
|
||||
break;
|
||||
|
||||
|
@ -340,9 +309,8 @@ static bool find_occurrences_html(const char *pattern, int p_len,
|
|||
match_offset = pos - cur->text;
|
||||
|
||||
entry = add_entry(cur->byte_offset + match_offset,
|
||||
cur->byte_offset +
|
||||
match_offset +
|
||||
match_length, context);
|
||||
cur->byte_offset + match_offset + match_length,
|
||||
context);
|
||||
if (!entry)
|
||||
return false;
|
||||
|
||||
|
@ -357,14 +325,46 @@ static bool find_occurrences_html(const char *pattern, int p_len,
|
|||
|
||||
/* and recurse */
|
||||
for (a = cur->children; a; a = a->next) {
|
||||
if (!find_occurrences_html(pattern, p_len, a, case_sens,
|
||||
context))
|
||||
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
|
||||
|
@ -376,34 +376,41 @@ static bool find_occurrences_html(const char *pattern, int p_len,
|
|||
* \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 search_context *context)
|
||||
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 = textplain_get_line(c, line,
|
||||
&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 = find_pattern(text, length,
|
||||
pattern, p_len, case_sens,
|
||||
&match_length);
|
||||
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);
|
||||
entry = add_entry(start_idx,
|
||||
start_idx + match_length,
|
||||
context);
|
||||
if (!entry)
|
||||
return false;
|
||||
|
||||
|
@ -423,7 +430,7 @@ static bool find_occurrences_text(const char *pattern, int p_len,
|
|||
* Specifies whether all matches or just the current match should
|
||||
* be highlighted in the search text.
|
||||
*/
|
||||
static void search_show_all(bool all, struct search_context *context)
|
||||
static void search_show_all(bool all, struct textsearch_context *context)
|
||||
{
|
||||
struct list_entry *a;
|
||||
|
||||
|
@ -473,11 +480,10 @@ static void search_show_all(bool all, struct search_context *context)
|
|||
static void
|
||||
search_text(const char *string,
|
||||
int string_len,
|
||||
struct search_context *context,
|
||||
struct textsearch_context *context,
|
||||
search_flags_t flags)
|
||||
{
|
||||
struct rect bounds;
|
||||
struct box *box = NULL;
|
||||
union content_msg_data msg_data;
|
||||
bool case_sensitive, forwards, showall;
|
||||
|
||||
|
@ -489,16 +495,6 @@ search_text(const char *string,
|
|||
if (context->c == NULL)
|
||||
return;
|
||||
|
||||
if (context->is_html == true) {
|
||||
html_content *html = (html_content *)context->c;
|
||||
|
||||
box = html->layout;
|
||||
|
||||
if (!box)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* check if we need to start a new search or continue an old one */
|
||||
if ((context->newsearch) ||
|
||||
(context->prev_case_sens != case_sensitive)) {
|
||||
|
@ -520,18 +516,18 @@ search_text(const char *string,
|
|||
|
||||
if (context->is_html == true) {
|
||||
res = find_occurrences_html(string, string_len,
|
||||
box, case_sensitive, context);
|
||||
context->c, case_sensitive, context);
|
||||
} else {
|
||||
res = find_occurrences_text(string, string_len,
|
||||
context->c, case_sensitive, context);
|
||||
}
|
||||
|
||||
guit->search->hourglass(false, context->gui_p);
|
||||
|
||||
if (!res) {
|
||||
free_matches(context);
|
||||
guit->search->hourglass(false, context->gui_p);
|
||||
return;
|
||||
}
|
||||
guit->search->hourglass(false, context->gui_p);
|
||||
|
||||
context->prev_case_sens = case_sensitive;
|
||||
|
||||
|
@ -587,76 +583,136 @@ search_text(const char *string,
|
|||
}
|
||||
|
||||
|
||||
/* Exported function documented in search.h */
|
||||
void
|
||||
search_step(struct search_context *context,
|
||||
search_flags_t flags,
|
||||
const char *string)
|
||||
/* Exported function documented in context/textsearch.h */
|
||||
nserror
|
||||
content_textsearch_step(struct textsearch_context *textsearch,
|
||||
search_flags_t flags,
|
||||
const char *string)
|
||||
{
|
||||
int string_len;
|
||||
int i = 0;
|
||||
|
||||
assert(context != NULL);
|
||||
assert(textsearch != NULL);
|
||||
|
||||
guit->search->add_recent(string, context->gui_p);
|
||||
guit->search->add_recent(string, textsearch->gui_p);
|
||||
|
||||
string_len = strlen(string);
|
||||
for (i = 0; i < string_len; i++)
|
||||
for (i = 0; i < string_len; i++) {
|
||||
if (string[i] != '#' && string[i] != '*')
|
||||
break;
|
||||
if (i >= string_len) {
|
||||
union content_msg_data msg_data;
|
||||
free_matches(context);
|
||||
}
|
||||
|
||||
guit->search->status(true, context->gui_p);
|
||||
guit->search->back_state(false, context->gui_p);
|
||||
guit->search->forward_state(false, context->gui_p);
|
||||
if (i < string_len) {
|
||||
search_text(string, string_len, textsearch, flags);
|
||||
} else {
|
||||
union content_msg_data msg_data;
|
||||
free_matches(textsearch);
|
||||
|
||||
guit->search->status(true, textsearch->gui_p);
|
||||
guit->search->back_state(false, textsearch->gui_p);
|
||||
guit->search->forward_state(false, textsearch->gui_p);
|
||||
|
||||
msg_data.scroll.area = false;
|
||||
msg_data.scroll.x0 = 0;
|
||||
msg_data.scroll.y0 = 0;
|
||||
content_broadcast(context->c, CONTENT_MSG_SCROLL, &msg_data);
|
||||
return;
|
||||
content_broadcast(textsearch->c, CONTENT_MSG_SCROLL, &msg_data);
|
||||
}
|
||||
search_text(string, string_len, context, flags);
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Exported function documented in search.h */
|
||||
bool search_term_highlighted(struct content *c,
|
||||
unsigned start_offset, unsigned end_offset,
|
||||
unsigned *start_idx, unsigned *end_idx,
|
||||
struct search_context *context)
|
||||
/* Exported function documented in content/textsearch.h */
|
||||
bool
|
||||
content_textsearch_ishighlighted(struct textsearch_context *textsearch,
|
||||
unsigned start_offset,
|
||||
unsigned end_offset,
|
||||
unsigned *start_idx,
|
||||
unsigned *end_idx)
|
||||
{
|
||||
if (c == context->c) {
|
||||
struct list_entry *a;
|
||||
for (a = context->found->next; a; a = a->next)
|
||||
if (a->sel && selection_defined(a->sel) &&
|
||||
selection_highlighted(a->sel,
|
||||
start_offset, end_offset,
|
||||
start_idx, end_idx))
|
||||
return true;
|
||||
struct list_entry *cur;
|
||||
|
||||
for (cur = textsearch->found->next; cur != NULL; cur = cur->next) {
|
||||
if (cur->sel &&
|
||||
selection_defined(cur->sel) &&
|
||||
selection_highlighted(cur->sel,
|
||||
start_offset,
|
||||
end_offset,
|
||||
start_idx,
|
||||
end_idx)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Exported function documented in content/textsearch.h */
|
||||
nserror
|
||||
content_textsearch_create(struct content *c,
|
||||
void *gui_data,
|
||||
struct textsearch_context **textsearch_out)
|
||||
{
|
||||
struct textsearch_context *context;
|
||||
struct list_entry *search_head;
|
||||
content_type type;
|
||||
|
||||
type = c->handler->type();
|
||||
|
||||
if (type != CONTENT_HTML && type != CONTENT_TEXTPLAIN) {
|
||||
return NSERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
context = malloc(sizeof(struct textsearch_context));
|
||||
if (context == NULL) {
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
search_head = malloc(sizeof(struct list_entry));
|
||||
if (search_head == NULL) {
|
||||
free(context);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
search_head->start_idx = 0;
|
||||
search_head->end_idx = 0;
|
||||
search_head->start_box = NULL;
|
||||
search_head->end_box = NULL;
|
||||
search_head->sel = NULL;
|
||||
search_head->prev = NULL;
|
||||
search_head->next = NULL;
|
||||
|
||||
context->found = search_head;
|
||||
context->current = NULL;
|
||||
context->string = NULL;
|
||||
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;
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Exported function documented in search.h */
|
||||
void search_destroy_context(struct search_context *context)
|
||||
nserror content_textsearch_destroy(struct textsearch_context *textsearch)
|
||||
{
|
||||
assert(context != NULL);
|
||||
assert(textsearch != NULL);
|
||||
|
||||
if (context->string != NULL) {
|
||||
guit->search->add_recent(context->string, context->gui_p);
|
||||
free(context->string);
|
||||
if (textsearch->string != NULL) {
|
||||
guit->search->add_recent(textsearch->string, textsearch->gui_p);
|
||||
free(textsearch->string);
|
||||
}
|
||||
|
||||
guit->search->forward_state(true, context->gui_p);
|
||||
guit->search->back_state(true, context->gui_p);
|
||||
guit->search->forward_state(true, textsearch->gui_p);
|
||||
guit->search->back_state(true, textsearch->gui_p);
|
||||
|
||||
free_matches(context);
|
||||
free(context);
|
||||
free_matches(textsearch);
|
||||
free(textsearch);
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
|
@ -21,32 +21,26 @@
|
|||
* Interface to HTML searching.
|
||||
*/
|
||||
|
||||
#ifndef NETSURF_HTML_SEARCH_H
|
||||
#define NETSURF_HTML_SEARCH_H
|
||||
#ifndef NETSURF_CONTENT_SEARCH_H
|
||||
#define NETSURF_CONTENT_SEARCH_H
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "desktop/search.h"
|
||||
|
||||
struct search_context;
|
||||
struct textsearch_context;
|
||||
struct content;
|
||||
|
||||
/**
|
||||
* create a search_context
|
||||
*
|
||||
* \param c The content the search_context is connected to
|
||||
* \param type The content type of c
|
||||
* \param c The content the search_context is connected to
|
||||
* \param context A context pointer passed to the provider routines.
|
||||
* \return A new search context or NULL on error.
|
||||
* \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
|
||||
*/
|
||||
struct search_context *search_create_context(struct content *c,
|
||||
content_type type, void *context);
|
||||
|
||||
/**
|
||||
* Ends the search process, invalidating all state
|
||||
* freeing the list of found boxes
|
||||
*/
|
||||
void search_destroy_context(struct search_context *context);
|
||||
nserror content_textsearch_create(struct content *c, void *context, struct textsearch_context **textsearch_out);
|
||||
|
||||
/**
|
||||
* Begins/continues the search process
|
||||
|
@ -57,25 +51,30 @@ void search_destroy_context(struct search_context *context);
|
|||
* \param flags The flags forward/back etc
|
||||
* \param string The string to match
|
||||
*/
|
||||
void search_step(struct search_context *context, search_flags_t flags,
|
||||
const char * string);
|
||||
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
|
||||
* found boxes.
|
||||
*/
|
||||
nserror content_textsearch_destroy(struct textsearch_context *textsearch);
|
||||
|
||||
/**
|
||||
* Determines whether any portion of the given text box should be
|
||||
* selected because it matches the current search string.
|
||||
*
|
||||
* \param c The content to hilight within.
|
||||
* \param textsearch The search context to hilight entries from.
|
||||
* \param c The content to highlight within.
|
||||
* \param start_offset byte offset within text of string to be checked
|
||||
* \param end_offset byte offset within text
|
||||
* \param start_idx byte offset within string of highlight start
|
||||
* \param end_idx byte offset of highlight end
|
||||
* \param context The search context to hilight entries from.
|
||||
* \return true iff part of the box should be highlighted
|
||||
*/
|
||||
bool search_term_highlighted(struct content *c,
|
||||
unsigned start_offset, unsigned end_offset,
|
||||
unsigned *start_idx, unsigned *end_idx,
|
||||
struct search_context *context);
|
||||
bool content_textsearch_ishighlighted(struct textsearch_context *textsearch,
|
||||
unsigned start_offset,
|
||||
unsigned end_offset,
|
||||
unsigned *start_idx,
|
||||
unsigned *end_idx);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue