Mercurial > dillo_port1.3
changeset 1035:474b9814a8fa
support CSS @import directive
author | Johannes Hofmann <Johannes.Hofmann@gmx.de> |
---|---|
date | Wed, 08 Apr 2009 16:33:02 +0200 |
parents | 03ac3106d5ac |
children | bfda92d18f03 |
files | ChangeLog src/css.cc src/cssparser.cc src/cssparser.hh src/html.cc src/html_common.hh src/styleengine.cc src/styleengine.hh |
diffstat | 8 files changed, 104 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Sat Apr 04 04:00:57 2009 +0000 +++ b/ChangeLog Wed Apr 08 16:33:02 2009 +0200 @@ -78,6 +78,7 @@ - Load <style></style> content only if applicable. - Allow negative values for specific CSS properties only. - Disable negative margins for now as dw/* does not support them yet. + - Support CSS @import directive. Patches: Johannes Hofmann +- Updated the GPL copyright note in the source files. Patch: Detlef Riekenberg
--- a/src/css.cc Sat Apr 04 04:00:57 2009 +0000 +++ b/src/css.cc Wed Apr 08 16:33:02 2009 +0200 @@ -482,7 +482,7 @@ "th {font-weight: bolder; text-align: center}" "code, tt, pre, samp, kbd {font-family: monospace}"; - CssParser::parse (this, cssBuf, strlen (cssBuf), CSS_ORIGIN_USER_AGENT); + CssParser::parse (NULL, NULL, this, cssBuf, strlen (cssBuf), CSS_ORIGIN_USER_AGENT); } void CssContext::buildUserStyle () { @@ -490,7 +490,7 @@ char *filename = dStrconcat(dGethomedir(), "/.dillo/style.css", NULL); if ((style = a_Misc_file2dstr(filename))) { - CssParser::parse (this, style->str, style->len, CSS_ORIGIN_USER); + CssParser::parse (NULL, NULL, this, style->str, style->len, CSS_ORIGIN_USER); dStr_free (style, 1); } dFree (filename);
--- a/src/cssparser.cc Sat Apr 04 04:00:57 2009 +0000 +++ b/src/cssparser.cc Wed Apr 08 16:33:02 2009 +0200 @@ -1198,17 +1198,91 @@ nextToken(); } +char * CssParser::parseUrl() { + Dstr *urlStr = NULL; + + if (ttype != CSS_TK_SYMBOL || + dStrcasecmp(tval, "url") != 0) + return NULL; + + nextToken(); + + if (ttype != CSS_TK_CHAR || tval[0] != '(') + return NULL; + + nextToken(); + + if (ttype == CSS_TK_STRING) { + urlStr = dStr_new(tval); + nextToken(); + } else { + urlStr = dStr_new(""); + while (ttype != CSS_TK_END && + (ttype != CSS_TK_CHAR || tval[0] != ')')) { + dStr_append(urlStr, tval); + nextToken(); + } + } + + if (ttype != CSS_TK_CHAR || tval[0] != ')') { + dStr_free(urlStr, 1); + urlStr = NULL; + } + + if (urlStr) { + char *url = urlStr->str; + dStr_free(urlStr, 0); + return url; + } else { + return NULL; + } +} + +void CssParser::parseImport(DilloHtml *html, DilloUrl *baseUrl) { + char *urlStr = NULL; + + if (html != NULL && + ttype == CSS_TK_SYMBOL && + dStrcasecmp(tval, "import") == 0) { + nextToken(); + + if (ttype == CSS_TK_SYMBOL && + dStrcasecmp(tval, "url") == 0) + urlStr = parseUrl(); + else if (ttype == CSS_TK_STRING) + urlStr = dStrdup (tval); + + /* Skip all tokens until the expected end. */ + while (!(ttype == CSS_TK_END || + (ttype == CSS_TK_CHAR && (tval[0] == ';')))) + nextToken(); + + if (urlStr) { + MSG("CssParser::parseImport(): @import %s\n", urlStr); + DilloUrl *url = a_Html_url_new (html, urlStr, a_Url_str(baseUrl), baseUrl ? 1 : 0); + a_Html_load_stylesheet(html, url); + a_Url_free(url); + dFree (urlStr); + } + } +} + const char * CssParser::propertyNameString(CssPropertyName name) { return Css_property_info[name].symbol; } -void CssParser::parse(CssContext * context, +void CssParser::parse(DilloHtml *html, DilloUrl *url, CssContext * context, const char *buf, int buflen, CssOrigin origin) { CssParser parser (context, origin, buf, buflen); + while (parser.ttype == CSS_TK_CHAR && parser.tval[0] == '@') { + parser.nextToken(); + parser.parseImport(html, url); + } + while (parser.ttype != CSS_TK_END) parser.parseRuleset(); }
--- a/src/cssparser.hh Sat Apr 04 04:00:57 2009 +0000 +++ b/src/cssparser.hh Wed Apr 08 16:33:02 2009 +0200 @@ -2,6 +2,7 @@ #define __CSSPARSER_HH__ #include "css.hh" +#include "html_common.hh" class CssParser { private: @@ -34,12 +35,14 @@ void parseDeclaration(CssPropertyList * props, CssPropertyList * importantProps); bool parseSimpleSelector(CssSimpleSelector *selector); + char *parseUrl(); + void parseImport(DilloHtml *html, DilloUrl *url); CssSelector *parseSelector(); void parseRuleset(); public: static CssPropertyList *parseDeclarationBlock(const char *buf, int buflen); - static void parse(CssContext *context, const char *buf, int buflen, + static void parse(DilloHtml *html, DilloUrl *url, CssContext *context, const char *buf, int buflen, CssOrigin origin); static const char *propertyNameString(CssPropertyName name); };
--- a/src/html.cc Sat Apr 04 04:00:57 2009 +0000 +++ b/src/html.cc Wed Apr 08 16:33:02 2009 +0200 @@ -110,7 +110,6 @@ DilloImage *image); static void Html_callback(int Op, CacheClient_t *Client); static void Html_tag_cleanup_at_close(DilloHtml *html, int TagIdx); -static void Html_load_stylesheet(DilloHtml *html, DilloUrl *url); /*----------------------------------------------------------------------------- * Local Data @@ -1586,7 +1585,7 @@ /* charset is already set, load remote stylesheets now */ for (int i = 0; i < html->cssUrls->size(); i++) { - Html_load_stylesheet(html, html->cssUrls->get(i)); + a_Html_load_stylesheet(html, html->cssUrls->get(i)); } } } @@ -1670,7 +1669,7 @@ static void Html_tag_close_style(DilloHtml *html, int TagIdx) { if (prefs.parse_embedded_css && html->loadCssFromStash) - html->styleEngine->parse(html->Stash->str, html->Stash->len, + html->styleEngine->parse(html, NULL, html->Stash->str, html->Stash->len, CSS_ORIGIN_AUTHOR); } @@ -2868,18 +2867,18 @@ /* * Tell cache to retrieve a stylesheet */ -static void Html_load_stylesheet(DilloHtml *html, DilloUrl *url) +void a_Html_load_stylesheet(DilloHtml *html, DilloUrl *url) { char *data; int len; - dReturn_if (url == NULL); + dReturn_if (url == NULL || ! prefs.load_stylesheets); _MSG("Html_load_stylesheet: "); if (a_Capi_get_buf(url, &data, &len)) { _MSG("cached URL=%s len=%d", URL_STR(url), len); if (a_Capi_get_flags(url) & CAPI_Completed) - html->styleEngine->parse(data, len, CSS_ORIGIN_AUTHOR); + html->styleEngine->parse(html, url, data, len, CSS_ORIGIN_AUTHOR); a_Capi_unref_buf(url); } else { /* Fill a Web structure for the cache query */ @@ -2923,7 +2922,6 @@ } /* Remote stylesheets enabled? */ dReturn_if_fail (prefs.load_stylesheets); - /* CSS stylesheet link */ if (!(attrbuf = a_Html_get_attr(html, tag, tagsize, "rel")) || dStrcasecmp(attrbuf, "stylesheet"))
--- a/src/html_common.hh Sat Apr 04 04:00:57 2009 +0000 +++ b/src/html_common.hh Wed Apr 08 16:33:02 2009 +0200 @@ -255,4 +255,6 @@ const char *tag, int tagsize, CssPropertyList *props); +void a_Html_load_stylesheet(DilloHtml *html, DilloUrl *url); + #endif /* __HTML_COMMON_HH__ */
--- a/src/styleengine.cc Sat Apr 04 04:00:57 2009 +0000 +++ b/src/styleengine.cc Wed Apr 08 16:33:02 2009 +0200 @@ -12,6 +12,7 @@ #include <stdio.h> #include <math.h> #include "../dlib/dlib.h" +#include "msg.h" #include "prefs.h" #include "html_common.hh" #include "styleengine.hh" @@ -26,6 +27,7 @@ cssContext = new CssContext (); this->layout = layout; num = 0; + importDepth = 0; stack->increase (); Node *n = stack->getRef (stack->size () - 1); @@ -561,6 +563,13 @@ return stack->getRef (stack->size () - 1)->wordStyle; } -void StyleEngine::parse (const char *buf, int buflen, CssOrigin origin) { - CssParser::parse (cssContext, buf, buflen, origin); +void StyleEngine::parse (DilloHtml *html, DilloUrl *url, const char *buf, int buflen, CssOrigin origin) { + if (importDepth > 10) { // avoid looping with recursive @import directives + MSG_WARN("Maximum depth of CSS @import reached - ignoring stylesheet.\n"); + return; + } + + importDepth++; + CssParser::parse (html, url, cssContext, buf, buflen, origin); + importDepth--; }
--- a/src/styleengine.hh Sat Apr 04 04:00:57 2009 +0000 +++ b/src/styleengine.hh Wed Apr 08 16:33:02 2009 +0200 @@ -1,6 +1,8 @@ #ifndef __STYLEENGINE_HH__ #define __STYLEENGINE_HH__ +class StyleEngine; + #include "dw/core.hh" #include "doctree.hh" #include "css.hh" @@ -20,6 +22,7 @@ lout::misc::SimpleVector <Node> *stack; CssContext *cssContext; int num; + int importDepth; dw::core::style::Style *style0 (CssPropertyList *nonCssHints = NULL); dw::core::style::Style *wordStyle0 (CssPropertyList *nonCssHints = NULL); @@ -46,7 +49,7 @@ return NULL; }; - void parse (const char *buf, int buflen, CssOrigin origin); + void parse (DilloHtml *html, DilloUrl *url, const char *buf, int buflen, CssOrigin origin); void startElement (int tag); void startElement (const char *tagname); void setId (const char *id);