diff --git a/src/document/dom/renderer.c b/src/document/dom/renderer.c index cfd826c7..6cc70e0ec 100644 --- a/src/document/dom/renderer.c +++ b/src/document/dom/renderer.c @@ -677,7 +677,7 @@ render_dom_attribute_source(struct dom_stack *stack, struct dom_node *node, void return node; } -static dom_stack_callback_T dom_source_renderer_callbacks[DOM_NODES] = { +static dom_stack_callback_T dom_source_renderer_push_callbacks[DOM_NODES] = { /* */ NULL, /* DOM_NODE_ELEMENT */ render_dom_element_source, /* DOM_NODE_ATTRIBUTE */ render_dom_attribute_source, @@ -693,6 +693,22 @@ static dom_stack_callback_T dom_source_renderer_callbacks[DOM_NODES] = { /* DOM_NODE_NOTATION */ render_dom_node_source, }; +static dom_stack_callback_T dom_source_renderer_pop_callbacks[DOM_NODES] = { + /* */ NULL, + /* DOM_NODE_ELEMENT */ NULL, + /* DOM_NODE_ATTRIBUTE */ NULL, + /* DOM_NODE_TEXT */ NULL, + /* DOM_NODE_CDATA_SECTION */ NULL, + /* DOM_NODE_ENTITY_REFERENCE */ NULL, + /* DOM_NODE_ENTITY */ NULL, + /* DOM_NODE_PROC_INSTRUCTION */ NULL, + /* DOM_NODE_COMMENT */ NULL, + /* DOM_NODE_DOCUMENT */ NULL, + /* DOM_NODE_DOCUMENT_TYPE */ NULL, + /* DOM_NODE_DOCUMENT_FRAGMENT */ NULL, + /* DOM_NODE_NOTATION */ NULL, +}; + /* Shared multiplexor between renderers */ void @@ -703,7 +719,6 @@ render_dom_document(struct cache_entry *cached, struct document *document, struct dom_node *root; struct dom_renderer renderer; struct conv_table *convert_table; - dom_stack_callback_T *callbacks = dom_source_renderer_callbacks; struct sgml_parser *parser; assert(document->options.plain); @@ -719,7 +734,9 @@ render_dom_document(struct cache_entry *cached, struct document *document, document->bgcolor = document->options.default_bg; parser = init_sgml_parser(SGML_PARSER_STREAM, &renderer, cached, - document, callbacks); + document, + dom_source_renderer_push_callbacks, + dom_source_renderer_pop_callbacks); if (!parser) return; root = parse_sgml(parser, buffer); diff --git a/src/document/dom/stack.c b/src/document/dom/stack.c index a0d78806..c6be1b61 100644 --- a/src/document/dom/stack.c +++ b/src/document/dom/stack.c @@ -46,7 +46,8 @@ realloc_dom_stack_state_objects(struct dom_stack *stack) void init_dom_stack(struct dom_stack *stack, void *parser, void *renderer, - dom_stack_callback_T callbacks[DOM_NODES], + dom_stack_callback_T push_callbacks[DOM_NODES], + dom_stack_callback_T pop_callbacks[DOM_NODES], size_t object_size) { assert(stack); @@ -57,8 +58,10 @@ init_dom_stack(struct dom_stack *stack, void *parser, void *renderer, stack->renderer = renderer; stack->object_size = object_size; - if (callbacks) - memcpy(stack->callbacks, callbacks, DOM_STACK_CALLBACKS_SIZE); + if (push_callbacks) + memcpy(stack->push_callbacks, push_callbacks, DOM_STACK_CALLBACKS_SIZE); + if (pop_callbacks) + memcpy(stack->pop_callbacks, pop_callbacks, DOM_STACK_CALLBACKS_SIZE); } void @@ -111,7 +114,7 @@ push_dom_node(struct dom_stack *stack, struct dom_node *node) * in the callbacks */ stack->depth++; - callback = stack->callbacks[node->type]; + callback = stack->push_callbacks[node->type]; if (callback) { void *state_data = get_dom_stack_state_data(stack, state); @@ -132,11 +135,18 @@ static int do_pop_dom_node(struct dom_stack *stack, struct dom_stack_state *parent) { struct dom_stack_state *state; + dom_stack_callback_T callback; assert(stack); if (!dom_stack_has_parents(stack)) return 0; state = get_dom_stack_top(stack); + callback = stack->pop_callbacks[state->node->type]; + if (callback) { + void *state_data = get_dom_stack_state_data(stack, state); + + callback(stack, state->node, state_data); + } stack->depth--; assert(stack->depth >= 0); diff --git a/src/document/dom/stack.h b/src/document/dom/stack.h index 57bb7726..a147ada2 100644 --- a/src/document/dom/stack.h +++ b/src/document/dom/stack.h @@ -45,7 +45,8 @@ struct dom_stack { size_t object_size; /* Renderer specific callbacks for the streaming parser mode. */ - dom_stack_callback_T callbacks[DOM_NODES]; + dom_stack_callback_T push_callbacks[DOM_NODES]; + dom_stack_callback_T pop_callbacks[DOM_NODES]; /* Data specific to the parser and renderer. */ void *renderer; @@ -107,7 +108,8 @@ 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 *parser, void *renderer, - dom_stack_callback_T callbacks[DOM_NODES], + dom_stack_callback_T push_callbacks[DOM_NODES], + dom_stack_callback_T pop_callbacks[DOM_NODES], size_t object_size); void done_dom_stack(struct dom_stack *stack); diff --git a/src/document/sgml/parser.c b/src/document/sgml/parser.c index 238db88a..4d1b5967 100644 --- a/src/document/sgml/parser.c +++ b/src/document/sgml/parser.c @@ -311,7 +311,8 @@ parse_sgml_document(struct dom_stack *stack, struct scanner *scanner) struct sgml_parser * init_sgml_parser(enum sgml_parser_type type, void *renderer, struct cache_entry *cached, struct document *document, - dom_stack_callback_T callbacks[DOM_NODES]) + dom_stack_callback_T push_callbacks[DOM_NODES], + dom_stack_callback_T pop_callbacks[DOM_NODES]) { size_t obj_size = sizeof(struct sgml_parser_state); struct sgml_parser *parser; @@ -324,7 +325,8 @@ init_sgml_parser(enum sgml_parser_type type, void *renderer, parser->cache_entry = cached; parser->info = &sgml_html_info; - init_dom_stack(&parser->stack, parser, renderer, callbacks, obj_size); + init_dom_stack(&parser->stack, parser, renderer, + push_callbacks, pop_callbacks, obj_size); return parser; } diff --git a/src/document/sgml/parser.h b/src/document/sgml/parser.h index fbacc088..688ebc27 100644 --- a/src/document/sgml/parser.h +++ b/src/document/sgml/parser.h @@ -46,7 +46,8 @@ struct sgml_parser_state { struct sgml_parser * init_sgml_parser(enum sgml_parser_type type, void *renderer, struct cache_entry *cached, struct document *document, - dom_stack_callback_T callbacks[DOM_NODES]); + dom_stack_callback_T push_callbacks[DOM_NODES], + dom_stack_callback_T pop_callbacks[DOM_NODES]); void done_sgml_parser(struct sgml_parser *parser);