diff options
Diffstat (limited to 'src/html.cc')
-rw-r--r-- | src/html.cc | 1175 |
1 files changed, 489 insertions, 686 deletions
diff --git a/src/html.cc b/src/html.cc index 77128927..2c348fc8 100644 --- a/src/html.cc +++ b/src/html.cc @@ -106,14 +106,10 @@ static const char *Html_get_attr2(DilloHtml *html, int tagsize, const char *attrname, int tag_parsing_flags); -static void Html_add_widget(DilloHtml *html, Widget *widget, - char *width_str, char *height_str, - StyleAttrs *style_attrs); static int Html_write_raw(DilloHtml *html, char *buf, int bufsize, int Eof); static void Html_load_image(BrowserWindow *bw, DilloUrl *url, DilloImage *image); static void Html_callback(int Op, CacheClient_t *Client); -static int Html_tag_index(const char *tag); static void Html_tag_cleanup_at_close(DilloHtml *html, int TagIdx); /*----------------------------------------------------------------------------- @@ -312,52 +308,30 @@ static int Html_add_new_linkimage(DilloHtml *html, } /* - * Set the font at the top of the stack. BImask specifies which - * attributes in BI should be changed. - */ -void a_Html_set_top_font(DilloHtml *html, const char *name, int size, - int BI, int BImask) -{ - FontAttrs font_attrs; - - font_attrs = *S_TOP(html)->style->font; - if (name) - font_attrs.name = name; - if (size) - font_attrs.size = size; - if (BImask & 1) - font_attrs.weight = (BI & 1) ? 700 : 400; - if (BImask & 2) - font_attrs.style = (BI & 2) ? FONT_STYLE_ITALIC : FONT_STYLE_NORMAL; - - HTML_SET_TOP_ATTR (html, font, - Font::create (HT2LT(html), &font_attrs)); -} - -/* * Evaluates the ALIGN attribute (left|center|right|justify) and * sets the style at the top of the stack. */ void a_Html_tag_set_align_attr(DilloHtml *html, + CssPropertyList *props, const char *tag, int tagsize) { - const char *align, *charattr; + const char *align; if ((align = a_Html_get_attr(html, tag, tagsize, "align"))) { - Style *old_style = S_TOP(html)->style; - StyleAttrs style_attrs = *old_style; + TextAlignType textAlignType = TEXT_ALIGN_LEFT; if (dStrcasecmp (align, "left") == 0) - style_attrs.textAlign = TEXT_ALIGN_LEFT; + textAlignType = TEXT_ALIGN_LEFT; else if (dStrcasecmp (align, "right") == 0) - style_attrs.textAlign = TEXT_ALIGN_RIGHT; + textAlignType = TEXT_ALIGN_RIGHT; else if (dStrcasecmp (align, "center") == 0) - style_attrs.textAlign = TEXT_ALIGN_CENTER; + textAlignType = TEXT_ALIGN_CENTER; else if (dStrcasecmp (align, "justify") == 0) - style_attrs.textAlign = TEXT_ALIGN_JUSTIFY; + textAlignType = TEXT_ALIGN_JUSTIFY; +#if 0 else if (dStrcasecmp (align, "char") == 0) { /* TODO: Actually not supported for <p> etc. */ - style_attrs.textAlign = TEXT_ALIGN_STRING; + v.textAlign = TEXT_ALIGN_STRING; if ((charattr = a_Html_get_attr(html, tag, tagsize, "char"))) { if (charattr[0] == 0) /* TODO: ALIGN=" ", and even ALIGN="&32;" will reult in @@ -371,8 +345,8 @@ void a_Html_tag_set_align_attr(DilloHtml *html, /* TODO: Examine LANG attr of <html>. */ style_attrs.textAlignChar = '.'; } - S_TOP(html)->style = Style::create (HT2LT(html), &style_attrs); - old_style->unref (); +#endif + props->set (CssProperty::CSS_PROPERTY_TEXT_ALIGN, textAlignType); } } @@ -381,19 +355,22 @@ void a_Html_tag_set_align_attr(DilloHtml *html, * sets the style in style_attrs. Returns true when set. */ bool a_Html_tag_set_valign_attr(DilloHtml *html, const char *tag, - int tagsize, StyleAttrs *style_attrs) + int tagsize, CssPropertyList *props) { const char *attr; + VAlignType valign; if ((attr = a_Html_get_attr(html, tag, tagsize, "valign"))) { if (dStrcasecmp (attr, "top") == 0) - style_attrs->valign = VALIGN_TOP; + valign = VALIGN_TOP; else if (dStrcasecmp (attr, "bottom") == 0) - style_attrs->valign = VALIGN_BOTTOM; + valign = VALIGN_BOTTOM; else if (dStrcasecmp (attr, "baseline") == 0) - style_attrs->valign = VALIGN_BASELINE; + valign = VALIGN_BASELINE; else - style_attrs->valign = VALIGN_MIDDLE; + valign = VALIGN_MIDDLE; + + props->set (CssProperty::CSS_PROPERTY_VERTICAL_ALIGN, valign); return true; } else return false; @@ -401,87 +378,23 @@ bool a_Html_tag_set_valign_attr(DilloHtml *html, const char *tag, /* - * Add a new DwPage into the current DwPage, for indentation. - * left and right are the horizontal indentation amounts, space is the - * vertical space around the block. + * Create and add a new Textblock to the current Textblock */ -static void Html_add_indented_widget(DilloHtml *html, Widget *textblock, - int left, int right, int space) +static void Html_add_textblock(DilloHtml *html, int space) { - StyleAttrs style_attrs; - Style *style; - - style_attrs = *S_TOP(html)->style; - - style_attrs.margin.setVal (0); - style_attrs.borderWidth.setVal (0); - style_attrs.padding.setVal(0); - - /* Activate this for debugging */ -#if 0 - style_attrs.borderWidth.setVal (1); - style_attrs.setBorderColor ( - Color::createShaded (HT2LT(html), style_attrs.color->getColor()); - style_attrs.setBorderStyle (BORDER_DASHED); -#endif - - style_attrs.margin.left = left; - style_attrs.margin.right = right; - style = Style::create (HT2LT(html), &style_attrs); + Textblock *textblock = new Textblock (prefs.limit_text_width); - DW2TB(html->dw)->addParbreak (space, style); - DW2TB(html->dw)->addWidget (textblock, style); - DW2TB(html->dw)->addParbreak (space, style); + DW2TB(html->dw)->addParbreak (space, html->styleEngine->wordStyle ()); + DW2TB(html->dw)->addWidget (textblock, html->styleEngine->style ()); + DW2TB(html->dw)->addParbreak (space, html->styleEngine->wordStyle ()); S_TOP(html)->textblock = html->dw = textblock; S_TOP(html)->hand_over_break = true; - style->unref (); /* Handle it when the user clicks on a link */ html->connectSignals(textblock); } /* - * Create and add a new indented DwPage to the current DwPage - */ -static void Html_add_indented(DilloHtml *html, int left, int right, int space) -{ - Textblock *textblock = new Textblock (prefs.limit_text_width); - Html_add_indented_widget (html, textblock, left, right, space); -} - -/* - * Given a font_size, this will return the correct 'level'. - * (or the closest, if the exact level isn't found). - */ -static int Html_fontsize_to_level(int fontsize) -{ - int i, level; - double normalized_size = fontsize / prefs.font_factor, - approximation = FontSizes[FontSizesNum-1] + 1; - - for (i = level = 0; i < FontSizesNum; i++) - if (approximation >= fabs(normalized_size - FontSizes[i])) { - approximation = fabs(normalized_size - FontSizes[i]); - level = i; - } else { - break; - } - - return level; -} - -/* - * Given a level of a font, this will return the correct 'size'. - */ -static int Html_level_to_fontsize(int level) -{ - level = MAX(0, level); - level = MIN(FontSizesNum - 1, level); - - return (int)rint(FontSizes[level]*prefs.font_factor); -} - -/* * Create and initialize a new DilloHtml class */ DilloHtml::DilloHtml(BrowserWindow *p_bw, const DilloUrl *url, @@ -510,6 +423,7 @@ DilloHtml::DilloHtml(BrowserWindow *p_bw, const DilloUrl *url, a_Misc_parse_content_type(content_type, NULL, NULL, &charset); stop_parser = false; + repush_after_head = false; CurrTagOfs = 0; OldTagOfs = 0; @@ -520,8 +434,7 @@ DilloHtml::DilloHtml(BrowserWindow *p_bw, const DilloUrl *url, stack = new misc::SimpleVector <DilloHtmlState> (16); stack->increase(); - stack->getRef(0)->style = NULL; - stack->getRef(0)->table_cell_style = NULL; + stack->getRef(0)->table_cell_props = NULL; stack->getRef(0)->parse_mode = DILLO_HTML_PARSE_MODE_INIT; stack->getRef(0)->table_mode = DILLO_HTML_TABLE_MODE_NONE; stack->getRef(0)->cell_text_align_set = false; @@ -534,6 +447,8 @@ DilloHtml::DilloHtml(BrowserWindow *p_bw, const DilloUrl *url, stack->getRef(0)->current_bg_color = prefs.bg_color; stack->getRef(0)->hand_over_break = false; + styleEngine = new StyleEngine (HT2LT (this)); + InFlags = IN_NONE; Stash = dStr_new(""); @@ -561,8 +476,8 @@ DilloHtml::DilloHtml(BrowserWindow *p_bw, const DilloUrl *url, images = new misc::SimpleVector <DilloLinkImage*> (16); //a_Dw_image_map_list_init(&maps); - link_color = prefs.link_color; - visited_color = prefs.visited_color; + link_color = -1; + visited_color = -1; /* Initialize the main widget */ initDw(); @@ -575,26 +490,12 @@ DilloHtml::DilloHtml(BrowserWindow *p_bw, const DilloUrl *url, */ void DilloHtml::initDw() { - StyleAttrs style_attrs; - FontAttrs font_attrs; - dReturn_if_fail (dw == NULL); /* Create the main widget */ dw = stack->getRef(0)->textblock = new Textblock (prefs.limit_text_width); - /* Create a dummy font, attribute, and tag for the bottom of the stack. */ - font_attrs.name = prefs.vw_fontname; - font_attrs.size = Html_level_to_fontsize(FontSizesBase); - font_attrs.weight = 400; - font_attrs.style = FONT_STYLE_NORMAL; - - style_attrs.initValues (); - style_attrs.font = Font::create (HT2LT(this), &font_attrs); - style_attrs.color = Color::createSimple (HT2LT(this), prefs.text_color); - stack->getRef(0)->style = Style::create (HT2LT(this), &style_attrs); - - stack->getRef(0)->table_cell_style = NULL; + stack->getRef(0)->table_cell_props = NULL; /* Handle it when the user clicks on a link */ connectSignals(dw); @@ -640,6 +541,8 @@ DilloHtml::~DilloHtml() } delete (images); + delete styleEngine; + //a_Dw_image_map_list_free(&maps); } @@ -661,7 +564,15 @@ void DilloHtml::write(char *Buf, int BufSize, int Eof) char *buf = Buf + Start_Ofs; int bufsize = BufSize - Start_Ofs; + MSG("DilloHtml::write BufSize=%d Start_Ofs=%d\n", BufSize, Start_Ofs); +#if 0 + char *aux = dStrndup(Buf, BufSize); + MSG(" {%s}\n", aux); + dFree(aux); +#endif + dReturn_if_fail (dw != NULL); + dReturn_if_fail (stop_parser == FALSE); Start_Buf = Buf; token_start = Html_write_raw(this, buf, bufsize, Eof); @@ -694,7 +605,6 @@ int DilloHtml::getCurTagLineNumber() */ void DilloHtml::freeParseData() { - (stack->getRef(0)->style)->unref (); /* template style */ delete(stack); dStr_free(Stash, TRUE); @@ -1150,11 +1060,11 @@ static void Html_process_space(DilloHtml *html, const char *space, if (spaceCnt) { spc = dStrnfill(spaceCnt, ' '); - DW2TB(html->dw)->addText (spc, S_TOP(html)->style); + DW2TB(html->dw)->addText (spc, html->styleEngine->wordStyle ()); dFree(spc); spaceCnt = 0; } - DW2TB(html->dw)->addLinebreak (S_TOP(html)->style); + DW2TB(html->dw)->addLinebreak (html->styleEngine->wordStyle ()); html->pre_column = 0; } html->PreFirstChar = false; @@ -1182,7 +1092,7 @@ static void Html_process_space(DilloHtml *html, const char *space, if (spaceCnt) { spc = dStrnfill(spaceCnt, ' '); - DW2TB(html->dw)->addText (spc, S_TOP(html)->style); + DW2TB(html->dw)->addText (spc, html->styleEngine->wordStyle ()); dFree(spc); } @@ -1190,7 +1100,7 @@ static void Html_process_space(DilloHtml *html, const char *space, if (SGML_SPCDEL) { /* SGML_SPCDEL ignores white space inmediately after an open tag */ } else if (!html->PrevWasSPC) { - DW2TB(html->dw)->addSpace(S_TOP(html)->style); + DW2TB(html->dw)->addSpace(html->styleEngine->wordStyle ()); html->PrevWasSPC = true; } @@ -1243,7 +1153,7 @@ static void Html_process_word(DilloHtml *html, const char *word, int size) while (Pword[++i] && !isspace(Pword[i])) ; ch = Pword[i]; Pword[i] = 0; - DW2TB(html->dw)->addText(Pword, S_TOP(html)->style); + DW2TB(html->dw)->addText(Pword, html->styleEngine->wordStyle ()); Pword[i] = ch; html->pre_column += i - start; html->PreFirstChar = false; @@ -1253,7 +1163,7 @@ static void Html_process_word(DilloHtml *html, const char *word, int size) } else { if (!memchr(word,'&', size)) { /* No entities */ - DW2TB(html->dw)->addText(word, S_TOP(html)->style); + DW2TB(html->dw)->addText(word, html->styleEngine->wordStyle ()); } else { /* Collapse white-space entities inside the word (except ) */ Pword = a_Html_parse_entities(html, word, size); @@ -1261,7 +1171,7 @@ static void Html_process_word(DilloHtml *html, const char *word, int size) if (strchr("\t\f\n\r", Pword[i])) for (j = i; (Pword[j] = Pword[j+1]); ++j) ; - DW2TB(html->dw)->addText(Pword, S_TOP(html)->style); + DW2TB(html->dw)->addText(Pword, html->styleEngine->wordStyle ()); dFree(Pword); } } @@ -1297,7 +1207,7 @@ static void Html_eventually_pop_dw(DilloHtml *html, bool hand_over_break) { if (html->dw != S_TOP(html)->textblock) { if (hand_over_break) - DW2TB(html->dw)->handOverBreak (S_TOP(html)->style); + DW2TB(html->dw)->handOverBreak (html->styleEngine->style ()); DW2TB(html->dw)->flush (); html->dw = S_TOP(html)->textblock; } @@ -1316,10 +1226,8 @@ static void Html_push_tag(DilloHtml *html, int tag_idx) * instead of copying all fields except for tag. --Jcid */ *html->stack->getRef(n_items) = *html->stack->getRef(n_items - 1); html->stack->getRef(n_items)->tag_idx = tag_idx; - /* proper memory management, may be unref'd later */ - (S_TOP(html)->style)->ref (); - if (S_TOP(html)->table_cell_style) - (S_TOP(html)->table_cell_style)->ref (); + if (S_TOP(html)->table_cell_props) + S_TOP(html)->table_cell_props->ref (); html->dw = S_TOP(html)->textblock; } @@ -1329,6 +1237,7 @@ static void Html_push_tag(DilloHtml *html, int tag_idx) */ static void Html_force_push_tag(DilloHtml *html, int tag_idx) { + html->styleEngine->startElement (tag_idx); Html_push_tag(html, tag_idx); } @@ -1339,9 +1248,9 @@ static void Html_real_pop_tag(DilloHtml *html) { bool hand_over_break; - (S_TOP(html)->style)->unref (); - if (S_TOP(html)->table_cell_style) - (S_TOP(html)->table_cell_style)->unref (); + html->styleEngine->endElement (S_TOP(html)->tag_idx); + if (S_TOP(html)->table_cell_props) + S_TOP(html)->table_cell_props->unref (); hand_over_break = S_TOP(html)->hand_over_break; html->stack->setSize (html->stack->size() - 1); Html_eventually_pop_dw(html, hand_over_break); @@ -1416,10 +1325,10 @@ static void Html_tag_cleanup_at_close(DilloHtml *html, int TagIdx) /* * Used by a_Html_parse_length */ -static Length Html_parse_length_or_multi_length (const char *attr, - char **endptr) +static CssLength Html_parse_length_or_multi_length (const char *attr, + char **endptr) { - Length l; + CssLength l; double v; char *end; @@ -1427,12 +1336,12 @@ static Length Html_parse_length_or_multi_length (const char *attr, switch (*end) { case '%': end++; - l = createPerLength (v / 100); + l = CSS_CREATE_LENGTH (v / 100, CSS_LENGTH_TYPE_PERCENTAGE); break; case '*': end++; - l = createRelLength (v); + l = CSS_CREATE_LENGTH (v, CSS_LENGTH_TYPE_RELATIVE); break; /* The "px" suffix seems not allowed by HTML4.01 SPEC. @@ -1441,7 +1350,7 @@ static Length Html_parse_length_or_multi_length (const char *attr, end += 2; */ default: - l = createAbsLength ((int)v); + l = CSS_CREATE_LENGTH (v, CSS_LENGTH_TYPE_PX); break; } @@ -1455,24 +1364,24 @@ static Length Html_parse_length_or_multi_length (const char *attr, * Returns a length or a percentage, or UNDEF_LENGTH in case * of an error, or if attr is NULL. */ -Length a_Html_parse_length (DilloHtml *html, const char *attr) +CssLength a_Html_parse_length (DilloHtml *html, const char *attr) { - Length l; + CssLength l; char *end; l = Html_parse_length_or_multi_length (attr, &end); - if (isRelLength (l)) + if (CSS_LENGTH_TYPE (l) == CSS_LENGTH_TYPE_RELATIVE) /* not allowed as &Length; */ - return LENGTH_AUTO; + l = CSS_CREATE_LENGTH(0.0, CSS_LENGTH_TYPE_AUTO); else { /* allow only whitespaces */ if (*end && !isspace (*end)) { BUG_MSG("Garbage after length: %s\n", attr); - return LENGTH_AUTO; + l = CSS_CREATE_LENGTH(0.0, CSS_LENGTH_TYPE_AUTO); } } - _MSG("a_Html_parse_length: \"%s\" %d\n", attr, absLengthVal(l)); + _MSG("a_Html_parse_length: \"%s\" %d\n", attr, CSS_LENGTH_VALUE(l)); return l; } @@ -1649,14 +1558,23 @@ static void Html_tag_open_head(DilloHtml *html, const char *tag, int tagsize) * Handle close HEAD element * Note: as a side effect of Html_test_section() this function is called * twice when the head element is closed implicitly. + * Note2: HEAD is parsed once completely got. This asserts that a + * linked stylesheet will always arrive after HEAD contents. */ static void Html_tag_close_head(DilloHtml *html, int TagIdx) { if (html->InFlags & IN_HEAD) { + _MSG("Closing HEAD section\n"); if (html->Num_TITLE == 0) BUG_MSG("HEAD section lacks the TITLE element\n"); - + html->InFlags &= ~IN_HEAD; + + if (html->repush_after_head) { + html->stop_parser = true; + MSG(" [html->stop_parser = true]\n"); + a_Nav_repush(html->bw); + } } } @@ -1706,11 +1624,27 @@ static void Html_tag_close_script(DilloHtml *html, int TagIdx) /* * Handle open STYLE - * store the contents to the stash where (in the future) the style - * sheet interpreter can get it. + * Store contents in the stash where the style sheet interpreter can get it. */ static void Html_tag_open_style(DilloHtml *html, const char *tag, int tagsize) { + const char *attrbuf; + + if (!(attrbuf = a_Html_get_attr(html, tag, tagsize, "type"))) { + BUG_MSG("type attribute is required for <style>\n"); + } else if (dStrcasecmp(attrbuf, "text/css")) { + MSG("Shouldn't be applying <style type=\"%s\">\n", attrbuf); + /* We need to inform close_style() */ + } + if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "media")) && + dStrcasecmp(attrbuf, "all") && !dStristr(attrbuf, "screen")) { + /* HTML 4.01 sec. 6.13 says that media descriptors are case-sensitive, + * but sec. 14.2.3 says that the attribute is case-insensitive. + * TODO can be a comma-separated list. + * TODO handheld. + */ + MSG("Shouldn't be applying <style media=\"%s\">\n", attrbuf); + } a_Html_stash_init(html); S_TOP(html)->parse_mode = DILLO_HTML_PARSE_MODE_VERBATIM; } @@ -1720,7 +1654,8 @@ static void Html_tag_open_style(DilloHtml *html, const char *tag, int tagsize) */ static void Html_tag_close_style(DilloHtml *html, int TagIdx) { - /* eventually the stash will be sent to an interpreter for parsing */ + html->styleEngine->parse(html->Stash->str, html->Stash->len, + 0, CSS_ORIGIN_AUTHOR); } /* @@ -1730,8 +1665,7 @@ static void Html_tag_open_body(DilloHtml *html, const char *tag, int tagsize) { const char *attrbuf; Textblock *textblock; - StyleAttrs style_attrs; - Style *style; + CssPropertyList props; int32_t color; if (!(html->InFlags & IN_BODY)) @@ -1749,43 +1683,37 @@ static void Html_tag_open_body(DilloHtml *html, const char *tag, int tagsize) textblock = DW2TB(html->dw); - if (!prefs.force_my_colors) { - if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "bgcolor"))) { - color = a_Html_color_parse(html, attrbuf, prefs.bg_color); - if (color == 0xffffff && !prefs.allow_white_bg) - color = prefs.bg_color; - - style_attrs = *html->dw->getStyle (); - style_attrs.backgroundColor = Color::createShaded(HT2LT(html), color); - style = Style::create (HT2LT(html), &style_attrs); - html->dw->setStyle (style); - style->unref (); - S_TOP(html)->current_bg_color = color; - } + if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "bgcolor"))) { + color = a_Html_color_parse(html, attrbuf, prefs.bg_color); + if (color == 0xffffff && !prefs.allow_white_bg) + color = prefs.bg_color; + S_TOP(html)->current_bg_color = color; + props.set (CssProperty::CSS_PROPERTY_BACKGROUND_COLOR, color); + } - if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "text"))) { - color = a_Html_color_parse(html, attrbuf, prefs.text_color); - HTML_SET_TOP_ATTR (html, color, - Color::createSimple (HT2LT(html),color)); - } + if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "text"))) { + color = a_Html_color_parse(html, attrbuf, prefs.text_color); + props.set (CssProperty::CSS_PROPERTY_COLOR, color); + } - if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "link"))) - html->link_color = a_Html_color_parse(html,attrbuf,prefs.link_color); + if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "link"))) + html->link_color = a_Html_color_parse(html, attrbuf, -1); - if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "vlink"))) - html->visited_color = a_Html_color_parse(html, attrbuf, - prefs.visited_color); + if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "vlink"))) + html->visited_color = a_Html_color_parse(html, attrbuf, -1); - if (prefs.contrast_visited_color) { - /* get a color that has a "safe distance" from text, link and bg */ - html->visited_color = + if (prefs.contrast_visited_color) { + /* get a color that has a "safe distance" from text, link and bg */ + html->visited_color = a_Color_vc(html->visited_color, - S_TOP(html)->style->color->getColor(), + html->styleEngine->style ()->color->getColor(), html->link_color, S_TOP(html)->current_bg_color); - } } + html->styleEngine->setNonCssHints (&props); + html->dw->setStyle (html->styleEngine->style ()); + S_TOP(html)->parse_mode = DILLO_HTML_PARSE_MODE_BODY; } @@ -1807,13 +1735,16 @@ static void Html_tag_close_body(DilloHtml *html, int TagIdx) */ static void Html_tag_open_p(DilloHtml *html, const char *tag, int tagsize) { + CssPropertyList props; + if ((html->InFlags & IN_LI) && !html->WordAfterLI) { /* ignore first parbreak after an empty <LI> */ html->WordAfterLI = true; } else { - DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); + DW2TB(html->dw)->addParbreak (9, html->styleEngine->wordStyle ()); } - a_Html_tag_set_align_attr (html, tag, tagsize); + a_Html_tag_set_align_attr (html, &props, tag, tagsize); + html->styleEngine->setNonCssHints (&props); } /* @@ -1827,9 +1758,8 @@ static void Html_tag_open_frame (DilloHtml *html, const char *tag, int tagsize) char *src; DilloUrl *url; Textblock *textblock; - StyleAttrs style_attrs; - Style *link_style; Widget *bullet; + CssPropertyList props; textblock = DW2TB(html->dw); @@ -1841,46 +1771,41 @@ static void Html_tag_open_frame (DilloHtml *html, const char *tag, int tagsize) src = dStrdup(attrbuf); - style_attrs = *(S_TOP(html)->style); - if (a_Capi_get_flags(url) & CAPI_IsCached) { /* visited frame */ - style_attrs.color = - Color::createSimple (HT2LT(html), html->visited_color); + html->styleEngine->setPseudoVisited (); } else { /* unvisited frame */ - style_attrs.color = Color::createSimple (HT2LT(html), html->link_color); + html->styleEngine->setPseudoLink (); } - style_attrs.textDecoration |= TEXT_DECORATION_UNDERLINE; - style_attrs.x_link = Html_set_new_link(html, &url); - style_attrs.cursor = CURSOR_POINTER; - link_style = Style::create (HT2LT(html), &style_attrs); - textblock->addParbreak (5, S_TOP(html)->style); + props.set (CssProperty::PROPERTY_X_LINK, Html_set_new_link(html, &url)); + html->styleEngine->setNonCssHints (&props); + + textblock->addParbreak (5, html->styleEngine->wordStyle ()); /* The bullet will be assigned the current list style, which should * be "disc" by default, but may in very weird pages be different. * Anyway, there should be no harm. */ bullet = new Bullet(); - textblock->addWidget(bullet, S_TOP(html)->style); - textblock->addSpace(S_TOP(html)->style); + textblock->addWidget(bullet, html->styleEngine->style ()); + textblock->addSpace(html->styleEngine->wordStyle ()); if (tolower(tag[1]) == 'i') { /* IFRAME usually comes with very long advertising/spying URLS, * to not break rendering we will force name="IFRAME" */ - textblock->addText ("IFRAME", link_style); + textblock->addText ("IFRAME", html->styleEngine->wordStyle ()); } else { /* FRAME: * If 'name' tag is present use it, if not use 'src' value */ if (!(attrbuf = a_Html_get_attr(html, tag, tagsize, "name"))) { - textblock->addText (src, link_style); + textblock->addText (src, html->styleEngine->wordStyle ()); } else { - textblock->addText (attrbuf, link_style); + textblock->addText (attrbuf, html->styleEngine->wordStyle ()); } } - textblock->addParbreak (5, S_TOP(html)->style); + textblock->addParbreak (5, html->styleEngine->wordStyle ()); - link_style->unref (); dFree(src); } @@ -1892,9 +1817,9 @@ static void Html_tag_open_frame (DilloHtml *html, const char *tag, int tagsize) static void Html_tag_open_frameset (DilloHtml *html, const char *tag, int tagsize) { - DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); - DW2TB(html->dw)->addText("--FRAME--", S_TOP(html)->style); - Html_add_indented(html, 40, 0, 5); + DW2TB(html->dw)->addParbreak (9, html->styleEngine->wordStyle ()); + DW2TB(html->dw)->addText("--FRAME--", html->styleEngine->wordStyle ()); + Html_add_textblock(html, 5); } /* @@ -1902,18 +1827,19 @@ static void Html_tag_open_frameset (DilloHtml *html, */ static void Html_tag_open_h(DilloHtml *html, const char *tag, int tagsize) { - DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); + CssPropertyList props; - /* TODO: combining these two would be slightly faster */ - a_Html_set_top_font(html, prefs.vw_fontname, - Html_level_to_fontsize(FontSizesNum - (tag[2] - '0')), - 1, 3); - a_Html_tag_set_align_attr (html, tag, tagsize); + + html->styleEngine->inheritBackgroundColor (); + a_Html_tag_set_align_attr (html, &props, tag, tagsize); + html->styleEngine->setNonCssHints (&props); + + DW2TB(html->dw)->addParbreak (9, html->styleEngine->wordStyle ()); /* First finalize unclosed H tags (we test if already named anyway) */ a_Menu_pagemarks_set_text(html->bw, html->Stash->str); a_Menu_pagemarks_add(html->bw, DW2TB(html->dw), - S_TOP(html)->style, (tag[2] - '0')); + html->styleEngine->style (), (tag[2] - '0')); a_Html_stash_init(html); S_TOP(html)->parse_mode = DILLO_HTML_PARSE_MODE_STASH_AND_BODY; @@ -1925,29 +1851,22 @@ static void Html_tag_open_h(DilloHtml *html, const char *tag, int tagsize) static void Html_tag_close_h(DilloHtml *html, int TagIdx) { a_Menu_pagemarks_set_text(html->bw, html->Stash->str); - DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); + DW2TB(html->dw)->addParbreak (9, html->styleEngine->wordStyle ()); } -/* - * <BIG> | <SMALL> - */ -static void Html_tag_open_big_small(DilloHtml *html, - const char *tag, int tagsize) +static void Html_tag_open_span(DilloHtml *html, + const char *tag, int tagsize) { - int level; - - level = - Html_fontsize_to_level(S_TOP(html)->style->font->size) + - ((dStrncasecmp(tag+1, "big", 3)) ? -1 : 1); - a_Html_set_top_font(html, NULL, Html_level_to_fontsize(level), 0, 0); + html->styleEngine->inheritBackgroundColor(); } + /* * <BR> */ static void Html_tag_open_br(DilloHtml *html, const char *tag, int tagsize) { - DW2TB(html->dw)->addLinebreak (S_TOP(html)->style); + DW2TB(html->dw)->addLinebreak (html->styleEngine->wordStyle ()); } /* @@ -1955,39 +1874,27 @@ static void Html_tag_open_br(DilloHtml *html, const char *tag, int tagsize) */ static void Html_tag_open_font(DilloHtml *html, const char *tag, int tagsize) { - StyleAttrs style_attrs; - Style *old_style; /*Font font;*/ const char *attrbuf; int32_t color; - - if (!prefs.force_my_colors) { - old_style = S_TOP(html)->style; - style_attrs = *old_style; - - if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "color"))) { - if (prefs.contrast_visited_color && html->InVisitedLink) { - color = html->visited_color; - } else { - /* use the tag-specified color */ - color = a_Html_color_parse(html, attrbuf, - style_attrs.color->getColor()); - style_attrs.color = Color::createSimple (HT2LT(html), color); - } + CssPropertyList props; + + if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "color"))) { + if (prefs.contrast_visited_color && html->InVisitedLink) { + color = html->visited_color; + } else { + /* use the tag-specified color */ + color = a_Html_color_parse(html, attrbuf, -1); } + if (color != -1) + props.set (CssProperty::CSS_PROPERTY_COLOR, color); + } -#if 0 - //if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "face"))) { - // font = *( style_attrs.font ); - // font.name = attrbuf; - // style_attrs.font = a_Dw_style_font_new_from_list (&font); - //} -#endif +// \todo reenable font face handling when font selection is implemented +// if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "face"))) +// props.set (CssProperty::CSS_PROPERTY_FONT_FAMILY, attrbuf); - S_TOP(html)->style = - Style::create (HT2LT(html), &style_attrs); - old_style->unref (); - } + html->styleEngine->setNonCssHints (&props); } /* @@ -2005,52 +1912,11 @@ static void Html_tag_open_abbr(DilloHtml *html, const char *tag, int tagsize) } /* - * <B> - */ -static void Html_tag_open_b(DilloHtml *html, const char *tag, int tagsize) -{ - a_Html_set_top_font(html, NULL, 0, 1, 1); -} - -/* - * <STRONG> - */ -static void Html_tag_open_strong(DilloHtml *html, const char *tag, int tagsize) -{ - a_Html_set_top_font(html, NULL, 0, 1, 1); -} - -/* - * <I> - */ -static void Html_tag_open_i(DilloHtml *html, const char *tag, int tagsize) -{ - a_Html_set_top_font(html, NULL, 0, 2, 2); -} - -/* - * <EM> - */ -static void Html_tag_open_em(DilloHtml *html, const char *tag, int tagsize) -{ - a_Html_set_top_font(html, NULL, 0, 2, 2); -} - -/* - * <CITE> - */ -static void Html_tag_open_cite(DilloHtml *html, const char *tag, int tagsize) -{ - a_Html_set_top_font(html, NULL, 0, 2, 2); -} - -/* * <CENTER> */ static void Html_tag_open_center(DilloHtml *html, const char *tag, int tagsize) { - DW2TB(html->dw)->addParbreak (0, S_TOP(html)->style); - HTML_SET_TOP_ATTR(html, textAlign, TEXT_ALIGN_CENTER); + DW2TB(html->dw)->addParbreak (0, html->styleEngine->wordStyle ()); } /* @@ -2059,16 +1925,7 @@ static void Html_tag_open_center(DilloHtml *html, const char *tag, int tagsize) static void Html_tag_open_address(DilloHtml *html, const char *tag, int tagsize) { - DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); - a_Html_set_top_font(html, NULL, 0, 2, 2); -} - -/* - * <TT> - */ -static void Html_tag_open_tt(DilloHtml *html, const char *tag, int tagsize) -{ - a_Html_set_top_font(html, prefs.fw_fontname, 0, 0, 0); + DW2TB(html->dw)->addParbreak (9, html->styleEngine->wordStyle ()); } /* @@ -2077,7 +1934,6 @@ static void Html_tag_open_tt(DilloHtml *html, const char *tag, int tagsize) */ DilloImage *a_Html_add_new_image(DilloHtml *html, const char *tag, int tagsize, DilloUrl *url, - dw::core::style::StyleAttrs *style_attrs, bool add) { const int MAX_W = 6000, MAX_H = 6000; @@ -2085,9 +1941,11 @@ DilloImage *a_Html_add_new_image(DilloHtml *html, const char *tag, DilloImage *Image; char *width_ptr, *height_ptr, *alt_ptr; const char *attrbuf; - Length l_w, l_h; - int space, w = 0, h = 0; + Length l_w = CSS_CREATE_LENGTH(0.0, CSS_LENGTH_TYPE_AUTO); + Length l_h = CSS_CREATE_LENGTH(0.0, CSS_LENGTH_TYPE_AUTO); + int space, border, w = 0, h = 0; bool load_now; + CssPropertyList props; // if (prefs.show_tooltip && // (attrbuf = a_Html_get_attr(html, tag, tagsize, "title"))) @@ -2104,17 +1962,24 @@ DilloImage *a_Html_add_new_image(DilloHtml *html, const char *tag, // TODO: the same for percentage and relative lengths. if (width_ptr) { l_w = a_Html_parse_length (html, width_ptr); - w = isAbsLength(l_w) ? absLengthVal(l_w) : 0; + w = (int) (CSS_LENGTH_TYPE(l_w) == CSS_LENGTH_TYPE_PX ? + CSS_LENGTH_VALUE(l_w) : 0); } if (height_ptr) { l_h = a_Html_parse_length (html, height_ptr); - h = isAbsLength(l_h) ? absLengthVal(l_h) : 0; + h = (int) (CSS_LENGTH_TYPE(l_h) == CSS_LENGTH_TYPE_PX ? + CSS_LENGTH_VALUE(l_h) : 0); } if (w < 0 || h < 0 || abs(w*h) > MAX_W * MAX_H) { dFree(width_ptr); dFree(height_ptr); width_ptr = height_ptr = NULL; MSG("a_Html_add_new_image: suspicious image size request %dx%d\n", w, h); + } else { + if (CSS_LENGTH_TYPE(l_w) != CSS_LENGTH_TYPE_AUTO) + props.set (CssProperty::CSS_PROPERTY_WIDTH, l_w); + if (CSS_LENGTH_TYPE(l_h) != CSS_LENGTH_TYPE_AUTO) + props.set (CssProperty::CSS_PROPERTY_HEIGHT, l_h); } /* TODO: we should scale the image respecting its ratio. @@ -2127,27 +1992,52 @@ DilloImage *a_Html_add_new_image(DilloHtml *html, const char *tag, /* Spacing to the left and right */ if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "hspace"))) { space = strtol(attrbuf, NULL, 10); - if (space > 0) - style_attrs->margin.left = style_attrs->margin.right = space; + if (space > 0) { + space = CSS_CREATE_LENGTH(space, CSS_LENGTH_TYPE_PX); + props.set (CssProperty::CSS_PROPERTY_MARGIN_LEFT, space); + props.set (CssProperty::CSS_PROPERTY_MARGIN_RIGHT, space); + } } /* Spacing at the top and bottom */ if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "vspace"))) { space = strtol(attrbuf, NULL, 10); - if (space > 0) - style_attrs->margin.top = style_attrs->margin.bottom = space; + if (space > 0) { + space = CSS_CREATE_LENGTH(space, CSS_LENGTH_TYPE_PX); + props.set (CssProperty::CSS_PROPERTY_MARGIN_TOP, space); + props.set (CssProperty::CSS_PROPERTY_MARGIN_BOTTOM, space); + } + } + + /* Border */ + if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "border"))) { + border = strtol(attrbuf, NULL, 10); + if (border >= 0) { + border = CSS_CREATE_LENGTH(border, CSS_LENGTH_TYPE_PX); + props.set (CssProperty::CSS_PROPERTY_BORDER_TOP_WIDTH, border); + props.set (CssProperty::CSS_PROPERTY_BORDER_BOTTOM_WIDTH, border); + props.set (CssProperty::CSS_PROPERTY_BORDER_LEFT_WIDTH, border); + props.set (CssProperty::CSS_PROPERTY_BORDER_RIGHT_WIDTH, border); + + props.set (CssProperty::CSS_PROPERTY_BORDER_TOP_STYLE, BORDER_SOLID); + props.set (CssProperty::CSS_PROPERTY_BORDER_BOTTOM_STYLE, + BORDER_SOLID); + props.set (CssProperty::CSS_PROPERTY_BORDER_LEFT_STYLE, BORDER_SOLID); + props.set (CssProperty::CSS_PROPERTY_BORDER_RIGHT_STYLE,BORDER_SOLID); + } } /* x_img is an index to a list of {url,image} pairs. * We know Html_add_new_linkimage() will use size() as its next index */ - style_attrs->x_img = html->images->size(); + props.set (CssProperty::PROPERTY_X_IMG, html->images->size()); + + html->styleEngine->setNonCssHints(&props); /* Add a new image widget to this page */ Image = a_Image_new(0, 0, alt_ptr, S_TOP(html)->current_bg_color); - if (add) { - Html_add_widget(html, (Widget*)Image->dw, width_ptr, height_ptr, - style_attrs); - } + if (add) + DW2TB(html->dw)->addWidget((Widget*)Image->dw, + html->styleEngine->style()); load_now = a_UIcmd_get_images_enabled(html->bw) || (a_Capi_get_flags(url) & CAPI_IsCached); @@ -2191,9 +2081,7 @@ static void Html_tag_open_img(DilloHtml *html, const char *tag, int tagsize) DilloImage *Image; DilloUrl *url, *usemap_url; Textblock *textblock; - StyleAttrs style_attrs; const char *attrbuf; - int border; /* This avoids loading images. Useful for viewing suspicious HTML email. */ if (URL_FLAGS(html->base_url) & URL_SpamSafe) @@ -2210,34 +2098,13 @@ static void Html_tag_open_img(DilloHtml *html, const char *tag, int tagsize) /* TODO: usemap URLs outside of the document are not used. */ usemap_url = a_Html_url_new(html, attrbuf, NULL, 0); - /* Set the style attributes for this image */ - style_attrs = *S_TOP(html)->style; - if (S_TOP(html)->style->x_link != -1 || - usemap_url != NULL) { - /* Images within links */ - border = 1; - if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "border"))) - border = strtol (attrbuf, NULL, 10); - - if (S_TOP(html)->style->x_link != -1) { - /* In this case we can use the text color */ - style_attrs.setBorderColor ( - Color::createShaded (HT2LT(html), style_attrs.color->getColor())); - } else { - style_attrs.setBorderColor ( - Color::createShaded (HT2LT(html), html->link_color)); - } - style_attrs.setBorderStyle (BORDER_SOLID); - style_attrs.borderWidth.setVal (border); - } - - Image = a_Html_add_new_image(html, tag, tagsize, url, &style_attrs, true); + Image = a_Html_add_new_image(html, tag, tagsize, url, true); /* Image maps */ if (a_Html_get_attr(html, tag, tagsize, "ismap")) { ((::dw::Image*)Image->dw)->setIsMap(); _MSG(" Html_tag_open_img: server-side map (ISMAP)\n"); - } else if (S_TOP(html)->style->x_link != -1 && + } else if (html->styleEngine->style ()->x_link != -1 && usemap_url == NULL) { /* For simple links, we have to suppress the "image_pressed" signal. * This is overridden for USEMAP images. */ @@ -2404,10 +2271,9 @@ static void Html_tag_open_area(DilloHtml *html, const char *tag, int tagsize) */ static void Html_tag_open_object(DilloHtml *html, const char *tag, int tagsize) { - StyleAttrs style_attrs; - Style *style; DilloUrl *url, *base_url = NULL; const char *attrbuf; + CssPropertyList props; if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "codebase"))) { base_url = a_Html_url_new(html, attrbuf, NULL, 0); @@ -2418,31 +2284,16 @@ static void Html_tag_open_object(DilloHtml *html, const char *tag, int tagsize) URL_STR(base_url), (base_url != NULL)); dReturn_if_fail ( url != NULL ); - style_attrs = *S_TOP(html)->style; - if (a_Capi_get_flags(url) & CAPI_IsCached) { - style_attrs.color = Color::createSimple ( - HT2LT(html), - html->visited_color -/* - a_Color_vc(html->visited_color, - S_TOP(html)->style->color->getColor(), - html->link_color, - S_TOP(html)->style->backgroundColor->getColor()), -*/ - ); + html->styleEngine->setPseudoVisited (); } else { - style_attrs.color = Color::createSimple(HT2LT(html), - html->link_color); + html->styleEngine->setPseudoLink (); } + + props.set(CssProperty::PROPERTY_X_LINK, Html_set_new_link(html, &url)); + html->styleEngine->setNonCssHints (&props); - style_attrs.textDecoration |= TEXT_DECORATION_UNDERLINE; - style_attrs.x_link = Html_set_new_link(html, &url); - style_attrs.cursor = CURSOR_POINTER; - - style = Style::create (HT2LT(html), &style_attrs); - DW2TB(html->dw)->addText("[OBJECT]", style); - style->unref (); + DW2TB(html->dw)->addText("[OBJECT]", html->styleEngine->wordStyle ()); } a_Url_free(base_url); } @@ -2476,7 +2327,7 @@ static const char* Html_get_javascript_link(DilloHtml *html) static void Html_add_anchor(DilloHtml *html, const char *name) { _MSG("Registering ANCHOR: %s\n", name); - if (!DW2TB(html->dw)->addAnchor (name, S_TOP(html)->style)) + if (!DW2TB(html->dw)->addAnchor (name, html->styleEngine->style ())) BUG_MSG("Anchor names must be unique within the document\n"); /* * According to Sec. 12.2.1 of the HTML 4.01 spec, "anchor names that @@ -2493,9 +2344,8 @@ static void Html_add_anchor(DilloHtml *html, const char *name) */ static void Html_tag_open_a(DilloHtml *html, const char *tag, int tagsize) { - StyleAttrs style_attrs; - Style *old_style; DilloUrl *url; + CssPropertyList props; const char *attrbuf; /* TODO: add support for MAP with A HREF */ @@ -2510,38 +2360,24 @@ static void Html_tag_open_a(DilloHtml *html, const char *tag, int tagsize) url = a_Html_url_new(html, attrbuf, NULL, 0); dReturn_if_fail ( url != NULL ); - old_style = S_TOP(html)->style; - style_attrs = *old_style; - if (a_Capi_get_flags(url) & CAPI_IsCached) { html->InVisitedLink = true; - style_attrs.color = Color::createSimple ( - HT2LT(html), - html->visited_color -/* - a_Color_vc(html->visited_color, - S_TOP(html)->style->color->getColor(), - html->link_color, - S_TOP(html)->current_bg_color), -*/ - ); + html->styleEngine->setPseudoVisited (); + if (html->visited_color != -1) + props.set (CssProperty::CSS_PROPERTY_COLOR, html->visited_color); } else { - style_attrs.color = Color::createSimple(HT2LT(html), - html->link_color); + html->styleEngine->setPseudoLink (); + if (html->link_color != -1) + props.set (CssProperty::CSS_PROPERTY_COLOR, html->link_color); } -// if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "title"))) -// style_attrs.x_tooltip = a_Dw_tooltip_new_no_ref(attrbuf); + props.set (CssProperty::PROPERTY_X_LINK, Html_set_new_link(html, &url)); - style_attrs.textDecoration |= TEXT_DECORATION_UNDERLINE; - style_attrs.x_link = Html_set_new_link(html, &url); - style_attrs.cursor = CURSOR_POINTER; - - S_TOP(html)->style = - Style::create (HT2LT(html), &style_attrs); - old_style->unref (); + html->styleEngine->setNonCssHints (&props); } + html->styleEngine->inheritBackgroundColor (); + if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "name"))) { if (prefs.show_extra_warnings) Html_check_name_val(html, attrbuf, "name"); @@ -2560,45 +2396,13 @@ static void Html_tag_close_a(DilloHtml *html, int TagIdx) } /* - * Insert underlined text in the page. - */ -static void Html_tag_open_u(DilloHtml *html, const char *tag, int tagsize) -{ - Style *style; - StyleAttrs style_attrs; - - style = S_TOP(html)->style; - style_attrs = *style; - style_attrs.textDecoration |= TEXT_DECORATION_UNDERLINE; - S_TOP(html)->style = - Style::create (HT2LT(html), &style_attrs); - style->unref (); -} - -/* - * Insert strike-through text. Used by <S>, <STRIKE> and <DEL>. - */ -static void Html_tag_open_strike(DilloHtml *html, const char *tag, int tagsize) -{ - Style *style; - StyleAttrs style_attrs; - - style = S_TOP(html)->style; - style_attrs = *style; - style_attrs.textDecoration |= TEXT_DECORATION_LINE_THROUGH; - S_TOP(html)->style = - Style::create (HT2LT(html), &style_attrs); - style->unref (); -} - -/* * <BLOCKQUOTE> */ static void Html_tag_open_blockquote(DilloHtml *html, const char *tag, int tagsize) { - DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); - Html_add_indented(html, 40, 40, 9); + DW2TB(html->dw)->addParbreak (9, html->styleEngine->wordStyle ()); + Html_add_textblock(html, 9); } /* @@ -2612,7 +2416,7 @@ static void Html_tag_open_q(DilloHtml *html, const char *tag, int tagsize) */ const char *U201C = "\xe2\x80\x9c"; - DW2TB(html->dw)->addText (U201C, S_TOP(html)->style); + DW2TB(html->dw)->addText (U201C, html->styleEngine->wordStyle ()); } /* @@ -2623,7 +2427,7 @@ static void Html_tag_close_q(DilloHtml *html, int TagIdx) /* Right Double Quotation Mark */ const char *U201D = "\xe2\x80\x9d"; - DW2TB(html->dw)->addText (U201D, S_TOP(html)->style); + DW2TB(html->dw)->addText (U201D, html->styleEngine->wordStyle ()); } /* @@ -2634,10 +2438,9 @@ static void Html_tag_open_ul(DilloHtml *html, const char *tag, int tagsize) const char *attrbuf; ListStyleType list_style_type; - DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); - Html_add_indented(html, 40, 0, 9); - if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "type"))) { + CssPropertyList props; + /* list_style_type explicitly defined */ if (dStrncasecmp(attrbuf, "disc", 4) == 0) list_style_type = LIST_STYLE_TYPE_DISC; @@ -2648,33 +2451,15 @@ static void Html_tag_open_ul(DilloHtml *html, const char *tag, int tagsize) else /* invalid value */ list_style_type = LIST_STYLE_TYPE_DISC; - } else { - if (S_TOP(html)->list_type == HTML_LIST_UNORDERED) { - /* Nested <UL>'s. */ - /* --EG :: I changed the behavior here : types are cycling instead of - * being forced to square. It's easier for mixed lists level counting. - */ - switch (S_TOP(html)->style->listStyleType) { - case LIST_STYLE_TYPE_DISC: - list_style_type = LIST_STYLE_TYPE_CIRCLE; - break; - case LIST_STYLE_TYPE_CIRCLE: - list_style_type = LIST_STYLE_TYPE_SQUARE; - break; - case LIST_STYLE_TYPE_SQUARE: - default: /* this is actually a bug */ - list_style_type = LIST_STYLE_TYPE_DISC; - break; - } - } else { - /* Either first <UL>, or a <OL> before. */ - list_style_type = LIST_STYLE_TYPE_DISC; - } - } - HTML_SET_TOP_ATTR(html, listStyleType, list_style_type); - S_TOP(html)->list_type = HTML_LIST_UNORDERED; + props.set(CssProperty::CSS_PROPERTY_LIST_STYLE_TYPE, list_style_type); + html->styleEngine->setNonCssHints (&props); + } + + DW2TB(html->dw)->addParbreak (9, html->styleEngine->wordStyle ()); + Html_add_textblock(html, 9); + S_TOP(html)->list_type = HTML_LIST_UNORDERED; S_TOP(html)->list_number = 0; S_TOP(html)->ref_list_item = NULL; } @@ -2685,11 +2470,8 @@ static void Html_tag_open_ul(DilloHtml *html, const char *tag, int tagsize) */ static void Html_tag_open_dir(DilloHtml *html, const char *tag, int tagsize) { - ListStyleType list_style_type = LIST_STYLE_TYPE_DISC; + DW2TB(html->dw)->addParbreak (9, html->styleEngine->wordStyle ()); - DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); - Html_add_indented(html, 40, 0, 9); - HTML_SET_TOP_ATTR(html, listStyleType, list_style_type); S_TOP(html)->list_type = HTML_LIST_UNORDERED; S_TOP(html)->list_number = 0; S_TOP(html)->ref_list_item = NULL; @@ -2712,28 +2494,30 @@ static void Html_tag_open_menu(DilloHtml *html, const char *tag, int tagsize) static void Html_tag_open_ol(DilloHtml *html, const char *tag, int tagsize) { const char *attrbuf; - ListStyleType list_style_type; int n = 1; - DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); - Html_add_indented(html, 40, 0, 9); - - list_style_type = LIST_STYLE_TYPE_DECIMAL; - if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "type"))) { + CssPropertyList props; + ListStyleType listStyleType = LIST_STYLE_TYPE_DECIMAL; + if (*attrbuf == '1') - list_style_type = LIST_STYLE_TYPE_DECIMAL; + listStyleType = LIST_STYLE_TYPE_DECIMAL; else if (*attrbuf == 'a') - list_style_type = LIST_STYLE_TYPE_LOWER_ALPHA; + listStyleType = LIST_STYLE_TYPE_LOWER_ALPHA; else if (*attrbuf == 'A') - list_style_type = LIST_STYLE_TYPE_UPPER_ALPHA; + listStyleType = LIST_STYLE_TYPE_UPPER_ALPHA; else if (*attrbuf == 'i') - list_style_type = LIST_STYLE_TYPE_LOWER_ROMAN; + listStyleType = LIST_STYLE_TYPE_LOWER_ROMAN; else if (*attrbuf == 'I') - list_style_type = LIST_STYLE_TYPE_UPPER_ROMAN; + listStyleType = LIST_STYLE_TYPE_UPPER_ROMAN; + + props.set (CssProperty::CSS_PROPERTY_LIST_STYLE_TYPE, listStyleType); + html->styleEngine->setNonCssHints (&props); } - HTML_SET_TOP_ATTR(html, listStyleType, list_style_type); + DW2TB(html->dw)->addParbreak (9, html->styleEngine->wordStyle ()); + Html_add_textblock(html, 9); + S_TOP(html)->list_type = HTML_LIST_ORDERED; if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "start")) && @@ -2750,13 +2534,16 @@ static void Html_tag_open_ol(DilloHtml *html, const char *tag, int tagsize) */ static void Html_tag_open_li(DilloHtml *html, const char *tag, int tagsize) { - StyleAttrs style_attrs; - Style *item_style, *word_style; + Style *style = html->styleEngine->style (); + Style *wordStyle = html->styleEngine->wordStyle (); Widget **ref_list_item; ListItem *list_item; int *list_number; const char *attrbuf; char buf[16]; + + if (S_TOP(html)->list_type == HTML_LIST_NONE) + BUG_MSG("<li> outside <ul> or <ol>\n"); html->InFlags |= IN_LI; html->WordAfterLI = false; @@ -2765,44 +2552,33 @@ static void Html_tag_open_li(DilloHtml *html, const char *tag, int tagsize) list_number = &html->stack->getRef(html->stack->size()-2)->list_number; ref_list_item = &html->stack->getRef(html->stack->size()-2)->ref_list_item; - /* set the item style */ - word_style = S_TOP(html)->style; - style_attrs = *word_style; - //style_attrs.backgroundColor = Color::createShaded (HT2LT(html), 0xffff40); - //style_attrs.setBorderColor (Color::createSimple (HT2LT(html), 0x000000)); - //style_attrs.setBorderStyle (BORDER_SOLID); - //style_attrs.borderWidth.setVal (1); - item_style = Style::create (HT2LT(html), &style_attrs); - - DW2TB(html->dw)->addParbreak (2, word_style); + DW2TB(html->dw)->addParbreak (2, wordStyle); list_item = new ListItem ((ListItem*)*ref_list_item,prefs.limit_text_width); - DW2TB(html->dw)->addWidget (list_item, item_style); - DW2TB(html->dw)->addParbreak (2, word_style); + DW2TB(html->dw)->addWidget (list_item, style); + DW2TB(html->dw)->addParbreak (2, wordStyle); *ref_list_item = list_item; S_TOP(html)->textblock = html->dw = list_item; - item_style->unref(); /* Handle it when the user clicks on a link */ html->connectSignals(list_item); - switch (S_TOP(html)->list_type) { - case HTML_LIST_ORDERED: + if (style->listStyleType == LIST_STYLE_TYPE_NONE) { + // none + } else if (style->listStyleType >= LIST_STYLE_TYPE_DECIMAL) { + // ordered if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "value")) && (*list_number = strtol(attrbuf, NULL, 10)) < 0) { BUG_MSG("illegal negative LIST VALUE attribute; Starting from 0\n"); *list_number = 0; } - numtostr((*list_number)++, buf, 16, S_TOP(html)->style->listStyleType); - list_item->initWithText (dStrdup(buf), word_style); - list_item->addSpace (word_style); + numtostr((*list_number)++, buf, 16, style->listStyleType); + list_item->initWithText (dStrdup(buf), wordStyle); + list_item->addSpace (wordStyle); html->PrevWasSPC = true; - break; - case HTML_LIST_NONE: - BUG_MSG("<li> outside <ul> or <ol>\n"); - default: - list_item->initWithWidget (new Bullet(), word_style); - list_item->addSpace (word_style); - break; + } else { + // unordered + list_item->initWithWidget (new Bullet(), wordStyle); + list_item->addSpace (wordStyle); } } @@ -2822,58 +2598,50 @@ static void Html_tag_close_li(DilloHtml *html, int TagIdx) static void Html_tag_open_hr(DilloHtml *html, const char *tag, int tagsize) { Widget *hruler; - StyleAttrs style_attrs; - Style *style; + CssPropertyList props; char *width_ptr; const char *attrbuf; int32_t size = 0; - style_attrs = *S_TOP(html)->style; - - width_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "width", "100%"); - style_attrs.width = a_Html_parse_length (html, width_ptr); - dFree(width_ptr); + width_ptr = a_Html_get_attr_wdef(html, tag, tagsize, "width", NULL); + if (width_ptr) { + props.set (CssProperty::CSS_PROPERTY_WIDTH, + a_Html_parse_length (html, width_ptr)); + dFree(width_ptr); + } if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "size"))) size = strtol(attrbuf, NULL, 10); - - if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "align"))) { - if (dStrcasecmp (attrbuf, "left") == 0) - style_attrs.textAlign = TEXT_ALIGN_LEFT; - else if (dStrcasecmp (attrbuf, "right") == 0) - style_attrs.textAlign = TEXT_ALIGN_RIGHT; - else if (dStrcasecmp (attrbuf, "center") == 0) - style_attrs.textAlign = TEXT_ALIGN_CENTER; - } + + a_Html_tag_set_align_attr(html, &props, tag, tagsize); /* TODO: evaluate attribute */ if (a_Html_get_attr(html, tag, tagsize, "noshade")) { - style_attrs.setBorderStyle (BORDER_SOLID); - style_attrs.setBorderColor ( - Color::createShaded (HT2LT(html), style_attrs.color->getColor())); - if (size < 1) + props.set (CssProperty::CSS_PROPERTY_BORDER_TOP_STYLE, BORDER_SOLID); + props.set (CssProperty::CSS_PROPERTY_BORDER_BOTTOM_STYLE, BORDER_SOLID); + props.set (CssProperty::CSS_PROPERTY_BORDER_LEFT_STYLE, BORDER_SOLID); + props.set (CssProperty::CSS_PROPERTY_BORDER_RIGHT_STYLE, BORDER_SOLID); + + if (size <= 0) size = 1; - } else { - style_attrs.setBorderStyle (BORDER_INSET); - style_attrs.setBorderColor - (Color::createShaded (HT2LT(html), - S_TOP(html)->current_bg_color)); - if (size < 2) - size = 2; } - - style_attrs.borderWidth.top = - style_attrs.borderWidth.left = (size + 1) / 2; - style_attrs.borderWidth.bottom = - style_attrs.borderWidth.right = size / 2; - style = Style::create (HT2LT(html), &style_attrs); + + if (size > 0) { + CssLength size_top = CSS_CREATE_LENGTH ((size+1)/2, CSS_LENGTH_TYPE_PX); + CssLength size_bottom = CSS_CREATE_LENGTH (size / 2, CSS_LENGTH_TYPE_PX); + props.set (CssProperty::CSS_PROPERTY_BORDER_TOP_WIDTH, size_top); + props.set (CssProperty::CSS_PROPERTY_BORDER_LEFT_WIDTH, size_top); + props.set (CssProperty::CSS_PROPERTY_BORDER_BOTTOM_WIDTH, size_bottom); + props.set (CssProperty::CSS_PROPERTY_BORDER_RIGHT_WIDTH, size_bottom); + } - DW2TB(html->dw)->addParbreak (5, S_TOP(html)->style); + DW2TB(html->dw)->addParbreak (5, html->styleEngine->wordStyle ()); + + html->styleEngine->setNonCssHints (&props); hruler = new Ruler(); - hruler->setStyle (style); - DW2TB(html->dw)->addWidget (hruler, style); - style->unref (); - DW2TB(html->dw)->addParbreak (5, S_TOP(html)->style); + hruler->setStyle (html->styleEngine->style ()); + DW2TB(html->dw)->addWidget (hruler, html->styleEngine->style ()); + DW2TB(html->dw)->addParbreak (5, html->styleEngine->wordStyle ()); } /* @@ -2882,7 +2650,7 @@ static void Html_tag_open_hr(DilloHtml *html, const char *tag, int tagsize) static void Html_tag_open_dl(DilloHtml *html, const char *tag, int tagsize) { /* may want to actually do some stuff here. */ - DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); + DW2TB(html->dw)->addParbreak (9, html->styleEngine->wordStyle ()); } /* @@ -2890,8 +2658,7 @@ static void Html_tag_open_dl(DilloHtml *html, const char *tag, int tagsize) */ static void Html_tag_open_dt(DilloHtml *html, const char *tag, int tagsize) { - DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); - a_Html_set_top_font(html, NULL, 0, 1, 1); + DW2TB(html->dw)->addParbreak (9, html->styleEngine->wordStyle ()); } /* @@ -2899,8 +2666,8 @@ static void Html_tag_open_dt(DilloHtml *html, const char *tag, int tagsize) */ static void Html_tag_open_dd(DilloHtml *html, const char *tag, int tagsize) { - DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); - Html_add_indented(html, 40, 40, 9); + DW2TB(html->dw)->addParbreak (9, html->styleEngine->wordStyle ()); + Html_add_textblock(html, 9); } /* @@ -2908,12 +2675,10 @@ static void Html_tag_open_dd(DilloHtml *html, const char *tag, int tagsize) */ static void Html_tag_open_pre(DilloHtml *html, const char *tag, int tagsize) { - DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); - a_Html_set_top_font(html, prefs.fw_fontname, 0, 0, 0); + DW2TB(html->dw)->addParbreak (9, html->styleEngine->wordStyle ()); /* Is the placement of this statement right? */ S_TOP(html)->parse_mode = DILLO_HTML_PARSE_MODE_PRE; - HTML_SET_TOP_ATTR (html, whiteSpace, WHITE_SPACE_PRE); html->pre_column = 0; html->PreFirstChar = true; html->InFlags |= IN_PRE; @@ -2925,7 +2690,7 @@ static void Html_tag_open_pre(DilloHtml *html, const char *tag, int tagsize) static void Html_tag_close_pre(DilloHtml *html, int TagIdx) { html->InFlags &= ~IN_PRE; - DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); + DW2TB(html->dw)->addParbreak (9, html->styleEngine->wordStyle ()); } /* @@ -2941,7 +2706,7 @@ static int Html_tag_pre_excludes(int tag_idx) /* initialize array */ if (!ei_set[0]) for (i = 0; es_set[i]; ++i) - ei_set[i] = Html_tag_index(es_set[i]); + ei_set[i] = a_Html_tag_index(es_set[i]); for (i = 0; ei_set[i]; ++i) if (tag_idx == ei_set[i]) @@ -3015,15 +2780,13 @@ static void Html_tag_open_meta(DilloHtml *html, const char *tag, int tagsize) } else if (!dStrcasecmp(equiv, "content-type") && (content = a_Html_get_attr(html, tag, tagsize, "content"))) { if (a_Misc_content_type_cmp(html->content_type, content)) { - const bool_t force = FALSE; const char *new_content = - a_Capi_set_content_type(html->page_url, content, force); + a_Capi_set_content_type(html->page_url, content); /* Cannot ask cache whether the content type was changed, as * this code in another bw might have already changed it for us. */ if (a_Misc_content_type_cmp(html->content_type, new_content)) { - a_Nav_repush(html->bw); - html->stop_parser = true; + html->repush_after_head = true; } } } @@ -3031,6 +2794,97 @@ static void Html_tag_open_meta(DilloHtml *html, const char *tag, int tagsize) } /* + * Called by the network engine when a stylesheet has new data. + */ +static void Html_css_load_callback(int Op, CacheClient_t *Client) +{ + _MSG("Css_callback: Op=%d\n", Op); + if (Op) { /* EOF */ + BrowserWindow *bw = ((DilloWeb *)Client->Web)->bw; + /* Repush when we've got them all */ + if (--bw->NumPendingStyleSheets == 0) + a_Nav_repush(bw); + } +} + +/* + * Tell cache to retrieve a stylesheet + */ +static void Html_load_stylesheet(DilloHtml *html, DilloUrl *url) +{ + char *data; + int len; + if (a_Nav_get_buf(url, &data, &len)) { + /* Haven't looked into what origin_count is */ + if (a_Capi_get_flags(url) & CAPI_Completed) + html->styleEngine->parse(data, len, 0, CSS_ORIGIN_AUTHOR); + a_Nav_unref_buf(url); + } else if (!html->repush_after_head) { + /* Fill a Web structure for the cache query */ + int ClientKey; + DilloWeb *Web = a_Web_new(url); + Web->bw = html->bw; + //Web->flags |= WEB_Stylesheet; + if ((ClientKey = a_Capi_open_url(Web, Html_css_load_callback, NULL))) { + ++html->bw->NumPendingStyleSheets; + a_Bw_add_client(html->bw, ClientKey, 0); + a_Bw_add_url(html->bw, url); + MSG("Html_load_stylesheet: NumPendingStyleSheets=%d\n", + html->bw->NumPendingStyleSheets); + } + } +} + +/* + * Parse the LINK element (Only CSS stylesheets by now). + * (If it either hits or misses, is not relevant here; that's up to the + * cache functions) + */ +static void Html_tag_open_link(DilloHtml *html, const char *tag, int tagsize) +{ + DilloUrl *url; + const char *attrbuf; + + //char *tag_str = dStrndup(tag, tagsize); + //MSG("Html_tag_open_link(): %s\n", tag_str); + //dFree(tag_str); + + /* When viewing suspicious HTML email, don't load LINK */ + if (URL_FLAGS(html->base_url) & URL_SpamSafe) + return; + /* Ignore LINK outside HEAD */ + if (!(html->InFlags & IN_HEAD)) { + BUG_MSG("the LINK element must be inside the HEAD section\n"); + return; + } + + /* TODO: How will we know when to use "handheld"? Ask the html->bw->ui for + screen dimensions, or a dillorc preference. */ + + if (!prefs.load_stylesheets) + return; + + /* CSS stylesheet link */ + if ((!(attrbuf = a_Html_get_attr(html, tag, tagsize, "rel")) || + dStrcasecmp(attrbuf, "stylesheet")) || + (!(attrbuf = a_Html_get_attr(html, tag, tagsize, "href")) || + !(url = a_Html_url_new(html, attrbuf, NULL, 0)))) + return; + /* IMPLIED attributes? */ + if (((attrbuf = a_Html_get_attr(html, tag, tagsize, "type")) && + dStrcasecmp(attrbuf, "text/css")) || + ((attrbuf = a_Html_get_attr(html, tag, tagsize, "media")) && + !dStristr(attrbuf, "screen") && dStrcasecmp(attrbuf, "all"))) + return; + + MSG(" Html_tag_open_link(): URL=%s\n", URL_STR(url)); + _MSG(" repush after HEAD=%d\n", html->repush_after_head); + + Html_load_stylesheet(html, url); + a_Url_free(url); +} + +/* * Set the history of the menu to be consistent with the active menuitem. */ //static void Html_select_set_history(DilloHtmlInput *input) @@ -3073,60 +2927,8 @@ static void Html_tag_open_base(DilloHtml *html, const char *tag, int tagsize) } } -/* - * <CODE> - */ -static void Html_tag_open_code(DilloHtml *html, const char *tag, int tagsize) -{ - a_Html_set_top_font(html, prefs.fw_fontname, 0, 0, 0); -} - -/* - * <DFN> - */ -static void Html_tag_open_dfn(DilloHtml *html, const char *tag, int tagsize) -{ - a_Html_set_top_font(html, NULL, 0, 2, 3); -} - -/* - * <KBD> - */ -static void Html_tag_open_kbd(DilloHtml *html, const char *tag, int tagsize) -{ - a_Html_set_top_font(html, prefs.fw_fontname, 0, 0, 0); -} - -/* - * <SAMP> - */ -static void Html_tag_open_samp(DilloHtml *html, const char *tag, int tagsize) -{ - a_Html_set_top_font(html, prefs.fw_fontname, 0, 0, 0); -} - -/* - * <VAR> - */ -static void Html_tag_open_var(DilloHtml *html, const char *tag, int tagsize) -{ - a_Html_set_top_font(html, NULL, 0, 2, 2); -} - -/* - * <SUB> - */ -static void Html_tag_open_sub(DilloHtml *html, const char *tag, int tagsize) +static void Html_tag_open_default(DilloHtml *html,const char *tag,int tagsize) { - HTML_SET_TOP_ATTR (html, valign, VALIGN_SUB); -} - -/* - * <SUP> - */ -static void Html_tag_open_sup(DilloHtml *html, const char *tag, int tagsize) -{ - HTML_SET_TOP_ATTR (html, valign, VALIGN_SUPER); } /* @@ -3134,8 +2936,11 @@ static void Html_tag_open_sup(DilloHtml *html, const char *tag, int tagsize) */ static void Html_tag_open_div(DilloHtml *html, const char *tag, int tagsize) { - DW2TB(html->dw)->addParbreak (0, S_TOP(html)->style); - a_Html_tag_set_align_attr (html, tag, tagsize); + CssPropertyList props; + + a_Html_tag_set_align_attr (html, &props, tag, tagsize); + html->styleEngine->setNonCssHints (&props); + Html_add_textblock(html, 0); } /* @@ -3143,7 +2948,7 @@ static void Html_tag_open_div(DilloHtml *html, const char *tag, int tagsize) */ static void Html_tag_close_div(DilloHtml *html, int TagIdx) { - DW2TB(html->dw)->addParbreak (0, S_TOP(html)->style); + DW2TB(html->dw)->addParbreak (0, html->styleEngine->wordStyle ()); } /* @@ -3158,7 +2963,7 @@ static void Html_tag_close_default(DilloHtml *html, int TagIdx) */ static void Html_tag_close_par(DilloHtml *html, int TagIdx) { - DW2TB(html->dw)->addParbreak (9, S_TOP(html)->style); + DW2TB(html->dw)->addParbreak (9, html->styleEngine->wordStyle ()); } @@ -3197,30 +3002,30 @@ const TagInfo Tags[] = { /* acronym 010101 */ {"address", B8(010110),'R',2, Html_tag_open_address, Html_tag_close_par}, {"area", B8(010001),'F',0, Html_tag_open_area, Html_tag_close_default}, - {"b", B8(010101),'R',2, Html_tag_open_b, Html_tag_close_default}, + {"b", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, {"base", B8(100001),'F',0, Html_tag_open_base, Html_tag_close_default}, /* basefont 010001 */ /* bdo 010101 */ - {"big", B8(010101),'R',2, Html_tag_open_big_small, Html_tag_close_default}, + {"big", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, {"blockquote", B8(011110),'R',2,Html_tag_open_blockquote,Html_tag_close_par}, {"body", B8(011110),'O',1, Html_tag_open_body, Html_tag_close_body}, {"br", B8(010001),'F',0, Html_tag_open_br, Html_tag_close_default}, {"button", B8(011101),'R',2, Html_tag_open_button, Html_tag_close_button}, /* caption */ {"center", B8(011110),'R',2, Html_tag_open_center, Html_tag_close_div}, - {"cite", B8(010101),'R',2, Html_tag_open_cite, Html_tag_close_default}, - {"code", B8(010101),'R',2, Html_tag_open_code, Html_tag_close_default}, + {"cite", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, + {"code", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, /* col 010010 'F' */ /* colgroup */ {"dd", B8(011110),'O',1, Html_tag_open_dd, Html_tag_close_par}, - {"del", B8(011101),'R',2, Html_tag_open_strike, Html_tag_close_default}, - {"dfn", B8(010101),'R',2, Html_tag_open_dfn, Html_tag_close_default}, + {"del", B8(011101),'R',2, Html_tag_open_default, Html_tag_close_default}, + {"dfn", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, {"dir", B8(011010),'R',2, Html_tag_open_dir, Html_tag_close_par}, /* TODO: complete <div> support! */ {"div", B8(011110),'R',2, Html_tag_open_div, Html_tag_close_div}, {"dl", B8(011010),'R',2, Html_tag_open_dl, Html_tag_close_par}, {"dt", B8(010110),'O',1, Html_tag_open_dt, Html_tag_close_par}, - {"em", B8(010101),'R',2, Html_tag_open_em, Html_tag_close_default}, + {"em", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, /* fieldset */ {"font", B8(010101),'R',2, Html_tag_open_font, Html_tag_close_default}, {"form", B8(011110),'R',2, Html_tag_open_form, Html_tag_close_form}, @@ -3235,17 +3040,17 @@ const TagInfo Tags[] = { {"head", B8(101101),'O',1, Html_tag_open_head, Html_tag_close_head}, {"hr", B8(010010),'F',0, Html_tag_open_hr, Html_tag_close_default}, {"html", B8(001110),'O',1, Html_tag_open_html, Html_tag_close_html}, - {"i", B8(010101),'R',2, Html_tag_open_i, Html_tag_close_default}, + {"i", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, {"iframe", B8(011110),'R',2, Html_tag_open_frame, Html_tag_close_default}, {"img", B8(010001),'F',0, Html_tag_open_img, Html_tag_close_default}, {"input", B8(010001),'F',0, Html_tag_open_input, Html_tag_close_default}, /* ins */ {"isindex", B8(110001),'F',0, Html_tag_open_isindex, Html_tag_close_default}, - {"kbd", B8(010101),'R',2, Html_tag_open_kbd, Html_tag_close_default}, + {"kbd", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, /* label 010101 */ /* legend 01?? */ {"li", B8(011110),'O',1, Html_tag_open_li, Html_tag_close_li}, - /* link 100000 'F' */ + {"link", B8(100001),'F',0, Html_tag_open_link, Html_tag_close_default}, {"map", B8(011001),'R',2, Html_tag_open_map, Html_tag_close_map}, /* menu 1010 -- TODO: not exactly 1010, it can contain LI and inline */ {"menu", B8(011010),'R',2, Html_tag_open_menu, Html_tag_close_par}, @@ -3260,17 +3065,17 @@ const TagInfo Tags[] = { /* param 010001 'F' */ {"pre", B8(010110),'R',2, Html_tag_open_pre, Html_tag_close_pre}, {"q", B8(010101),'R',2, Html_tag_open_q, Html_tag_close_q}, - {"s", B8(010101),'R',2, Html_tag_open_strike, Html_tag_close_default}, - {"samp", B8(010101),'R',2, Html_tag_open_samp, Html_tag_close_default}, + {"s", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, + {"samp", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, {"script", B8(111001),'R',2, Html_tag_open_script, Html_tag_close_script}, {"select", B8(010101),'R',2, Html_tag_open_select, Html_tag_close_select}, - {"small", B8(010101),'R',2, Html_tag_open_big_small, Html_tag_close_default}, - /* span 0101 */ - {"strike", B8(010101),'R',2, Html_tag_open_strike, Html_tag_close_default}, - {"strong", B8(010101),'R',2, Html_tag_open_strong, Html_tag_close_default}, + {"small", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, + {"span", B8(010101),'R',2, Html_tag_open_span, Html_tag_close_default}, + {"strike", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, + {"strong", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, {"style", B8(100101),'R',2, Html_tag_open_style, Html_tag_close_style}, - {"sub", B8(010101),'R',2, Html_tag_open_sub, Html_tag_close_default}, - {"sup", B8(010101),'R',2, Html_tag_open_sup, Html_tag_close_default}, + {"sub", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, + {"sup", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, {"table", B8(011010),'R',5, Html_tag_open_table, Html_tag_close_div}, /* tbody */ {"td", B8(011110),'O',3, Html_tag_open_td, Html_tag_close_default}, @@ -3280,10 +3085,10 @@ const TagInfo Tags[] = { /* thead */ {"title", B8(100101),'R',2, Html_tag_open_title, Html_tag_close_title}, {"tr", B8(011010),'O',4, Html_tag_open_tr, Html_tag_close_default}, - {"tt", B8(010101),'R',2, Html_tag_open_tt, Html_tag_close_default}, - {"u", B8(010101),'R',2, Html_tag_open_u, Html_tag_close_default}, + {"tt", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, + {"u", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default}, {"ul", B8(011010),'R',2, Html_tag_open_ul, Html_tag_close_par}, - {"var", B8(010101),'R',2, Html_tag_open_var, Html_tag_close_default} + {"var", B8(010101),'R',2, Html_tag_open_default, Html_tag_close_default} }; #define NTAGS (sizeof(Tags)/sizeof(Tags[0])) @@ -3309,7 +3114,7 @@ static int Html_tag_compare(const char *p1, const char *p2) * Get 'tag' index * return -1 if tag is not handled yet */ -static int Html_tag_index(const char *tag) +int a_Html_tag_index(const char *tag) { int low, high, mid, cond; @@ -3340,17 +3145,17 @@ static int Html_needs_optional_close(int old_idx, int cur_idx) if (i_P == -1) { /* initialize the indexes of elements with optional close */ - i_P = Html_tag_index("p"), - i_LI = Html_tag_index("li"), - i_TD = Html_tag_index("td"), - i_TR = Html_tag_index("tr"), - i_TH = Html_tag_index("th"), - i_DD = Html_tag_index("dd"), - i_DT = Html_tag_index("dt"), - i_OPTION = Html_tag_index("option"); - // i_THEAD = Html_tag_index("thead"); - // i_TFOOT = Html_tag_index("tfoot"); - // i_COLGROUP = Html_tag_index("colgroup"); + i_P = a_Html_tag_index("p"), + i_LI = a_Html_tag_index("li"), + i_TD = a_Html_tag_index("td"), + i_TR = a_Html_tag_index("tr"), + i_TH = a_Html_tag_index("th"), + i_DD = a_Html_tag_index("dd"), + i_DT = a_Html_tag_index("dt"), + i_OPTION = a_Html_tag_index("option"); + // i_THEAD = a_Html_tag_index("thead"); + // i_TFOOT = a_Html_tag_index("tfoot"); + // i_COLGROUP = a_Html_tag_index("colgroup"); } if (old_idx == i_P || old_idx == i_DT) { @@ -3447,7 +3252,7 @@ static void Html_test_section(DilloHtml *html, int new_idx, int IsCloseTag) if (!(html->InFlags & IN_HTML)) { tag = "<html>"; - tag_idx = Html_tag_index(tag + 1); + tag_idx = a_Html_tag_index(tag + 1); if (tag_idx != new_idx || IsCloseTag) { /* implicit open */ Html_force_push_tag(html, tag_idx); @@ -3460,7 +3265,7 @@ static void Html_test_section(DilloHtml *html, int new_idx, int IsCloseTag) /* head element */ if (!(html->InFlags & IN_HEAD)) { tag = "<head>"; - tag_idx = Html_tag_index(tag + 1); + tag_idx = a_Html_tag_index(tag + 1); if (tag_idx != new_idx || IsCloseTag) { /* implicit open of the head element */ Html_force_push_tag(html, tag_idx); @@ -3473,11 +3278,11 @@ static void Html_test_section(DilloHtml *html, int new_idx, int IsCloseTag) /* body element */ if (html->InFlags & IN_HEAD) { tag = "</head>"; - tag_idx = Html_tag_index(tag + 2); + tag_idx = a_Html_tag_index(tag + 2); Html_tag_cleanup_at_close(html, tag_idx); } tag = "<body>"; - tag_idx = Html_tag_index(tag + 1); + tag_idx = a_Html_tag_index(tag + 1); if (tag_idx != new_idx || IsCloseTag) { /* implicit open */ Html_force_push_tag(html, tag_idx); @@ -3499,7 +3304,9 @@ static void Html_process_tag(DilloHtml *html, char *tag, int tagsize) char *start = tag + 1; /* discard the '<' */ int IsCloseTag = (*start == '/'); - ni = Html_tag_index(start + IsCloseTag); + dReturn_if_fail ( html->stop_parser == false ); + + ni = a_Html_tag_index(start + IsCloseTag); if (ni == -1) { /* TODO: doctype parsing is a bit fuzzy, but enough for the time being */ if (!(html->InFlags & IN_HTML)) { @@ -3533,11 +3340,8 @@ static void Html_process_tag(DilloHtml *html, char *tag, int tagsize) /* Push the tag into the stack */ Html_push_tag(html, ni); - /* Call the open function for this tag */ + html->styleEngine->startElement (ni); _MSG("Open : %*s%s\n", html->stack->size(), " ", Tags[ni].name); - Tags[ni].open (html, tag, tagsize); - if (html->stop_parser) - break; /* Now parse attributes that can appear on any tag */ if (tagsize >= 8 && /* length of "<t id=i>" */ @@ -3549,6 +3353,9 @@ static void Html_process_tag(DilloHtml *html, char *tag, int tagsize) * spec states in Sec. 7.5.2 that anchor ids are case-sensitive. * So we don't do it and hope for better specs in the future ... */ + if (attrbuf) + html->styleEngine->setId (attrbuf); + Html_check_name_val(html, attrbuf, "id"); /* We compare the "id" value with the url-decoded "name" value */ if (!html->NameVal || strcmp(html->NameVal, attrbuf)) { @@ -3564,6 +3371,24 @@ static void Html_process_tag(DilloHtml *html, char *tag, int tagsize) html->NameVal = NULL; } + if (tagsize >= 10) { /* length of "<t class=i>" */ + attrbuf = Html_get_attr2(html, tag, tagsize, "class", + HTML_LeftTrim | HTML_RightTrim); + if (attrbuf) + html->styleEngine->setClass (attrbuf); + } + + if (tagsize >= 11) { /* length of "<t style=i>" */ + attrbuf = Html_get_attr2(html, tag, tagsize, "style", + HTML_LeftTrim | HTML_RightTrim); + if (attrbuf) + html->styleEngine->setStyle (attrbuf); + } + + /* Call the open function for this tag */ + _MSG("Open : %s\n", Tags[ni].name); + Tags[ni].open (html, tag, tagsize); + /* Request inmediate close for elements with forbidden close tag. */ /* TODO: XHTML always requires close tags. A simple implementation * of the commented clause below will make it work. */ @@ -3582,6 +3407,7 @@ static void Html_process_tag(DilloHtml *html, char *tag, int tagsize) (strchr(" \"'", tag[tagsize-3]) || /* [ "']/> */ (size_t)tagsize == strlen(Tags[ni].name) + 3))) { /* <x/> */ + _MSG("Close: %s\n", Tags[ni].name); Html_tag_cleanup_at_close(html, ni); /* This was a close tag */ html->ReqTagClose = false; @@ -3726,29 +3552,6 @@ char *a_Html_get_attr_wdef(DilloHtml *html, } /* - * Add a widget to the page. - */ -static void Html_add_widget(DilloHtml *html, - Widget *widget, - char *width_str, - char *height_str, - StyleAttrs *style_attrs) -{ - StyleAttrs new_style_attrs; - Style *style; - - new_style_attrs = *style_attrs; - new_style_attrs.width = width_str ? - a_Html_parse_length (html, width_str) : LENGTH_AUTO; - new_style_attrs.height = height_str ? - a_Html_parse_length (html, height_str) : LENGTH_AUTO; - style = Style::create (HT2LT(html), &new_style_attrs); - DW2TB(html->dw)->addWidget (widget, style); - style->unref (); -} - - -/* * Dispatch the apropriate function for 'Op' * This function is a Cache client and gets called whenever new data arrives * Op : operation to perform. |