Go to most recent revision | Details | Last modification | View Log | RSS feed
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 John-Mark Bell |
||
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 | * Handle token in "before html" insertion mode |
||
19 | * |
||
20 | * \param treebuilder The treebuilder instance |
||
21 | * \param token The token to handle |
||
22 | * \return True to reprocess token, false otherwise |
||
23 | */ |
||
24 | hubbub_error handle_before_html(hubbub_treebuilder *treebuilder, |
||
25 | const hubbub_token *token) |
||
26 | { |
||
27 | hubbub_error err = HUBBUB_OK; |
||
28 | bool handled = false; |
||
29 | |||
30 | switch (token->type) { |
||
31 | case HUBBUB_TOKEN_DOCTYPE: |
||
32 | /** \todo parse error */ |
||
33 | break; |
||
34 | case HUBBUB_TOKEN_COMMENT: |
||
35 | err = process_comment_append(treebuilder, token, |
||
36 | treebuilder->context.document); |
||
37 | break; |
||
38 | case HUBBUB_TOKEN_CHARACTER: |
||
39 | err = process_characters_expect_whitespace(treebuilder, |
||
40 | token, false); |
||
41 | break; |
||
42 | case HUBBUB_TOKEN_START_TAG: |
||
43 | { |
||
44 | element_type type = element_type_from_name(treebuilder, |
||
45 | &token->data.tag.name); |
||
46 | |||
47 | if (type == HTML) { |
||
48 | handled = true; |
||
49 | } else { |
||
50 | err = HUBBUB_REPROCESS; |
||
51 | } |
||
52 | } |
||
53 | break; |
||
54 | case HUBBUB_TOKEN_END_TAG: |
||
55 | case HUBBUB_TOKEN_EOF: |
||
56 | err = HUBBUB_REPROCESS; |
||
57 | break; |
||
58 | } |
||
59 | |||
60 | |||
61 | if (handled || err == HUBBUB_REPROCESS) { |
||
62 | hubbub_error e; |
||
63 | void *html, *appended; |
||
64 | |||
65 | /* We can't use insert_element() here, as it assumes |
||
66 | * that we're inserting into current_node. There is |
||
67 | * no current_node to insert into at this point so |
||
68 | * we get to do it manually. */ |
||
69 | |||
70 | if (err == HUBBUB_REPROCESS) { |
||
71 | /* Need to manufacture html element */ |
||
72 | hubbub_tag tag; |
||
73 | |||
74 | tag.ns = HUBBUB_NS_HTML; |
||
75 | tag.name.ptr = (const uint8_t *) "html"; |
||
76 | tag.name.len = SLEN("html"); |
||
77 | |||
78 | tag.n_attributes = 0; |
||
79 | tag.attributes = NULL; |
||
80 | |||
81 | e = treebuilder->tree_handler->create_element( |
||
82 | treebuilder->tree_handler->ctx, |
||
83 | &tag, &html); |
||
84 | } else { |
||
85 | e = treebuilder->tree_handler->create_element( |
||
86 | treebuilder->tree_handler->ctx, |
||
87 | &token->data.tag, &html); |
||
88 | } |
||
89 | |||
90 | if (e != HUBBUB_OK) |
||
91 | return e; |
||
92 | |||
93 | e = treebuilder->tree_handler->append_child( |
||
94 | treebuilder->tree_handler->ctx, |
||
95 | treebuilder->context.document, |
||
96 | html, &appended); |
||
97 | |||
98 | treebuilder->tree_handler->unref_node( |
||
99 | treebuilder->tree_handler->ctx, |
||
100 | html); |
||
101 | |||
102 | if (e != HUBBUB_OK) |
||
103 | return e; |
||
104 | |||
105 | /* We can't use element_stack_push() here, as it |
||
106 | * assumes that current_node is pointing at the index |
||
107 | * before the one to insert at. For the first entry in |
||
108 | * the stack, this does not hold so we must insert |
||
109 | * manually. */ |
||
110 | treebuilder->context.element_stack[0].type = HTML; |
||
111 | treebuilder->context.element_stack[0].node = appended; |
||
112 | treebuilder->context.current_node = 0; |
||
113 | |||
114 | /** \todo cache selection algorithm */ |
||
115 | |||
116 | treebuilder->context.mode = BEFORE_HEAD; |
||
117 | } |
||
118 | |||
119 | return err; |
||
120 | } |
||
121 |