Subversion Repositories Kolibri OS

Rev

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

  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 <jmb@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 "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.  
  122.