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

📄 html.c

📁 嵌入式下基于MiniGUI的Web Browser
💻 C
📖 第 1 页 / 共 5 页
字号:
         a_Dw_page_add_space(DW_PAGE (html->dw),                             html->stack[html->stack_top].style);      /* actually white-space entities inside the word could be       * collapsed (except &nbsp;), but that's too much overhead       * for a very rare case of ill-formed HTML  --Jcid */      Pword = Html_parse_entities(html, 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);    }   html->PrevWasOpenTag = FALSE;   html->SPCPending = FALSE;}/* * 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, int tagsize){    int 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;}/* * 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){    /* This function is called after popping from the stack, so the     * relevant hand_over_break is at html->stack_top + 1. */    if (html->dw != html->stack[html->stack_top].page) {        if (html->stack[html->stack_top + 1].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;    }}/* * Push the tag (copying attributes from the top of the stack) */static void Html_push_tag(DilloHtml *html, int tag_idx){    char *tagstr;    int n_items;    /* Save the element's name (no parameters) into tagstr. */    tagstr = g_strdup(Tags[tag_idx].name);    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 and its index     * instead of copying all fields except for tag.  --Jcid */    html->stack[n_items] = html->stack[n_items - 1];    html->stack[n_items].tag_name = tagstr;    html->stack[n_items].tag_idx = tag_idx;    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;}/* * Push the tag (used to force en element with optional open into the stack) * Note: now it's the same as Html_push_tag(), but things may change... */static void Html_force_push_tag(DilloHtml *html, gint tag_idx){   Html_push_tag(html, tag_idx);}/* * Pop the top tag in the stack */static void Html_real_pop_tag(DilloHtml *html){   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_name);   Html_eventually_pop_dw(html);}/* * Default close function for tags. * (conditional cleanup of the stack) * There're several ways of doing it. Considering the HTML 4.01 spec * which defines optional close tags, and the will to deliver useful diagnose * messages for bad-formed HTML, it'll go as follows: *   1.- Search the stack for the first tag that requires a close tag. *   2.- If it matches, clean all the optional-close tags in between. *   3.- Cleanup the matching tag. (on error, give a warning message) * * If 'w3c_mode' is NOT enabled: *   1.- Search the stack for a matching tag based on tag level. *   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_cleanup_at_close(DilloHtml *html, gint TagIdx){   gint w3c_mode = !prefs.w3c_plus_heuristics;   gint stack_idx, cmp = 1;   gint new_idx = TagIdx;   if (html->CloseOneTag) {      Html_real_pop_tag(html);      html->CloseOneTag = FALSE;      return;   }   /* Look for the candidate tag to close */   stack_idx = html->stack_top;   while (stack_idx &&          (cmp = (new_idx != html->stack[stack_idx].tag_idx)) &&          ((w3c_mode &&            Tags[html->stack[stack_idx].tag_idx].EndTag == 'O') ||           (!w3c_mode &&            Tags[html->stack[stack_idx].tag_idx].TagLevel <            Tags[new_idx].TagLevel))) {      --stack_idx;   }   /* clean, up to the matching tag */   if (cmp == 0 && stack_idx > 0) {      /* There's a valid matching tag in the stack */      while (html->stack_top >= stack_idx) {         gint toptag_idx = html->stack[html->stack_top].tag_idx;         /* Warn when we decide to close an open tag (for !w3c_mode) */         if (html->stack_top > stack_idx &&             Tags[toptag_idx].EndTag != 'O')            MSG_HTML("  - forcing close of open tag: <%s>\n",                     Tags[toptag_idx].name);         /* Close this and only this tag */         html->CloseOneTag = TRUE;         Tags[toptag_idx].close (html, toptag_idx);      }   } else {      MSG_HTML("unexpected closing tag: </%s>. -- expected </%s>\n",               Tags[new_idx].name, html->stack[stack_idx].tag_name);   }}#if 0/* * 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;}#endif/* * Cleanup (conditional), and Pop the tag (if it matches) */static void Html_pop_tag(DilloHtml *html, gint TagIdx){   Html_tag_cleanup_at_close(html, TagIdx);}#if 0/* * 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, int tagsize){    Html_push_tag (html, tag, tagsize);    a_Dw_page_add_parbreak (DW_PAGE (html->dw), 9,                          html->stack[(html)->stack_top].style);}#endif/* * Some parsing routines. *//* * Used by Html_parse_length and Html_parse_multi_length_list. */static DwStyleLength Html_parse_length_or_multi_length (const char *attr,                                                        char **endptr){    DwStyleLength l;    double v;    char *end;    v = (double)strtol (attr, &end, 10);    switch (*end) {    case '%':        end++;        l = DW_STYLE_CREATE_PER_LENGTH (v / 100);        break;    case '*':        end++;        l = DW_STYLE_CREATE_REL_LENGTH (v);        break;    default:        l = DW_STYLE_CREATE_ABS_LENGTH ((int)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 char *attr){    DwStyleLength l;    char *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;}/* * Returns a vector of lenghts/percentages. The caller has to g_free the * result when it is not longer used. *//*static DwStyleLength *Html_parse_multi_length_list (const char *attr){   DwStyleLength *l;   int n, max_n;   char *end;   n = 0;   max_n = 8;   l = g_malloc0 (max_n, sizeof (DwStyleLength));   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_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){    int 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;   for (i = 0; val[i]; ++i)      if (!(isalnum(val[i]) || strchr(":_.-", val[i])))         break;   if (val[i] || !isalpha(val[0]))      MSG_HTML("'%s' value is not of the form "               "[A-Za-z][A-Za-z0-9:_.-]*\n", attrname);   return !(val[i]);}/* * Handle open HTML element */static void Html_tag_open_html(DilloHtml *html, char *tag, gint tagsize){   if (!(html->InFlags & IN_HTML))      html->InFlags |= IN_HTML;   ++html->Num_HTML;   if (html->Num_HTML > 1) {      MSG_HTML("HTML element was already open\n");   }}/* * Handle close HTML element */static void Html_tag_close_html(DilloHtml *html, gint TagIdx){   /* todo: may add some checks here */   html->InFlags &= ~IN_HTML;   Html_pop_tag(html, TagIdx);}/* * Handle open HEAD element */static void Html_tag_open_head(DilloHtml *html, char *tag, int tagsize){   if (html->InFlags & IN_BODY) {      MSG_HTML("HEAD element must go before the BODY section\n");      html->ReqTagClose = TRUE;      return;   }   if (!(html->InFlags & IN_HEAD))      html->InFlags |= IN_HEAD;   ++html->Num_HEAD;   if (html->Num_HEAD > 1) {      MSG_HTML("HEAD element was already open\n");   }}/* * Handle close HEAD element */static void Html_tag_close_head(DilloHtml *html, int TagIdx){   if (html->InFlags & IN_HEAD) {      if (html->Num_TITLE == 0)         MSG_HTML("HEAD section lacks the TITLE element\n");         html->InFlags &= ~IN_HEAD;   }   Html_pop_tag(html, TagIdx);}/* * Handle open TITLE * calls stash init, where the title string will be stored */static void Html_tag_open_title(DilloHtml *html, char *tag, int tagsize){	++html->Num_TITLE;    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, int TagIdx){    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, TagIdx);

⌨️ 快捷键说明

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