aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/css.cc102
-rw-r--r--src/css.hh19
-rw-r--r--src/cssparser.cc13
-rw-r--r--src/styleengine.cc13
4 files changed, 77 insertions, 70 deletions
diff --git a/src/css.cc b/src/css.cc
index f8522654..4a110161 100644
--- a/src/css.cc
+++ b/src/css.cc
@@ -45,41 +45,37 @@ void CssPropertyList::print () {
getRef (i)->print ();
}
-CssSelector::CssSelector (int element, const char *klass,
- const char *pseudo, const char *id) {
+CssSelector::CssSelector () {
+ struct CombinatorAndSelector *cs;
+
refCount = 0;
selectorList = new lout::misc::SimpleVector
<struct CombinatorAndSelector> (1);
selectorList->increase ();
- selectorList->getRef (0)->notMatchingBefore = -1;
- top ()->element = element;
- top ()->klass = klass;
- top ()->pseudo = pseudo;
- top ()->id = id;
+ cs = selectorList->getRef (selectorList->size () - 1);
+
+ cs->notMatchingBefore = -1;
+ cs->selector.element = CssSimpleSelector::ELEMENT_ANY;
+ cs->selector.klass = NULL;
+ cs->selector.pseudo = NULL;
+ cs->selector.id = NULL;
};
CssSelector::~CssSelector () {
delete selectorList;
}
-bool CssSelector::match (Doctree *docTree) {
+bool CssSelector::match (Doctree *docTree, const DoctreeNode *node) {
CssSimpleSelector *sel;
- Combinator comb;
+ Combinator comb = CHILD;
int *notMatchingBefore;
- const DoctreeNode *n, *node = docTree->top ();
+ const DoctreeNode *n;
- assert (selectorList->size () > 0);
+ for (int i = selectorList->size () - 1; i >= 0; i--) {
+ struct CombinatorAndSelector *cs = selectorList->getRef (i);
- sel = top ();
-
- if (! sel->match (node))
- return false;
-
- for (int i = selectorList->size () - 2; i >= 0; i--) {
- sel = &selectorList->getRef (i)->selector;
- comb = selectorList->getRef (i + 1)->combinator;
- notMatchingBefore = &selectorList->getRef (i + 1)->notMatchingBefore;
- node = docTree->parent (node);
+ sel = &cs->selector;
+ notMatchingBefore = &cs->notMatchingBefore;
if (node == NULL)
return false;
@@ -93,7 +89,7 @@ bool CssSelector::match (Doctree *docTree) {
n = node;
while (true) {
- if (node == NULL || node->num < *notMatchingBefore) {
+ if (node == NULL || node->num <= *notMatchingBefore) {
*notMatchingBefore = n->num;
return false;
}
@@ -107,23 +103,26 @@ bool CssSelector::match (Doctree *docTree) {
default:
return false; // \todo implement other combinators
}
+
+ comb = cs->combinator;
+ node = docTree->parent (node);
}
return true;
}
-void CssSelector::addSimpleSelector (Combinator c, int element,
- const char *klass, const char *pseudo,
- const char *id) {
- selectorList->increase ();
-
- selectorList->getRef (selectorList->size () - 1)->combinator = c;
- selectorList->getRef (selectorList->size () - 1)->notMatchingBefore = -1;
- top ()->element = element;
- top ()->klass = klass;
- top ()->pseudo = pseudo;
- top ()->id = id;
+void CssSelector::addSimpleSelector (Combinator c) {
+ struct CombinatorAndSelector *cs;
+ selectorList->increase ();
+ cs = selectorList->getRef (selectorList->size () - 1);
+
+ cs->combinator = c;
+ cs->notMatchingBefore = -1;
+ cs->selector.element = CssSimpleSelector::ELEMENT_ANY;
+ cs->selector.klass = NULL;
+ cs->selector.pseudo = NULL;
+ cs->selector.id = NULL;
}
void CssSelector::print () {
@@ -169,6 +168,8 @@ void CssSimpleSelector::print () {
}
CssRule::CssRule (CssSelector *selector, CssPropertyList *props) {
+ assert (selector->size () > 0);
+
this->selector = selector;
this->selector->ref ();
this->props = props;
@@ -180,8 +181,9 @@ CssRule::~CssRule () {
props->unref ();
};
-void CssRule::apply (CssPropertyList *props, Doctree *docTree) {
- if (selector->match (docTree))
+void CssRule::apply (CssPropertyList *props,
+ Doctree *docTree, const DoctreeNode *node) {
+ if (selector->match (docTree, node))
this->props->apply (props);
}
@@ -247,18 +249,18 @@ void CssStyleSheet::addRule (CssSelector *selector, CssPropertyList *props) {
addRule (rule);
}
-void CssStyleSheet::apply (CssPropertyList *props, Doctree *docTree) {
+void CssStyleSheet::apply (CssPropertyList *props,
+ Doctree *docTree, const DoctreeNode *node) {
RuleList *ruleList[4] = {NULL, NULL, NULL, NULL};
- const DoctreeNode *top = docTree->top ();
- if (top->id) {
- lout::object::String idString (top->id);
+ if (node->id) {
+ lout::object::String idString (node->id);
ruleList[3] = idTable->get (&idString);
}
- if (top->klass) {
- lout::object::String classString (top->klass);
+ if (node->klass) {
+ lout::object::String classString (node->klass);
ruleList[2] = classTable->get (&classString);
}
@@ -266,19 +268,12 @@ void CssStyleSheet::apply (CssPropertyList *props, Doctree *docTree) {
ruleList[1] = elementTable[docTree->top ()->element];
ruleList[0] = anyTable;
-#if 0
- fprintf(stderr, "==> ");
- for (int j = 0; j < 4; j++)
- fprintf(stderr, "%d ", ruleList[j]?ruleList[j]->size():0);
- fprintf(stderr, "\n");
-#endif
-
for (int i = 0;; i++) {
int n = 0;
for (int j = 0; j < 4; j++) {
if (ruleList[j] && ruleList[j]->size () > i) {
- ruleList[j]->get (i)->apply (props, docTree);
+ ruleList[j]->get (i)->apply (props, docTree, node);
n++;
}
}
@@ -323,17 +318,18 @@ CssContext::~CssContext () {
void CssContext::apply (CssPropertyList *props, Doctree *docTree,
CssPropertyList *tagStyle, CssPropertyList *nonCssHints) {
+ const DoctreeNode *node = docTree->top ();
for (int o = CSS_PRIMARY_USER_AGENT; o <= CSS_PRIMARY_USER; o++)
if (sheet[o])
- sheet[o]->apply (props, docTree);
+ sheet[o]->apply (props, docTree, node);
if (nonCssHints)
nonCssHints->apply (props);
for (int o = CSS_PRIMARY_AUTHOR; o <= CSS_PRIMARY_USER_IMPORTANT; o++)
if (sheet[o])
- sheet[o]->apply (props, docTree);
+ sheet[o]->apply (props, docTree, node);
if (tagStyle)
tagStyle->apply (props);
@@ -358,10 +354,10 @@ void CssContext::buildUserAgentStyle () {
"center {text-align: center}"
"dt {font-weight: bolder}"
":link {color: blue; text-decoration: underline; cursor: pointer}"
- ":visited {color: green; text-decoration: underline; cursor: pointer}"
+ ":visited {color: #800080; text-decoration: underline; cursor: pointer}"
"h1, h2, h3, h4, h5, h6, b, strong {font-weight: bolder}"
"i, em, cite, address {font-style: italic}"
- "img:link, img:visited {border: 1px solid}"
+ ":link img, :visited img {border: 1px solid}"
"frameset, ul, ol, dir {margin-left: 40px}"
"h1 {font-size: 2em; margin-top: .67em; margin-bottom: 0}"
"h2 {font-size: 1.5em; margin-top: .75em; margin-bottom: 0}"
diff --git a/src/css.hh b/src/css.hh
index d3472740..122215f7 100644
--- a/src/css.hh
+++ b/src/css.hh
@@ -232,19 +232,14 @@ class CssSelector {
lout::misc::SimpleVector <struct CombinatorAndSelector> *selectorList;
public:
- CssSelector (int element = CssSimpleSelector::ELEMENT_ANY,
- const char *klass = NULL,
- const char *pseudo = NULL, const char *id = NULL);
+ CssSelector ();
~CssSelector ();
- void addSimpleSelector (Combinator c,
- int element = CssSimpleSelector::ELEMENT_ANY,
- const char *klass = NULL,
- const char *pseudo = NULL, const char *id=NULL);
+ void addSimpleSelector (Combinator c);
inline CssSimpleSelector *top () {
return &selectorList->getRef (selectorList->size () - 1)->selector;
};
-
- bool match (Doctree *dt);
+ inline int size () { return selectorList->size (); };
+ bool match (Doctree *dt, const DoctreeNode *node);
void print ();
inline void ref () { refCount++; }
inline void unref () { if(--refCount == 0) delete this; }
@@ -264,7 +259,8 @@ class CssRule {
CssRule (CssSelector *selector, CssPropertyList *props);
~CssRule ();
- void apply (CssPropertyList *props, Doctree *docTree);
+ void apply (CssPropertyList *props,
+ Doctree *docTree, const DoctreeNode *node);
void print ();
};
@@ -306,7 +302,8 @@ class CssStyleSheet {
~CssStyleSheet();
void addRule (CssRule *rule);
void addRule (CssSelector *selector, CssPropertyList *props);
- void apply (CssPropertyList *props, Doctree *docTree);
+ void apply (CssPropertyList *props,
+ Doctree *docTree, const DoctreeNode *node);
};
/**
diff --git a/src/cssparser.cc b/src/cssparser.cc
index f11e0a86..a50ef9da 100644
--- a/src/cssparser.cc
+++ b/src/cssparser.cc
@@ -696,7 +696,9 @@ static bool Css_parse_value(CssParser * parser,
val->intVal = CSS_CREATE_LENGTH(fval, lentype);
} else if (parser->ttype == CSS_TK_SYMBOL &&
strcmp(parser->tval, "auto") == 0) {
+ ret = true;
val->intVal = CSS_LENGTH_TYPE_AUTO;
+ Css_next_token(parser);
}
break;
@@ -1004,6 +1006,13 @@ static bool Css_parse_simple_selector(CssParser * parser,
break;
case ':':
pp = &selector->pseudo;
+ if (*pp)
+ // pseudo class has been set already.
+ // As dillo currently only supports :link and :visisted, a
+ // selector with more than one pseudo class will never match.
+ // By returning false, the whole CssRule will be dropped.
+ // \todo adapt this when supporting :hover, :active...
+ return false;
break;
}
}
@@ -1181,8 +1190,10 @@ CssPropertyList *a_Css_parse_declaration(const char *buf, int buflen)
parser.space_separated = false;
Css_next_token(&parser);
- while (parser.ttype != CSS_TK_END)
+ do
Css_parse_declaration(&parser, props, NULL);
+ while (!(parser.ttype == CSS_TK_END ||
+ (parser.ttype == CSS_TK_CHAR && parser.tval[0] == '}')));
if (props->size () == 0) {
delete props;
diff --git a/src/styleengine.cc b/src/styleengine.cc
index 4e234a3c..fbf9c8ee 100644
--- a/src/styleengine.cc
+++ b/src/styleengine.cc
@@ -31,7 +31,7 @@ StyleEngine::StyleEngine (dw::core::Layout *layout) {
/* Create a dummy font, attribute, and tag for the bottom of the stack. */
font_attrs.name = "helvetica";
- font_attrs.size = (int) (12 * prefs.font_factor + 0.5);
+ font_attrs.size = (int) (14 * prefs.font_factor + 0.5);
font_attrs.weight = CssProperty::CSS_FONT_WEIGHT_NORMAL;
font_attrs.style = FONT_STYLE_NORMAL;
@@ -377,10 +377,13 @@ bool StyleEngine::computeLength (dw::core::style::Length *dest,
if (CSS_LENGTH_TYPE (value) == CSS_LENGTH_TYPE_PERCENTAGE) {
*dest = createPerLength (CSS_LENGTH_VALUE (value));
return true;
- } else if (computeValue (&v, value, font)) {
- *dest = createAbsLength (v);
- return true;
- }
+ } else if (CSS_LENGTH_TYPE (value) == CSS_LENGTH_TYPE_AUTO) {
+ *dest = dw::core::style::LENGTH_AUTO;
+ return true;
+ } else if (computeValue (&v, value, font)) {
+ *dest = createAbsLength (v);
+ return true;
+ }
return false;
}