mirror of
https://github.com/rkd77/elinks.git
synced 2024-09-29 03:17:53 -04:00
Allow for multiple callbacks to be attached to the DOM stack
This commit is contained in:
parent
e309de8950
commit
625725f0e9
@ -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;
|
||||
|
@ -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,18 +91,20 @@ static void
|
||||
call_dom_stack_callbacks(struct dom_stack *stack, struct dom_stack_state *state,
|
||||
enum dom_stack_action action)
|
||||
{
|
||||
/* 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;
|
||||
|
||||
for (i = 0; i < stack->callbacks_size; i++) {
|
||||
dom_stack_callback_T callback;
|
||||
|
||||
if (!stack->callbacks)
|
||||
callback = NULL;
|
||||
else if (action == DOM_STACK_PUSH)
|
||||
callback = stack->callbacks->push[state->node->type];
|
||||
if (action == DOM_STACK_PUSH)
|
||||
callback = stack->callbacks[i]->push[state->node->type];
|
||||
else
|
||||
callback = stack->callbacks->pop[state->node->type];
|
||||
|
||||
if (callback) {
|
||||
void *state_data = get_dom_stack_state_data(stack, state);
|
||||
callback = stack->callbacks[i]->pop[state->node->type];
|
||||
|
||||
if (callback)
|
||||
callback(stack, state->node, state_data);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user