📄 html.c
字号:
* 3.- Cleanup the matching tag. (on error, give a warning message) * * If 'old_mode' is enabled: * 1.- Search the stack for a matching tag. * 2.- If it exists, clean all the tags in between. * 3.- Cleanup the matching tag. (on error, give a warning message) */static void Html_tag_cond_cleanup(DilloHtml *html, char *tag, gint tagsize, gint old_mode){ gint stack_idx, cmp = 1; /* Look for the candidate tag to close */ stack_idx = html->stack_top; while (stack_idx && (cmp = strcmp(Html_tags_get_name(html->CurrTagIdx), html->stack[stack_idx].tag)) && (old_mode || Html_tags_get_endtag(html->stack[stack_idx].tag_idx) == 'O')){ --stack_idx; } if (stack_idx == 0) return; /* clean, up to the matching tag */ if (cmp == 0) { /* There's a valid matching tag in the stack */ while (html->stack_top >= stack_idx) { 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); } else { gchar *stag = g_strndup(tag, tagsize); MSG_HTML("unexpected closing tag: %s. -- expected </%s>\n", stag, html->stack[stack_idx].tag); g_free(stag); }}/* * 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);}/* * Cleanup (conditional), and Pop the tag (if it matches) */static void Html_pop_tag(DilloHtml *html, char *tag, gint tagsize){ Html_tag_cond_cleanup(html, tag, tagsize, FALSE);}/* * Some parsing routines. *//* * Used by Html_parse_length */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_PER_LENGTH (v / 100); break; case '*': end++; l = DW_STYLE_CREATE_REL_LENGTH (v); break;/* The "px" suffix seems not allowed by HTML4.01 SPEC. case 'p': if (end[1] == 'x') end += 2;*/ default: l = DW_STYLE_CREATE_ABS_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 (DilloHtml *html, const gchar *attr){ DwStyleLength l; gchar *end; l = Html_parse_length_or_multi_length (attr, &end); if (DW_STYLE_IS_REL_LENGTH (l)) /* not allowed as &Length; */ return DW_STYLE_LENGTH_AUTO; else { /* allow only whitespaces */ if (*end && !isspace (*end)) { MSG_HTML("Garbage after length: %s\n", attr); return DW_STYLE_LENGTH_AUTO; } } return l;}/* * Parse a color attribute. * Return value: parsed color, or default_color (+ error msg) on error. */static gint32 Html_color_parse(DilloHtml *html, const char *subtag, gint32 default_color){ gint err = 1; gint32 color = a_Color_parse(subtag, default_color, &err); if (err) { MSG_HTML("color is not in \"#RRGGBB\" format\n"); } return color;}/* * Check that 'val' is composed of characters inside [A-Za-z0-9:_.-] * Note: ID can't have entities, but this check is enough (no '&'). * Return value: 1 if OK, 0 otherwise. */static gint Html_check_name_val(DilloHtml *html, const char *val, const char *attrname){ gint i; if (!isalpha(val[0])) MSG_HTML("first character of '%s' value is outside" " the [A-Za-z] set\n", attrname); for (i = 0; val[i]; ++i) if (!(isalnum(val[i]) || strchr(":_.-", val[i]))) break; if (val[i]) MSG_HTML("'%s' value has characters outside" " the [A-Za-z0-9:_.-] set\n", attrname); return !(val[i]);}/* * Handle open HEAD element */static void Html_tag_open_head(DilloHtml *html, char *tag, gint tagsize){ if (html->InFlags & IN_BODY) { MSG_HTML("HEAD element must go before the BODY section\n"); } else { 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); } else { MSG_HTML("the TITLE element must be inside the HEAD section\n"); } Html_pop_tag(html, tag, tagsize);}/* * Handle open SCRIPT * initializes stash, where the embedded code will be stored. * MODE_VERBATIM 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_VERBATIM;}/* * Handle close SCRIPT */static void Html_tag_close_script(DilloHtml *html, char *tag, gint tagsize){ /* 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_VERBATIM;}/* * 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); /* HEAD to BODY section transition was done by Html_test_body_section() */ if (!prefs.force_my_colors) { if ((attrbuf = Html_get_attr(html, tag, tagsize, "bgcolor"))) { color = Html_color_parse(html, 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 = Html_color_parse(html, 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 = Html_color_parse(html, attrbuf, prefs.link_color); if ((attrbuf = Html_get_attr(html, tag, tagsize, "vlink"))) html->linkblock->visited_color = Html_color_parse(html, 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); } } Html_push_tag (html, tag, tagsize); html->stack[html->stack_top].parse_mode = DILLO_HTML_PARSE_MODE_BODY; html->InFlags |= IN_BODY;}/* * <P> * todo: what's the point between adding the parbreak before and * after the push? * todo: <P> should be closed upon openning a 'block' element. */static void Html_tag_open_p(DilloHtml *html, char *tag, gint tagsize){ //Html_cleanup_tag(html, "p>"); 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;#endif Html_push_tag(html, tag, tagsize); a_Dw_page_add_parbreak(DW_PAGE (html->dw), 0, html->stack[(html)->stack_top].style);#ifdef USE_TABLES if ((attrbuf = Html_get_attr(html, tag, tagsize, "border"))) border = isdigit(attrbuf[0]) ? strtol (attrbuf, NULL, 10) : 1; if ((attrbuf = Html_get_attr(html, tag, tagsize, "cellspacing"))) cellspacing = strtol (attrbuf, NULL, 10); if ((attrbuf = Html_get_attr(html, tag, tagsize, "cellpadding"))) cellpadding = strtol (attrbuf, NULL, 10); /* The style for the table */ style_attrs = *html->stack[html->stack_top].style; /* When dillo was started with the --debug-rendering option, there * is always a border around the table. */ if (dillo_dbg_rendering) a_Dw_style_box_set_val (&style_attrs.border_width, MIN (border, 1)); else a_Dw_style_box_set_val (&style_attrs.border_width, border); a_Dw_style_box_set_border_color (&style_attrs, a_Dw_style_shaded_color_new ( html->stack[html->stack_top].current_bg_color, html->bw->main_window->window)); a_Dw_style_box_set_border_style (&style_attrs, DW_STYLE_BORDER_OUTSET); style_attrs.border_spacing = cellspacing; if ((attrbuf = Html_get_attr(html, tag, tagsize, "width"))) style_attrs.width = Html_parse_length (html, attrbuf); if ((attrbuf = Html_get_attr(html, tag, tagsize, "align"))) { if (g_strcasecmp (attrbuf, "left") == 0) style_attrs.text_align = DW_STYLE_TEXT_ALIGN_LEFT; else if (g_strcasecmp (attrbuf, "right") == 0) style_attrs.text_align = DW_STYLE_TEXT_ALIGN_RIGHT; else if (g_strcasecmp (attrbuf, "center") == 0) style_attrs.text_align = DW_STYLE_TEXT_ALIGN_CENTER; } if (!prefs.force_my_colors && (attrbuf = Html_get_attr(html, tag, tagsize, "bgcolor"))) { bgcolor = Html_color_parse(html, attrbuf, -1); if (bgcolor != -1) { if (bgcolor == 0xffffff && !prefs.allow_white_bg) bgcolor = prefs.bg_color; html->stack[html->stack_top].current_bg_color = bgcolor; style_attrs.background_color = a_Dw_style_color_new (bgcolor, html->bw->main_window->window); } } tstyle = a_Dw_style_new (&style_attrs, html->bw->main_window->window); /* The style for the cells */ style_attrs = *html->stack[html->stack_top].style;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -