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 <takkaria@netsurf-browser.org>
6 */
7
8 #include <assert.h>
9 #include <string.h>
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 "after body" 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 */
handle_after_body(hubbub_treebuilder * treebuilder,const hubbub_token * token)24 hubbub_error handle_after_body(hubbub_treebuilder *treebuilder,
25 const hubbub_token *token)
26 {
27 hubbub_error err = HUBBUB_OK;
28
29 switch (token->type) {
30 case HUBBUB_TOKEN_CHARACTER:
31 {
32 /* mostly cribbed from process_characters_expect_whitespace */
33 const uint8_t *data = token->data.character.ptr;
34 size_t len = token->data.character.len;
35 size_t c;
36
37 /* Scan for whitespace */
38 for (c = 0; c < len; c++) {
39 if (data[c] != 0x09 && data[c] != 0x0A &&
40 data[c] != 0x0C && data[c] != 0x20)
41 break;
42 }
43
44 /* Whitespace characters in token, so handle as in body */
45 if (c > 0) {
46 hubbub_token temp = *token;
47 temp.data.character.len = c;
48
49 err = handle_in_body(treebuilder, &temp);
50 if (err != HUBBUB_OK)
51 return err;
52 }
53
54 /* Anything else, switch to in body */
55 if (c != len) {
56 /* Update token data to strip leading whitespace */
57 ((hubbub_token *) token)->data.character.ptr += c;
58 ((hubbub_token *) token)->data.character.len -= c;
59
60 treebuilder->context.mode = IN_BODY;
61 err = HUBBUB_REPROCESS;
62 }
63 }
64 break;
65 case HUBBUB_TOKEN_COMMENT:
66 err = process_comment_append(treebuilder, token,
67 treebuilder->context.element_stack[
68 0].node);
69 break;
70 case HUBBUB_TOKEN_DOCTYPE:
71 /** \todo parse error */
72 break;
73 case HUBBUB_TOKEN_START_TAG:
74 {
75 element_type type = element_type_from_name(treebuilder,
76 &token->data.tag.name);
77
78 if (type == HTML) {
79 /* Process as if "in body" */
80 err = handle_in_body(treebuilder, token);
81 } else {
82 /** \todo parse error */
83 treebuilder->context.mode = IN_BODY;
84 err = HUBBUB_REPROCESS;
85 }
86 }
87 break;
88 case HUBBUB_TOKEN_END_TAG:
89 {
90 element_type type = element_type_from_name(treebuilder,
91 &token->data.tag.name);
92
93 if (type == HTML) {
94 /** \todo fragment case */
95 /** \todo parse error */
96 treebuilder->context.mode = AFTER_AFTER_BODY;
97 } else {
98 /** \todo parse error */
99 treebuilder->context.mode = IN_BODY;
100 err = HUBBUB_REPROCESS;
101 }
102 }
103 break;
104 case HUBBUB_TOKEN_EOF:
105 break;
106 }
107
108 return err;
109 }
110
111