1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-28 01:35:32 +00:00

Allow for multiple callbacks to be attached to the DOM stack

This commit is contained in:
Jonas Fonseca 2005-12-20 20:27:20 +01:00 committed by Jonas Fonseca
parent e309de8950
commit 625725f0e9
4 changed files with 41 additions and 18 deletions

View File

@ -376,7 +376,7 @@ parse_dom_select(struct dom_select *select, unsigned char *string, int length)
struct dom_select_node sel;
init_scanner(&scanner, &css_scanner_info, string, string + length);
init_dom_stack(&stack, select, NULL, 0, 1);
init_dom_stack(&stack, select, 0, 1);
memset(&sel, 0, sizeof(sel));
@ -830,8 +830,10 @@ select_dom_nodes(struct dom_select *select, struct dom_node *root)
select_data.select = select;;
init_dom_stack(&stack, &select_data, &dom_select_callbacks, 0, 1);
init_dom_stack(&select_data.stack, &select_data, NULL, obj_size, 1);
init_dom_stack(&stack, &select_data, 0, 1);
add_dom_stack_callbacks(&stack, &dom_select_callbacks);
init_dom_stack(&select_data.stack, &select_data, obj_size, 1);
if (push_dom_node(&select_data.stack, &select->selector->node)) {
get_dom_stack_top(&select_data.stack)->immutable = 1;

View File

@ -46,7 +46,6 @@ realloc_dom_stack_state_objects(struct dom_stack *stack)
void
init_dom_stack(struct dom_stack *stack, void *data,
struct dom_stack_callbacks *callbacks,
size_t object_size, int keep_nodes)
{
assert(stack);
@ -56,7 +55,6 @@ init_dom_stack(struct dom_stack *stack, void *data,
stack->data = data;
stack->object_size = object_size;
stack->keep_nodes = !!keep_nodes;
stack->callbacks = callbacks;
}
void
@ -64,12 +62,26 @@ done_dom_stack(struct dom_stack *stack)
{
assert(stack);
mem_free_if(stack->callbacks);
mem_free_if(stack->states);
mem_free_if(stack->state_objects);
memset(stack, 0, sizeof(*stack));
}
void
add_dom_stack_callbacks(struct dom_stack *stack,
struct dom_stack_callbacks *callbacks)
{
struct dom_stack_callbacks **list;
list = mem_realloc(stack->callbacks, sizeof(*list) * (stack->callbacks_size + 1));
if (!list) return;
stack->callbacks = list;
stack->callbacks[stack->callbacks_size++] = callbacks;
}
enum dom_stack_action {
DOM_STACK_PUSH,
DOM_STACK_POP,
@ -79,19 +91,21 @@ static void
call_dom_stack_callbacks(struct dom_stack *stack, struct dom_stack_state *state,
enum dom_stack_action action)
{
dom_stack_callback_T callback;
/* FIME: Variable stack data, so the parse/selector/renderer/etc. can
* really work in parallel. */
void *state_data = get_dom_stack_state_data(stack, state);
int i;
if (!stack->callbacks)
callback = NULL;
else if (action == DOM_STACK_PUSH)
callback = stack->callbacks->push[state->node->type];
else
callback = stack->callbacks->pop[state->node->type];
for (i = 0; i < stack->callbacks_size; i++) {
dom_stack_callback_T callback;
if (callback) {
void *state_data = get_dom_stack_state_data(stack, state);
if (action == DOM_STACK_PUSH)
callback = stack->callbacks[i]->push[state->node->type];
else
callback = stack->callbacks[i]->pop[state->node->type];
callback(stack, state->node, state_data);
if (callback)
callback(stack, state->node, state_data);
}
}

View File

@ -54,7 +54,8 @@ struct dom_stack {
size_t object_size;
/* Callbacks which should be called for the pushed and popped nodes. */
struct dom_stack_callbacks *callbacks;
struct dom_stack_callbacks **callbacks;
size_t callbacks_size;
/* Data specific to the parser and renderer. */
void *data;
@ -115,10 +116,13 @@ search_dom_stack(struct dom_stack *stack, enum dom_node_type type,
* state to be assigned to the state's @data member. Zero means no state data should
* be allocated. */
void init_dom_stack(struct dom_stack *stack, void *data,
struct dom_stack_callbacks *callbacks,
size_t object_size, int keep_nodes);
void done_dom_stack(struct dom_stack *stack);
/* Add a callback collection to the stack. */
void add_dom_stack_callbacks(struct dom_stack *stack,
struct dom_stack_callbacks *callbacks);
/* Decends down to the given node making it the current parent */
/* If an error occurs the node is free()d and NULL is returned */
struct dom_node *push_dom_node(struct dom_stack *stack, struct dom_node *node);

View File

@ -319,8 +319,11 @@ init_sgml_parser(enum sgml_parser_type type, enum sgml_document_type doctype,
parser->info = get_sgml_info(doctype);
parser->data = data;
init_dom_stack(&parser->stack, parser, callbacks, obj_size,
init_dom_stack(&parser->stack, parser, obj_size,
type != SGML_PARSER_STREAM);
/* FIXME: Some sgml backend specific callbacks? Handle HTML script tags,
* and feed document.write() data back to the parser. */
add_dom_stack_callbacks(&parser->stack, callbacks);
parser->root = add_sgml_document(&parser->stack, parser->uri);
if (!parser->root) {