⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 html.c

📁 嵌入式浏览器Dillo源码
💻 C
📖 第 1 页 / 共 5 页
字号:
      /* Here we add the word Verbatim, not parsed */      Pword = g_strndup(word, size);      g_string_append(html->Stash, Pword);      g_free(Pword);   } else if ( parse_mode == DILLO_HTML_PARSE_MODE_PRE ) {      /* all this overhead is to catch white-space entities */      Pword = Html_parse_entities(word, size);      for (start = i = 0; Pword[i]; start = i)         if (isspace(Pword[i])) {            while (Pword[++i] && isspace(Pword[i]));            Html_process_space(html, Pword + start, i - start);         } else {            while (Pword[++i] && !isspace(Pword[i]));            a_Dw_page_add_text(DW_PAGE (html->dw),                               g_strndup(Pword + start, i - start),                               html->stack[html->stack_top].style);            html->pre_column += i - start;            html->PreFirstChar = FALSE;         }      g_free(Pword);   } else {      if (memchr(word, '&', size) == NULL) {         a_Dw_page_add_text(DW_PAGE (html->dw),                            g_strndup(word, size),                            html->stack[html->stack_top].style);      } else {         /* actually white-space entities inside the word should be          * collapsed (except &nbsp;), but that's too much overhead          * for a very rare case of bad-formed HTML  --Jcid */         Pword = Html_parse_entities(word, size);         g_strdelimit(Pword, "\t\f\n\r", ' ');         a_Dw_page_add_text(DW_PAGE (html->dw),                            Pword,                            html->stack[html->stack_top].style);      }   }}/* * Does the tag in tagstr (e.g. "p") match the tag in the tag, tagsize * structure, with the initial < skipped over (e.g. "P align=center>") */static gboolean Html_match_tag(const char *tagstr, char *tag, gint tagsize){   gint i;   for (i = 0; i < tagsize && tagstr[i] != '\0'; i++) {      if (tolower(tagstr[i]) != tolower(tag[i]))         return FALSE;   }   /* The test for '/' is for xml compatibility: "empty/>" will be matched. */   if (i < tagsize && (isspace(tag[i]) || tag[i] == '>' || tag[i] == '/'))      return TRUE;   return FALSE;}/* * Push the tag (copying attributes from the top of the stack) */static void Html_push_tag(DilloHtml *html, char *tag, gint tagsize){   char *tagstr;   gint tag_end;   gint n_items;   /* Copy the tag itself (no parameters) into tagstr. */   for (tag_end = 1; tag_end < tagsize && isalnum(tag[tag_end]); tag_end++);   tagstr = g_strndup(tag + 1, tag_end - 1);   n_items = html->stack_top + 1;   a_List_add(html->stack, n_items, html->stack_max);   /* We'll copy the former stack item and just change the tag    * instead of copying all fields except for tag.  --Jcid */   html->stack[n_items] = html->stack[n_items - 1];   html->stack[n_items].tag = tagstr;   html->stack_top = n_items;   /* proper memory management, may be unref'd later */   a_Dw_style_ref (html->stack[html->stack_top].style);   if (html->stack[html->stack_top].table_cell_style)      a_Dw_style_ref (html->stack[html->stack_top].table_cell_style);   html->dw = html->stack[html->stack_top].page;}/* * This function is called by Html_cleanup_tag and Html_pop_tag, to * handle nested DwPage widgets. */static void Html_eventually_pop_dw(DilloHtml *html){   if(html->dw != html->stack[html->stack_top].page) {      if(html->stack[html->stack_top].hand_over_break)         a_Dw_page_hand_over_break(DW_PAGE(html->dw),                                   html->stack[(html)->stack_top].style);      a_Dw_page_flush(DW_PAGE(html->dw));      html->dw = html->stack[html->stack_top].page;   }}/* * Remove the stack's topmost tag (only if it matches) * If it matches, TRUE is returned. */static gboolean Html_cleanup_tag(DilloHtml *html, char *tag){   if ( html->stack_top &&        Html_match_tag(html->stack[html->stack_top].tag, tag, strlen(tag)) ) {      a_Dw_style_unref (html->stack[html->stack_top].style);      if (html->stack[html->stack_top].table_cell_style)         a_Dw_style_unref (html->stack[html->stack_top].table_cell_style);      g_free(html->stack[html->stack_top--].tag);      Html_eventually_pop_dw(html);      return TRUE;   } else      return FALSE;}/* * Do a paragraph break and push the tag. This pops unclosed <p> tags * off the stack, if there are any. */static void Html_par_push_tag(DilloHtml *html, char *tag, gint tagsize){   Html_cleanup_tag(html, "p>");   Html_push_tag(html, tag, tagsize);   a_Dw_page_add_parbreak(DW_PAGE (html->dw), 9,                          html->stack[(html)->stack_top].style);}/* * Pop the tag. At the moment, this assumes tags nest! */static void Html_pop_tag(DilloHtml *html, char *tag, gint tagsize){   gint tag_index;   /* todo: handle non-nesting case more gracefully (search stack    * downwards for matching tag). */   for (tag_index = html->stack_top; tag_index > 0; tag_index--) {      if (Html_match_tag(html->stack[tag_index].tag, tag + 2, tagsize - 2)) {         while (html->stack_top >= tag_index) {            a_Dw_style_unref (html->stack[html->stack_top].style);            if (html->stack[html->stack_top].table_cell_style)               a_Dw_style_unref(html->stack[html->stack_top].table_cell_style);            g_free(html->stack[html->stack_top--].tag);         }         Html_eventually_pop_dw(html);         return;      }   }   /* Not found, just ignore. */}/* * Some parsing routines. *//* * Used by Html_parse_length and Html_parse_multi_length_list. */static DwStyleLength Html_parse_length_or_multi_length (const gchar *attr,                                                        gchar **endptr){   DwStyleLength l;   double v;   gchar *end;   v = strtod (attr, &end);   switch (*end) {   case '%':      end++;      l = DW_STYLE_CREATE_PERCENTAGE (v / 100);      break;   case '*':      end++;      l = DW_STYLE_CREATE_RELATIVE (v);      break;   default:      l = DW_STYLE_CREATE_LENGTH ((gint)v);      break;   }   if (endptr)      *endptr = end;   return l;}/* * Returns a length or a percentage, or DW_STYLE_UNDEF_LENGTH in case * of an error, or if attr is NULL. */static DwStyleLength Html_parse_length (const gchar *attr){   DwStyleLength l;   gchar *end;   l = Html_parse_length_or_multi_length (attr, &end);   if (DW_STYLE_IS_RELATIVE (l))      /* not allowed as &Length; */      return DW_STYLE_UNDEF_LENGTH;   else {      /* allow only whitespaces */      if (*end && !isspace (*end)) {         DEBUG_HTML_MSG("Garbage after length: %s\n", attr);         return DW_STYLE_UNDEF_LENGTH;      }   }   return l;}/* * Returns a vector of lenghts/percentages. The caller has to free the * result when it is not longer used. */G_GNUC_UNUSED static DwStyleLength*Html_parse_multi_length_list (const gchar *attr){   DwStyleLength *l;   gint n, max_n;   gchar *end;   n = 0;   max_n = 8;   l = g_new (DwStyleLength, max_n);   while (TRUE) {      l[n] = Html_parse_length_or_multi_length (attr, &end);      n++;      a_List_add (l, n, max_n);      while (isspace (*end))         end++;      if (*end == ',')         attr = end + 1;      else         /* error or end */         break;   }   l[n] = DW_STYLE_UNDEF_LENGTH;   return l;}/* * Handle open HEAD element */static void Html_tag_open_head(DilloHtml *html, char *tag, gint tagsize){   Html_push_tag(html, tag, tagsize);   html->InFlags |= IN_HEAD;}/* * Handle close HEAD element */static void Html_tag_close_head(DilloHtml *html, char *tag, gint tagsize){   Html_pop_tag(html, tag, tagsize);   html->InFlags &= ~IN_HEAD;}/* * Handle open TITLE * calls stash init, where the title string will be stored */static void Html_tag_open_title(DilloHtml *html, char *tag, gint tagsize){   Html_push_tag(html, tag, tagsize);   Html_stash_init(html);}/* * Handle close TITLE * set page-title in the browser window and in the history. */static void Html_tag_close_title(DilloHtml *html, char *tag, gint tagsize){   if (html->InFlags & IN_HEAD) {      /* title is only valid inside HEAD */      a_Interface_set_page_title(html->linkblock->bw, html->Stash->str);      a_History_set_title(NAV_TOP(html->linkblock->bw), html->Stash->str);   }   Html_pop_tag(html, tag, tagsize);}/* * Handle open SCRIPT * initializes stash, where the embedded code will be stored * MODE_SCRIPT is used because MODE_STASH catches entities */static void Html_tag_open_script(DilloHtml *html, char *tag, gint tagsize){   Html_push_tag(html, tag, tagsize);   Html_stash_init(html);   html->stack[html->stack_top].parse_mode = DILLO_HTML_PARSE_MODE_SCRIPT;}/* * Handle close SCRIPT */static void Html_tag_close_script(DilloHtml *html, char *tag, gint tagsize){#ifdef VERBOSE   g_print("Html_tag_close_script: script text -> '%s'\n", html->Stash->str);#endif   /* eventually the stash will be sent to an interpreter for parsing */   Html_pop_tag(html, tag, tagsize);}/* * Handle open STYLE * store the contents to the stash where (in the future) the style * sheet interpreter can get it. */static void Html_tag_open_style(DilloHtml *html, char *tag, gint tagsize){   Html_push_tag(html, tag, tagsize);   Html_stash_init(html);   html->stack[html->stack_top].parse_mode = DILLO_HTML_PARSE_MODE_SCRIPT;}/* * Handle close STYLE */static void Html_tag_close_style(DilloHtml *html, char *tag, gint tagsize){   /* eventually the stash will be sent to an interpreter for parsing */   Html_pop_tag(html, tag, tagsize);}/* * <BODY> */static void Html_tag_open_body(DilloHtml *html, char *tag, gint tagsize){   const char *attrbuf;   DwPage *page;   DwStyle style_attrs, *style;   gint32 color;   page = DW_PAGE (html->dw);   if (!prefs.force_my_colors) {      if ((attrbuf = Html_get_attr(html, tag, tagsize, "bgcolor"))) {         color = a_Color_parse (attrbuf, prefs.bg_color);         if ( (color == 0xffffff && !prefs.allow_white_bg) ||              prefs.force_my_colors )            color = prefs.bg_color;         style_attrs = *html->dw->style;         style_attrs.background_color =            a_Dw_style_color_new (color, html->bw->main_window->window);         style = a_Dw_style_new (&style_attrs, html->bw->main_window->window);         a_Dw_widget_set_style (html->dw, style);         a_Dw_style_unref (style);         html->stack[html->stack_top].current_bg_color = color;      }      if ((attrbuf = Html_get_attr(html, tag, tagsize, "text"))) {         color = a_Color_parse (attrbuf, prefs.text_color);         HTML_SET_TOP_ATTR            (html, color,             a_Dw_style_color_new (color, html->bw->main_window->window));      }      if ((attrbuf = Html_get_attr(html, tag, tagsize, "link")))         html->linkblock->link_color = a_Color_parse(attrbuf,                                                     prefs.link_color);      if ((attrbuf = Html_get_attr(html, tag, tagsize, "vlink")))         html->linkblock->visited_color =            a_Color_parse (attrbuf, prefs.visited_color);      if (prefs.force_visited_color &&          html->linkblock->link_color == html->linkblock->visited_color) {         /* get a color that has a "safe distance" from text, link and bg */         html->linkblock->visited_color =            a_Color_vc(html->stack[html->stack_top].style->color->color_val,                       html->linkblock->link_color,                       html->stack[html->stack_top].current_bg_color);      }   }   /* If we are still in HEAD, cleanup after HEAD tag;    * assume document author forgot to close HEAD */   if (html->InFlags & IN_HEAD) {      Html_cleanup_tag(html, "head>");      html->InFlags &= ~IN_HEAD;   }   Html_push_tag (html, tag, tagsize);   html->stack[html->stack_top].parse_mode = DILLO_HTML_PARSE_MODE_BODY;   html->InFlags |= IN_BODY;}/* * <P> */static void Html_tag_open_p(DilloHtml *html, char *tag, gint tagsize){   Html_par_push_tag(html, tag, tagsize);   Html_tag_set_align_attr (html, tag, tagsize);}/* * <TABLE> */static void Html_tag_open_table(DilloHtml *html, char *tag, gint tagsize){#ifdef USE_TABLES   DwWidget *table;   DwStyle style_attrs, *tstyle, *old_style;   const char *attrbuf;   gint32 border = 0, cellspacing = 1, cellpadding = 2, bgcolor;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -