mirror of
https://github.com/rkd77/elinks.git
synced 2024-10-01 03:36:26 -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;
|
struct dom_select_node sel;
|
||||||
|
|
||||||
init_scanner(&scanner, &css_scanner_info, string, string + length);
|
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));
|
memset(&sel, 0, sizeof(sel));
|
||||||
|
|
||||||
@ -830,8 +830,10 @@ select_dom_nodes(struct dom_select *select, struct dom_node *root)
|
|||||||
|
|
||||||
select_data.select = select;;
|
select_data.select = select;;
|
||||||
|
|
||||||
init_dom_stack(&stack, &select_data, &dom_select_callbacks, 0, 1);
|
init_dom_stack(&stack, &select_data, 0, 1);
|
||||||
init_dom_stack(&select_data.stack, &select_data, NULL, obj_size, 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)) {
|
if (push_dom_node(&select_data.stack, &select->selector->node)) {
|
||||||
get_dom_stack_top(&select_data.stack)->immutable = 1;
|
get_dom_stack_top(&select_data.stack)->immutable = 1;
|
||||||
|
@ -46,7 +46,6 @@ realloc_dom_stack_state_objects(struct dom_stack *stack)
|
|||||||
|
|
||||||
void
|
void
|
||||||
init_dom_stack(struct dom_stack *stack, void *data,
|
init_dom_stack(struct dom_stack *stack, void *data,
|
||||||
struct dom_stack_callbacks *callbacks,
|
|
||||||
size_t object_size, int keep_nodes)
|
size_t object_size, int keep_nodes)
|
||||||
{
|
{
|
||||||
assert(stack);
|
assert(stack);
|
||||||
@ -56,7 +55,6 @@ init_dom_stack(struct dom_stack *stack, void *data,
|
|||||||
stack->data = data;
|
stack->data = data;
|
||||||
stack->object_size = object_size;
|
stack->object_size = object_size;
|
||||||
stack->keep_nodes = !!keep_nodes;
|
stack->keep_nodes = !!keep_nodes;
|
||||||
stack->callbacks = callbacks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -64,12 +62,26 @@ done_dom_stack(struct dom_stack *stack)
|
|||||||
{
|
{
|
||||||
assert(stack);
|
assert(stack);
|
||||||
|
|
||||||
|
mem_free_if(stack->callbacks);
|
||||||
mem_free_if(stack->states);
|
mem_free_if(stack->states);
|
||||||
mem_free_if(stack->state_objects);
|
mem_free_if(stack->state_objects);
|
||||||
|
|
||||||
memset(stack, 0, sizeof(*stack));
|
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 {
|
enum dom_stack_action {
|
||||||
DOM_STACK_PUSH,
|
DOM_STACK_PUSH,
|
||||||
DOM_STACK_POP,
|
DOM_STACK_POP,
|
||||||
@ -79,18 +91,20 @@ static void
|
|||||||
call_dom_stack_callbacks(struct dom_stack *stack, struct dom_stack_state *state,
|
call_dom_stack_callbacks(struct dom_stack *stack, struct dom_stack_state *state,
|
||||||
enum dom_stack_action action)
|
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;
|
dom_stack_callback_T callback;
|
||||||
|
|
||||||
if (!stack->callbacks)
|
if (action == DOM_STACK_PUSH)
|
||||||
callback = NULL;
|
callback = stack->callbacks[i]->push[state->node->type];
|
||||||
else if (action == DOM_STACK_PUSH)
|
|
||||||
callback = stack->callbacks->push[state->node->type];
|
|
||||||
else
|
else
|
||||||
callback = stack->callbacks->pop[state->node->type];
|
callback = stack->callbacks[i]->pop[state->node->type];
|
||||||
|
|
||||||
if (callback) {
|
|
||||||
void *state_data = get_dom_stack_state_data(stack, state);
|
|
||||||
|
|
||||||
|
if (callback)
|
||||||
callback(stack, state->node, state_data);
|
callback(stack, state->node, state_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,8 @@ struct dom_stack {
|
|||||||
size_t object_size;
|
size_t object_size;
|
||||||
|
|
||||||
/* Callbacks which should be called for the pushed and popped nodes. */
|
/* 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. */
|
/* Data specific to the parser and renderer. */
|
||||||
void *data;
|
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
|
* state to be assigned to the state's @data member. Zero means no state data should
|
||||||
* be allocated. */
|
* be allocated. */
|
||||||
void init_dom_stack(struct dom_stack *stack, void *data,
|
void init_dom_stack(struct dom_stack *stack, void *data,
|
||||||
struct dom_stack_callbacks *callbacks,
|
|
||||||
size_t object_size, int keep_nodes);
|
size_t object_size, int keep_nodes);
|
||||||
void done_dom_stack(struct dom_stack *stack);
|
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 */
|
/* Decends down to the given node making it the current parent */
|
||||||
/* If an error occurs the node is free()d and NULL is returned */
|
/* 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);
|
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->info = get_sgml_info(doctype);
|
||||||
parser->data = data;
|
parser->data = data;
|
||||||
|
|
||||||
init_dom_stack(&parser->stack, parser, callbacks, obj_size,
|
init_dom_stack(&parser->stack, parser, obj_size,
|
||||||
type != SGML_PARSER_STREAM);
|
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);
|
parser->root = add_sgml_document(&parser->stack, parser->uri);
|
||||||
if (!parser->root) {
|
if (!parser->root) {
|
||||||
|
Loading…
Reference in New Issue
Block a user