aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/css.cc4
-rw-r--r--src/cssparser.cc76
-rw-r--r--src/cssparser.hh5
-rw-r--r--src/html.cc12
-rw-r--r--src/html_common.hh2
-rw-r--r--src/styleengine.cc13
-rw-r--r--src/styleengine.hh5
7 files changed, 103 insertions, 14 deletions
diff --git a/src/css.cc b/src/css.cc
index ef2f7af0..048d67b6 100644
--- a/src/css.cc
+++ b/src/css.cc
@@ -482,7 +482,7 @@ void CssContext::buildUserAgentStyle () {
"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 @@ void CssContext::buildUserStyle () {
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);
diff --git a/src/cssparser.cc b/src/cssparser.cc
index 1864bd49..69fb6d0b 100644
--- a/src/cssparser.cc
+++ b/src/cssparser.cc
@@ -1198,17 +1198,91 @@ void CssParser::parseRuleset()
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();
}
diff --git a/src/cssparser.hh b/src/cssparser.hh
index 71d83a63..8011a342 100644
--- a/src/cssparser.hh
+++ b/src/cssparser.hh
@@ -2,6 +2,7 @@
#define __CSSPARSER_HH__
#include "css.hh"
+#include "html_common.hh"
class CssParser {
private:
@@ -34,12 +35,14 @@ class CssParser {
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);
};
diff --git a/src/html.cc b/src/html.cc
index 2a2216fd..70eb8981 100644
--- a/src/html.cc
+++ b/src/html.cc
@@ -110,7 +110,6 @@ static void Html_load_image(BrowserWindow *bw, DilloUrl *url,
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 @@ static void Html_tag_close_head(DilloHtml *html, int TagIdx)
/* 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_open_style(DilloHtml *html, const char *tag, int tagsize)
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 @@ static void Html_css_load_callback(int Op, CacheClient_t *Client)
/*
* 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 @@ static void Html_tag_open_link(DilloHtml *html, const char *tag, int tagsize)
}
/* 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"))
diff --git a/src/html_common.hh b/src/html_common.hh
index c4bab6f7..7a6fda8f 100644
--- a/src/html_common.hh
+++ b/src/html_common.hh
@@ -255,4 +255,6 @@ bool a_Html_tag_set_valign_attr(DilloHtml *html,
const char *tag, int tagsize,
CssPropertyList *props);
+void a_Html_load_stylesheet(DilloHtml *html, DilloUrl *url);
+
#endif /* __HTML_COMMON_HH__ */
diff --git a/src/styleengine.cc b/src/styleengine.cc
index 4c00f362..63dac1ec 100644
--- a/src/styleengine.cc
+++ b/src/styleengine.cc
@@ -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 @@ StyleEngine::StyleEngine (dw::core::Layout *layout) {
cssContext = new CssContext ();
this->layout = layout;
num = 0;
+ importDepth = 0;
stack->increase ();
Node *n = stack->getRef (stack->size () - 1);
@@ -561,6 +563,13 @@ Style * StyleEngine::wordStyle0 (CssPropertyList *nonCssProperties) {
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--;
}
diff --git a/src/styleengine.hh b/src/styleengine.hh
index dd5e4886..24ac1d56 100644
--- a/src/styleengine.hh
+++ b/src/styleengine.hh
@@ -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 @@ class StyleEngine : public Doctree {
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 @@ class StyleEngine : public Doctree {
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);