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 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.  * Clear the stack back to a table row context.
  19.  *
  20.  * \param treebuilder   The treebuilder instance
  21.  */
  22. static inline void close_cell(hubbub_treebuilder *treebuilder)
  23. {
  24.         hubbub_ns ns;
  25.         element_type otype = UNKNOWN;
  26.         void *node;
  27.  
  28.         element_type type;
  29.  
  30.         if (element_in_scope(treebuilder, TD, true)) {
  31.                 type = TD;
  32.         } else {
  33.                 type = TH;
  34.         }
  35.  
  36.         /* Act as if an end tag token of type `type` has been seen */
  37.  
  38.         close_implied_end_tags(treebuilder, UNKNOWN);
  39.         /** \todo parse error */
  40.  
  41.         while (otype != type) {
  42.                 element_stack_pop(treebuilder, &ns, &otype, &node);
  43.  
  44.                 treebuilder->tree_handler->unref_node(
  45.                                 treebuilder->tree_handler->ctx,
  46.                                 node);
  47.         }
  48.  
  49.         clear_active_formatting_list_to_marker(treebuilder);
  50.         treebuilder->context.mode = IN_ROW;
  51.  
  52.         return;
  53. }
  54.  
  55.  
  56. /**
  57.  * Handle tokens in "in cell" insertion mode
  58.  *
  59.  * \param treebuilder  The treebuilder instance
  60.  * \param token        The token to process
  61.  * \return True to reprocess the token, false otherwise
  62.  */
  63. hubbub_error handle_in_cell(hubbub_treebuilder *treebuilder,
  64.                 const hubbub_token *token)
  65. {
  66.         hubbub_error err = HUBBUB_OK;
  67.  
  68.         switch (token->type) {
  69.         case HUBBUB_TOKEN_START_TAG:
  70.         {
  71.                 element_type type = element_type_from_name(treebuilder,
  72.                                 &token->data.tag.name);
  73.  
  74.                 if (type == CAPTION || type == COL ||
  75.                                 type == COLGROUP || type == TBODY ||
  76.                                 type == TD || type == TFOOT || type == TH ||
  77.                                 type == THEAD || type == TR) {
  78.                         /** \todo fragment case */
  79.                         close_cell(treebuilder);
  80.                         err = HUBBUB_REPROCESS;
  81.                 } else {
  82.                         err = handle_in_body(treebuilder, token);
  83.                 }
  84.         }
  85.                 break;
  86.         case HUBBUB_TOKEN_END_TAG:
  87.         {
  88.                 element_type type = element_type_from_name(treebuilder,
  89.                                 &token->data.tag.name);
  90.  
  91.                 if (type == TH || type == TD) {
  92.                         if (element_in_scope(treebuilder, type, true)) {
  93.                                 hubbub_ns ns;
  94.                                 element_type otype = UNKNOWN;
  95.                                 void *node;
  96.  
  97.                                 close_implied_end_tags(treebuilder, UNKNOWN);
  98.                                 /** \todo parse error */
  99.  
  100.                                 while (otype != type) {
  101.                                         element_stack_pop(treebuilder,
  102.                                                         &ns, &otype, &node);
  103.  
  104.                                         treebuilder->tree_handler->unref_node(
  105.                                                 treebuilder->tree_handler->ctx,
  106.                                                 node);
  107.                                 }
  108.  
  109.                                 clear_active_formatting_list_to_marker(
  110.                                                 treebuilder);
  111.  
  112.                                 treebuilder->context.mode = IN_ROW;
  113.                         } else {
  114.                                 /** \todo parse error */
  115.                         }
  116.                 } else if (type == BODY || type == CAPTION || type == COL ||
  117.                                 type == COLGROUP || type == HTML) {
  118.                         /** \todo parse error */
  119.                 } else if (type == TABLE  || type == TBODY || type == TFOOT ||
  120.                                 type == THEAD || type == TR) {
  121.                         if (element_in_scope(treebuilder, type, true)) {
  122.                                 close_cell(treebuilder);
  123.                                 err = HUBBUB_REPROCESS;
  124.                         } else {
  125.                                 /** \todo parse error */
  126.                         }
  127.                 } else {
  128.                         err = handle_in_body(treebuilder, token);
  129.                 }
  130.         }
  131.                 break;
  132.         case HUBBUB_TOKEN_CHARACTER:
  133.         case HUBBUB_TOKEN_COMMENT:
  134.         case HUBBUB_TOKEN_DOCTYPE:
  135.         case HUBBUB_TOKEN_EOF:
  136.                 err = handle_in_body(treebuilder, token);
  137.                 break;
  138.         }
  139.  
  140.         return err;
  141. }
  142.  
  143.