diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/css.cc | 102 | ||||
-rw-r--r-- | src/css.hh | 19 | ||||
-rw-r--r-- | src/cssparser.cc | 13 | ||||
-rw-r--r-- | src/styleengine.cc | 13 |
4 files changed, 77 insertions, 70 deletions
@@ -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}" @@ -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; } |