diff options
author | Johannes Hofmann <Johannes.Hofmann@gmx.de> | 2014-04-01 21:48:15 +0200 |
---|---|---|
committer | Johannes Hofmann <Johannes.Hofmann@gmx.de> | 2014-04-01 21:48:15 +0200 |
commit | f284ce5c34cdf37854135524814bbacbd2932f25 (patch) | |
tree | 62047de8c15b27fab0caa0a9105a15dfea156c87 | |
parent | 4e3f41b9e5307fd951c710818687f96e8a68ca35 (diff) |
resolve CSS background-image URLs relative to styleheet URL
-rw-r--r-- | src/cssparser.cc | 26 | ||||
-rw-r--r-- | src/cssparser.hh | 10 | ||||
-rw-r--r-- | src/html.cc | 4 | ||||
-rw-r--r-- | src/html_common.hh | 12 | ||||
-rw-r--r-- | src/plain.cc | 10 | ||||
-rw-r--r-- | src/styleengine.cc | 54 | ||||
-rw-r--r-- | src/styleengine.hh | 27 | ||||
-rw-r--r-- | src/web.cc | 6 |
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); }; }; @@ -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); |