aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Hofmann <Johannes.Hofmann@gmx.de>2014-04-01 21:48:15 +0200
committerJohannes Hofmann <Johannes.Hofmann@gmx.de>2014-04-01 21:48:15 +0200
commitf284ce5c34cdf37854135524814bbacbd2932f25 (patch)
tree62047de8c15b27fab0caa0a9105a15dfea156c87
parent4e3f41b9e5307fd951c710818687f96e8a68ca35 (diff)
resolve CSS background-image URLs relative to styleheet URL
-rw-r--r--src/cssparser.cc26
-rw-r--r--src/cssparser.hh10
-rw-r--r--src/html.cc4
-rw-r--r--src/html_common.hh12
-rw-r--r--src/plain.cc10
-rw-r--r--src/styleengine.cc54
-rw-r--r--src/styleengine.hh27
-rw-r--r--src/web.cc6
8 files changed, 78 insertions, 71 deletions
diff --git a/src/cssparser.cc b/src/cssparser.cc
index c7a9c281..369dd67f 100644
--- a/src/cssparser.cc
+++ b/src/cssparser.cc
@@ -435,6 +435,7 @@ static const CssShorthandInfo Css_shorthand_info[] = {
* ---------------------------------------------------------------------- */
CssParser::CssParser(CssContext *context, CssOrigin origin,
+ const DilloUrl *baseUrl,
const char *buf, int buflen)
{
this->context = context;
@@ -444,6 +445,7 @@ CssParser::CssParser(CssContext *context, CssOrigin origin,
this->bufptr = 0;
this->spaceSeparated = false;
this->withinBlock = false;
+ this->baseUrl = baseUrl;
nextToken ();
}
@@ -1558,15 +1560,17 @@ char * CssParser::parseUrl()
}
if (urlStr) {
- char *url = urlStr->str;
- dStr_free(urlStr, 0);
+ DilloUrl *dilloUrl = a_Url_new(urlStr->str, a_Url_str(this->baseUrl));
+ char *url = dStrdup(a_Url_str(dilloUrl));
+ a_Url_free(dilloUrl);
+ dStr_free(urlStr, 1);
return url;
} else {
return NULL;
}
}
-void CssParser::parseImport(DilloHtml *html, DilloUrl *baseUrl)
+void CssParser::parseImport(DilloHtml *html)
{
char *urlStr = NULL;
bool importSyntaxIsOK = false;
@@ -1612,8 +1616,8 @@ void CssParser::parseImport(DilloHtml *html, DilloUrl *baseUrl)
if (urlStr) {
if (importSyntaxIsOK && mediaIsSelected) {
MSG("CssParser::parseImport(): @import %s\n", urlStr);
- DilloUrl *url = a_Html_url_new (html, urlStr, a_Url_str(baseUrl),
- baseUrl ? 1 : 0);
+ DilloUrl *url = a_Html_url_new (html, urlStr, a_Url_str(this->baseUrl),
+ this->baseUrl ? 1 : 0);
a_Html_load_stylesheet(html, url);
a_Url_free(url);
}
@@ -1705,11 +1709,12 @@ void CssParser::ignoreStatement()
}
}
-void CssParser::parse(DilloHtml *html, DilloUrl *url, CssContext *context,
+void CssParser::parse(DilloHtml *html, const DilloUrl *baseUrl,
+ CssContext *context,
const char *buf,
int buflen, CssOrigin origin)
{
- CssParser parser (context, origin, buf, buflen);
+ CssParser parser (context, origin, baseUrl, buf, buflen);
bool importsAreAllowed = true;
while (parser.ttype != CSS_TK_END) {
@@ -1720,7 +1725,7 @@ void CssParser::parse(DilloHtml *html, DilloUrl *url, CssContext *context,
if (dStrAsciiCasecmp(parser.tval, "import") == 0 &&
html != NULL &&
importsAreAllowed) {
- parser.parseImport(html, url);
+ parser.parseImport(html);
} else if (dStrAsciiCasecmp(parser.tval, "media") == 0) {
parser.parseMedia();
} else {
@@ -1736,11 +1741,12 @@ void CssParser::parse(DilloHtml *html, DilloUrl *url, CssContext *context,
}
}
-void CssParser::parseDeclarationBlock(const char *buf, int buflen,
+void CssParser::parseDeclarationBlock(const DilloUrl *baseUrl,
+ const char *buf, int buflen,
CssPropertyList *props,
CssPropertyList *propsImortant)
{
- CssParser parser (NULL, CSS_ORIGIN_AUTHOR, buf, buflen);
+ CssParser parser (NULL, CSS_ORIGIN_AUTHOR, baseUrl, buf, buflen);
parser.withinBlock = true;
diff --git a/src/cssparser.hh b/src/cssparser.hh
index 30d02eee..eb074320 100644
--- a/src/cssparser.hh
+++ b/src/cssparser.hh
@@ -15,6 +15,7 @@ class CssParser {
static const int maxStrLen = 256;
CssContext *context;
CssOrigin origin;
+ const DilloUrl *baseUrl;
const char *buf;
int buflen, bufptr;
@@ -24,7 +25,7 @@ class CssParser {
bool withinBlock;
bool spaceSeparated; /* used when parsing CSS selectors */
- CssParser(CssContext *context, CssOrigin origin,
+ CssParser(CssContext *context, CssOrigin origin, const DilloUrl *baseUrl,
const char *buf, int buflen);
int getChar();
void ungetChar();
@@ -40,7 +41,7 @@ class CssParser {
CssPropertyList * importantProps);
bool parseSimpleSelector(CssSimpleSelector *selector);
char *parseUrl();
- void parseImport(DilloHtml *html, DilloUrl *url);
+ void parseImport(DilloHtml *html);
void parseMedia();
CssSelector *parseSelector();
void parseRuleset();
@@ -48,10 +49,11 @@ class CssParser {
void ignoreStatement();
public:
- static void parseDeclarationBlock(const char *buf, int buflen,
+ static void parseDeclarationBlock(const DilloUrl *baseUrl,
+ const char *buf, int buflen,
CssPropertyList *props,
CssPropertyList *propsImortant);
- static void parse(DilloHtml *html, DilloUrl *url, CssContext *context,
+ static void parse(DilloHtml *html, const DilloUrl *baseUrl, 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 b6d3e285..3a6c3c89 100644
--- a/src/html.cc
+++ b/src/html.cc
@@ -404,7 +404,7 @@ DilloHtml::DilloHtml(BrowserWindow *p_bw, const DilloUrl *url,
DocType = DT_NONE; /* assume Tag Soup 0.0! :-) */
DocTypeVersion = 0.0f;
- styleEngine = new StyleEngine (HT2LT (this));
+ styleEngine = new StyleEngine (HT2LT (this), base_url);
cssUrls = new misc::SimpleVector <DilloUrl*> (1);
@@ -1798,7 +1798,7 @@ static void Html_tag_open_style(DilloHtml *html, const char *tag, int tagsize)
static void Html_tag_close_style(DilloHtml *html)
{
if (prefs.parse_embedded_css && html->loadCssFromStash)
- html->styleEngine->parse(html, NULL, html->Stash->str, html->Stash->len,
+ html->styleEngine->parse(html, html->base_url, html->Stash->str, html->Stash->len,
CSS_ORIGIN_AUTHOR);
}
diff --git a/src/html_common.hh b/src/html_common.hh
index de3069cb..147807b3 100644
--- a/src/html_common.hh
+++ b/src/html_common.hh
@@ -222,18 +222,18 @@ public:
// useful shortcuts
inline void startElement (int tag)
- { styleEngine->startElement (tag, bw, base_url); }
+ { styleEngine->startElement (tag, bw); }
inline void startElement (const char *tagname)
- { styleEngine->startElement (tagname, bw, base_url); }
+ { styleEngine->startElement (tagname, bw); }
inline dw::core::style::Style *backgroundStyle ()
- { return styleEngine->backgroundStyle (bw, base_url); }
+ { return styleEngine->backgroundStyle (bw); }
inline dw::core::style::Style *style ()
- { return styleEngine->style (bw, base_url); }
+ { return styleEngine->style (bw); }
inline dw::core::style::Style *wordStyle ()
- { return styleEngine->wordStyle (bw, base_url); }
+ { return styleEngine->wordStyle (bw); }
- inline void restyle () { styleEngine->restyle (bw, base_url); }
+ inline void restyle () { styleEngine->restyle (bw); }
};
diff --git a/src/plain.cc b/src/plain.cc
index d09f6d79..810efda1 100644
--- a/src/plain.cc
+++ b/src/plain.cc
@@ -95,12 +95,12 @@ DilloPlain::DilloPlain(BrowserWindow *p_bw)
state = ST_SeekingEol;
Layout *layout = (Layout*) bw->render_layout;
- StyleEngine styleEngine (layout);
+ // TODO (1x) No URL?
+ StyleEngine styleEngine (layout, NULL);
- // TODO (3x) No URL?
- styleEngine.startElement ("body", bw, NULL);
- styleEngine.startElement ("pre", bw, NULL);
- widgetStyle = styleEngine.wordStyle (bw, NULL);
+ styleEngine.startElement ("body", bw);
+ styleEngine.startElement ("pre", bw);
+ widgetStyle = styleEngine.wordStyle (bw);
widgetStyle->ref ();
/* The context menu */
diff --git a/src/styleengine.cc b/src/styleengine.cc
index 25e2e600..5b88798a 100644
--- a/src/styleengine.cc
+++ b/src/styleengine.cc
@@ -58,7 +58,7 @@ void StyleImageDeletionReceiver::deleted (lout::signal::ObservedObject *object)
// ----------------------------------------------------------------------
-StyleEngine::StyleEngine (dw::core::Layout *layout) {
+StyleEngine::StyleEngine (dw::core::Layout *layout, const DilloUrl *baseUrl) {
StyleAttrs style_attrs;
FontAttrs font_attrs;
@@ -67,6 +67,7 @@ StyleEngine::StyleEngine (dw::core::Layout *layout) {
cssContext = new CssContext ();
buildUserStyle ();
this->layout = layout;
+ this->baseUrl = baseUrl;
importDepth = 0;
stackPush ();
@@ -130,8 +131,8 @@ void StyleEngine::stackPop () {
/**
* \brief tell the styleEngine that a new html element has started.
*/
-void StyleEngine::startElement (int element, BrowserWindow *bw, DilloUrl *url) {
- style (bw, url); // ensure that style of current node is computed
+void StyleEngine::startElement (int element, BrowserWindow *bw) {
+ style (bw); // ensure that style of current node is computed
stackPush ();
Node *n = stack->getLastRef ();
@@ -141,9 +142,8 @@ void StyleEngine::startElement (int element, BrowserWindow *bw, DilloUrl *url) {
n->doctreeNode = dn;
}
-void StyleEngine::startElement (const char *tagname, BrowserWindow *bw,
- DilloUrl *url) {
- startElement (a_Html_tag_index (tagname), bw, url);
+void StyleEngine::startElement (const char *tagname, BrowserWindow *bw) {
+ startElement (a_Html_tag_index (tagname), bw);
}
void StyleEngine::setId (const char *id) {
@@ -191,7 +191,7 @@ void StyleEngine::setStyle (const char *styleAttr) {
n->styleAttrProperties = new CssPropertyList (true);
n->styleAttrPropertiesImportant = new CssPropertyList (true);
- CssParser::parseDeclarationBlock (styleAttr, strlen (styleAttr),
+ CssParser::parseDeclarationBlock (baseUrl, styleAttr, strlen (styleAttr),
n->styleAttrProperties,
n->styleAttrPropertiesImportant);
}
@@ -351,7 +351,7 @@ void StyleEngine::postprocessAttrs (dw::core::style::StyleAttrs *attrs) {
* \brief Make changes to StyleAttrs attrs according to CssPropertyList props.
*/
void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
- BrowserWindow *bw, DilloUrl *url) {
+ BrowserWindow *bw) {
FontAttrs fontAttrs = *attrs->font;
Font *parentFont = stack->get (i - 1).style->font;
char *c, *fontName;
@@ -525,8 +525,8 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
case CSS_PROPERTY_BACKGROUND_IMAGE:
if (prefs.load_background_images)
{
- DilloUrl *imgUrl =
- a_Url_new (p->value.strVal, a_Url_str (url));
+ // p->value.strVal should be absolute, so baseUrl is not needed
+ DilloUrl *imgUrl = a_Url_new (p->value.strVal, NULL);
attrs->backgroundImage = StyleImage::create();
DilloImage *image =
@@ -535,7 +535,7 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
->getMainImgRenderer(),
0xffffff);
- DilloWeb *web = a_Web_new(bw, imgUrl, url);
+ DilloWeb *web = a_Web_new(bw, imgUrl, baseUrl);
web->Image = image;
a_Image_ref(image);
web->flags |= WEB_Image;
@@ -543,7 +543,7 @@ void StyleEngine::apply (int i, StyleAttrs *attrs, CssPropertyList *props,
int clientKey;
if ((clientKey = a_Capi_open_url(web, NULL, NULL)) != 0) {
a_Bw_add_client(bw, clientKey, 0);
- a_Bw_add_url(bw, url);
+ a_Bw_add_url(bw, imgUrl);
attrs->backgroundImage->connectDeletion
(new StyleImageDeletionReceiver (clientKey));
}
@@ -818,9 +818,9 @@ void StyleEngine::computeBorderWidth (int *dest, CssProperty *p,
* A normal style might have backgroundColor == NULL to indicate a transparent
* background. This method ensures that backgroundColor is set.
*/
-Style * StyleEngine::backgroundStyle (BrowserWindow *bw, DilloUrl *url) {
+Style * StyleEngine::backgroundStyle (BrowserWindow *bw) {
if (!stack->getRef (stack->size () - 1)->backgroundStyle) {
- StyleAttrs attrs = *style (bw, url);
+ StyleAttrs attrs = *style (bw);
for (int i = stack->size () - 1; i >= 0 && ! attrs.backgroundColor; i--)
attrs.backgroundColor = stack->getRef (i)->style->backgroundColor;
@@ -837,7 +837,7 @@ Style * StyleEngine::backgroundStyle (BrowserWindow *bw, DilloUrl *url) {
* HTML elements and the nonCssProperties that have been set.
* This method is private. Call style() to get a current style object.
*/
-Style * StyleEngine::style0 (int i, BrowserWindow *bw, DilloUrl *url) {
+Style * StyleEngine::style0 (int i, BrowserWindow *bw) {
CssPropertyList props, *styleAttrProperties, *styleAttrPropertiesImportant;
CssPropertyList *nonCssProperties;
// get previous style from the stack
@@ -865,7 +865,7 @@ Style * StyleEngine::style0 (int i, BrowserWindow *bw, DilloUrl *url) {
nonCssProperties);
// apply style
- apply (i, &attrs, &props, bw, url);
+ apply (i, &attrs, &props, bw);
postprocessAttrs (&attrs);
@@ -874,20 +874,20 @@ Style * StyleEngine::style0 (int i, BrowserWindow *bw, DilloUrl *url) {
return stack->getRef (i)->style;
}
-Style * StyleEngine::wordStyle0 (BrowserWindow *bw, DilloUrl *url) {
- StyleAttrs attrs = *style (bw, url);
+Style * StyleEngine::wordStyle0 (BrowserWindow *bw) {
+ StyleAttrs attrs = *style (bw);
attrs.resetValues ();
if (stack->getRef (stack->size() - 1)->inheritBackgroundColor) {
- attrs.backgroundColor = style (bw, url)->backgroundColor;
- attrs.backgroundImage = style (bw, url)->backgroundImage;
- attrs.backgroundRepeat = style (bw, url)->backgroundRepeat;
- attrs.backgroundAttachment = style (bw, url)->backgroundAttachment;
- attrs.backgroundPositionX = style (bw, url)->backgroundPositionX;
- attrs.backgroundPositionY = style (bw, url)->backgroundPositionY;
+ attrs.backgroundColor = style (bw)->backgroundColor;
+ attrs.backgroundImage = style (bw)->backgroundImage;
+ attrs.backgroundRepeat = style (bw)->backgroundRepeat;
+ attrs.backgroundAttachment = style (bw)->backgroundAttachment;
+ attrs.backgroundPositionX = style (bw)->backgroundPositionX;
+ attrs.backgroundPositionY = style (bw)->backgroundPositionY;
}
- attrs.valign = style (bw, url)->valign;
+ attrs.valign = style (bw)->valign;
stack->getRef(stack->size() - 1)->wordStyle = Style::create(&attrs);
return stack->getRef (stack->size () - 1)->wordStyle;
@@ -900,7 +900,7 @@ Style * StyleEngine::wordStyle0 (BrowserWindow *bw, DilloUrl *url) {
* and thereby after the HTML-element has been opened.
* Note that restyle() does not change any styles in the widget tree.
*/
-void StyleEngine::restyle (BrowserWindow *bw, DilloUrl *url) {
+void StyleEngine::restyle (BrowserWindow *bw) {
for (int i = 1; i < stack->size (); i++) {
Node *n = stack->getRef (i);
if (n->style) {
@@ -916,7 +916,7 @@ void StyleEngine::restyle (BrowserWindow *bw, DilloUrl *url) {
n->backgroundStyle = NULL;
}
- style0 (i, bw, url);
+ style0 (i, bw);
}
}
diff --git a/src/styleengine.hh b/src/styleengine.hh
index bec4875b..59c17a1a 100644
--- a/src/styleengine.hh
+++ b/src/styleengine.hh
@@ -35,12 +35,13 @@ class StyleEngine {
CssContext *cssContext;
Doctree *doctree;
int importDepth;
+ const DilloUrl *baseUrl;
void stackPush ();
void stackPop ();
void buildUserStyle ();
- dw::core::style::Style *style0 (int i, BrowserWindow *bw, DilloUrl *url);
- dw::core::style::Style *wordStyle0 (BrowserWindow *bw, DilloUrl *url);
+ dw::core::style::Style *style0 (int i, BrowserWindow *bw);
+ dw::core::style::Style *wordStyle0 (BrowserWindow *bw);
inline void setNonCssHint(CssPropertyName name, CssValueType type,
CssPropertyValue value) {
Node *n = stack->getRef (stack->size () - 1);
@@ -52,7 +53,7 @@ class StyleEngine {
void preprocessAttrs (dw::core::style::StyleAttrs *attrs);
void postprocessAttrs (dw::core::style::StyleAttrs *attrs);
void apply (int i, dw::core::style::StyleAttrs *attrs,
- CssPropertyList *props, BrowserWindow *bw, DilloUrl *url);
+ CssPropertyList *props, BrowserWindow *bw);
bool computeValue (int *dest, CssLength value,
dw::core::style::Font *font);
bool computeValue (int *dest, CssLength value,
@@ -65,13 +66,13 @@ class StyleEngine {
public:
static void init ();
- StyleEngine (dw::core::Layout *layout);
+ StyleEngine (dw::core::Layout *layout, const DilloUrl *baseUrl);
~StyleEngine ();
void parse (DilloHtml *html, DilloUrl *url, const char *buf, int buflen,
CssOrigin origin);
- void startElement (int tag, BrowserWindow *bw, DilloUrl *url);
- void startElement (const char *tagname, BrowserWindow *bw, DilloUrl *url);
+ void startElement (int tag, BrowserWindow *bw);
+ void startElement (const char *tagname, BrowserWindow *bw);
void setId (const char *id);
const char * getId () { return doctree->top ()->id; };
void setClass (const char *klass);
@@ -93,10 +94,9 @@ class StyleEngine {
}
void inheritNonCssHints ();
void clearNonCssHints ();
- void restyle (BrowserWindow *bw, DilloUrl *url);
+ void restyle (BrowserWindow *bw);
void inheritBackgroundColor (); /* \todo get rid of this somehow */
- dw::core::style::Style *backgroundStyle (BrowserWindow *bw,
- DilloUrl *url);
+ dw::core::style::Style *backgroundStyle (BrowserWindow *bw);
dw::core::style::Color *backgroundColor ();
dw::core::style::StyleImage *backgroundImage
(dw::core::style::BackgroundRepeat *bgRepeat,
@@ -104,21 +104,20 @@ class StyleEngine {
dw::core::style::Length *bgPositionX,
dw::core::style::Length *bgPositionY);
- inline dw::core::style::Style *style (BrowserWindow *bw, DilloUrl *url) {
+ inline dw::core::style::Style *style (BrowserWindow *bw) {
dw::core::style::Style *s = stack->getRef (stack->size () - 1)->style;
if (s)
return s;
else
- return style0 (stack->size () - 1, bw, url);
+ return style0 (stack->size () - 1, bw);
};
- inline dw::core::style::Style *wordStyle (BrowserWindow *bw,
- DilloUrl *url) {
+ inline dw::core::style::Style *wordStyle (BrowserWindow *bw) {
dw::core::style::Style *s = stack->getRef(stack->size()-1)->wordStyle;
if (s)
return s;
else
- return wordStyle0 (bw, url);
+ return wordStyle0 (bw);
};
};
diff --git a/src/web.cc b/src/web.cc
index 0a8ee710..617afbbe 100644
--- a/src/web.cc
+++ b/src/web.cc
@@ -73,14 +73,14 @@ int a_Web_dispatch_by_type (const char *Type, DilloWeb *Web,
style::createPerLength (0));
/* Set a style for the widget */
- StyleEngine styleEngine (layout);
- styleEngine.startElement ("body", Web->bw, Web->url);
+ StyleEngine styleEngine (layout, Web->url);
+ styleEngine.startElement ("body", Web->bw);
dw = (Widget*) viewer(Type, Web, Call, Data);
if (dw == NULL)
return -1;
- dw->setStyle (styleEngine.style (Web->bw, Web->url));
+ dw->setStyle (styleEngine.style (Web->bw));
/* This method frees the old dw if any */
layout->setWidget(dw);