Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

and anything that acts "as if" was emitted.
Rev Author Line No. Line
3584 sourcerer 1
/*
2
 * This file is part of Hubbub.
3
 * Licensed under the MIT License,
4
 *                http://www.opensource.org/licenses/mit-license.php
5
 * Copyright 2008 Andrew Sidwell 
6
 */
7
 
8
#include 
9
#include 
10
 
11
#include "treebuilder/modes.h"
12
#include "treebuilder/internal.h"
13
#include "treebuilder/treebuilder.h"
14
#include "utils/utils.h"
15
 
16
 
17
/**
18
 * Clear the stack back to a table row context.
19
 *
20
 * \param treebuilder	The treebuilder instance
21
 */
22
static void table_clear_stack(hubbub_treebuilder *treebuilder)
23
{
24
	element_type cur_node = current_node(treebuilder);
25
 
26
	while (cur_node != TR && cur_node != HTML) {
27
		hubbub_ns ns;
28
		element_type type;
29
		void *node;
30
 
31
		element_stack_pop(treebuilder, &ns, &type, &node);
32
 
33
		treebuilder->tree_handler->unref_node(
34
				treebuilder->tree_handler->ctx,
35
				node);
36
 
37
		cur_node = current_node(treebuilder);
38
	}
39
 
40
	return;
41
}
42
 
43
 
44
/**
45
 * Handle 
46
 *
47
 * \param treebuilder	The treebuilder instance
48
 * \return True to reprocess the token, false otherwise
49
 */
50
static hubbub_error act_as_if_end_tag_tr(hubbub_treebuilder *treebuilder)
51
{
52
	hubbub_ns ns;
53
	element_type otype;
54
	void *node;
55
 
56
	/** \todo fragment case */
57
 
58
	table_clear_stack(treebuilder);
59
 
60
	element_stack_pop(treebuilder, &ns, &otype, &node);
61
 
62
	treebuilder->tree_handler->unref_node(treebuilder->tree_handler->ctx,
63
			node);
64
 
65
	treebuilder->context.mode = IN_TABLE_BODY;
66
 
67
	return HUBBUB_REPROCESS;
68
}
69
 
70
 
71
/**
72
 * Handle tokens in "in row" insertion mode
73
 *
74
 * \param treebuilder  The treebuilder instance
75
 * \param token        The token to process
76
 * \return True to reprocess the token, false otherwise
77
 */
78
hubbub_error handle_in_row(hubbub_treebuilder *treebuilder,
79
		const hubbub_token *token)
80
{
81
	hubbub_error err = HUBBUB_OK;
82
 
83
	switch (token->type) {
84
	case HUBBUB_TOKEN_START_TAG:
85
	{
86
		element_type type = element_type_from_name(treebuilder,
87
				&token->data.tag.name);
88
 
89
		if (type == TH || type == TD) {
90
			table_clear_stack(treebuilder);
91
 
92
			err = insert_element(treebuilder, &token->data.tag,
93
					true);
94
			if (err != HUBBUB_OK)
95
				return err;
96
 
97
			treebuilder->context.mode = IN_CELL;
98
 
99
			/* ref node for formatting list */
100
			treebuilder->tree_handler->ref_node(
101
				treebuilder->tree_handler->ctx,
102
				treebuilder->context.element_stack[
103
				treebuilder->context.current_node].node);
104
 
105
			err = formatting_list_append(treebuilder,
106
					token->data.tag.ns, type,
107
					treebuilder->context.element_stack[
108
					treebuilder->context.current_node].node,
109
					treebuilder->context.current_node);
110
			if (err != HUBBUB_OK) {
111
				hubbub_ns ns;
112
				element_type type;
113
				void *node;
114
 
115
				/* Revert changes */
116
 
117
				remove_node_from_dom(treebuilder,
118
					treebuilder->context.element_stack[
119
					treebuilder->context.current_node].node);
120
				element_stack_pop(treebuilder, &ns, &type,
121
						&node);
122
 
123
				return err;
124
			}
125
		} else if (type == CAPTION || type == COL ||
126
				type == COLGROUP || type == TBODY ||
127
				type == TFOOT || type == THEAD || type == TR) {
128
			err = act_as_if_end_tag_tr(treebuilder);
129
		} else {
130
			err = handle_in_table(treebuilder, token);
131
		}
132
	}
133
		break;
134
	case HUBBUB_TOKEN_END_TAG:
135
	{
136
		element_type type = element_type_from_name(treebuilder,
137
				&token->data.tag.name);
138
 
139
		if (type == TR) {
140
			/* We're done with this token, but act_as_if_end_tag_tr
141
			 * will return HUBBUB_REPROCESS. Therefore, ignore the
142
			 * return value. */
143
			(void) act_as_if_end_tag_tr(treebuilder);
144
		} else if (type == TABLE) {
145
			err = act_as_if_end_tag_tr(treebuilder);
146
		} else if (type == BODY || type == CAPTION || type == COL ||
147
				type == COLGROUP || type == HTML ||
148
				type == TD || type == TH) {
149
			/** \todo parse error */
150
			/* Ignore the token */
151
		} else {
152
			err = handle_in_table(treebuilder, token);
153
		}
154
	}
155
		break;
156
	case HUBBUB_TOKEN_CHARACTER:
157
	case HUBBUB_TOKEN_COMMENT:
158
	case HUBBUB_TOKEN_DOCTYPE:
159
	case HUBBUB_TOKEN_EOF:
160
		err = handle_in_table(treebuilder, token);
161
		break;
162
	}
163
 
164
	return err;
165
}
166