1
0
mirror of https://github.com/rkd77/elinks.git synced 2025-02-02 15:09:23 -05:00

[links] Added reverse_link_lookup. Refs #346

Now goto_link_number ought to work with and without tabindex.
This commit is contained in:
Witold Filipczyk 2024-12-30 18:59:28 +01:00
parent 806f95bd46
commit 1e383b54d1
5 changed files with 75 additions and 1 deletions

View File

@ -325,6 +325,7 @@ reset_document(struct document *document)
mem_free_set(&document->links, NULL);
document->nlinks = 0;
}
mem_free_set(&document->reverse_link_lookup, NULL);
if (document->data) {
int pos;
@ -391,6 +392,7 @@ done_document(struct document *document)
mem_free(document->links);
}
mem_free_set(&document->reverse_link_lookup, NULL);
if (document->data) {
int pos;

View File

@ -137,6 +137,7 @@ struct link {
int npoints;
int number;
unsigned int tabindex;
/** This is supposed to be the colour-pair of the link, but the actual
* colours on the canvas can differ--e.g., with image links. */
@ -153,6 +154,11 @@ struct link {
} data;
};
struct reverse_link_lookup {
int number;
int i;
};
#define get_link_index(document, link) (link - document->links)
#define link_is_textinput(link) \
@ -271,6 +277,8 @@ struct document {
struct line *data;
struct link *links;
struct reverse_link_lookup *reverse_link_lookup;
/** @name Arrays with one item per rendered document's line.
* @{ */
struct link **lines1; /**< The first link on the line. */

View File

@ -1309,7 +1309,7 @@ new_link(struct html_context *html_context, const char *name, int namelen)
link = &document->links[document->nlinks++];
link->number = link_number - 1;
if (document->options.use_tabindex) link->number += elformat.tabindex;
link->tabindex = document->options.use_tabindex ? elformat.tabindex : 0;
link->accesskey = elformat.accesskey;
link->title = null_or_stracpy(elformat.title);
link->where_img = null_or_stracpy(elformat.image);

View File

@ -358,6 +358,14 @@ comp_links(const void *v1, const void *v2)
assert(l1 && l2);
if_assert_failed return 0;
if (l1->tabindex < l2->tabindex) {
return -1;
}
if (l1->tabindex > l2->tabindex) {
return 1;
}
if (l1->number < l2->number) {
return -1;
}
@ -369,6 +377,26 @@ comp_links(const void *v1, const void *v2)
return 0;
}
static int
comp_ints(const void *v1, const void *v2)
{
const struct reverse_link_lookup *l1 = (const struct reverse_link_lookup *)v1, *l2 = (const struct reverse_link_lookup *)v2;
assert(l1 && l2);
if_assert_failed return 0;
if (l1->number < l2->number) {
return -1;
}
if (l1->number > l2->number) {
return 1;
}
return 0;
}
void
sort_links(struct document *document)
{
@ -420,6 +448,21 @@ sort_links(struct document *document)
document->lines1[j] = &document->links[i];
}
}
mem_free_set(&document->reverse_link_lookup, NULL);
if (document->options.use_tabindex) {
document->reverse_link_lookup = mem_alloc(document->nlinks * sizeof(*document->reverse_link_lookup));
if (document->reverse_link_lookup) {
for (i = 0; i < document->nlinks; i++) {
struct link *link = &document->links[i];
document->reverse_link_lookup[i].number = link->number;
document->reverse_link_lookup[i].i = i;
}
qsort(document->reverse_link_lookup, document->nlinks, sizeof(*document->reverse_link_lookup), comp_ints);
}
}
document->links_sorted = 1;
}

View File

@ -1281,6 +1281,15 @@ jump_to_link_number(struct session *ses, struct document_view *doc_view, int n)
current_link_hover(doc_view);
}
static int
compare(const void *a, const void *b)
{
int na = ((struct reverse_link_lookup *)a)->number;
int nb = ((struct reverse_link_lookup *)b)->number;
return na - nb;
}
/** This is common backend for goto_link_number() and try_document_key(). */
static void
goto_link_number_do(struct session *ses, struct document_view *doc_view, int n)
@ -1289,6 +1298,18 @@ goto_link_number_do(struct session *ses, struct document_view *doc_view, int n)
assert(ses && doc_view && doc_view->document);
if_assert_failed return;
struct document *document = doc_view->document;
if (document->reverse_link_lookup) {
struct reverse_link_lookup key = { .number = n+1, .i = 0 };
struct reverse_link_lookup *res = bsearch(&key, document->reverse_link_lookup, document->nlinks, sizeof(*res), compare);
if (res == NULL) {
return;
}
n = res->i;
}
if (n < 0 || n >= doc_view->document->nlinks) return;
jump_to_link_number(ses, doc_view, n);