webengine/osswebengine/WebCore/css/cssstyleselector.cpp
changeset 0 dd21522fd290
child 13 10e98eab6f85
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /**
       
     2  * This file is part of the CSS implementation for KDE.
       
     3  *
       
     4  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
       
     5  *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
       
     6  *           (C) 2006 Nicholas Shanks (webkit@nickshanks.com)
       
     7  * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
       
     8  *
       
     9  * This library is free software; you can redistribute it and/or
       
    10  * modify it under the terms of the GNU Library General Public
       
    11  * License as published by the Free Software Foundation; either
       
    12  * version 2 of the License, or (at your option) any later version.
       
    13  *
       
    14  * This library is distributed in the hope that it will be useful,
       
    15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    17  * Library General Public License for more details.
       
    18  *
       
    19  * You should have received a copy of the GNU Library General Public License
       
    20  * along with this library; see the file COPYING.LIB.  If not, write to
       
    21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    22  * Boston, MA 02110-1301, USA.
       
    23  */
       
    24 
       
    25 #include "config.h"
       
    26 #include "CSSStyleSelector.h"
       
    27 
       
    28 #include "CSSBorderImageValue.h"
       
    29 #include "CSSCursorImageValue.h"
       
    30 #include "CSSImageValue.h"
       
    31 #include "CSSImportRule.h"
       
    32 #include "CSSMediaRule.h"
       
    33 #include "CSSProperty.h"
       
    34 #include "CSSPropertyNames.h"
       
    35 #include "CSSRuleList.h"
       
    36 #include "CSSSelector.h"
       
    37 #include "CSSStyleRule.h"
       
    38 #include "CSSStyleSheet.h"
       
    39 #include "CSSValueKeywords.h"
       
    40 #include "CSSValueList.h"
       
    41 #include "CachedImage.h"
       
    42 #include "Counter.h"
       
    43 #include "DashboardRegion.h"
       
    44 #include "FontFamilyValue.h"
       
    45 #include "FontValue.h"
       
    46 #include "Frame.h"
       
    47 #include "FrameView.h"
       
    48 #include "GlobalHistory.h"
       
    49 #include "HTMLDocument.h"
       
    50 #include "HTMLElement.h"
       
    51 #include "HTMLInputElement.h"
       
    52 #include "HTMLNames.h"
       
    53 #include "MediaList.h"
       
    54 #include "MediaQueryEvaluator.h"
       
    55 #include "Pair.h"
       
    56 #include "Rect.h"
       
    57 #include "RenderTheme.h"
       
    58 #include "Settings.h"
       
    59 #include "ShadowValue.h"
       
    60 #include "StyleSheetList.h"
       
    61 #include "UserAgentStyleSheets.h"
       
    62 #include "loader.h"
       
    63 
       
    64 #if ENABLE(SVG)
       
    65 #include "XLinkNames.h"
       
    66 #include "SVGNames.h"
       
    67 #endif
       
    68 
       
    69 #if PLATFORM(SYMBIAN)
       
    70 #include "Frame.h"
       
    71 #include "WebCoreFrameBridge.h"
       
    72 #endif
       
    73 
       
    74 
       
    75 using namespace std;
       
    76 
       
    77 namespace WebCore {
       
    78 
       
    79 using namespace HTMLNames;
       
    80 
       
    81 // #define STYLE_SHARING_STATS 1
       
    82 
       
    83 #define HANDLE_INHERIT(prop, Prop) \
       
    84 if (isInherit) { \
       
    85     style->set##Prop(parentStyle->prop()); \
       
    86     return; \
       
    87 }
       
    88 
       
    89 #define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
       
    90 HANDLE_INHERIT(prop, Prop) \
       
    91 if (isInitial) { \
       
    92     style->set##Prop(RenderStyle::initial##Prop()); \
       
    93     return; \
       
    94 }
       
    95 
       
    96 #define HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(prop, Prop, Value) \
       
    97 HANDLE_INHERIT(prop, Prop) \
       
    98 if (isInitial) { \
       
    99     style->set##Prop(RenderStyle::initial##Value());\
       
   100     return;\
       
   101 }
       
   102 
       
   103 #define HANDLE_BACKGROUND_INHERIT_AND_INITIAL(prop, Prop) \
       
   104 if (isInherit) { \
       
   105     BackgroundLayer* currChild = style->accessBackgroundLayers(); \
       
   106     BackgroundLayer* prevChild = 0; \
       
   107     const BackgroundLayer* currParent = parentStyle->backgroundLayers(); \
       
   108     while (currParent && currParent->is##Prop##Set()) { \
       
   109         if (!currChild) { \
       
   110             /* Need to make a new layer.*/ \
       
   111             currChild = new BackgroundLayer(); \
       
   112             prevChild->setNext(currChild); \
       
   113         } \
       
   114         currChild->set##Prop(currParent->prop()); \
       
   115         prevChild = currChild; \
       
   116         currChild = prevChild->next(); \
       
   117         currParent = currParent->next(); \
       
   118     } \
       
   119     \
       
   120     while (currChild) { \
       
   121         /* Reset any remaining layers to not have the property set. */ \
       
   122         currChild->clear##Prop(); \
       
   123         currChild = currChild->next(); \
       
   124     } \
       
   125     return; \
       
   126 } \
       
   127 if (isInitial) { \
       
   128     BackgroundLayer* currChild = style->accessBackgroundLayers(); \
       
   129     currChild->set##Prop(RenderStyle::initial##Prop()); \
       
   130     for (currChild = currChild->next(); currChild; currChild = currChild->next()) \
       
   131         currChild->clear##Prop(); \
       
   132     return; \
       
   133 }
       
   134 
       
   135 #define HANDLE_BACKGROUND_VALUE(prop, Prop, value) { \
       
   136 HANDLE_BACKGROUND_INHERIT_AND_INITIAL(prop, Prop) \
       
   137 if (!value->isPrimitiveValue() && !value->isValueList()) \
       
   138     return; \
       
   139 BackgroundLayer* currChild = style->accessBackgroundLayers(); \
       
   140 BackgroundLayer* prevChild = 0; \
       
   141 if (value->isPrimitiveValue()) { \
       
   142     map##Prop(currChild, value); \
       
   143     currChild = currChild->next(); \
       
   144 } \
       
   145 else { \
       
   146     /* Walk each value and put it into a layer, creating new layers as needed. */ \
       
   147     CSSValueList* valueList = static_cast<CSSValueList*>(value); \
       
   148     for (unsigned int i = 0; i < valueList->length(); i++) { \
       
   149         if (!currChild) { \
       
   150             /* Need to make a new layer to hold this value */ \
       
   151             currChild = new BackgroundLayer(); \
       
   152             prevChild->setNext(currChild); \
       
   153         } \
       
   154         map##Prop(currChild, valueList->item(i)); \
       
   155         prevChild = currChild; \
       
   156         currChild = currChild->next(); \
       
   157     } \
       
   158 } \
       
   159 while (currChild) { \
       
   160     /* Reset all remaining layers to not have the property set. */ \
       
   161     currChild->clear##Prop(); \
       
   162     currChild = currChild->next(); \
       
   163 } }
       
   164 
       
   165 #define HANDLE_INHERIT_COND(propID, prop, Prop) \
       
   166 if (id == propID) { \
       
   167     style->set##Prop(parentStyle->prop()); \
       
   168     return; \
       
   169 }
       
   170 
       
   171 #define HANDLE_INITIAL_COND(propID, Prop) \
       
   172 if (id == propID) { \
       
   173     style->set##Prop(RenderStyle::initial##Prop()); \
       
   174     return; \
       
   175 }
       
   176 
       
   177 #define HANDLE_INITIAL_COND_WITH_VALUE(propID, Prop, Value) \
       
   178 if (id == propID) { \
       
   179     style->set##Prop(RenderStyle::initial##Value()); \
       
   180     return; \
       
   181 }
       
   182 
       
   183 class CSSRuleSet
       
   184 {
       
   185 public:
       
   186     CSSRuleSet();
       
   187     ~CSSRuleSet();
       
   188     
       
   189     typedef HashMap<AtomicStringImpl*, CSSRuleDataList*> AtomRuleMap;
       
   190     
       
   191     void addRulesFromSheet(CSSStyleSheet* sheet, MediaQueryEvaluator* medium);
       
   192     
       
   193     void addRule(CSSStyleRule* rule, CSSSelector* sel);
       
   194     void addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map,
       
   195                       CSSStyleRule* rule, CSSSelector* sel);
       
   196     
       
   197     CSSRuleDataList* getIDRules(AtomicStringImpl* key) { return m_idRules.get(key); }
       
   198     CSSRuleDataList* getClassRules(AtomicStringImpl* key) { return m_classRules.get(key); }
       
   199     CSSRuleDataList* getTagRules(AtomicStringImpl* key) { return m_tagRules.get(key); }
       
   200     CSSRuleDataList* getUniversalRules() { return m_universalRules; }
       
   201     
       
   202 public:
       
   203     AtomRuleMap m_idRules;
       
   204     AtomRuleMap m_classRules;
       
   205     AtomRuleMap m_tagRules;
       
   206     CSSRuleDataList* m_universalRules;
       
   207     
       
   208     unsigned m_ruleCount;
       
   209 };
       
   210 
       
   211 CSSRuleSet* CSSStyleSelector::defaultStyle = 0;
       
   212 CSSRuleSet* CSSStyleSelector::defaultQuirksStyle = 0;
       
   213 CSSRuleSet* CSSStyleSelector::defaultPrintStyle = 0;
       
   214 CSSRuleSet* CSSStyleSelector::defaultViewSourceStyle = 0;
       
   215 
       
   216 CSSStyleSheet* CSSStyleSelector::defaultSheet = 0;
       
   217 RenderStyle* CSSStyleSelector::styleNotYetAvailable = 0;
       
   218 CSSStyleSheet* CSSStyleSelector::quirksSheet = 0;
       
   219 CSSStyleSheet* CSSStyleSelector::viewSourceSheet = 0;
       
   220 
       
   221 #if ENABLE(SVG)
       
   222 CSSStyleSheet *CSSStyleSelector::svgSheet = 0;
       
   223 #endif
       
   224 
       
   225 static CSSStyleSelector::Encodedurl *currentEncodedURL = 0;
       
   226 static PseudoState pseudoState;
       
   227 
       
   228 CSSStyleSelector::CSSStyleSelector(Document* doc, const String& userStyleSheet, StyleSheetList *styleSheets, bool _strictParsing)
       
   229 {
       
   230     init();
       
   231     
       
   232     m_document = doc;
       
   233 
       
   234     strictParsing = _strictParsing;
       
   235     if (!defaultStyle)
       
   236         loadDefaultStyle();
       
   237 
       
   238     m_userStyle = 0;
       
   239 
       
   240     // construct document root element default style. this is needed
       
   241     // to evaluate media queries that contain relative constraints, like "screen and (max-width: 10em)"
       
   242     // This is here instead of constructor, because when constructor is run,
       
   243     // document doesn't have documentElement
       
   244     // NOTE: this assumes that element that gets passed to styleForElement -call
       
   245     // is always from the document that owns the style selector
       
   246     FrameView* view = m_document->view();
       
   247     if (view)
       
   248         m_medium = new MediaQueryEvaluator(view->mediaType());
       
   249     else
       
   250         m_medium = new MediaQueryEvaluator("all");
       
   251 
       
   252     Element* root = doc->documentElement();
       
   253 
       
   254     if (root)
       
   255         m_rootDefaultStyle = styleForElement(root, 0, false, true); // dont ref, because the RenderStyle is allocated from global heap
       
   256 
       
   257     if (m_rootDefaultStyle && view) {
       
   258         delete m_medium;
       
   259         m_medium = new MediaQueryEvaluator(view->mediaType(), view->frame()->page(), m_rootDefaultStyle);
       
   260     }
       
   261 
       
   262     // FIXME: This sucks! The user sheet is reparsed every time!
       
   263     if (!userStyleSheet.isEmpty()) {
       
   264         m_userSheet = new CSSStyleSheet(doc);
       
   265         m_userSheet->parseString(userStyleSheet, strictParsing);
       
   266 
       
   267         m_userStyle = new CSSRuleSet();
       
   268         m_userStyle->addRulesFromSheet(m_userSheet.get(), m_medium);
       
   269     }
       
   270 
       
   271     // add stylesheets from document
       
   272     m_authorStyle = new CSSRuleSet();
       
   273 
       
   274     DeprecatedPtrListIterator<StyleSheet> it(styleSheets->styleSheets);
       
   275     for (; it.current(); ++it)
       
   276         if (it.current()->isCSSStyleSheet() && !it.current()->disabled())
       
   277             m_authorStyle->addRulesFromSheet(static_cast<CSSStyleSheet*>(it.current()), m_medium);
       
   278 
       
   279 }
       
   280 
       
   281 CSSStyleSelector::CSSStyleSelector(CSSStyleSheet *sheet)
       
   282 {
       
   283     init();
       
   284 
       
   285     if (!defaultStyle)
       
   286         loadDefaultStyle();
       
   287     FrameView *view = sheet->doc()->view();
       
   288 
       
   289     if (view)
       
   290         m_medium = new MediaQueryEvaluator(view->mediaType());
       
   291     else
       
   292         m_medium = new MediaQueryEvaluator("all");
       
   293 
       
   294     Element* root = sheet->doc()->documentElement();
       
   295     if (root)
       
   296         m_rootDefaultStyle = styleForElement(root, 0, false, true);
       
   297 
       
   298     if (m_rootDefaultStyle && view) {
       
   299         delete m_medium;
       
   300         m_medium = new MediaQueryEvaluator(view->mediaType(), view->frame()->page(), m_rootDefaultStyle);
       
   301     }
       
   302 
       
   303     m_authorStyle = new CSSRuleSet();
       
   304     m_authorStyle->addRulesFromSheet(sheet, m_medium);
       
   305 }
       
   306 
       
   307 void CSSStyleSelector::init()
       
   308 {
       
   309     element = 0;
       
   310     m_matchedDecls.clear();
       
   311     m_ruleList = 0;
       
   312     m_collectRulesOnly = false;
       
   313     m_rootDefaultStyle = 0;
       
   314     m_medium = 0;
       
   315 }
       
   316 
       
   317 void CSSStyleSelector::setEncodedURL(const KURL& url)
       
   318 {
       
   319     KURL u = url;
       
   320 
       
   321     u.setQuery(DeprecatedString::null);
       
   322     u.setRef(DeprecatedString::null);
       
   323     encodedurl.file = u.url();
       
   324     int pos = encodedurl.file.findRev('/');
       
   325     encodedurl.path = encodedurl.file;
       
   326     if (pos > 0) {
       
   327         encodedurl.path.truncate(pos);
       
   328         encodedurl.path += '/';
       
   329     }
       
   330     u.setPath(DeprecatedString::null);
       
   331     encodedurl.host = u.url();
       
   332 }
       
   333 
       
   334 CSSStyleSelector::~CSSStyleSelector()
       
   335 {
       
   336     delete m_medium;
       
   337     ::delete m_rootDefaultStyle;
       
   338 
       
   339     delete m_authorStyle;
       
   340     delete m_userStyle;
       
   341 }
       
   342 
       
   343 static CSSStyleSheet* parseUASheet(const char* characters, unsigned size)
       
   344 {
       
   345     CSSStyleSheet* const parent = 0;
       
   346     CSSStyleSheet* sheet = new CSSStyleSheet(parent);
       
   347     sheet->ref(); // leak the sheet on purpose since it will be stored in a global variable
       
   348     sheet->parseString(String(characters, size));
       
   349     return sheet;
       
   350 }
       
   351 
       
   352 template<typename T> CSSStyleSheet* parseUASheet(const T& array)
       
   353 {
       
   354     return parseUASheet((const char*)array, sizeof(array));
       
   355 
       
   356 }
       
   357 
       
   358 void CSSStyleSelector::loadDefaultStyle()
       
   359 {
       
   360     if (defaultStyle)
       
   361         return;
       
   362 
       
   363     defaultStyle = new CSSRuleSet;
       
   364     defaultPrintStyle = new CSSRuleSet;
       
   365     defaultQuirksStyle = new CSSRuleSet;
       
   366     defaultViewSourceStyle = new CSSRuleSet;
       
   367 
       
   368     MediaQueryEvaluator screenEval("screen");
       
   369     MediaQueryEvaluator printEval("print");
       
   370 
       
   371     // Strict-mode rules.
       
   372     defaultSheet = parseUASheet(html4UserAgentStyleSheet);
       
   373     defaultStyle->addRulesFromSheet(defaultSheet, &screenEval);
       
   374     defaultPrintStyle->addRulesFromSheet(defaultSheet, &printEval);
       
   375 
       
   376 #if ENABLE(SVG)
       
   377     // SVG rules.
       
   378     svgSheet = parseUASheet(svgUserAgentStyleSheet);
       
   379     defaultStyle->addRulesFromSheet(svgSheet, &screenEval);
       
   380     defaultPrintStyle->addRulesFromSheet(svgSheet, &printEval);
       
   381 #endif
       
   382 
       
   383     // Quirks-mode rules.
       
   384     quirksSheet = parseUASheet(quirksUserAgentStyleSheet);
       
   385     defaultQuirksStyle->addRulesFromSheet(quirksSheet, &screenEval);
       
   386     
       
   387     // View source rules.
       
   388     viewSourceSheet = parseUASheet(sourceUserAgentStyleSheet);
       
   389     defaultViewSourceStyle->addRulesFromSheet(viewSourceSheet, &screenEval);
       
   390 }
       
   391 
       
   392 void CSSStyleSelector::matchRules(CSSRuleSet* rules, int& firstRuleIndex, int& lastRuleIndex)
       
   393 {
       
   394     m_matchedRules.clear();
       
   395 
       
   396     if (!rules || !element)
       
   397         return;
       
   398     
       
   399     // We need to collect the rules for id, class, tag, and everything else into a buffer and
       
   400     // then sort the buffer.
       
   401     if (element->hasID())
       
   402         matchRulesForList(rules->getIDRules(element->getIDAttribute().impl()), firstRuleIndex, lastRuleIndex);
       
   403     if (element->hasClass()) {
       
   404         for (const AtomicStringList* singleClass = element->getClassList(); singleClass; singleClass = singleClass->next())
       
   405             matchRulesForList(rules->getClassRules(singleClass->string().impl()), firstRuleIndex, lastRuleIndex);
       
   406     }
       
   407     matchRulesForList(rules->getTagRules(element->localName().impl()), firstRuleIndex, lastRuleIndex);
       
   408     matchRulesForList(rules->getUniversalRules(), firstRuleIndex, lastRuleIndex);
       
   409     
       
   410     // If we didn't match any rules, we're done.
       
   411     if (m_matchedRules.isEmpty())
       
   412         return;
       
   413     
       
   414     // Sort the set of matched rules.
       
   415     sortMatchedRules(0, m_matchedRules.size());
       
   416     
       
   417     // Now transfer the set of matched rules over to our list of decls.
       
   418     if (!m_collectRulesOnly) {
       
   419         for (unsigned i = 0; i < m_matchedRules.size(); i++)
       
   420             addMatchedDeclaration(m_matchedRules[i]->rule()->declaration());
       
   421     } else {
       
   422         for (unsigned i = 0; i < m_matchedRules.size(); i++) {
       
   423             if (!m_ruleList)
       
   424                 m_ruleList = new CSSRuleList();
       
   425             m_ruleList->append(m_matchedRules[i]->rule());
       
   426         }
       
   427     }
       
   428 }
       
   429 
       
   430 void CSSStyleSelector::matchRulesForList(CSSRuleDataList* rules, int& firstRuleIndex, int& lastRuleIndex)
       
   431 {
       
   432     if (!rules)
       
   433         return;
       
   434 
       
   435     for (CSSRuleData* d = rules->first(); d; d = d->next()) {
       
   436         CSSStyleRule* rule = d->rule();
       
   437         const AtomicString& localName = element->localName();
       
   438         const AtomicString& selectorLocalName = d->selector()->m_tag.localName();
       
   439         if ((localName == selectorLocalName || selectorLocalName == starAtom) && checkSelector(d->selector(), element)) {
       
   440             // If the rule has no properties to apply, then ignore it.
       
   441             CSSMutableStyleDeclaration* decl = rule->declaration();
       
   442             if (!decl || !decl->length())
       
   443                 continue;
       
   444             
       
   445             // If we're matching normal rules, set a pseudo bit if 
       
   446             // we really just matched a pseudo-element.
       
   447             if (dynamicPseudo != RenderStyle::NOPSEUDO && pseudoStyle == RenderStyle::NOPSEUDO) {
       
   448                 if (m_collectRulesOnly)
       
   449                     return;
       
   450                 style->setHasPseudoStyle(dynamicPseudo);
       
   451             } else {
       
   452                 // Update our first/last rule indices in the matched rules array.
       
   453                 lastRuleIndex = m_matchedDecls.size() + m_matchedRules.size();
       
   454                 if (firstRuleIndex == -1)
       
   455                     firstRuleIndex = lastRuleIndex;
       
   456 
       
   457                 // Add this rule to our list of matched rules.
       
   458                 addMatchedRule(d);
       
   459             }
       
   460         }
       
   461     }
       
   462 }
       
   463 
       
   464 bool operator >(CSSRuleData& r1, CSSRuleData& r2)
       
   465 {
       
   466     int spec1 = r1.selector()->specificity();
       
   467     int spec2 = r2.selector()->specificity();
       
   468     return (spec1 == spec2) ? r1.position() > r2.position() : spec1 > spec2; 
       
   469 }
       
   470 bool operator <=(CSSRuleData& r1, CSSRuleData& r2)
       
   471 {
       
   472     return !(r1 > r2);
       
   473 }
       
   474 
       
   475 void CSSStyleSelector::sortMatchedRules(unsigned start, unsigned end)
       
   476 {
       
   477     if (start >= end || (end - start == 1))
       
   478         return; // Sanity check.
       
   479 
       
   480     if (end - start <= 6) {
       
   481         // Apply a bubble sort for smaller lists.
       
   482         for (unsigned i = end - 1; i > start; i--) {
       
   483             bool sorted = true;
       
   484             for (unsigned j = start; j < i; j++) {
       
   485                 CSSRuleData* elt = m_matchedRules[j];
       
   486                 CSSRuleData* elt2 = m_matchedRules[j + 1];
       
   487                 if (*elt > *elt2) {
       
   488                     sorted = false;
       
   489                     m_matchedRules[j] = elt2;
       
   490                     m_matchedRules[j + 1] = elt;
       
   491                 }
       
   492             }
       
   493             if (sorted)
       
   494                 return;
       
   495         }
       
   496         return;
       
   497     }
       
   498 
       
   499     // Peform a merge sort for larger lists.
       
   500     unsigned mid = (start + end) / 2;
       
   501     sortMatchedRules(start, mid);
       
   502     sortMatchedRules(mid, end);
       
   503     
       
   504     CSSRuleData* elt = m_matchedRules[mid - 1];
       
   505     CSSRuleData* elt2 = m_matchedRules[mid];
       
   506     
       
   507     // Handle the fast common case (of equal specificity).  The list may already
       
   508     // be completely sorted.
       
   509     if (*elt <= *elt2)
       
   510         return;
       
   511     
       
   512     // We have to merge sort.  Ensure our merge buffer is big enough to hold
       
   513     // all the items.
       
   514     Vector<CSSRuleData*> rulesMergeBuffer;
       
   515     rulesMergeBuffer.reserveCapacity(end - start); 
       
   516 
       
   517     unsigned i1 = start;
       
   518     unsigned i2 = mid;
       
   519     
       
   520     elt = m_matchedRules[i1];
       
   521     elt2 = m_matchedRules[i2];
       
   522     
       
   523     while (i1 < mid || i2 < end) {
       
   524         if (i1 < mid && (i2 == end || *elt <= *elt2)) {
       
   525             rulesMergeBuffer.append(elt);
       
   526             if (++i1 < mid)
       
   527                 elt = m_matchedRules[i1];
       
   528         } else {
       
   529             rulesMergeBuffer.append(elt2);
       
   530             if (++i2 < end)
       
   531                 elt2 = m_matchedRules[i2];
       
   532         }
       
   533     }
       
   534     
       
   535     for (unsigned i = start; i < end; i++)
       
   536         m_matchedRules[i] = rulesMergeBuffer[i - start];
       
   537 }
       
   538 
       
   539 void CSSStyleSelector::initElementAndPseudoState(Element* e)
       
   540 {
       
   541     element = e;
       
   542     if (element && element->isStyledElement())
       
   543         styledElement = static_cast<StyledElement*>(element);
       
   544     else
       
   545         styledElement = 0;
       
   546     currentEncodedURL = &encodedurl;
       
   547     pseudoState = PseudoUnknown;
       
   548 }
       
   549 
       
   550 void CSSStyleSelector::initForStyleResolve(Element* e, RenderStyle* defaultParent)
       
   551 {
       
   552     // set some variables we will need
       
   553     pseudoStyle = RenderStyle::NOPSEUDO;
       
   554 
       
   555     parentNode = e->parentNode();
       
   556 
       
   557 #if ENABLE(SVG)
       
   558     if (!parentNode && e->isSVGElement() && e->isShadowNode())
       
   559         parentNode = e->shadowParentNode();
       
   560 #endif
       
   561 
       
   562     if (defaultParent)
       
   563         parentStyle = defaultParent;
       
   564     else
       
   565         parentStyle = parentNode ? parentNode->renderStyle() : 0;
       
   566     isXMLDoc = !element->document()->isHTMLDocument();
       
   567 
       
   568     style = 0;
       
   569     
       
   570     m_matchedDecls.clear();
       
   571 
       
   572     m_ruleList = 0;
       
   573 
       
   574     fontDirty = false;
       
   575 }
       
   576 
       
   577 // modified version of the one in kurl.cpp
       
   578 static void cleanpath(DeprecatedString &path)
       
   579 {
       
   580     int pos;
       
   581     while ((pos = path.find("/../")) != -1) {
       
   582         int prev = 0;
       
   583         if (pos > 0)
       
   584             prev = path.findRev("/", pos -1);
       
   585         // don't remove the host, i.e. http://foo.org/../foo.html
       
   586         if (prev < 0 || (prev > 3 && path.findRev("://", prev-1) == prev-2))
       
   587             path.remove(pos, 3);
       
   588         else
       
   589             // matching directory found ?
       
   590             path.remove(prev, pos- prev + 3);
       
   591     }
       
   592     pos = 0;
       
   593     
       
   594     // Don't remove "//" from an anchor identifier. -rjw
       
   595     // Set refPos to -2 to mean "I haven't looked for the anchor yet".
       
   596     // We don't want to waste a function call on the search for the the anchor
       
   597     // in the vast majority of cases where there is no "//" in the path.
       
   598     int refPos = -2;
       
   599     while ((pos = path.find("//", pos)) != -1) {
       
   600         if (refPos == -2)
       
   601             refPos = path.find("#");
       
   602         if (refPos > 0 && pos >= refPos)
       
   603             break;
       
   604         
       
   605         if (pos == 0 || path[pos-1] != ':')
       
   606             path.remove(pos, 1);
       
   607         else
       
   608             pos += 2;
       
   609     }
       
   610     while ((pos = path.find("/./")) != -1)
       
   611         path.remove(pos, 2);
       
   612 }
       
   613 
       
   614 static void checkPseudoState(Element *e, bool checkVisited = true)
       
   615 {
       
   616     if (!e->isLink()) {
       
   617         pseudoState = PseudoNone;
       
   618         return;
       
   619     }
       
   620     
       
   621     AtomicString attr;
       
   622     if (e->isHTMLElement())
       
   623         attr = e->getAttribute(hrefAttr);
       
   624 #if ENABLE(SVG)
       
   625     else if (e->isSVGElement())
       
   626         attr = e->getAttribute(XLinkNames::hrefAttr);
       
   627 #endif
       
   628     if (attr.isNull()) {
       
   629         pseudoState = PseudoNone;
       
   630         return;
       
   631     }
       
   632     
       
   633     if (!checkVisited) {
       
   634         pseudoState = PseudoAnyLink;
       
   635         return;
       
   636     }
       
   637     
       
   638     DeprecatedConstString cu(reinterpret_cast<const DeprecatedChar*>(attr.characters()), attr.length());
       
   639     DeprecatedString u = cu.string();
       
   640     if (!u.contains("://")) {
       
   641         if (u[0] == '/')
       
   642             u.prepend(currentEncodedURL->host);
       
   643         else if (u[0] == '#')
       
   644             u.prepend(currentEncodedURL->file);
       
   645         else
       
   646             u.prepend(currentEncodedURL->path);
       
   647         cleanpath(u);
       
   648     }
       
   649     pseudoState = historyContains(u) ? PseudoVisited : PseudoLink;
       
   650 }
       
   651 
       
   652 #ifdef STYLE_SHARING_STATS
       
   653 static int fraction = 0;
       
   654 static int total = 0;
       
   655 #endif
       
   656 
       
   657 static const unsigned cStyleSearchThreshold = 10;
       
   658 
       
   659 Node* CSSStyleSelector::locateCousinList(Element* parent, unsigned depth)
       
   660 {
       
   661     if (parent && parent->isStyledElement()) {
       
   662         StyledElement* p = static_cast<StyledElement*>(parent);
       
   663         if (!p->inlineStyleDecl() && !p->hasID()) {
       
   664             Node* r = p->previousSibling();
       
   665             unsigned subcount = 0;
       
   666             RenderStyle* st = p->renderStyle();
       
   667             while (r) {
       
   668                 if (r->renderStyle() == st)
       
   669                     return r->lastChild();
       
   670                 if (subcount++ == cStyleSearchThreshold)
       
   671                     return 0;
       
   672                 r = r->previousSibling();
       
   673             }
       
   674             if (!r && depth < cStyleSearchThreshold)
       
   675                 r = locateCousinList(static_cast<Element*>(parent->parentNode()), depth + 1);
       
   676             while (r) {
       
   677                 if (r->renderStyle() == st)
       
   678                     return r->lastChild();
       
   679                 if (subcount++ == cStyleSearchThreshold)
       
   680                     return 0;
       
   681                 r = r->previousSibling();
       
   682             }
       
   683         }
       
   684     }
       
   685     return 0;
       
   686 }
       
   687 
       
   688 bool CSSStyleSelector::canShareStyleWithElement(Node* n)
       
   689 {
       
   690     if (n->isStyledElement()) {
       
   691         StyledElement* s = static_cast<StyledElement*>(n);
       
   692         RenderStyle* style = s->renderStyle();
       
   693         if (style && !style->unique() &&
       
   694             (s->tagQName() == element->tagQName()) && !s->hasID() &&
       
   695             (s->hasClass() == element->hasClass()) && !s->inlineStyleDecl() &&
       
   696             (s->hasMappedAttributes() == styledElement->hasMappedAttributes()) &&
       
   697             (s->isLink() == element->isLink()) && 
       
   698             !style->affectedByAttributeSelectors() &&
       
   699             (s->hovered() == element->hovered()) &&
       
   700             (s->active() == element->active()) &&
       
   701             (s->focused() == element->focused()) &&
       
   702             (s != s->document()->getCSSTarget() && element != element->document()->getCSSTarget()) &&
       
   703             (s->getAttribute(typeAttr) == element->getAttribute(typeAttr)) &&
       
   704             (s->getAttribute(readonlyAttr) == element->getAttribute(readonlyAttr))) {
       
   705             bool isControl = s->isControl();
       
   706             if (isControl != element->isControl())
       
   707                 return false;
       
   708             if (isControl && (s->isEnabled() != element->isEnabled()) ||
       
   709                              (s->isIndeterminate() != element->isIndeterminate()) ||
       
   710                              (s->isChecked() != element->isChecked()))
       
   711                 return false;
       
   712             
       
   713             bool classesMatch = true;
       
   714             if (s->hasClass()) {
       
   715                 const AtomicString& class1 = element->getAttribute(classAttr);
       
   716                 const AtomicString& class2 = s->getAttribute(classAttr);
       
   717                 classesMatch = (class1 == class2);
       
   718             }
       
   719             
       
   720             if (classesMatch) {
       
   721                 bool mappedAttrsMatch = true;
       
   722                 if (s->hasMappedAttributes())
       
   723                     mappedAttrsMatch = s->mappedAttributes()->mapsEquivalent(styledElement->mappedAttributes());
       
   724                 if (mappedAttrsMatch) {
       
   725                     bool linksMatch = true;
       
   726                     if (s->isLink()) {
       
   727                         // We need to check to see if the visited state matches.
       
   728                         Color linkColor = element->document()->linkColor();
       
   729                         Color visitedColor = element->document()->visitedLinkColor();
       
   730                         if (pseudoState == PseudoUnknown)
       
   731                             checkPseudoState(element, style->pseudoState() != PseudoAnyLink || linkColor != visitedColor);
       
   732                         linksMatch = (pseudoState == style->pseudoState());
       
   733                     }
       
   734                     
       
   735                     if (linksMatch)
       
   736                         return true;
       
   737                 }
       
   738             }
       
   739         }
       
   740     }
       
   741     return false;
       
   742 }
       
   743 
       
   744 RenderStyle* CSSStyleSelector::locateSharedStyle()
       
   745 {
       
   746     if (styledElement && !styledElement->inlineStyleDecl() && !styledElement->hasID() &&
       
   747         !styledElement->document()->usesSiblingRules()) {
       
   748         // Check previous siblings.
       
   749         unsigned count = 0;
       
   750         Node* n;
       
   751         for (n = element->previousSibling(); n && !n->isElementNode(); n = n->previousSibling());
       
   752         while (n) {
       
   753             if (canShareStyleWithElement(n))
       
   754                 return n->renderStyle();
       
   755             if (count++ == cStyleSearchThreshold)
       
   756                 return 0;
       
   757             for (n = n->previousSibling(); n && !n->isElementNode(); n = n->previousSibling());
       
   758         }
       
   759         if (!n) 
       
   760             n = locateCousinList(static_cast<Element*>(element->parentNode()));
       
   761         while (n) {
       
   762             if (canShareStyleWithElement(n))
       
   763                 return n->renderStyle();
       
   764             if (count++ == cStyleSearchThreshold)
       
   765                 return 0;
       
   766             for (n = n->previousSibling(); n && !n->isElementNode(); n = n->previousSibling());
       
   767         }        
       
   768     }
       
   769     return 0;
       
   770 }
       
   771 
       
   772 void CSSStyleSelector::matchUARules(int& firstUARule, int& lastUARule)
       
   773 {
       
   774     // First we match rules from the user agent sheet.
       
   775     CSSRuleSet* userAgentStyleSheet = m_medium->mediaTypeMatchSpecific("print")
       
   776         ? defaultPrintStyle : defaultStyle;
       
   777     matchRules(userAgentStyleSheet, firstUARule, lastUARule);
       
   778 
       
   779     // In quirks mode, we match rules from the quirks user agent sheet.
       
   780     if (!strictParsing)
       
   781         matchRules(defaultQuirksStyle, firstUARule, lastUARule);
       
   782         
       
   783     // If we're in view source mode, then we match rules from the view source style sheet.
       
   784     if (m_document->frame() && m_document->frame()->inViewSourceMode())
       
   785         matchRules(defaultViewSourceStyle, firstUARule, lastUARule);
       
   786 }
       
   787 
       
   788 // If resolveForRootDefault is true, style based on user agent style sheet only. This is used in media queries, where
       
   789 // relative units are interpreted according to document root element style, styled only with UA stylesheet
       
   790 
       
   791 RenderStyle* CSSStyleSelector::styleForElement(Element* e, RenderStyle* defaultParent, bool allowSharing, bool resolveForRootDefault)
       
   792 {
       
   793     // Once an element has a renderer, we don't try to destroy it, since otherwise the renderer
       
   794     // will vanish if a style recalc happens during loading.
       
   795     if (allowSharing && !e->document()->haveStylesheetsLoaded() && !e->renderer()) {
       
   796         if (!styleNotYetAvailable) {
       
   797             styleNotYetAvailable = ::new RenderStyle;
       
   798             styleNotYetAvailable->ref();
       
   799             styleNotYetAvailable->setDisplay(NONE);
       
   800             styleNotYetAvailable->font().update();
       
   801         }
       
   802         styleNotYetAvailable->ref();
       
   803         e->document()->setHasNodesWithPlaceholderStyle();
       
   804         return styleNotYetAvailable;
       
   805     }
       
   806     
       
   807     initElementAndPseudoState(e);
       
   808     if (allowSharing) {
       
   809         style = locateSharedStyle();
       
   810 #ifdef STYLE_SHARING_STATS
       
   811         fraction += style != 0;
       
   812         total++;
       
   813         printf("Sharing %d out of %d\n", fraction, total);
       
   814 #endif
       
   815         if (style) {
       
   816             style->ref();
       
   817             return style;
       
   818         }
       
   819     }
       
   820     initForStyleResolve(e, defaultParent);
       
   821 
       
   822     if (resolveForRootDefault) {
       
   823         style = ::new RenderStyle();
       
   824         // don't ref, because we want to delete this, but we cannot unref it
       
   825     } else {
       
   826         style = new (e->document()->renderArena()) RenderStyle();
       
   827         style->ref();
       
   828     }
       
   829     if (parentStyle)
       
   830         style->inheritFrom(parentStyle);
       
   831     else
       
   832         parentStyle = style;
       
   833 
       
   834     int firstUARule = -1, lastUARule = -1;
       
   835     int firstUserRule = -1, lastUserRule = -1;
       
   836     int firstAuthorRule = -1, lastAuthorRule = -1;
       
   837     matchUARules(firstUARule, lastUARule);
       
   838 
       
   839     if (!resolveForRootDefault) {
       
   840         // 4. Now we check user sheet rules.
       
   841         matchRules(m_userStyle, firstUserRule, lastUserRule);
       
   842 
       
   843         // 5. Now check author rules, beginning first with presentational attributes
       
   844         // mapped from HTML.
       
   845         if (styledElement) {
       
   846             // Ask if the HTML element has mapped attributes.
       
   847             if (styledElement->hasMappedAttributes()) {
       
   848                 // Walk our attribute list and add in each decl.
       
   849                 const NamedMappedAttrMap* map = styledElement->mappedAttributes();
       
   850                 for (unsigned i = 0; i < map->length(); i++) {
       
   851                     MappedAttribute* attr = map->attributeItem(i);
       
   852                     if (attr->decl()) {
       
   853                         lastAuthorRule = m_matchedDecls.size();
       
   854                         if (firstAuthorRule == -1)
       
   855                             firstAuthorRule = lastAuthorRule;
       
   856                         addMatchedDeclaration(attr->decl());
       
   857                     }
       
   858                 }
       
   859             }
       
   860 
       
   861             // Now we check additional mapped declarations.
       
   862             // Tables and table cells share an additional mapped rule that must be applied
       
   863             // after all attributes, since their mapped style depends on the values of multiple attributes.
       
   864             CSSMutableStyleDeclaration* attributeDecl = styledElement->additionalAttributeStyleDecl();
       
   865             if (attributeDecl) {
       
   866                 lastAuthorRule = m_matchedDecls.size();
       
   867                 if (firstAuthorRule == -1)
       
   868                     firstAuthorRule = lastAuthorRule;
       
   869                 addMatchedDeclaration(attributeDecl);
       
   870             }
       
   871         }
       
   872     
       
   873         // 6. Check the rules in author sheets next.
       
   874         matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);
       
   875     
       
   876         // 7. Now check our inline style attribute.
       
   877         if (styledElement) {
       
   878             CSSMutableStyleDeclaration* inlineDecl = styledElement->inlineStyleDecl();
       
   879             if (inlineDecl) {
       
   880                 lastAuthorRule = m_matchedDecls.size();
       
   881                 if (firstAuthorRule == -1)
       
   882                     firstAuthorRule = lastAuthorRule;
       
   883                 addMatchedDeclaration(inlineDecl);
       
   884             }
       
   885         }
       
   886     }
       
   887 
       
   888     // Now we have all of the matched rules in the appropriate order.  Walk the rules and apply
       
   889     // high-priority properties first, i.e., those properties that other properties depend on.
       
   890     // The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
       
   891     // and (4) normal important.
       
   892     m_lineHeightValue = 0;
       
   893     applyDeclarations(true, false, 0, m_matchedDecls.size() - 1);
       
   894     if (!resolveForRootDefault) {
       
   895         applyDeclarations(true, true, firstAuthorRule, lastAuthorRule);
       
   896         applyDeclarations(true, true, firstUserRule, lastUserRule);
       
   897     }
       
   898     applyDeclarations(true, true, firstUARule, lastUARule);
       
   899     
       
   900     // If our font got dirtied, go ahead and update it now.
       
   901     if (fontDirty)
       
   902         updateFont();
       
   903 
       
   904     // Line-height is set when we are sure we decided on the font-size
       
   905     if (m_lineHeightValue)
       
   906         applyProperty(CSS_PROP_LINE_HEIGHT, m_lineHeightValue);
       
   907 
       
   908     // Now do the normal priority UA properties.
       
   909     applyDeclarations(false, false, firstUARule, lastUARule);
       
   910     
       
   911     // Cache our border and background so that we can examine them later.
       
   912     cacheBorderAndBackground();
       
   913     
       
   914     // Now do the author and user normal priority properties and all the !important properties.
       
   915     if (!resolveForRootDefault) {
       
   916         applyDeclarations(false, false, lastUARule + 1, m_matchedDecls.size() - 1);
       
   917         applyDeclarations(false, true, firstAuthorRule, lastAuthorRule);
       
   918         applyDeclarations(false, true, firstUserRule, lastUserRule);
       
   919     }
       
   920     applyDeclarations(false, true, firstUARule, lastUARule);
       
   921     
       
   922     // If our font got dirtied by one of the non-essential font props, 
       
   923     // go ahead and update it a second time.
       
   924     if (fontDirty)
       
   925         updateFont();
       
   926     
       
   927     // Clean up our style object's display and text decorations (among other fixups).
       
   928     adjustRenderStyle(style, e);
       
   929 
       
   930     // If we are a link, cache the determined pseudo-state.
       
   931     if (e->isLink())
       
   932         style->setPseudoState(pseudoState);
       
   933 
       
   934     // If we have first-letter pseudo style, do not share this style
       
   935     if (style->hasPseudoStyle(RenderStyle::FIRST_LETTER))
       
   936         style->setUnique();
       
   937 
       
   938     // Now return the style.
       
   939     return style;
       
   940 }
       
   941 
       
   942 RenderStyle* CSSStyleSelector::pseudoStyleForElement(RenderStyle::PseudoId pseudo, Element* e, RenderStyle* parentStyle)
       
   943 {
       
   944     if (!e)
       
   945         return 0;
       
   946 
       
   947     initElementAndPseudoState(e);
       
   948     initForStyleResolve(e, parentStyle);
       
   949     pseudoStyle = pseudo;
       
   950     
       
   951     // Since we don't use pseudo-elements in any of our quirk/print user agent rules, don't waste time walking
       
   952     // those rules.
       
   953     
       
   954     // Check UA, user and author rules.
       
   955     int firstUARule = -1, lastUARule = -1, firstUserRule = -1, lastUserRule = -1, firstAuthorRule = -1, lastAuthorRule = -1;
       
   956     matchUARules(firstUARule, lastUARule);
       
   957     matchRules(m_userStyle, firstUserRule, lastUserRule);
       
   958     matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);
       
   959     
       
   960     if (m_matchedDecls.isEmpty())
       
   961         return 0;
       
   962     
       
   963     style = new (e->document()->renderArena()) RenderStyle();
       
   964     style->ref();
       
   965     if (parentStyle)
       
   966         style->inheritFrom(parentStyle);
       
   967     else
       
   968         parentStyle = style;
       
   969     style->noninherited_flags._styleType = pseudoStyle;
       
   970     
       
   971     m_lineHeightValue = 0;
       
   972     // High-priority properties.
       
   973     applyDeclarations(true, false, 0, m_matchedDecls.size() - 1);
       
   974     applyDeclarations(true, true, firstAuthorRule, lastAuthorRule);
       
   975     applyDeclarations(true, true, firstUserRule, lastUserRule);
       
   976     applyDeclarations(true, true, firstUARule, lastUARule);
       
   977     
       
   978     // If our font got dirtied, go ahead and update it now.
       
   979     if (fontDirty)
       
   980         updateFont();
       
   981 
       
   982     // Line-height is set when we are sure we decided on the font-size
       
   983     if (m_lineHeightValue)
       
   984         applyProperty(CSS_PROP_LINE_HEIGHT, m_lineHeightValue);
       
   985     
       
   986     // Now do the normal priority properties.
       
   987     applyDeclarations(false, false, firstUARule, lastUARule);
       
   988     
       
   989     // Cache our border and background so that we can examine them later.
       
   990     cacheBorderAndBackground();
       
   991     
       
   992     applyDeclarations(false, false, lastUARule + 1, m_matchedDecls.size() - 1);
       
   993     applyDeclarations(false, true, firstAuthorRule, lastAuthorRule);
       
   994     applyDeclarations(false, true, firstUserRule, lastUserRule);
       
   995     applyDeclarations(false, true, firstUARule, lastUARule);
       
   996     
       
   997     // If our font got dirtied by one of the non-essential font props, 
       
   998     // go ahead and update it a second time.
       
   999     if (fontDirty)
       
  1000         updateFont();
       
  1001     // Clean up our style object's display and text decorations (among other fixups).
       
  1002     adjustRenderStyle(style, 0);
       
  1003 
       
  1004     // Now return the style.
       
  1005     return style;
       
  1006 }
       
  1007 
       
  1008 static void addIntrinsicMargins(RenderStyle* style)
       
  1009 {
       
  1010     // Intrinsic margin value.
       
  1011     const int intrinsicMargin = 2;
       
  1012     
       
  1013     // FIXME: Using width/height alone and not also dealing with min-width/max-width is flawed.
       
  1014     // FIXME: Using "quirk" to decide the margin wasn't set is kind of lame.
       
  1015     if (style->width().isIntrinsicOrAuto()) {
       
  1016         if (style->marginLeft().quirk())
       
  1017             style->setMarginLeft(Length(intrinsicMargin, Fixed));
       
  1018         if (style->marginRight().quirk())
       
  1019             style->setMarginRight(Length(intrinsicMargin, Fixed));
       
  1020     }
       
  1021 
       
  1022     if (style->height().isAuto()) {
       
  1023         if (style->marginTop().quirk())
       
  1024             style->setMarginTop(Length(intrinsicMargin, Fixed));
       
  1025         if (style->marginBottom().quirk())
       
  1026             style->setMarginBottom(Length(intrinsicMargin, Fixed));
       
  1027     }
       
  1028 }
       
  1029 
       
  1030 void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, Element *e)
       
  1031 {
       
  1032     // Cache our original display.
       
  1033     style->setOriginalDisplay(style->display());
       
  1034 
       
  1035     if (style->display() != NONE) {
       
  1036         // If we have a <td> that specifies a float property, in quirks mode we just drop the float
       
  1037         // property.
       
  1038         // Sites also commonly use display:inline/block on <td>s and <table>s.  In quirks mode we force
       
  1039         // these tags to retain their display types.
       
  1040         if (!strictParsing && e) {
       
  1041             if (e->hasTagName(tdTag)) {
       
  1042                 style->setDisplay(TABLE_CELL);
       
  1043                 style->setFloating(FNONE);
       
  1044             }
       
  1045             else if (e->hasTagName(tableTag))
       
  1046                 style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE);
       
  1047         }
       
  1048 
       
  1049         // Tables never support the -webkit-* values for text-align and will reset back to the default.
       
  1050         if (e && e->hasTagName(tableTag) && (style->textAlign() == WEBKIT_LEFT || style->textAlign() == WEBKIT_CENTER || style->textAlign() == WEBKIT_RIGHT))
       
  1051             style->setTextAlign(TAAUTO);
       
  1052 
       
  1053         // Frames and framesets never honor position:relative or position:absolute.  This is necessary to
       
  1054         // fix a crash where a site tries to position these objects.  They also never honor display.
       
  1055         if (e && (e->hasTagName(frameTag) || e->hasTagName(framesetTag))) {
       
  1056             style->setPosition(StaticPosition);
       
  1057             style->setDisplay(BLOCK);
       
  1058         }
       
  1059 
       
  1060         // Table headers with a text-align of auto will change the text-align to center.
       
  1061         if (e && e->hasTagName(thTag) && style->textAlign() == TAAUTO)
       
  1062             style->setTextAlign(CENTER);
       
  1063         
       
  1064         // Mutate the display to BLOCK or TABLE for certain cases, e.g., if someone attempts to
       
  1065         // position or float an inline, compact, or run-in.  Cache the original display, since it
       
  1066         // may be needed for positioned elements that have to compute their static normal flow
       
  1067         // positions.  We also force inline-level roots to be block-level.
       
  1068         if (style->display() != BLOCK && style->display() != TABLE && style->display() != BOX &&
       
  1069             (style->position() == AbsolutePosition || style->position() == FixedPosition || style->floating() != FNONE ||
       
  1070              (e && e->document()->documentElement() == e))) {
       
  1071             if (style->display() == INLINE_TABLE)
       
  1072                 style->setDisplay(TABLE);
       
  1073             else if (style->display() == INLINE_BOX)
       
  1074                 style->setDisplay(BOX);
       
  1075             else if (style->display() == LIST_ITEM) {
       
  1076                 // It is a WinIE bug that floated list items lose their bullets, so we'll emulate the quirk,
       
  1077                 // but only in quirks mode.
       
  1078                 if (!strictParsing && style->floating() != FNONE)
       
  1079                     style->setDisplay(BLOCK);
       
  1080             }
       
  1081             else
       
  1082                 style->setDisplay(BLOCK);
       
  1083         }
       
  1084         
       
  1085         // After performing the display mutation, check table rows.  We do not honor position:relative on
       
  1086         // table rows or cells.  This has been established in CSS2.1 (and caused a crash in containingBlock()
       
  1087         // on some sites).
       
  1088         if ((style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW_GROUP ||
       
  1089              style->display() == TABLE_FOOTER_GROUP || style->display() == TABLE_ROW || style->display() == TABLE_CELL) &&
       
  1090              style->position() == RelativePosition)
       
  1091             style->setPosition(StaticPosition);
       
  1092     }
       
  1093 
       
  1094     // Make sure our z-index value is only applied if the object is positioned,
       
  1095     // relatively positioned, or transparent.
       
  1096     if (style->position() == StaticPosition && style->opacity() == 1.0f)
       
  1097         style->setHasAutoZIndex();
       
  1098 
       
  1099     // Auto z-index becomes 0 for the root element and transparent objects.  This prevents
       
  1100     // cases where objects that should be blended as a single unit end up with a non-transparent
       
  1101     // object wedged in between them.
       
  1102     if (style->hasAutoZIndex() && ((e && e->document()->documentElement() == e) || style->opacity() < 1.0f))
       
  1103         style->setZIndex(0);
       
  1104     
       
  1105     // Button, legend, input, select and textarea all consider width values of 'auto' to be 'intrinsic'.
       
  1106     // This will be important when we use block flows for all form controls.
       
  1107     if (e && (e->hasTagName(legendTag) || e->hasTagName(buttonTag) || e->hasTagName(inputTag) ||
       
  1108               e->hasTagName(selectTag) || e->hasTagName(textareaTag))) {
       
  1109         if (style->width().isAuto())
       
  1110             style->setWidth(Length(Intrinsic));
       
  1111     }
       
  1112 
       
  1113     // Finally update our text decorations in effect, but don't allow text-decoration to percolate through
       
  1114     // tables, inline blocks, inline tables, or run-ins.
       
  1115     if (style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN
       
  1116         || style->display() == INLINE_BLOCK || style->display() == INLINE_BOX)
       
  1117         style->setTextDecorationsInEffect(style->textDecoration());
       
  1118     else
       
  1119         style->addToTextDecorationsInEffect(style->textDecoration());
       
  1120     
       
  1121     // If either overflow value is not visible, change to auto.
       
  1122     if (style->overflowX() == OMARQUEE && style->overflowY() != OMARQUEE)
       
  1123         style->setOverflowY(OMARQUEE);
       
  1124     else if (style->overflowY() == OMARQUEE && style->overflowX() != OMARQUEE)
       
  1125         style->setOverflowX(OMARQUEE);
       
  1126     else if (style->overflowX() == OVISIBLE && style->overflowY() != OVISIBLE)
       
  1127         style->setOverflowX(OAUTO);
       
  1128     else if (style->overflowY() == OVISIBLE && style->overflowX() != OVISIBLE)
       
  1129         style->setOverflowY(OAUTO);
       
  1130 
       
  1131     // Table rows, sections and the table itself will support overflow:hidden and will ignore scroll/auto.
       
  1132     // FIXME: Eventually table sections will support auto and scroll.
       
  1133     if (style->display() == TABLE || style->display() == INLINE_TABLE ||
       
  1134         style->display() == TABLE_ROW_GROUP || style->display() == TABLE_ROW) {
       
  1135         if (style->overflowX() != OVISIBLE && style->overflowX() != OHIDDEN) 
       
  1136             style->setOverflowX(OVISIBLE);
       
  1137         if (style->overflowY() != OVISIBLE && style->overflowY() != OHIDDEN) 
       
  1138             style->setOverflowY(OVISIBLE);
       
  1139     }
       
  1140 
       
  1141     // Cull out any useless layers and also repeat patterns into additional layers.
       
  1142     style->adjustBackgroundLayers();
       
  1143 
       
  1144     // Important: Intrinsic margins get added to controls before the theme has adjusted the style, since the theme will
       
  1145     // alter fonts and heights/widths.
       
  1146     if (e && e->isControl() && style->fontSize() >= 11) {
       
  1147         // Don't apply intrinsic margins to image buttons.  The designer knows how big the images are,
       
  1148         // so we have to treat all image buttons as though they were explicitly sized.
       
  1149         if (!e->hasTagName(inputTag) || static_cast<HTMLInputElement*>(e)->inputType() != HTMLInputElement::IMAGE)
       
  1150             addIntrinsicMargins(style);
       
  1151     }
       
  1152 
       
  1153     // Let the theme also have a crack at adjusting the style.
       
  1154     if (style->hasAppearance())
       
  1155         theme()->adjustStyle(this, style, e, m_hasUAAppearance, m_borderData, m_backgroundData, m_backgroundColor);
       
  1156 
       
  1157 #if ENABLE(SVG)
       
  1158     if (e && e->isSVGElement()) {
       
  1159         // Spec: http://www.w3.org/TR/SVG/masking.html#OverflowProperty
       
  1160         if (style->overflowY() == OSCROLL)
       
  1161             style->setOverflowY(OHIDDEN);
       
  1162         else if (style->overflowY() == OAUTO)
       
  1163             style->setOverflowY(OVISIBLE);
       
  1164 
       
  1165         if (style->overflowX() == OSCROLL)
       
  1166             style->setOverflowX(OHIDDEN);
       
  1167         else if (style->overflowX() == OAUTO)
       
  1168             style->setOverflowX(OVISIBLE);
       
  1169 
       
  1170         // Only the root <svg> element in an SVG document fragment tree honors css position
       
  1171         if (!(e->hasTagName(SVGNames::svgTag) && e->parentNode() && !e->parentNode()->isSVGElement()))
       
  1172             style->setPosition(RenderStyle::initialPosition());
       
  1173     }
       
  1174 #endif
       
  1175 }
       
  1176 
       
  1177 void CSSStyleSelector::updateFont()
       
  1178 {
       
  1179     checkForTextSizeAdjust();
       
  1180     checkForGenericFamilyChange(style, parentStyle);
       
  1181     style->font().update();
       
  1182     fontDirty = false;
       
  1183 }
       
  1184 
       
  1185 void CSSStyleSelector::cacheBorderAndBackground()
       
  1186 {
       
  1187     m_hasUAAppearance = style->hasAppearance();
       
  1188     if (m_hasUAAppearance) {
       
  1189         m_borderData = style->border();
       
  1190         m_backgroundData = *style->backgroundLayers();
       
  1191         m_backgroundColor = style->backgroundColor();
       
  1192     }
       
  1193 }
       
  1194 
       
  1195 RefPtr<CSSRuleList> CSSStyleSelector::styleRulesForElement(Element* e, bool authorOnly)
       
  1196 {
       
  1197     if (!e || !e->document()->haveStylesheetsLoaded())
       
  1198         return 0;
       
  1199 
       
  1200     m_collectRulesOnly = true;
       
  1201     
       
  1202     initElementAndPseudoState(e);
       
  1203     initForStyleResolve(e, 0);
       
  1204     
       
  1205     if (!authorOnly) {
       
  1206         int firstUARule = -1, lastUARule = -1;
       
  1207         // First we match rules from the user agent sheet.
       
  1208         matchUARules(firstUARule, lastUARule);
       
  1209 
       
  1210         // Now we check user sheet rules.
       
  1211         int firstUserRule = -1, lastUserRule = -1;
       
  1212         matchRules(m_userStyle, firstUserRule, lastUserRule);
       
  1213     }
       
  1214 
       
  1215     // Check the rules in author sheets.
       
  1216     int firstAuthorRule = -1, lastAuthorRule = -1;
       
  1217     matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);
       
  1218     
       
  1219     m_collectRulesOnly = false;
       
  1220     
       
  1221     return m_ruleList;
       
  1222 }
       
  1223 
       
  1224 RefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element* e, StringImpl* pseudoStyle, bool authorOnly)
       
  1225 {
       
  1226     // FIXME: Implement this.
       
  1227     return 0;
       
  1228 }
       
  1229 
       
  1230 static bool subject;
       
  1231 
       
  1232 bool CSSStyleSelector::checkSelector(CSSSelector* sel, Element *e)
       
  1233 {
       
  1234     dynamicPseudo = RenderStyle::NOPSEUDO;
       
  1235     
       
  1236     Node *n = e;
       
  1237 
       
  1238     // we have the subject part of the selector
       
  1239     subject = true;
       
  1240 
       
  1241     // We track whether or not the rule contains only :hover and :active in a simple selector. If
       
  1242     // so, we can't allow that to apply to every element on the page.  We assume the author intended
       
  1243     // to apply the rules only to links.
       
  1244     bool onlyHoverActive = (!sel->hasTag() &&
       
  1245                             (sel->m_match == CSSSelector::PseudoClass &&
       
  1246                               (sel->pseudoType() == CSSSelector::PseudoHover ||
       
  1247                                sel->pseudoType() == CSSSelector::PseudoActive)));
       
  1248     bool affectedByHover = style ? style->affectedByHoverRules() : false;
       
  1249     bool affectedByActive = style ? style->affectedByActiveRules() : false;
       
  1250     bool havePseudo = pseudoStyle != RenderStyle::NOPSEUDO;
       
  1251     
       
  1252     // first selector has to match
       
  1253     if (!checkOneSelector(sel, e))
       
  1254         return false;
       
  1255 
       
  1256     // check the subselectors
       
  1257     CSSSelector::Relation relation = sel->relation();
       
  1258     while((sel = sel->m_tagHistory)) {
       
  1259         if (!n->isElementNode())
       
  1260             return false;
       
  1261         if (relation != CSSSelector::SubSelector) {
       
  1262             subject = false;
       
  1263             if (havePseudo && dynamicPseudo != pseudoStyle)
       
  1264                 return false;
       
  1265         }
       
  1266         
       
  1267         switch(relation)
       
  1268         {
       
  1269         case CSSSelector::Descendant:
       
  1270             // FIXME: This match needs to know how to backtrack and be non-deterministic.
       
  1271             do {
       
  1272                 n = n->parentNode();
       
  1273                 if (!n || !n->isElementNode())
       
  1274                     return false;
       
  1275             } while (!checkOneSelector(sel, static_cast<Element*>(n)));
       
  1276             break;
       
  1277         case CSSSelector::Child:
       
  1278         {
       
  1279             n = n->parentNode();
       
  1280             if (!n || !n->isElementNode())
       
  1281                 return false;
       
  1282             if (!checkOneSelector(sel, static_cast<Element*>(n)))
       
  1283                 return false;
       
  1284             break;
       
  1285         }
       
  1286         case CSSSelector::DirectAdjacent:
       
  1287         {
       
  1288             n = n->previousSibling();
       
  1289             while (n && !n->isElementNode())
       
  1290                 n = n->previousSibling();
       
  1291             if (!n)
       
  1292                 return false;
       
  1293             if (!checkOneSelector(sel, static_cast<Element*>(n)))
       
  1294                 return false;
       
  1295             break;
       
  1296         }
       
  1297         case CSSSelector::IndirectAdjacent:
       
  1298             // FIXME: This match needs to know how to backtrack and be non-deterministic.
       
  1299             do {
       
  1300                 n = n->previousSibling();
       
  1301                 while (n && !n->isElementNode())
       
  1302                     n = n->previousSibling();
       
  1303                 if (!n)
       
  1304                     return false;
       
  1305             } while (!checkOneSelector(sel, static_cast<Element*>(n)));
       
  1306             break;
       
  1307        case CSSSelector::SubSelector:
       
  1308        {
       
  1309             if (onlyHoverActive)
       
  1310                 onlyHoverActive = (sel->m_match == CSSSelector::PseudoClass &&
       
  1311                                    (sel->pseudoType() == CSSSelector::PseudoHover ||
       
  1312                                     sel->pseudoType() == CSSSelector::PseudoActive));
       
  1313             
       
  1314             Element *elem = static_cast<Element*>(n);
       
  1315             // a selector is invalid if something follows :first-xxx
       
  1316             if (elem == element && dynamicPseudo != RenderStyle::NOPSEUDO)
       
  1317                 return false;
       
  1318             if (!checkOneSelector(sel, elem, true))
       
  1319                 return false;
       
  1320             break;
       
  1321         }
       
  1322         }
       
  1323         relation = sel->relation();
       
  1324     }
       
  1325 
       
  1326     if (subject && havePseudo && dynamicPseudo != pseudoStyle)
       
  1327         return false;
       
  1328     
       
  1329     // disallow *:hover, *:active, and *:hover:active except for links
       
  1330     if (!strictParsing && onlyHoverActive && subject) {
       
  1331         if (pseudoState == PseudoUnknown)
       
  1332             checkPseudoState(e);
       
  1333 
       
  1334         if (pseudoState == PseudoNone) {
       
  1335             if (!affectedByHover && style->affectedByHoverRules())
       
  1336                 style->setAffectedByHoverRules(false);
       
  1337             if (!affectedByActive && style->affectedByActiveRules())
       
  1338                 style->setAffectedByActiveRules(false);
       
  1339             return false;
       
  1340         }
       
  1341     }
       
  1342 
       
  1343     return true;
       
  1344 }
       
  1345 
       
  1346 bool CSSStyleSelector::checkOneSelector(CSSSelector* sel, Element* e, bool isSubSelector)
       
  1347 {
       
  1348     if(!e)
       
  1349         return false;
       
  1350 
       
  1351     if (sel->hasTag()) {
       
  1352         const AtomicString& localName = e->localName();
       
  1353         const AtomicString& ns = e->namespaceURI();
       
  1354         const AtomicString& selLocalName = sel->m_tag.localName();
       
  1355         const AtomicString& selNS = sel->m_tag.namespaceURI();
       
  1356     
       
  1357         if ((selLocalName != starAtom && localName != selLocalName) ||
       
  1358             (selNS != starAtom && ns != selNS))
       
  1359             return false;
       
  1360     }
       
  1361 
       
  1362     if (sel->hasAttribute()) {
       
  1363         if (sel->m_match == CSSSelector::Class) {
       
  1364             if (!e->hasClass())
       
  1365                 return false;
       
  1366             for (const AtomicStringList* c = e->getClassList(); c; c = c->next())
       
  1367                 if (c->string() == sel->m_value)
       
  1368                     return true;
       
  1369             return false;
       
  1370         }
       
  1371         else if (sel->m_match == CSSSelector::Id)
       
  1372             return e->hasID() && e->getIDAttribute() == sel->m_value;
       
  1373         else if (style && (e != element || !styledElement || (!styledElement->isMappedAttribute(sel->m_attr) && sel->m_attr != typeAttr && sel->m_attr != readonlyAttr))) {
       
  1374             style->setAffectedByAttributeSelectors(); // Special-case the "type" and "readonly" attributes so input form controls can share style.
       
  1375             m_selectorAttrs.add(sel->m_attr.localName().impl());
       
  1376         }
       
  1377 
       
  1378         const AtomicString& value = e->getAttribute(sel->m_attr);
       
  1379         if (value.isNull())
       
  1380             return false; // attribute is not set
       
  1381 
       
  1382         switch(sel->m_match) {
       
  1383         case CSSSelector::Exact:
       
  1384             if ((isXMLDoc && sel->m_value != value) || (!isXMLDoc && !equalIgnoringCase(sel->m_value, value)))
       
  1385                 return false;
       
  1386             break;
       
  1387         case CSSSelector::List:
       
  1388         {
       
  1389             // The selector's value can't contain a space, or it's totally bogus.
       
  1390             if (sel->m_value.contains(' '))
       
  1391                 return false;
       
  1392 
       
  1393             int startSearchAt = 0;
       
  1394             while (true) {
       
  1395                 int foundPos = value.find(sel->m_value, startSearchAt, isXMLDoc);
       
  1396                 if (foundPos == -1)
       
  1397                     return false;
       
  1398                 if (foundPos == 0 || value[foundPos-1] == ' ') {
       
  1399                     unsigned endStr = foundPos + sel->m_value.length();
       
  1400                     if (endStr == value.length() || value[endStr] == ' ')
       
  1401                         break; // We found a match.
       
  1402                 }
       
  1403                 
       
  1404                 // No match.  Keep looking.
       
  1405                 startSearchAt = foundPos + 1;
       
  1406             }
       
  1407             break;
       
  1408         }
       
  1409         case CSSSelector::Contain:
       
  1410             if (!value.contains(sel->m_value, isXMLDoc))
       
  1411                 return false;
       
  1412             break;
       
  1413         case CSSSelector::Begin:
       
  1414             if (!value.startsWith(sel->m_value, isXMLDoc))
       
  1415                 return false;
       
  1416             break;
       
  1417         case CSSSelector::End:
       
  1418             if (!value.endsWith(sel->m_value, isXMLDoc))
       
  1419                 return false;
       
  1420             break;
       
  1421         case CSSSelector::Hyphen:
       
  1422             if (value.length() < sel->m_value.length())
       
  1423                 return false;
       
  1424             if (!value.startsWith(sel->m_value, isXMLDoc))
       
  1425                 return false;
       
  1426             // It they start the same, check for exact match or following '-':
       
  1427             if (value.length() != sel->m_value.length() && value[sel->m_value.length()] != '-')
       
  1428                 return false;
       
  1429             break;
       
  1430         case CSSSelector::PseudoClass:
       
  1431         case CSSSelector::PseudoElement:
       
  1432         default:
       
  1433             break;
       
  1434         }
       
  1435     }
       
  1436     if(sel->m_match == CSSSelector::PseudoClass || sel->m_match == CSSSelector::PseudoElement)
       
  1437     {
       
  1438         // Pseudo elements. We need to check first child here. No dynamic pseudo
       
  1439         // elements for the moment
       
  1440             switch (sel->pseudoType()) {
       
  1441                 // Pseudo classes:
       
  1442             case CSSSelector::PseudoEmpty:
       
  1443                 if (!e->firstChild())
       
  1444                     return true;
       
  1445                 break;
       
  1446             case CSSSelector::PseudoFirstChild: {
       
  1447                 // first-child matches the first child that is an element!
       
  1448                 if (e->parentNode() && e->parentNode()->isElementNode()) {
       
  1449                     Node *n = e->previousSibling();
       
  1450                     while (n && !n->isElementNode())
       
  1451                         n = n->previousSibling();
       
  1452                     if (!n)
       
  1453                         return true;
       
  1454                 }
       
  1455                 break;
       
  1456             }
       
  1457             case CSSSelector::PseudoFirstOfType: {
       
  1458                 // first-of-type matches the first element of its type!
       
  1459                 if (e->parentNode() && e->parentNode()->isElementNode()) {
       
  1460                     const QualifiedName& type = e->tagQName();
       
  1461                     Node *n = e->previousSibling();
       
  1462                     while (n) {
       
  1463                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
       
  1464                             break;
       
  1465                         n = n->previousSibling();
       
  1466                     }
       
  1467                     if (!n)
       
  1468                         return true;
       
  1469                 }
       
  1470                 break;
       
  1471             }
       
  1472             case CSSSelector::PseudoTarget:
       
  1473                 if (e == e->document()->getCSSTarget())
       
  1474                     return true;
       
  1475                 break;
       
  1476             case CSSSelector::PseudoAnyLink:
       
  1477                 if (pseudoState == PseudoUnknown)
       
  1478                     checkPseudoState(e, false);
       
  1479                 if (pseudoState == PseudoAnyLink || pseudoState == PseudoLink || pseudoState == PseudoVisited)
       
  1480                     return true;
       
  1481                 break;
       
  1482             case CSSSelector::PseudoAutofill:
       
  1483                 if (e && e->hasTagName(inputTag))
       
  1484                     return static_cast<HTMLInputElement*>(e)->autofilled();
       
  1485                 break;
       
  1486             case CSSSelector::PseudoLink:
       
  1487                 if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink)
       
  1488                     checkPseudoState(e);
       
  1489                 if (pseudoState == PseudoLink)
       
  1490                     return true;
       
  1491                 break;
       
  1492             case CSSSelector::PseudoVisited:
       
  1493                 if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink)
       
  1494                     checkPseudoState(e);
       
  1495                 if (pseudoState == PseudoVisited)
       
  1496                     return true;
       
  1497                 break;
       
  1498             case CSSSelector::PseudoHover: {
       
  1499                 // If we're in quirks mode, then hover should never match anchors with no
       
  1500                 // href and *:hover should not match anything.  This is important for sites like wsj.com.
       
  1501                 if (strictParsing || isSubSelector || sel->relation() == CSSSelector::SubSelector || (sel->hasTag() && !e->hasTagName(aTag)) || e->isLink()) {
       
  1502                     if (element == e && style)
       
  1503                         style->setAffectedByHoverRules(true);
       
  1504                     if (element != e && e->renderStyle())
       
  1505                         e->renderStyle()->setAffectedByHoverRules(true);
       
  1506                     if (e->hovered())
       
  1507                         return true;
       
  1508                 }
       
  1509                 break;
       
  1510             }
       
  1511             case CSSSelector::PseudoDrag: {
       
  1512                 if (element == e && style)
       
  1513                     style->setAffectedByDragRules(true);
       
  1514                     if (element != e && e->renderStyle())
       
  1515                         e->renderStyle()->setAffectedByDragRules(true);
       
  1516                     if (e->renderer() && e->renderer()->isDragging())
       
  1517                         return true;
       
  1518                 break;
       
  1519             }
       
  1520             case CSSSelector::PseudoFocus:
       
  1521                 if (e && e->focused() && e->document()->frame()->isActive())
       
  1522                     return true;
       
  1523                 break;
       
  1524             case CSSSelector::PseudoActive:
       
  1525                 // If we're in quirks mode, then :active should never match anchors with no
       
  1526                 // href and *:active should not match anything. 
       
  1527                 if (strictParsing || isSubSelector || sel->relation() == CSSSelector::SubSelector || (sel->hasTag() && !e->hasTagName(aTag)) || e->isLink()) {
       
  1528                     if (element == e && style)
       
  1529                         style->setAffectedByActiveRules(true);
       
  1530                     else if (e->renderStyle())
       
  1531                         e->renderStyle()->setAffectedByActiveRules(true);
       
  1532                     if (e->active())
       
  1533                         return true;
       
  1534                 }
       
  1535                 break;
       
  1536             case CSSSelector::PseudoEnabled:
       
  1537                 if (e && e->isControl())
       
  1538                     // The UI spec states that you can't match :enabled unless you are an object that can
       
  1539                     // "receive focus and be activated."  We will limit matching of this pseudo-class to elements
       
  1540                     // that are controls.
       
  1541                     return e->isEnabled();                    
       
  1542                 break;
       
  1543             case CSSSelector::PseudoDisabled:
       
  1544                 if (e && e->isControl())
       
  1545                     // The UI spec states that you can't match :enabled unless you are an object that can
       
  1546                     // "receive focus and be activated."  We will limit matching of this pseudo-class to elements
       
  1547                     // that are controls.
       
  1548                     return !e->isEnabled();                    
       
  1549                 break;
       
  1550             case CSSSelector::PseudoChecked:
       
  1551                 // Even though WinIE allows checked and indeterminate to co-exist, the CSS selector spec says that
       
  1552                 // you can't be both checked and indeterminate.  We will behave like WinIE behind the scenes and just
       
  1553                 // obey the CSS spec here in the test for matching the pseudo.
       
  1554                 if (e && e->isChecked() && !e->isIndeterminate())
       
  1555                     return true;
       
  1556                 break;
       
  1557             case CSSSelector::PseudoIndeterminate:
       
  1558                 if (e && e->isIndeterminate())
       
  1559                     return true;
       
  1560                 break;
       
  1561             case CSSSelector::PseudoRoot:
       
  1562                 if (e == e->document()->documentElement())
       
  1563                     return true;
       
  1564                 break;
       
  1565             case CSSSelector::PseudoLang: {
       
  1566                 const AtomicString& value = e->getAttribute(langAttr);
       
  1567                 if (value.isEmpty() || !value.startsWith(sel->m_argument, false))
       
  1568                     break;
       
  1569                 if (value.length() != sel->m_argument.length() && value[sel->m_argument.length()] != '-')
       
  1570                     break;
       
  1571                 return true;
       
  1572             }
       
  1573             case CSSSelector::PseudoNot: {
       
  1574                 // check the simple selector
       
  1575                 for (CSSSelector* subSel = sel->m_simpleSelector; subSel; subSel = subSel->m_tagHistory) {
       
  1576                     // :not cannot nest. I don't really know why this is a
       
  1577                     // restriction in CSS3, but it is, so let's honour it.
       
  1578                     if (subSel->m_simpleSelector)
       
  1579                         break;
       
  1580                     if (!checkOneSelector(subSel, e))
       
  1581                         return true;
       
  1582                 }
       
  1583                 break;
       
  1584             }
       
  1585             case CSSSelector::PseudoUnknown:
       
  1586                 ASSERT_NOT_REACHED();
       
  1587                 break;
       
  1588             
       
  1589             // Pseudo-elements:
       
  1590             case CSSSelector::PseudoFirstLine:
       
  1591                 if (subject) {
       
  1592                     dynamicPseudo = RenderStyle::FIRST_LINE;
       
  1593                     return true;
       
  1594                 }
       
  1595                 break;
       
  1596             case CSSSelector::PseudoFirstLetter:
       
  1597                 if (subject) {
       
  1598                     dynamicPseudo = RenderStyle::FIRST_LETTER;
       
  1599                     if (Document* doc = e->document())
       
  1600                         doc->setUsesFirstLetterRules(true);
       
  1601                     return true;
       
  1602                 }
       
  1603                 break;
       
  1604             case CSSSelector::PseudoSelection:
       
  1605                 dynamicPseudo = RenderStyle::SELECTION;
       
  1606                 return true;
       
  1607             case CSSSelector::PseudoBefore:
       
  1608                 dynamicPseudo = RenderStyle::BEFORE;
       
  1609                 return true;
       
  1610             case CSSSelector::PseudoAfter:
       
  1611                 dynamicPseudo = RenderStyle::AFTER;
       
  1612                 return true;
       
  1613             case CSSSelector::PseudoFileUploadButton:
       
  1614                 dynamicPseudo = RenderStyle::FILE_UPLOAD_BUTTON;
       
  1615                 return true;
       
  1616             case CSSSelector::PseudoSliderThumb:
       
  1617                 dynamicPseudo = RenderStyle::SLIDER_THUMB;
       
  1618                 return true; 
       
  1619             case CSSSelector::PseudoSearchCancelButton:
       
  1620                 dynamicPseudo = RenderStyle::SEARCH_CANCEL_BUTTON;
       
  1621                 return true; 
       
  1622             case CSSSelector::PseudoSearchDecoration:
       
  1623                 dynamicPseudo = RenderStyle::SEARCH_DECORATION;
       
  1624                 return true;
       
  1625             case CSSSelector::PseudoSearchResultsDecoration:
       
  1626                 dynamicPseudo = RenderStyle::SEARCH_RESULTS_DECORATION;
       
  1627                 return true;
       
  1628             case CSSSelector::PseudoSearchResultsButton:
       
  1629                 dynamicPseudo = RenderStyle::SEARCH_RESULTS_BUTTON;
       
  1630                 return true;
       
  1631             case CSSSelector::PseudoNotParsed:
       
  1632                 ASSERT(false);
       
  1633                 break;
       
  1634         }
       
  1635         return false;
       
  1636     }
       
  1637     // ### add the rest of the checks...
       
  1638     return true;
       
  1639 }
       
  1640 
       
  1641 // -----------------------------------------------------------------
       
  1642 
       
  1643 CSSRuleSet::CSSRuleSet()
       
  1644 {
       
  1645     m_universalRules = 0;
       
  1646     m_ruleCount = 0;
       
  1647 }
       
  1648 
       
  1649 CSSRuleSet::~CSSRuleSet()
       
  1650 { 
       
  1651     deleteAllValues(m_idRules);
       
  1652     deleteAllValues(m_classRules);
       
  1653     deleteAllValues(m_tagRules);
       
  1654 
       
  1655     delete m_universalRules; 
       
  1656 }
       
  1657 
       
  1658 
       
  1659 void CSSRuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map,
       
  1660                               CSSStyleRule* rule, CSSSelector* sel)
       
  1661 {
       
  1662     if (!key) return;
       
  1663     CSSRuleDataList* rules = map.get(key);
       
  1664     if (!rules) {
       
  1665         rules = new CSSRuleDataList(m_ruleCount++, rule, sel);
       
  1666         map.set(key, rules);
       
  1667     } else
       
  1668         rules->append(m_ruleCount++, rule, sel);
       
  1669 }
       
  1670 
       
  1671 void CSSRuleSet::addRule(CSSStyleRule* rule, CSSSelector* sel)
       
  1672 {
       
  1673     if (sel->m_match == CSSSelector::Id) {
       
  1674         addToRuleSet(sel->m_value.impl(), m_idRules, rule, sel);
       
  1675         return;
       
  1676     }
       
  1677     if (sel->m_match == CSSSelector::Class) {
       
  1678         addToRuleSet(sel->m_value.impl(), m_classRules, rule, sel);
       
  1679         return;
       
  1680     }
       
  1681      
       
  1682     const AtomicString& localName = sel->m_tag.localName();
       
  1683     if (localName != starAtom) {
       
  1684         addToRuleSet(localName.impl(), m_tagRules, rule, sel);
       
  1685         return;
       
  1686     }
       
  1687     
       
  1688     // Just put it in the universal rule set.
       
  1689     if (!m_universalRules)
       
  1690         m_universalRules = new CSSRuleDataList(m_ruleCount++, rule, sel);
       
  1691     else
       
  1692         m_universalRules->append(m_ruleCount++, rule, sel);
       
  1693 }
       
  1694 
       
  1695 void CSSRuleSet::addRulesFromSheet(CSSStyleSheet* sheet,  MediaQueryEvaluator* medium)
       
  1696 {
       
  1697     if (!sheet || !sheet->isCSSStyleSheet())
       
  1698         return;
       
  1699 
       
  1700     // No media implies "all", but if a media list exists it must
       
  1701     // contain our current medium
       
  1702     if (sheet->media() && !medium->eval(sheet->media()))
       
  1703         return; // the style sheet doesn't apply
       
  1704 
       
  1705     int len = sheet->length();
       
  1706 
       
  1707     for (int i = 0; i < len; i++) {
       
  1708         StyleBase* item = sheet->item(i);
       
  1709         if (item->isStyleRule()) {
       
  1710             CSSStyleRule* rule = static_cast<CSSStyleRule*>(item);
       
  1711             for (CSSSelector* s = rule->selector(); s; s = s->next())
       
  1712                 addRule(rule, s);
       
  1713         }
       
  1714         else if(item->isImportRule()) {
       
  1715             CSSImportRule* import = static_cast<CSSImportRule*>(item);
       
  1716             if (!import->media() || medium->eval(import->media()))
       
  1717                 addRulesFromSheet(import->styleSheet(), medium);
       
  1718         }
       
  1719         else if(item->isMediaRule()) {
       
  1720             CSSMediaRule* r = static_cast<CSSMediaRule*>(item);
       
  1721             CSSRuleList* rules = r->cssRules();
       
  1722 
       
  1723             if ((!r->media() || medium->eval(r->media())) && rules) {
       
  1724                 // Traverse child elements of the @media rule.
       
  1725                 for (unsigned j = 0; j < rules->length(); j++) {
       
  1726                     CSSRule *childItem = rules->item(j);
       
  1727                     if (childItem->isStyleRule()) {
       
  1728                         // It is a StyleRule, so append it to our list
       
  1729                         CSSStyleRule* rule = static_cast<CSSStyleRule*>(childItem);
       
  1730                         for (CSSSelector* s = rule->selector(); s; s = s->next())
       
  1731                             addRule(rule, s);
       
  1732                         
       
  1733                     }
       
  1734                 }   // for rules
       
  1735             }   // if rules
       
  1736         }
       
  1737     }
       
  1738 }
       
  1739 
       
  1740 // -------------------------------------------------------------------------------------
       
  1741 // this is mostly boring stuff on how to apply a certain rule to the renderstyle...
       
  1742 
       
  1743 static Length convertToLength(CSSPrimitiveValue *primitiveValue, RenderStyle *style, bool *ok = 0)
       
  1744 {
       
  1745     Length l;
       
  1746     if (!primitiveValue) {
       
  1747         if (ok)
       
  1748             *ok = false;
       
  1749     } else {
       
  1750         int type = primitiveValue->primitiveType();
       
  1751         if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
       
  1752             l = Length(primitiveValue->computeLengthIntForLength(style), Fixed);
       
  1753         else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  1754             l = Length(primitiveValue->getDoubleValue(), Percent);
       
  1755         else if(type == CSSPrimitiveValue::CSS_NUMBER)
       
  1756             l = Length(primitiveValue->getDoubleValue() * 100.0, Percent);
       
  1757         else if (ok)
       
  1758             *ok = false;
       
  1759     }
       
  1760     return l;
       
  1761 }
       
  1762 
       
  1763 void CSSStyleSelector::applyDeclarations(bool applyFirst, bool isImportant,
       
  1764                                          int startIndex, int endIndex)
       
  1765 {
       
  1766     if (startIndex == -1) return;
       
  1767     for (int i = startIndex; i <= endIndex; i++) {
       
  1768         CSSMutableStyleDeclaration* decl = m_matchedDecls[i];
       
  1769         DeprecatedValueListConstIterator<CSSProperty> end;
       
  1770         for (DeprecatedValueListConstIterator<CSSProperty> it = decl->valuesIterator(); it != end; ++it) {
       
  1771             const CSSProperty& current = *it;
       
  1772             // give special priority to font-xxx, color properties
       
  1773             if (isImportant == current.isImportant()) {
       
  1774                 bool first;
       
  1775                 switch(current.id()) {
       
  1776                     case CSS_PROP_LINE_HEIGHT:
       
  1777                         m_lineHeightValue = current.value();
       
  1778                         first = !applyFirst; // we apply line-height later
       
  1779                         break;
       
  1780                     case CSS_PROP_COLOR:
       
  1781                     case CSS_PROP_DIRECTION:
       
  1782                     case CSS_PROP_DISPLAY:
       
  1783                     case CSS_PROP_FONT:
       
  1784                     case CSS_PROP_FONT_SIZE:
       
  1785                     case CSS_PROP_FONT_STYLE:
       
  1786                     case CSS_PROP_FONT_FAMILY:
       
  1787                     case CSS_PROP_FONT_WEIGHT:
       
  1788                     case CSS_PROP__WEBKIT_TEXT_SIZE_ADJUST:
       
  1789                     case CSS_PROP_FONT_VARIANT:
       
  1790                         // these have to be applied first, because other properties use the computed
       
  1791                         // values of these porperties.
       
  1792                         first = true;
       
  1793                         break;
       
  1794                     default:
       
  1795                         first = false;
       
  1796                         break;
       
  1797                 }
       
  1798                 if (first == applyFirst)
       
  1799                     applyProperty(current.id(), current.value());
       
  1800             }
       
  1801         }
       
  1802     }
       
  1803 }
       
  1804 
       
  1805 static void applyCounterList(RenderStyle* style, CSSValueList* list, bool isReset)
       
  1806 {
       
  1807     CounterDirectiveMap& map = style->accessCounterDirectives();
       
  1808     typedef CounterDirectiveMap::iterator Iterator;
       
  1809 
       
  1810     Iterator end = map.end();
       
  1811     for (Iterator it = map.begin(); it != end; ++it)
       
  1812         if (isReset)
       
  1813             it->second.m_reset = false;
       
  1814         else
       
  1815             it->second.m_increment = false;
       
  1816 
       
  1817     int length = list ? list->length() : 0;
       
  1818     for (int i = 0; i < length; ++i) {
       
  1819         Pair* pair = static_cast<CSSPrimitiveValue*>(list->item(i))->getPairValue();
       
  1820         AtomicString identifier = static_cast<CSSPrimitiveValue*>(pair->first())->getStringValue();
       
  1821         // FIXME: What about overflow?
       
  1822         int value = static_cast<CSSPrimitiveValue*>(pair->second())->getIntValue();
       
  1823         CounterDirectives& directives = map.add(identifier.impl(), CounterDirectives()).first->second;
       
  1824         if (isReset) {
       
  1825             directives.m_reset = true;
       
  1826             directives.m_resetValue = value;
       
  1827         } else {
       
  1828             if (directives.m_increment)
       
  1829                 directives.m_incrementValue += value;
       
  1830             else {
       
  1831                 directives.m_increment = true;
       
  1832                 directives.m_incrementValue = value;
       
  1833             }
       
  1834         }
       
  1835     }
       
  1836 }
       
  1837 
       
  1838 void CSSStyleSelector::applyProperty(int id, CSSValue *value)
       
  1839 {
       
  1840     CSSPrimitiveValue *primitiveValue = 0;
       
  1841     if(value->isPrimitiveValue()) primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  1842 
       
  1843     Length l;
       
  1844     bool apply = false;
       
  1845 
       
  1846     unsigned short valueType = value->cssValueType();
       
  1847 
       
  1848     bool isInherit = parentNode && valueType == CSSValue::CSS_INHERIT;
       
  1849     bool isInitial = valueType == CSSValue::CSS_INITIAL || (!parentNode && valueType == CSSValue::CSS_INHERIT);
       
  1850 
       
  1851     // These properties are used to set the correct margins/padding on RTL lists.
       
  1852     if (id == CSS_PROP__WEBKIT_MARGIN_START)
       
  1853         id = style->direction() == LTR ? CSS_PROP_MARGIN_LEFT : CSS_PROP_MARGIN_RIGHT;
       
  1854     else if (id == CSS_PROP__WEBKIT_PADDING_START)
       
  1855         id = style->direction() == LTR ? CSS_PROP_PADDING_LEFT : CSS_PROP_PADDING_RIGHT;
       
  1856 
       
  1857     // What follows is a list that maps the CSS properties into their corresponding front-end
       
  1858     // RenderStyle values.  Shorthands (e.g. border, background) occur in this list as well and
       
  1859     // are only hit when mapping "inherit" or "initial" into front-end values.
       
  1860     switch (static_cast<CSSPropertyID>(id))
       
  1861     {
       
  1862 // ident only properties
       
  1863     case CSS_PROP_BACKGROUND_ATTACHMENT:
       
  1864         HANDLE_BACKGROUND_VALUE(backgroundAttachment, BackgroundAttachment, value)
       
  1865         return;
       
  1866     case CSS_PROP__WEBKIT_BACKGROUND_CLIP:
       
  1867         HANDLE_BACKGROUND_VALUE(backgroundClip, BackgroundClip, value)
       
  1868         return;
       
  1869     case CSS_PROP__WEBKIT_BACKGROUND_COMPOSITE:
       
  1870         HANDLE_BACKGROUND_VALUE(backgroundComposite, BackgroundComposite, value)
       
  1871         return;
       
  1872     case CSS_PROP__WEBKIT_BACKGROUND_ORIGIN:
       
  1873         HANDLE_BACKGROUND_VALUE(backgroundOrigin, BackgroundOrigin, value)
       
  1874         return;
       
  1875     case CSS_PROP_BACKGROUND_REPEAT:
       
  1876         HANDLE_BACKGROUND_VALUE(backgroundRepeat, BackgroundRepeat, value)
       
  1877         return;
       
  1878     case CSS_PROP__WEBKIT_BACKGROUND_SIZE:
       
  1879         HANDLE_BACKGROUND_VALUE(backgroundSize, BackgroundSize, value)
       
  1880         return;
       
  1881     case CSS_PROP_BORDER_COLLAPSE:
       
  1882         HANDLE_INHERIT_AND_INITIAL(borderCollapse, BorderCollapse)
       
  1883         if(!primitiveValue) return;
       
  1884         switch(primitiveValue->getIdent())
       
  1885         {
       
  1886         case CSS_VAL_COLLAPSE:
       
  1887             style->setBorderCollapse(true);
       
  1888             break;
       
  1889         case CSS_VAL_SEPARATE:
       
  1890             style->setBorderCollapse(false);
       
  1891             break;
       
  1892         default:
       
  1893             return;
       
  1894         }
       
  1895         return;
       
  1896         
       
  1897     case CSS_PROP_BORDER_TOP_STYLE:
       
  1898         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderTopStyle, BorderTopStyle, BorderStyle)
       
  1899         if (!primitiveValue) return;
       
  1900         style->setBorderTopStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
       
  1901         return;
       
  1902     case CSS_PROP_BORDER_RIGHT_STYLE:
       
  1903         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderRightStyle, BorderRightStyle, BorderStyle)
       
  1904         if (!primitiveValue) return;
       
  1905         style->setBorderRightStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
       
  1906         return;
       
  1907     case CSS_PROP_BORDER_BOTTOM_STYLE:
       
  1908         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderBottomStyle, BorderBottomStyle, BorderStyle)
       
  1909         if (!primitiveValue) return;
       
  1910         style->setBorderBottomStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
       
  1911         return;
       
  1912     case CSS_PROP_BORDER_LEFT_STYLE:
       
  1913         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(borderLeftStyle, BorderLeftStyle, BorderStyle)
       
  1914         if (!primitiveValue) return;
       
  1915         style->setBorderLeftStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
       
  1916         return;
       
  1917     case CSS_PROP_OUTLINE_STYLE:
       
  1918         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(outlineStyle, OutlineStyle, BorderStyle)
       
  1919         if (!primitiveValue) return;
       
  1920         if (primitiveValue->getIdent() == CSS_VAL_AUTO)
       
  1921             style->setOutlineStyle(DOTTED, true);
       
  1922         else
       
  1923             style->setOutlineStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
       
  1924         return;
       
  1925     case CSS_PROP_CAPTION_SIDE:
       
  1926     {
       
  1927         HANDLE_INHERIT_AND_INITIAL(captionSide, CaptionSide)
       
  1928         if(!primitiveValue) return;
       
  1929         ECaptionSide c = RenderStyle::initialCaptionSide();
       
  1930         switch(primitiveValue->getIdent())
       
  1931         {
       
  1932         case CSS_VAL_LEFT:
       
  1933             c = CAPLEFT; break;
       
  1934         case CSS_VAL_RIGHT:
       
  1935             c = CAPRIGHT; break;
       
  1936         case CSS_VAL_TOP:
       
  1937             c = CAPTOP; break;
       
  1938         case CSS_VAL_BOTTOM:
       
  1939             c = CAPBOTTOM; break;
       
  1940         default:
       
  1941             return;
       
  1942         }
       
  1943         style->setCaptionSide(c);
       
  1944         return;
       
  1945     }
       
  1946     case CSS_PROP_CLEAR:
       
  1947     {
       
  1948         HANDLE_INHERIT_AND_INITIAL(clear, Clear)
       
  1949         if(!primitiveValue) return;
       
  1950         EClear c;
       
  1951         switch(primitiveValue->getIdent())
       
  1952         {
       
  1953         case CSS_VAL_NONE:
       
  1954             c = CNONE; break;
       
  1955         case CSS_VAL_LEFT:
       
  1956             c = CLEFT; break;
       
  1957         case CSS_VAL_RIGHT:
       
  1958             c = CRIGHT; break;
       
  1959         case CSS_VAL_BOTH:
       
  1960             c = CBOTH; break;
       
  1961         default:
       
  1962             return;
       
  1963         }
       
  1964         style->setClear(c);
       
  1965         return;
       
  1966     }
       
  1967     case CSS_PROP_DIRECTION:
       
  1968     {
       
  1969         HANDLE_INHERIT_AND_INITIAL(direction, Direction)
       
  1970         if(!primitiveValue) break;
       
  1971         style->setDirection(primitiveValue->getIdent() == CSS_VAL_LTR ? LTR : RTL);
       
  1972         return;
       
  1973     }
       
  1974     case CSS_PROP_DISPLAY:
       
  1975     {
       
  1976         HANDLE_INHERIT_AND_INITIAL(display, Display)
       
  1977         if(!primitiveValue) break;
       
  1978         int id = primitiveValue->getIdent();
       
  1979         EDisplay d;
       
  1980         if (id == CSS_VAL_NONE)
       
  1981             d = NONE;
       
  1982         else
       
  1983             d = EDisplay(primitiveValue->getIdent() - CSS_VAL_INLINE);
       
  1984 
       
  1985 #if PLATFORM(SYMBIAN)
       
  1986         if( id == CSS_VAL__WAP_MARQUEE ) {
       
  1987             style->setOverflowX(OMARQUEE);
       
  1988         } 
       
  1989 #endif
       
  1990         style->setDisplay(d);
       
  1991 
       
  1992         return;
       
  1993     }
       
  1994 
       
  1995     case CSS_PROP_EMPTY_CELLS:
       
  1996     {
       
  1997         HANDLE_INHERIT_AND_INITIAL(emptyCells, EmptyCells)
       
  1998         if (!primitiveValue) break;
       
  1999         int id = primitiveValue->getIdent();
       
  2000         if (id == CSS_VAL_SHOW)
       
  2001             style->setEmptyCells(SHOW);
       
  2002         else if (id == CSS_VAL_HIDE)
       
  2003             style->setEmptyCells(HIDE);
       
  2004         return;
       
  2005     }
       
  2006     case CSS_PROP_FLOAT:
       
  2007     {
       
  2008         HANDLE_INHERIT_AND_INITIAL(floating, Floating)
       
  2009         if(!primitiveValue) return;
       
  2010         EFloat f;
       
  2011         switch(primitiveValue->getIdent())
       
  2012         {
       
  2013         case CSS_VAL_LEFT:
       
  2014             f = FLEFT; break;
       
  2015         case CSS_VAL_RIGHT:
       
  2016             f = FRIGHT; break;
       
  2017         case CSS_VAL_NONE:
       
  2018         case CSS_VAL_CENTER:  //Non standart CSS-Value
       
  2019             f = FNONE; break;
       
  2020         default:
       
  2021             return;
       
  2022         }
       
  2023         
       
  2024         style->setFloating(f);
       
  2025         return;
       
  2026     }
       
  2027 
       
  2028     case CSS_PROP_FONT_STYLE:
       
  2029     {
       
  2030         FontDescription fontDescription = style->fontDescription();
       
  2031         if (isInherit)
       
  2032             fontDescription.setItalic(parentStyle->fontDescription().italic());
       
  2033         else if (isInitial)
       
  2034             fontDescription.setItalic(false);
       
  2035         else {
       
  2036             if (!primitiveValue) return;
       
  2037             switch (primitiveValue->getIdent()) {
       
  2038                 case CSS_VAL_OBLIQUE:
       
  2039                 // FIXME: oblique is the same as italic for the moment...
       
  2040                 case CSS_VAL_ITALIC:
       
  2041                     fontDescription.setItalic(true);
       
  2042                     break;
       
  2043                 case CSS_VAL_NORMAL:
       
  2044                     fontDescription.setItalic(false);
       
  2045                     break;
       
  2046                 default:
       
  2047                     return;
       
  2048             }
       
  2049         }
       
  2050         if (style->setFontDescription(fontDescription))
       
  2051             fontDirty = true;
       
  2052         return;
       
  2053     }
       
  2054 
       
  2055     case CSS_PROP_FONT_VARIANT:
       
  2056     {
       
  2057         FontDescription fontDescription = style->fontDescription();
       
  2058         if (isInherit) 
       
  2059             fontDescription.setSmallCaps(parentStyle->fontDescription().smallCaps());
       
  2060         else if (isInitial)
       
  2061             fontDescription.setSmallCaps(false);
       
  2062         else {
       
  2063             if (!primitiveValue) return;
       
  2064             int id = primitiveValue->getIdent();
       
  2065             if (id == CSS_VAL_NORMAL)
       
  2066                 fontDescription.setSmallCaps(false);
       
  2067             else if (id == CSS_VAL_SMALL_CAPS)
       
  2068                 fontDescription.setSmallCaps(true);
       
  2069             else
       
  2070                 return;
       
  2071         }
       
  2072         if (style->setFontDescription(fontDescription))
       
  2073             fontDirty = true;
       
  2074         return;        
       
  2075     }
       
  2076 
       
  2077     case CSS_PROP_FONT_WEIGHT:
       
  2078     {
       
  2079         FontDescription fontDescription = style->fontDescription();
       
  2080         if (isInherit)
       
  2081             fontDescription.setWeight(parentStyle->fontDescription().weight());
       
  2082         else if (isInitial)
       
  2083             fontDescription.setWeight(cNormalWeight);
       
  2084         else {
       
  2085             if (!primitiveValue) return;
       
  2086             if (primitiveValue->getIdent()) {
       
  2087                 switch (primitiveValue->getIdent()) {
       
  2088                     // FIXME: We aren't genuinely supporting specific weight values.
       
  2089                     case CSS_VAL_BOLD:
       
  2090                     case CSS_VAL_BOLDER:
       
  2091                     case CSS_VAL_600:
       
  2092                     case CSS_VAL_700:
       
  2093                     case CSS_VAL_800:
       
  2094                     case CSS_VAL_900:
       
  2095                         fontDescription.setWeight(cBoldWeight);
       
  2096                         break;
       
  2097                     case CSS_VAL_NORMAL:
       
  2098                     case CSS_VAL_LIGHTER:
       
  2099                     case CSS_VAL_100:
       
  2100                     case CSS_VAL_200:
       
  2101                     case CSS_VAL_300:
       
  2102                     case CSS_VAL_400:
       
  2103                     case CSS_VAL_500:
       
  2104                         fontDescription.setWeight(cNormalWeight);
       
  2105                         break;
       
  2106                     default:
       
  2107                         return;
       
  2108                 }
       
  2109             }
       
  2110             else
       
  2111             {
       
  2112                 // ### fix parsing of 100-900 values in parser, apply them here
       
  2113             }
       
  2114         }
       
  2115         if (style->setFontDescription(fontDescription))
       
  2116             fontDirty = true;
       
  2117         return;
       
  2118     }
       
  2119         
       
  2120     case CSS_PROP_LIST_STYLE_POSITION:
       
  2121     {
       
  2122         HANDLE_INHERIT_AND_INITIAL(listStylePosition, ListStylePosition)
       
  2123         if (!primitiveValue) return;
       
  2124         if (primitiveValue->getIdent())
       
  2125             style->setListStylePosition((EListStylePosition) (primitiveValue->getIdent() - CSS_VAL_OUTSIDE));
       
  2126         return;
       
  2127     }
       
  2128 
       
  2129     case CSS_PROP_LIST_STYLE_TYPE:
       
  2130     {
       
  2131         HANDLE_INHERIT_AND_INITIAL(listStyleType, ListStyleType)
       
  2132         if (!primitiveValue) return;
       
  2133         if (primitiveValue->getIdent())
       
  2134         {
       
  2135             EListStyleType t;
       
  2136             int id = primitiveValue->getIdent();
       
  2137             if (id == CSS_VAL_NONE) { // important!!
       
  2138               t = LNONE;
       
  2139             } else {
       
  2140               t = EListStyleType(id - CSS_VAL_DISC);
       
  2141             }
       
  2142             style->setListStyleType(t);
       
  2143         }
       
  2144         return;
       
  2145     }
       
  2146 
       
  2147     case CSS_PROP_OVERFLOW:
       
  2148     {
       
  2149         if (isInherit) {
       
  2150             style->setOverflowX(parentStyle->overflowX());
       
  2151             style->setOverflowY(parentStyle->overflowY());
       
  2152             return;
       
  2153         }
       
  2154         
       
  2155         if (isInitial) {
       
  2156             style->setOverflowX(RenderStyle::initialOverflowX());
       
  2157             style->setOverflowY(RenderStyle::initialOverflowY());
       
  2158             return;
       
  2159         }
       
  2160             
       
  2161         EOverflow o;
       
  2162         switch(primitiveValue->getIdent()) {
       
  2163             case CSS_VAL_VISIBLE:
       
  2164                 o = OVISIBLE; break;
       
  2165             case CSS_VAL_HIDDEN:
       
  2166                 o = OHIDDEN; break;
       
  2167             case CSS_VAL_SCROLL:
       
  2168                 o = OSCROLL; break;
       
  2169             case CSS_VAL_AUTO:
       
  2170                 o = OAUTO; break;
       
  2171             case CSS_VAL__WEBKIT_MARQUEE:
       
  2172                 o = OMARQUEE; break;
       
  2173             case CSS_VAL_OVERLAY:
       
  2174                 o = OOVERLAY; break;
       
  2175             default:
       
  2176                 return;
       
  2177         }
       
  2178         style->setOverflowX(o);
       
  2179         style->setOverflowY(o);
       
  2180         return;
       
  2181     }
       
  2182 
       
  2183     case CSS_PROP_OVERFLOW_X:
       
  2184     {
       
  2185         HANDLE_INHERIT_AND_INITIAL(overflowX, OverflowX)
       
  2186         EOverflow o;
       
  2187         switch(primitiveValue->getIdent())
       
  2188         {
       
  2189         case CSS_VAL_VISIBLE:
       
  2190             o = OVISIBLE; break;
       
  2191         case CSS_VAL_HIDDEN:
       
  2192             o = OHIDDEN; break;
       
  2193         case CSS_VAL_SCROLL:
       
  2194             o = OSCROLL; break;
       
  2195         case CSS_VAL_AUTO:
       
  2196             o = OAUTO; break;
       
  2197         case CSS_VAL__WEBKIT_MARQUEE:
       
  2198             o = OMARQUEE; break;
       
  2199         case CSS_VAL_OVERLAY:
       
  2200             o = OOVERLAY; break;
       
  2201         default:
       
  2202             return;
       
  2203         }
       
  2204         style->setOverflowX(o);
       
  2205         return;
       
  2206     }
       
  2207 
       
  2208     case CSS_PROP_OVERFLOW_Y:
       
  2209     {
       
  2210         HANDLE_INHERIT_AND_INITIAL(overflowY, OverflowY)
       
  2211         EOverflow o;
       
  2212         switch(primitiveValue->getIdent())
       
  2213         {
       
  2214         case CSS_VAL_VISIBLE:
       
  2215             o = OVISIBLE; break;
       
  2216         case CSS_VAL_HIDDEN:
       
  2217             o = OHIDDEN; break;
       
  2218         case CSS_VAL_SCROLL:
       
  2219             o = OSCROLL; break;
       
  2220         case CSS_VAL_AUTO:
       
  2221             o = OAUTO; break;
       
  2222         case CSS_VAL__WEBKIT_MARQUEE:
       
  2223             o = OMARQUEE; break;
       
  2224         case CSS_VAL_OVERLAY:
       
  2225             o = OOVERLAY; break;
       
  2226         default:
       
  2227             return;
       
  2228         }
       
  2229         style->setOverflowY(o);
       
  2230         return;
       
  2231     }
       
  2232 
       
  2233     case CSS_PROP_PAGE_BREAK_BEFORE:
       
  2234     {
       
  2235         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakBefore, PageBreakBefore, PageBreak)
       
  2236         if (!primitiveValue) return;
       
  2237         switch (primitiveValue->getIdent()) {
       
  2238             case CSS_VAL_AUTO:
       
  2239                 style->setPageBreakBefore(PBAUTO);
       
  2240                 break;
       
  2241             case CSS_VAL_LEFT:
       
  2242             case CSS_VAL_RIGHT:
       
  2243             case CSS_VAL_ALWAYS:
       
  2244                 style->setPageBreakBefore(PBALWAYS); // CSS2.1: "Conforming user agents may map left/right to always."
       
  2245                 break;
       
  2246             case CSS_VAL_AVOID:
       
  2247                 style->setPageBreakBefore(PBAVOID);
       
  2248                 break;
       
  2249         }
       
  2250         return;
       
  2251     }
       
  2252 
       
  2253     case CSS_PROP_PAGE_BREAK_AFTER:
       
  2254     {
       
  2255         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakAfter, PageBreakAfter, PageBreak)
       
  2256         if (!primitiveValue) return;
       
  2257         switch (primitiveValue->getIdent()) {
       
  2258             case CSS_VAL_AUTO:
       
  2259                 style->setPageBreakAfter(PBAUTO);
       
  2260                 break;
       
  2261             case CSS_VAL_LEFT:
       
  2262             case CSS_VAL_RIGHT:
       
  2263             case CSS_VAL_ALWAYS:
       
  2264                 style->setPageBreakAfter(PBALWAYS); // CSS2.1: "Conforming user agents may map left/right to always."
       
  2265                 break;
       
  2266             case CSS_VAL_AVOID:
       
  2267                 style->setPageBreakAfter(PBAVOID);
       
  2268                 break;
       
  2269         }
       
  2270         return;
       
  2271     }
       
  2272 
       
  2273     case CSS_PROP_PAGE_BREAK_INSIDE: {
       
  2274         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakInside, PageBreakInside, PageBreak)
       
  2275         if (!primitiveValue) return;
       
  2276         if (primitiveValue->getIdent() == CSS_VAL_AUTO)
       
  2277             style->setPageBreakInside(PBAUTO);
       
  2278         else if (primitiveValue->getIdent() == CSS_VAL_AVOID)
       
  2279             style->setPageBreakInside(PBAVOID);
       
  2280         return;
       
  2281     }
       
  2282         
       
  2283     case CSS_PROP_POSITION:
       
  2284     {
       
  2285         HANDLE_INHERIT_AND_INITIAL(position, Position)
       
  2286         if(!primitiveValue) return;
       
  2287         EPosition p;
       
  2288         switch(primitiveValue->getIdent())
       
  2289         {
       
  2290         case CSS_VAL_STATIC:
       
  2291             p = StaticPosition;
       
  2292             break;
       
  2293         case CSS_VAL_RELATIVE:
       
  2294             p = RelativePosition;
       
  2295             break;
       
  2296         case CSS_VAL_ABSOLUTE:
       
  2297             p = AbsolutePosition;
       
  2298             break;
       
  2299         case CSS_VAL_FIXED:
       
  2300             p = FixedPosition;
       
  2301             break;
       
  2302         default:
       
  2303             return;
       
  2304         }
       
  2305         style->setPosition(p);
       
  2306         return;
       
  2307     }
       
  2308 
       
  2309     case CSS_PROP_TABLE_LAYOUT: {
       
  2310         HANDLE_INHERIT_AND_INITIAL(tableLayout, TableLayout)
       
  2311 
       
  2312         if (!primitiveValue->getIdent())
       
  2313             return;
       
  2314 
       
  2315         ETableLayout l = RenderStyle::initialTableLayout();
       
  2316         switch(primitiveValue->getIdent()) {
       
  2317             case CSS_VAL_FIXED:
       
  2318                 l = TFIXED;
       
  2319                 // fall through
       
  2320             case CSS_VAL_AUTO:
       
  2321                 style->setTableLayout(l);
       
  2322             default:
       
  2323                 break;
       
  2324         }
       
  2325         return;
       
  2326     }
       
  2327         
       
  2328     case CSS_PROP_UNICODE_BIDI: {
       
  2329         HANDLE_INHERIT_AND_INITIAL(unicodeBidi, UnicodeBidi)
       
  2330         switch (primitiveValue->getIdent()) {
       
  2331             case CSS_VAL_NORMAL:
       
  2332                 style->setUnicodeBidi(UBNormal); 
       
  2333                 break;
       
  2334             case CSS_VAL_EMBED:
       
  2335                 style->setUnicodeBidi(Embed); 
       
  2336                 break;
       
  2337             case CSS_VAL_BIDI_OVERRIDE:
       
  2338                 style->setUnicodeBidi(Override);
       
  2339                 break;
       
  2340             default:
       
  2341                 return;
       
  2342         }
       
  2343         return;
       
  2344     }
       
  2345     case CSS_PROP_TEXT_TRANSFORM: {
       
  2346         HANDLE_INHERIT_AND_INITIAL(textTransform, TextTransform)
       
  2347         
       
  2348         if(!primitiveValue->getIdent()) return;
       
  2349 
       
  2350         ETextTransform tt;
       
  2351         switch(primitiveValue->getIdent()) {
       
  2352         case CSS_VAL_CAPITALIZE:  tt = CAPITALIZE;  break;
       
  2353         case CSS_VAL_UPPERCASE:   tt = UPPERCASE;   break;
       
  2354         case CSS_VAL_LOWERCASE:   tt = LOWERCASE;   break;
       
  2355         case CSS_VAL_NONE:
       
  2356         default:                  tt = TTNONE;      break;
       
  2357         }
       
  2358         style->setTextTransform(tt);
       
  2359         return;
       
  2360         }
       
  2361 
       
  2362     case CSS_PROP_VISIBILITY:
       
  2363     {
       
  2364         HANDLE_INHERIT_AND_INITIAL(visibility, Visibility)
       
  2365 
       
  2366         switch(primitiveValue->getIdent()) {
       
  2367         case CSS_VAL_HIDDEN:
       
  2368             style->setVisibility(HIDDEN);
       
  2369             break;
       
  2370         case CSS_VAL_VISIBLE:
       
  2371             style->setVisibility(VISIBLE);
       
  2372             break;
       
  2373         case CSS_VAL_COLLAPSE:
       
  2374             style->setVisibility(COLLAPSE);
       
  2375         default:
       
  2376             break;
       
  2377         }
       
  2378         return;
       
  2379     }
       
  2380     case CSS_PROP_WHITE_SPACE:
       
  2381         HANDLE_INHERIT_AND_INITIAL(whiteSpace, WhiteSpace)
       
  2382 
       
  2383         if(!primitiveValue->getIdent()) return;
       
  2384 
       
  2385         EWhiteSpace s;
       
  2386         switch(primitiveValue->getIdent()) {
       
  2387         case CSS_VAL__WEBKIT_NOWRAP:
       
  2388             s = KHTML_NOWRAP;
       
  2389             break;
       
  2390         case CSS_VAL_NOWRAP:
       
  2391             s = NOWRAP;
       
  2392             break;
       
  2393         case CSS_VAL_PRE:
       
  2394             s = PRE;
       
  2395             break;
       
  2396         case CSS_VAL_PRE_WRAP:
       
  2397             s = PRE_WRAP;
       
  2398             break;
       
  2399         case CSS_VAL_PRE_LINE:
       
  2400             s = PRE_LINE;
       
  2401             break;
       
  2402         case CSS_VAL_NORMAL:
       
  2403         default:
       
  2404             s = NORMAL;
       
  2405             break;
       
  2406         }
       
  2407         style->setWhiteSpace(s);
       
  2408         return;
       
  2409 
       
  2410     case CSS_PROP_BACKGROUND_POSITION:
       
  2411         HANDLE_BACKGROUND_INHERIT_AND_INITIAL(backgroundXPosition, BackgroundXPosition);
       
  2412         HANDLE_BACKGROUND_INHERIT_AND_INITIAL(backgroundYPosition, BackgroundYPosition);
       
  2413         return;
       
  2414     case CSS_PROP_BACKGROUND_POSITION_X: {
       
  2415         HANDLE_BACKGROUND_VALUE(backgroundXPosition, BackgroundXPosition, value)
       
  2416         return;
       
  2417     }
       
  2418     case CSS_PROP_BACKGROUND_POSITION_Y: {
       
  2419         HANDLE_BACKGROUND_VALUE(backgroundYPosition, BackgroundYPosition, value)
       
  2420         return;
       
  2421     }
       
  2422     case CSS_PROP_BORDER_SPACING: {
       
  2423         if (isInherit) {
       
  2424             style->setHorizontalBorderSpacing(parentStyle->horizontalBorderSpacing());
       
  2425             style->setVerticalBorderSpacing(parentStyle->verticalBorderSpacing());
       
  2426         }
       
  2427         else if (isInitial) {
       
  2428             style->setHorizontalBorderSpacing(0);
       
  2429             style->setVerticalBorderSpacing(0);
       
  2430         }
       
  2431         return;
       
  2432     }
       
  2433     case CSS_PROP__WEBKIT_BORDER_HORIZONTAL_SPACING: {
       
  2434         HANDLE_INHERIT_AND_INITIAL(horizontalBorderSpacing, HorizontalBorderSpacing)
       
  2435         if (!primitiveValue) return;
       
  2436         short spacing =  primitiveValue->computeLengthShort(style);
       
  2437         style->setHorizontalBorderSpacing(spacing);
       
  2438         return;
       
  2439     }
       
  2440     case CSS_PROP__WEBKIT_BORDER_VERTICAL_SPACING: {
       
  2441         HANDLE_INHERIT_AND_INITIAL(verticalBorderSpacing, VerticalBorderSpacing)
       
  2442         if (!primitiveValue) return;
       
  2443         short spacing =  primitiveValue->computeLengthShort(style);
       
  2444         style->setVerticalBorderSpacing(spacing);
       
  2445         return;
       
  2446     }
       
  2447     case CSS_PROP_CURSOR:
       
  2448         if (isInherit) {
       
  2449             style->setCursor(parentStyle->cursor());
       
  2450             style->setCursorList(parentStyle->cursors());
       
  2451             return;
       
  2452         }
       
  2453         style->clearCursorList();
       
  2454         if (isInitial) {
       
  2455             style->setCursor(RenderStyle::initialCursor());
       
  2456             return;
       
  2457         }
       
  2458         if (value->isValueList()) {
       
  2459             CSSValueList* list = static_cast<CSSValueList*>(value);
       
  2460             int len = list->length();
       
  2461             style->setCursor(CURSOR_AUTO);
       
  2462             for (int i = 0; i < len; i++) {
       
  2463                 CSSValue* item = list->item(i);
       
  2464                 if (!item->isPrimitiveValue())
       
  2465                     continue;
       
  2466                 primitiveValue = static_cast<CSSPrimitiveValue*>(item);
       
  2467                 int type = primitiveValue->primitiveType();
       
  2468                 if (type == CSSPrimitiveValue::CSS_URI) {
       
  2469 #if ENABLE(SVG)
       
  2470                     if (primitiveValue->getStringValue().find("#") == 0)
       
  2471                         style->addSVGCursor(primitiveValue->getStringValue().substring(1));
       
  2472                     else
       
  2473 #endif
       
  2474                     {
       
  2475                         CSSCursorImageValue* image = static_cast<CSSCursorImageValue*>(primitiveValue);
       
  2476                         style->addCursor(image->image(element->document()->docLoader()), image->hotspot());
       
  2477                     }
       
  2478                 } else if (type == CSSPrimitiveValue::CSS_IDENT) {
       
  2479                     int ident = primitiveValue->getIdent();
       
  2480                     if (ident == CSS_VAL_COPY)
       
  2481                         style->setCursor(CURSOR_COPY);
       
  2482                     else if (ident == CSS_VAL_NONE)
       
  2483                         style->setCursor(CURSOR_NONE);
       
  2484                     else
       
  2485                         style->setCursor((ECursor)(ident - CSS_VAL_AUTO));
       
  2486                 }
       
  2487             }
       
  2488         } else if (primitiveValue) {
       
  2489             int type = primitiveValue->primitiveType();
       
  2490             if (type == CSSPrimitiveValue::CSS_IDENT) {
       
  2491                 int ident = primitiveValue->getIdent();
       
  2492                 if (ident == CSS_VAL_COPY)
       
  2493                     style->setCursor(CURSOR_COPY);
       
  2494                 else if (ident == CSS_VAL_NONE)
       
  2495                     style->setCursor(CURSOR_NONE);
       
  2496                 else
       
  2497                     style->setCursor((ECursor)(ident - CSS_VAL_AUTO));
       
  2498             }
       
  2499         }
       
  2500         return;
       
  2501 // colors || inherit
       
  2502     case CSS_PROP_BACKGROUND_COLOR:
       
  2503     case CSS_PROP_BORDER_TOP_COLOR:
       
  2504     case CSS_PROP_BORDER_RIGHT_COLOR:
       
  2505     case CSS_PROP_BORDER_BOTTOM_COLOR:
       
  2506     case CSS_PROP_BORDER_LEFT_COLOR:
       
  2507     case CSS_PROP_COLOR:
       
  2508     case CSS_PROP_OUTLINE_COLOR:
       
  2509     case CSS_PROP__WEBKIT_COLUMN_RULE_COLOR:
       
  2510     case CSS_PROP__WEBKIT_TEXT_STROKE_COLOR:
       
  2511     case CSS_PROP__WEBKIT_TEXT_FILL_COLOR: {
       
  2512         Color col;
       
  2513         if (isInherit) {
       
  2514             HANDLE_INHERIT_COND(CSS_PROP_BACKGROUND_COLOR, backgroundColor, BackgroundColor)
       
  2515             HANDLE_INHERIT_COND(CSS_PROP_BORDER_TOP_COLOR, borderTopColor, BorderTopColor)
       
  2516             HANDLE_INHERIT_COND(CSS_PROP_BORDER_BOTTOM_COLOR, borderBottomColor, BorderBottomColor)
       
  2517             HANDLE_INHERIT_COND(CSS_PROP_BORDER_RIGHT_COLOR, borderRightColor, BorderRightColor)
       
  2518             HANDLE_INHERIT_COND(CSS_PROP_BORDER_LEFT_COLOR, borderLeftColor, BorderLeftColor)
       
  2519             HANDLE_INHERIT_COND(CSS_PROP_COLOR, color, Color)
       
  2520             HANDLE_INHERIT_COND(CSS_PROP_OUTLINE_COLOR, outlineColor, OutlineColor)
       
  2521             HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_COLUMN_RULE_COLOR, columnRuleColor, ColumnRuleColor)
       
  2522             HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_TEXT_STROKE_COLOR, textStrokeColor, TextStrokeColor)
       
  2523             HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_TEXT_FILL_COLOR, textFillColor, TextFillColor)
       
  2524             return;
       
  2525         }
       
  2526         if (isInitial) {
       
  2527             // The border/outline colors will just map to the invalid color |col| above.  This will have the
       
  2528             // effect of forcing the use of the currentColor when it comes time to draw the borders (and of
       
  2529             // not painting the background since the color won't be valid).
       
  2530             if (id == CSS_PROP_COLOR)
       
  2531                 col = RenderStyle::initialColor();
       
  2532         } else {
       
  2533             if (!primitiveValue)
       
  2534                 return;
       
  2535             col = getColorFromPrimitiveValue(primitiveValue);
       
  2536         }
       
  2537 
       
  2538         switch(id) {
       
  2539         case CSS_PROP_BACKGROUND_COLOR:
       
  2540             style->setBackgroundColor(col); break;
       
  2541         case CSS_PROP_BORDER_TOP_COLOR:
       
  2542             style->setBorderTopColor(col); break;
       
  2543         case CSS_PROP_BORDER_RIGHT_COLOR:
       
  2544             style->setBorderRightColor(col); break;
       
  2545         case CSS_PROP_BORDER_BOTTOM_COLOR:
       
  2546             style->setBorderBottomColor(col); break;
       
  2547         case CSS_PROP_BORDER_LEFT_COLOR:
       
  2548             style->setBorderLeftColor(col); break;
       
  2549         case CSS_PROP_COLOR:
       
  2550             style->setColor(col); break;
       
  2551         case CSS_PROP_OUTLINE_COLOR:
       
  2552             style->setOutlineColor(col); break;
       
  2553         case CSS_PROP__WEBKIT_COLUMN_RULE_COLOR:
       
  2554             style->setColumnRuleColor(col);
       
  2555             break;
       
  2556         case CSS_PROP__WEBKIT_TEXT_STROKE_COLOR:
       
  2557             style->setTextStrokeColor(col);
       
  2558             break;
       
  2559         case CSS_PROP__WEBKIT_TEXT_FILL_COLOR:
       
  2560             style->setTextFillColor(col);
       
  2561             break;
       
  2562         }
       
  2563         
       
  2564         return;
       
  2565     }
       
  2566     
       
  2567 // uri || inherit
       
  2568     case CSS_PROP_BACKGROUND_IMAGE:
       
  2569         HANDLE_BACKGROUND_VALUE(backgroundImage, BackgroundImage, value)
       
  2570         return;
       
  2571     case CSS_PROP_LIST_STYLE_IMAGE:
       
  2572     {
       
  2573         HANDLE_INHERIT_AND_INITIAL(listStyleImage, ListStyleImage)
       
  2574         if (!primitiveValue)
       
  2575             return;
       
  2576         style->setListStyleImage(static_cast<CSSImageValue*>(primitiveValue)->image(element->document()->docLoader()));
       
  2577         return;
       
  2578     }
       
  2579 
       
  2580 // length
       
  2581     case CSS_PROP_BORDER_TOP_WIDTH:
       
  2582     case CSS_PROP_BORDER_RIGHT_WIDTH:
       
  2583     case CSS_PROP_BORDER_BOTTOM_WIDTH:
       
  2584     case CSS_PROP_BORDER_LEFT_WIDTH:
       
  2585     case CSS_PROP_OUTLINE_WIDTH:
       
  2586     case CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH:
       
  2587     {
       
  2588         if (isInherit) {
       
  2589             HANDLE_INHERIT_COND(CSS_PROP_BORDER_TOP_WIDTH, borderTopWidth, BorderTopWidth)
       
  2590             HANDLE_INHERIT_COND(CSS_PROP_BORDER_RIGHT_WIDTH, borderRightWidth, BorderRightWidth)
       
  2591             HANDLE_INHERIT_COND(CSS_PROP_BORDER_BOTTOM_WIDTH, borderBottomWidth, BorderBottomWidth)
       
  2592             HANDLE_INHERIT_COND(CSS_PROP_BORDER_LEFT_WIDTH, borderLeftWidth, BorderLeftWidth)
       
  2593             HANDLE_INHERIT_COND(CSS_PROP_OUTLINE_WIDTH, outlineWidth, OutlineWidth)
       
  2594             HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH, columnRuleWidth, ColumnRuleWidth)
       
  2595             return;
       
  2596         }
       
  2597         else if (isInitial) {
       
  2598             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_TOP_WIDTH, BorderTopWidth, BorderWidth)
       
  2599             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_RIGHT_WIDTH, BorderRightWidth, BorderWidth)
       
  2600             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_BOTTOM_WIDTH, BorderBottomWidth, BorderWidth)
       
  2601             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BORDER_LEFT_WIDTH, BorderLeftWidth, BorderWidth)
       
  2602             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_OUTLINE_WIDTH, OutlineWidth, BorderWidth)
       
  2603             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH, ColumnRuleWidth, BorderWidth)
       
  2604             return;
       
  2605         }
       
  2606 
       
  2607         if(!primitiveValue) return;
       
  2608         short width = 3;
       
  2609         switch(primitiveValue->getIdent())
       
  2610         {
       
  2611         case CSS_VAL_THIN:
       
  2612             width = 1;
       
  2613             break;
       
  2614         case CSS_VAL_MEDIUM:
       
  2615             width = 3;
       
  2616             break;
       
  2617         case CSS_VAL_THICK:
       
  2618             width = 5;
       
  2619             break;
       
  2620         case CSS_VAL_INVALID:
       
  2621             width = primitiveValue->computeLengthShort(style);
       
  2622             break;
       
  2623         default:
       
  2624             return;
       
  2625         }
       
  2626 
       
  2627         if(width < 0) return;
       
  2628         switch(id)
       
  2629         {
       
  2630         case CSS_PROP_BORDER_TOP_WIDTH:
       
  2631             style->setBorderTopWidth(width);
       
  2632             break;
       
  2633         case CSS_PROP_BORDER_RIGHT_WIDTH:
       
  2634             style->setBorderRightWidth(width);
       
  2635             break;
       
  2636         case CSS_PROP_BORDER_BOTTOM_WIDTH:
       
  2637             style->setBorderBottomWidth(width);
       
  2638             break;
       
  2639         case CSS_PROP_BORDER_LEFT_WIDTH:
       
  2640             style->setBorderLeftWidth(width);
       
  2641             break;
       
  2642         case CSS_PROP_OUTLINE_WIDTH:
       
  2643             style->setOutlineWidth(width);
       
  2644             break;
       
  2645         case CSS_PROP__WEBKIT_COLUMN_RULE_WIDTH:
       
  2646             style->setColumnRuleWidth(width);
       
  2647             break;
       
  2648         default:
       
  2649             return;
       
  2650         }
       
  2651         return;
       
  2652     }
       
  2653 
       
  2654     case CSS_PROP_LETTER_SPACING:
       
  2655     case CSS_PROP_WORD_SPACING:
       
  2656     {
       
  2657         
       
  2658         if (isInherit) {
       
  2659             HANDLE_INHERIT_COND(CSS_PROP_LETTER_SPACING, letterSpacing, LetterSpacing)
       
  2660             HANDLE_INHERIT_COND(CSS_PROP_WORD_SPACING, wordSpacing, WordSpacing)
       
  2661             return;
       
  2662         }
       
  2663         else if (isInitial) {
       
  2664             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_LETTER_SPACING, LetterSpacing, LetterWordSpacing)
       
  2665             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_WORD_SPACING, WordSpacing, LetterWordSpacing)
       
  2666             return;
       
  2667         }
       
  2668         
       
  2669         int width = 0;
       
  2670         if (primitiveValue && primitiveValue->getIdent() == CSS_VAL_NORMAL){
       
  2671             width = 0;
       
  2672         } else {
       
  2673             if(!primitiveValue) return;
       
  2674             width = primitiveValue->computeLengthInt(style);
       
  2675         }
       
  2676         switch(id)
       
  2677         {
       
  2678         case CSS_PROP_LETTER_SPACING:
       
  2679             style->setLetterSpacing(width);
       
  2680             break;
       
  2681         case CSS_PROP_WORD_SPACING:
       
  2682             style->setWordSpacing(width);
       
  2683             break;
       
  2684             // ### needs the definitions in renderstyle
       
  2685         default: break;
       
  2686         }
       
  2687         return;
       
  2688     }
       
  2689 
       
  2690     case CSS_PROP_WORD_BREAK: {
       
  2691         HANDLE_INHERIT_AND_INITIAL(wordBreak, WordBreak)
       
  2692 
       
  2693         EWordBreak b;
       
  2694         switch (primitiveValue->getIdent()) {
       
  2695         case CSS_VAL_BREAK_ALL:
       
  2696             b = BreakAllWordBreak;
       
  2697             break;
       
  2698         case CSS_VAL_BREAK_WORD:
       
  2699             b = BreakWordBreak;
       
  2700             break;
       
  2701         case CSS_VAL_NORMAL:
       
  2702         default:
       
  2703             b = NormalWordBreak;
       
  2704             break;
       
  2705         }
       
  2706         style->setWordBreak(b);
       
  2707         return;
       
  2708     }
       
  2709 
       
  2710     case CSS_PROP_WORD_WRAP: {
       
  2711         HANDLE_INHERIT_AND_INITIAL(wordWrap, WordWrap)
       
  2712 
       
  2713         EWordWrap s;
       
  2714         switch(primitiveValue->getIdent()) {
       
  2715         case CSS_VAL_BREAK_WORD:
       
  2716             s = BreakWordWrap;
       
  2717             break;
       
  2718         case CSS_VAL_NORMAL:
       
  2719         default:
       
  2720             s = NormalWordWrap;
       
  2721             break;
       
  2722         }
       
  2723 
       
  2724         style->setWordWrap(s);
       
  2725         return;
       
  2726     }
       
  2727 
       
  2728     case CSS_PROP__WEBKIT_NBSP_MODE:
       
  2729     {
       
  2730         HANDLE_INHERIT_AND_INITIAL(nbspMode, NBSPMode)
       
  2731 
       
  2732         if (!primitiveValue->getIdent()) return;
       
  2733 
       
  2734         ENBSPMode m;
       
  2735         switch(primitiveValue->getIdent()) {
       
  2736         case CSS_VAL_SPACE:
       
  2737             m = SPACE;
       
  2738             break;
       
  2739         case CSS_VAL_NORMAL:
       
  2740         default:
       
  2741             m = NBNORMAL;
       
  2742             break;
       
  2743         }
       
  2744         style->setNBSPMode(m);
       
  2745         return;
       
  2746     }
       
  2747 
       
  2748     case CSS_PROP__WEBKIT_LINE_BREAK:
       
  2749     {
       
  2750         HANDLE_INHERIT_AND_INITIAL(khtmlLineBreak, KHTMLLineBreak)
       
  2751 
       
  2752         if (!primitiveValue->getIdent()) return;
       
  2753 
       
  2754         EKHTMLLineBreak b;
       
  2755         switch(primitiveValue->getIdent()) {
       
  2756         case CSS_VAL_AFTER_WHITE_SPACE:
       
  2757             b = AFTER_WHITE_SPACE;
       
  2758             break;
       
  2759         case CSS_VAL_NORMAL:
       
  2760         default:
       
  2761             b = LBNORMAL;
       
  2762             break;
       
  2763         }
       
  2764         style->setKHTMLLineBreak(b);
       
  2765         return;
       
  2766     }
       
  2767 
       
  2768     case CSS_PROP__WEBKIT_MATCH_NEAREST_MAIL_BLOCKQUOTE_COLOR:
       
  2769     {
       
  2770         HANDLE_INHERIT_AND_INITIAL(matchNearestMailBlockquoteColor, MatchNearestMailBlockquoteColor)
       
  2771 
       
  2772         if (!primitiveValue->getIdent()) return;
       
  2773 
       
  2774         EMatchNearestMailBlockquoteColor c;
       
  2775         switch(primitiveValue->getIdent()) {
       
  2776         case CSS_VAL_NORMAL:
       
  2777             c = BCNORMAL;
       
  2778             break;
       
  2779         case CSS_VAL_MATCH:
       
  2780         default:
       
  2781             c = MATCH;
       
  2782             break;
       
  2783         }
       
  2784         style->setMatchNearestMailBlockquoteColor(c);
       
  2785         return;
       
  2786     }
       
  2787 
       
  2788     case CSS_PROP_RESIZE:
       
  2789     {
       
  2790         HANDLE_INHERIT_AND_INITIAL(resize, Resize)
       
  2791 
       
  2792         if (!primitiveValue->getIdent()) return;
       
  2793 
       
  2794         EResize r = RESIZE_NONE;
       
  2795         switch(primitiveValue->getIdent()) {
       
  2796         case CSS_VAL_BOTH:
       
  2797             r = RESIZE_BOTH;
       
  2798             break;
       
  2799         case CSS_VAL_HORIZONTAL:
       
  2800             r = RESIZE_HORIZONTAL;
       
  2801             break;
       
  2802         case CSS_VAL_VERTICAL:
       
  2803             r = RESIZE_VERTICAL;
       
  2804             break;
       
  2805         case CSS_VAL_AUTO:
       
  2806             if (Settings* settings = m_document->settings())
       
  2807                 r = settings->textAreasAreResizable() ? RESIZE_BOTH : RESIZE_NONE;
       
  2808             break;
       
  2809         case CSS_VAL_NONE:
       
  2810         default:
       
  2811             r = RESIZE_NONE;
       
  2812             break;
       
  2813         }
       
  2814         style->setResize(r);
       
  2815         return;
       
  2816     }
       
  2817     
       
  2818     // length, percent
       
  2819     case CSS_PROP_MAX_WIDTH:
       
  2820         // +none +inherit
       
  2821         if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE)
       
  2822             apply = true;
       
  2823     case CSS_PROP_TOP:
       
  2824     case CSS_PROP_LEFT:
       
  2825     case CSS_PROP_RIGHT:
       
  2826     case CSS_PROP_BOTTOM:
       
  2827     case CSS_PROP_WIDTH:
       
  2828     case CSS_PROP_MIN_WIDTH:
       
  2829     case CSS_PROP_MARGIN_TOP:
       
  2830     case CSS_PROP_MARGIN_RIGHT:
       
  2831     case CSS_PROP_MARGIN_BOTTOM:
       
  2832     case CSS_PROP_MARGIN_LEFT:
       
  2833         // +inherit +auto
       
  2834         if (id == CSS_PROP_WIDTH || id == CSS_PROP_MIN_WIDTH || id == CSS_PROP_MAX_WIDTH) {
       
  2835             if (primitiveValue && primitiveValue->getIdent() == CSS_VAL_INTRINSIC) {
       
  2836                 l = Length(Intrinsic);
       
  2837                 apply = true;
       
  2838             }
       
  2839             else if (primitiveValue && primitiveValue->getIdent() == CSS_VAL_MIN_INTRINSIC) {
       
  2840                 l = Length(MinIntrinsic);
       
  2841                 apply = true;
       
  2842             }
       
  2843         }
       
  2844         if (id != CSS_PROP_MAX_WIDTH && primitiveValue && primitiveValue->getIdent() == CSS_VAL_AUTO)
       
  2845             apply = true;
       
  2846     case CSS_PROP_PADDING_TOP:
       
  2847     case CSS_PROP_PADDING_RIGHT:
       
  2848     case CSS_PROP_PADDING_BOTTOM:
       
  2849     case CSS_PROP_PADDING_LEFT:
       
  2850     case CSS_PROP_TEXT_INDENT:
       
  2851         // +inherit
       
  2852     {
       
  2853         if (isInherit) {
       
  2854             HANDLE_INHERIT_COND(CSS_PROP_MAX_WIDTH, maxWidth, MaxWidth)
       
  2855             HANDLE_INHERIT_COND(CSS_PROP_BOTTOM, bottom, Bottom)
       
  2856             HANDLE_INHERIT_COND(CSS_PROP_TOP, top, Top)
       
  2857             HANDLE_INHERIT_COND(CSS_PROP_LEFT, left, Left)
       
  2858             HANDLE_INHERIT_COND(CSS_PROP_RIGHT, right, Right)
       
  2859             HANDLE_INHERIT_COND(CSS_PROP_WIDTH, width, Width)
       
  2860             HANDLE_INHERIT_COND(CSS_PROP_MIN_WIDTH, minWidth, MinWidth)
       
  2861             HANDLE_INHERIT_COND(CSS_PROP_PADDING_TOP, paddingTop, PaddingTop)
       
  2862             HANDLE_INHERIT_COND(CSS_PROP_PADDING_RIGHT, paddingRight, PaddingRight)
       
  2863             HANDLE_INHERIT_COND(CSS_PROP_PADDING_BOTTOM, paddingBottom, PaddingBottom)
       
  2864             HANDLE_INHERIT_COND(CSS_PROP_PADDING_LEFT, paddingLeft, PaddingLeft)
       
  2865             HANDLE_INHERIT_COND(CSS_PROP_MARGIN_TOP, marginTop, MarginTop)
       
  2866             HANDLE_INHERIT_COND(CSS_PROP_MARGIN_RIGHT, marginRight, MarginRight)
       
  2867             HANDLE_INHERIT_COND(CSS_PROP_MARGIN_BOTTOM, marginBottom, MarginBottom)
       
  2868             HANDLE_INHERIT_COND(CSS_PROP_MARGIN_LEFT, marginLeft, MarginLeft)
       
  2869             HANDLE_INHERIT_COND(CSS_PROP_TEXT_INDENT, textIndent, TextIndent)
       
  2870             return;
       
  2871         }
       
  2872         else if (isInitial) {
       
  2873             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MAX_WIDTH, MaxWidth, MaxSize)
       
  2874             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_BOTTOM, Bottom, Offset)
       
  2875             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_TOP, Top, Offset)
       
  2876             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_LEFT, Left, Offset)
       
  2877             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_RIGHT, Right, Offset)
       
  2878             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_WIDTH, Width, Size)
       
  2879             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MIN_WIDTH, MinWidth, MinSize)
       
  2880             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_TOP, PaddingTop, Padding)
       
  2881             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_RIGHT, PaddingRight, Padding)
       
  2882             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_BOTTOM, PaddingBottom, Padding)
       
  2883             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_PADDING_LEFT, PaddingLeft, Padding)
       
  2884             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_TOP, MarginTop, Margin)
       
  2885             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_RIGHT, MarginRight, Margin)
       
  2886             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_BOTTOM, MarginBottom, Margin)
       
  2887             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MARGIN_LEFT, MarginLeft, Margin)
       
  2888             HANDLE_INITIAL_COND(CSS_PROP_TEXT_INDENT, TextIndent)
       
  2889             return;
       
  2890         } 
       
  2891 
       
  2892         if (primitiveValue && !apply) {
       
  2893             int type = primitiveValue->primitiveType();
       
  2894             if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
       
  2895                 // Handle our quirky margin units if we have them.
       
  2896                 l = Length(primitiveValue->computeLengthIntForLength(style), Fixed, 
       
  2897                            primitiveValue->isQuirkValue());
       
  2898             else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  2899                 l = Length(primitiveValue->getDoubleValue(), Percent);
       
  2900             else
       
  2901                 return;
       
  2902             if (id == CSS_PROP_PADDING_LEFT || id == CSS_PROP_PADDING_RIGHT ||
       
  2903                 id == CSS_PROP_PADDING_TOP || id == CSS_PROP_PADDING_BOTTOM)
       
  2904                 // Padding can't be negative
       
  2905                 apply = !((l.isFixed() || l.isPercent()) && l.calcValue(100) < 0);
       
  2906             else
       
  2907                 apply = true;
       
  2908         }
       
  2909         if(!apply) return;
       
  2910         switch(id)
       
  2911             {
       
  2912             case CSS_PROP_MAX_WIDTH:
       
  2913                 style->setMaxWidth(l); break;
       
  2914             case CSS_PROP_BOTTOM:
       
  2915                 style->setBottom(l); break;
       
  2916             case CSS_PROP_TOP:
       
  2917                 style->setTop(l); break;
       
  2918             case CSS_PROP_LEFT:
       
  2919                 style->setLeft(l); break;
       
  2920             case CSS_PROP_RIGHT:
       
  2921                 style->setRight(l); break;
       
  2922             case CSS_PROP_WIDTH:
       
  2923                 style->setWidth(l); break;
       
  2924             case CSS_PROP_MIN_WIDTH:
       
  2925                 style->setMinWidth(l); break;
       
  2926             case CSS_PROP_PADDING_TOP:
       
  2927                 style->setPaddingTop(l); break;
       
  2928             case CSS_PROP_PADDING_RIGHT:
       
  2929                 style->setPaddingRight(l); break;
       
  2930             case CSS_PROP_PADDING_BOTTOM:
       
  2931                 style->setPaddingBottom(l); break;
       
  2932             case CSS_PROP_PADDING_LEFT:
       
  2933                 style->setPaddingLeft(l); break;
       
  2934             case CSS_PROP_MARGIN_TOP:
       
  2935                 style->setMarginTop(l); break;
       
  2936             case CSS_PROP_MARGIN_RIGHT:
       
  2937                 style->setMarginRight(l); break;
       
  2938             case CSS_PROP_MARGIN_BOTTOM:
       
  2939                 style->setMarginBottom(l); break;
       
  2940             case CSS_PROP_MARGIN_LEFT:
       
  2941                 style->setMarginLeft(l); break;
       
  2942             case CSS_PROP_TEXT_INDENT:
       
  2943                 style->setTextIndent(l); break;
       
  2944             default: break;
       
  2945             }
       
  2946         return;
       
  2947     }
       
  2948 
       
  2949     case CSS_PROP_MAX_HEIGHT:
       
  2950         if (primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE) {
       
  2951             l = Length(undefinedLength, Fixed);
       
  2952             apply = true;
       
  2953         }
       
  2954     case CSS_PROP_HEIGHT:
       
  2955     case CSS_PROP_MIN_HEIGHT:
       
  2956         if (primitiveValue && primitiveValue->getIdent() == CSS_VAL_INTRINSIC) {
       
  2957             l = Length(Intrinsic);
       
  2958             apply = true;
       
  2959         } else if (primitiveValue && primitiveValue->getIdent() == CSS_VAL_MIN_INTRINSIC) {
       
  2960             l = Length(MinIntrinsic);
       
  2961             apply = true;
       
  2962         } else if (id != CSS_PROP_MAX_HEIGHT && primitiveValue && primitiveValue->getIdent() == CSS_VAL_AUTO)
       
  2963             apply = true;
       
  2964         if (isInherit) {
       
  2965             HANDLE_INHERIT_COND(CSS_PROP_MAX_HEIGHT, maxHeight, MaxHeight)
       
  2966             HANDLE_INHERIT_COND(CSS_PROP_HEIGHT, height, Height)
       
  2967             HANDLE_INHERIT_COND(CSS_PROP_MIN_HEIGHT, minHeight, MinHeight)
       
  2968             return;
       
  2969         }
       
  2970         if (isInitial) {
       
  2971             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MAX_HEIGHT, MaxHeight, MaxSize)
       
  2972             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_HEIGHT, Height, Size)
       
  2973             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_MIN_HEIGHT, MinHeight, MinSize)
       
  2974             return;
       
  2975         }
       
  2976 
       
  2977         if (primitiveValue && !apply) {
       
  2978             unsigned short type = primitiveValue->primitiveType();
       
  2979             if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
       
  2980                 l = Length(primitiveValue->computeLengthIntForLength(style), Fixed);
       
  2981             else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  2982                 l = Length(primitiveValue->getDoubleValue(), Percent);
       
  2983             else
       
  2984                 return;
       
  2985             apply = true;
       
  2986         }
       
  2987         if (apply)
       
  2988             switch (id) {
       
  2989                 case CSS_PROP_MAX_HEIGHT:
       
  2990                     style->setMaxHeight(l);
       
  2991                     break;
       
  2992                 case CSS_PROP_HEIGHT:
       
  2993                     style->setHeight(l);
       
  2994                     break;
       
  2995                 case CSS_PROP_MIN_HEIGHT:
       
  2996                     style->setMinHeight(l);
       
  2997                     break;
       
  2998             }
       
  2999         return;
       
  3000 
       
  3001     case CSS_PROP_VERTICAL_ALIGN:
       
  3002         HANDLE_INHERIT_AND_INITIAL(verticalAlign, VerticalAlign)
       
  3003         if (!primitiveValue) return;
       
  3004         if (primitiveValue->getIdent()) {
       
  3005           EVerticalAlign align;
       
  3006 
       
  3007           switch(primitiveValue->getIdent())
       
  3008             {
       
  3009                 case CSS_VAL_TOP:
       
  3010                     align = TOP; break;
       
  3011                 case CSS_VAL_BOTTOM:
       
  3012                     align = BOTTOM; break;
       
  3013                 case CSS_VAL_MIDDLE:
       
  3014                     align = MIDDLE; break;
       
  3015                 case CSS_VAL_BASELINE:
       
  3016                     align = BASELINE; break;
       
  3017                 case CSS_VAL_TEXT_BOTTOM:
       
  3018                     align = TEXT_BOTTOM; break;
       
  3019                 case CSS_VAL_TEXT_TOP:
       
  3020                     align = TEXT_TOP; break;
       
  3021                 case CSS_VAL_SUB:
       
  3022                     align = SUB; break;
       
  3023                 case CSS_VAL_SUPER:
       
  3024                     align = SUPER; break;
       
  3025                 case CSS_VAL__WEBKIT_BASELINE_MIDDLE:
       
  3026                     align = BASELINE_MIDDLE; break;
       
  3027                 default:
       
  3028                     return;
       
  3029             }
       
  3030           style->setVerticalAlign(align);
       
  3031           return;
       
  3032         } else {
       
  3033           int type = primitiveValue->primitiveType();
       
  3034           Length l;
       
  3035           if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
       
  3036             l = Length(primitiveValue->computeLengthIntForLength(style), Fixed);
       
  3037           else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  3038             l = Length(primitiveValue->getDoubleValue(), Percent);
       
  3039 
       
  3040           style->setVerticalAlign(LENGTH);
       
  3041           style->setVerticalAlignLength(l);
       
  3042         }
       
  3043         return;
       
  3044 
       
  3045     case CSS_PROP_FONT_SIZE:
       
  3046     {
       
  3047         FontDescription fontDescription = style->fontDescription();
       
  3048         fontDescription.setKeywordSize(0);
       
  3049         bool familyIsFixed = fontDescription.genericFamily() == FontDescription::MonospaceFamily;
       
  3050         float oldSize = 0;
       
  3051         float size = 0;
       
  3052         
       
  3053         bool parentIsAbsoluteSize = false;
       
  3054         if (parentNode) {
       
  3055             oldSize = parentStyle->fontDescription().specifiedSize();
       
  3056             parentIsAbsoluteSize = parentStyle->fontDescription().isAbsoluteSize();
       
  3057         }
       
  3058 
       
  3059         if (isInherit) {
       
  3060             size = oldSize;
       
  3061             if (parentNode)
       
  3062                 fontDescription.setKeywordSize(parentStyle->fontDescription().keywordSize());
       
  3063         } else if (isInitial) {
       
  3064             size = fontSizeForKeyword(CSS_VAL_MEDIUM, style->htmlHacks(), familyIsFixed);
       
  3065             fontDescription.setKeywordSize(CSS_VAL_MEDIUM - CSS_VAL_XX_SMALL + 1);
       
  3066         } else if (primitiveValue->getIdent()) {
       
  3067             // Keywords are being used.
       
  3068             switch (primitiveValue->getIdent()) {
       
  3069                 case CSS_VAL_XX_SMALL:
       
  3070                 case CSS_VAL_X_SMALL:
       
  3071                 case CSS_VAL_SMALL:
       
  3072                 case CSS_VAL_MEDIUM:
       
  3073                 case CSS_VAL_LARGE:
       
  3074                 case CSS_VAL_X_LARGE:
       
  3075                 case CSS_VAL_XX_LARGE:
       
  3076                 case CSS_VAL__WEBKIT_XXX_LARGE:
       
  3077                     size = fontSizeForKeyword(primitiveValue->getIdent(), style->htmlHacks(), familyIsFixed);
       
  3078                     fontDescription.setKeywordSize(primitiveValue->getIdent() - CSS_VAL_XX_SMALL + 1);
       
  3079                     break;
       
  3080                 case CSS_VAL_LARGER:
       
  3081                     size = largerFontSize(oldSize, style->htmlHacks());
       
  3082                     break;
       
  3083                 case CSS_VAL_SMALLER:
       
  3084                     size = smallerFontSize(oldSize, style->htmlHacks());
       
  3085                     break;
       
  3086                 default:
       
  3087                     return;
       
  3088             }
       
  3089 
       
  3090             fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize && 
       
  3091                                               (primitiveValue->getIdent() == CSS_VAL_LARGER ||
       
  3092                                                primitiveValue->getIdent() == CSS_VAL_SMALLER));
       
  3093         } else {
       
  3094             int type = primitiveValue->primitiveType();
       
  3095             fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize ||
       
  3096                                               (type != CSSPrimitiveValue::CSS_PERCENTAGE &&
       
  3097                                                type != CSSPrimitiveValue::CSS_EMS && 
       
  3098                                                type != CSSPrimitiveValue::CSS_EXS));
       
  3099             if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
       
  3100                 size = primitiveValue->computeLengthFloat(parentStyle, false);
       
  3101             else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  3102                 size = (primitiveValue->getFloatValue() * oldSize) / 100.0f;
       
  3103             else
       
  3104                 return;
       
  3105         }
       
  3106 
       
  3107         if (size < 0)
       
  3108             return;
       
  3109 
       
  3110         setFontSize(fontDescription, size);
       
  3111         if (style->setFontDescription(fontDescription))
       
  3112             fontDirty = true;
       
  3113         return;
       
  3114     }
       
  3115 
       
  3116     case CSS_PROP_Z_INDEX: {
       
  3117         if (isInherit) {
       
  3118             if (parentStyle->hasAutoZIndex())
       
  3119                 style->setHasAutoZIndex();
       
  3120             else
       
  3121                 style->setZIndex(parentStyle->zIndex());
       
  3122             return;
       
  3123         } else if (isInitial || primitiveValue->getIdent() == CSS_VAL_AUTO) {
       
  3124             style->setHasAutoZIndex();
       
  3125             return;
       
  3126         }
       
  3127         
       
  3128         // FIXME: Should clamp all sorts of other integer properties too.
       
  3129         const double minIntAsDouble = INT_MIN;
       
  3130         const double maxIntAsDouble = INT_MAX;
       
  3131         style->setZIndex(static_cast<int>(max(minIntAsDouble, min(primitiveValue->getDoubleValue(), maxIntAsDouble))));
       
  3132         return;
       
  3133     }
       
  3134     case CSS_PROP_WIDOWS:
       
  3135     {
       
  3136         HANDLE_INHERIT_AND_INITIAL(widows, Widows)
       
  3137         if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
       
  3138             return;
       
  3139         style->setWidows(primitiveValue->getIntValue());
       
  3140         return;
       
  3141     }
       
  3142         
       
  3143     case CSS_PROP_ORPHANS:
       
  3144     {
       
  3145         HANDLE_INHERIT_AND_INITIAL(orphans, Orphans)
       
  3146         if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
       
  3147             return;
       
  3148         style->setOrphans(primitiveValue->getIntValue());
       
  3149         return;
       
  3150     }        
       
  3151 
       
  3152 // length, percent, number
       
  3153     case CSS_PROP_LINE_HEIGHT:
       
  3154     {
       
  3155         HANDLE_INHERIT_AND_INITIAL(lineHeight, LineHeight)
       
  3156         if(!primitiveValue) return;
       
  3157         Length lineHeight;
       
  3158         int type = primitiveValue->primitiveType();
       
  3159         if (primitiveValue->getIdent() == CSS_VAL_NORMAL)
       
  3160             lineHeight = Length(-100.0, Percent);
       
  3161         else if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) {
       
  3162             double multiplier = 1.0;
       
  3163             // Scale for the font zoom factor only for types other than "em" and "ex", since those are
       
  3164             // already based on the font size.
       
  3165             if (type != CSSPrimitiveValue::CSS_EMS && type != CSSPrimitiveValue::CSS_EXS && style->textSizeAdjust() && m_document->frame()) {
       
  3166                 multiplier = m_document->frame()->zoomFactor() / 100.0;
       
  3167             }
       
  3168             lineHeight = Length(primitiveValue->computeLengthIntForLength(style, multiplier), Fixed);
       
  3169         } else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  3170             lineHeight = Length((style->fontSize() * primitiveValue->getIntValue()) / 100, Fixed);
       
  3171         else if (type == CSSPrimitiveValue::CSS_NUMBER)
       
  3172             lineHeight = Length(primitiveValue->getDoubleValue() * 100.0, Percent);
       
  3173         else
       
  3174             return;
       
  3175 
       
  3176 #if PLATFORM(SYMBIAN)
       
  3177         if (lineHeight.type() == Fixed)
       
  3178             lineHeight.setValue(lineHeight.value()-1);
       
  3179 #endif
       
  3180         style->setLineHeight(lineHeight);
       
  3181 
       
  3182         return;
       
  3183     }
       
  3184 
       
  3185 // string
       
  3186     case CSS_PROP_TEXT_ALIGN:
       
  3187     {
       
  3188         HANDLE_INHERIT_AND_INITIAL(textAlign, TextAlign)
       
  3189         if (!primitiveValue) return;
       
  3190         if (primitiveValue->getIdent())
       
  3191             style->setTextAlign((ETextAlign) (primitiveValue->getIdent() - CSS_VAL__WEBKIT_AUTO));
       
  3192         return;
       
  3193     }
       
  3194 
       
  3195 // rect
       
  3196     case CSS_PROP_CLIP:
       
  3197     {
       
  3198         Length top;
       
  3199         Length right;
       
  3200         Length bottom;
       
  3201         Length left;
       
  3202         bool hasClip = true;
       
  3203         if (isInherit) {
       
  3204             if (parentStyle->hasClip()) {
       
  3205                 top = parentStyle->clipTop();
       
  3206                 right = parentStyle->clipRight();
       
  3207                 bottom = parentStyle->clipBottom();
       
  3208                 left = parentStyle->clipLeft();
       
  3209             }
       
  3210             else {
       
  3211                 hasClip = false;
       
  3212                 top = right = bottom = left = Length();
       
  3213             }
       
  3214         } else if (isInitial) {
       
  3215             hasClip = false;
       
  3216             top = right = bottom = left = Length();
       
  3217         } else if (!primitiveValue) {
       
  3218             return;
       
  3219         } else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RECT) {
       
  3220             Rect* rect = primitiveValue->getRectValue();
       
  3221             if (!rect)
       
  3222                 return;
       
  3223             top = convertToLength(rect->top(), style);
       
  3224             right = convertToLength(rect->right(), style);
       
  3225             bottom = convertToLength(rect->bottom(), style);
       
  3226             left = convertToLength(rect->left(), style);
       
  3227 
       
  3228         } else if (primitiveValue->getIdent() != CSS_VAL_AUTO) {
       
  3229             return;
       
  3230         }
       
  3231         style->setClip(top, right, bottom, left);
       
  3232         style->setHasClip(hasClip);
       
  3233     
       
  3234         // rect, ident
       
  3235         return;
       
  3236     }
       
  3237 
       
  3238 // lists
       
  3239     case CSS_PROP_CONTENT:
       
  3240         // list of string, uri, counter, attr, i
       
  3241     {
       
  3242         // FIXME: In CSS3, it will be possible to inherit content.  In CSS2 it is not.  This
       
  3243         // note is a reminder that eventually "inherit" needs to be supported.
       
  3244 
       
  3245         if (isInitial) {
       
  3246             style->clearContent();
       
  3247             return;
       
  3248         }
       
  3249         
       
  3250         if (!value->isValueList())
       
  3251             return;
       
  3252 
       
  3253         CSSValueList* list = static_cast<CSSValueList*>(value);
       
  3254         int len = list->length();
       
  3255 
       
  3256         bool didSet = false;
       
  3257         for (int i = 0; i < len; i++) {
       
  3258             CSSValue* item = list->item(i);
       
  3259             if (!item->isPrimitiveValue())
       
  3260                 continue;
       
  3261             
       
  3262             CSSPrimitiveValue* val = static_cast<CSSPrimitiveValue*>(item);
       
  3263             switch (val->primitiveType()) {
       
  3264                 case CSSPrimitiveValue::CSS_STRING:
       
  3265                     style->setContent(val->getStringValue().impl(), didSet);
       
  3266                     didSet = true;
       
  3267                     break;
       
  3268                 case CSSPrimitiveValue::CSS_ATTR: {
       
  3269                     // FIXME: Can a namespace be specified for an attr(foo)?
       
  3270                     if (style->styleType() == RenderStyle::NOPSEUDO)
       
  3271                         style->setUnique();
       
  3272                     else
       
  3273                         parentStyle->setUnique();
       
  3274                     QualifiedName attr(nullAtom, val->getStringValue().impl(), nullAtom);
       
  3275                     style->setContent(element->getAttribute(attr).impl(), didSet);
       
  3276                     didSet = true;
       
  3277                     // register the fact that the attribute value affects the style
       
  3278                     m_selectorAttrs.add(attr.localName().impl());
       
  3279                     break;
       
  3280                 }
       
  3281                 case CSSPrimitiveValue::CSS_URI: {
       
  3282                     CSSImageValue *image = static_cast<CSSImageValue*>(val);
       
  3283                     style->setContent(image->image(element->document()->docLoader()), didSet);
       
  3284                     didSet = true;
       
  3285                     break;
       
  3286                 }
       
  3287                 case CSSPrimitiveValue::CSS_COUNTER: {
       
  3288                     Counter* counterValue = val->getCounterValue();
       
  3289                     CounterContent* counter = new CounterContent(counterValue->identifier(),
       
  3290                         (EListStyleType)counterValue->listStyleNumber(), counterValue->separator());
       
  3291                     style->setContent(counter, didSet);
       
  3292                     didSet = true;
       
  3293                 }
       
  3294             }
       
  3295         }
       
  3296         if (!didSet)
       
  3297             style->clearContent();
       
  3298         return;
       
  3299     }
       
  3300 
       
  3301     case CSS_PROP_COUNTER_INCREMENT:
       
  3302         applyCounterList(style, value->isValueList() ? static_cast<CSSValueList*>(value) : 0, false);
       
  3303         return;
       
  3304     case CSS_PROP_COUNTER_RESET:
       
  3305         applyCounterList(style, value->isValueList() ? static_cast<CSSValueList*>(value) : 0, true);
       
  3306         return;
       
  3307 
       
  3308     case CSS_PROP_FONT_FAMILY: {
       
  3309         // list of strings and ids
       
  3310         if (isInherit) {
       
  3311             FontDescription parentFontDescription = parentStyle->fontDescription();
       
  3312             FontDescription fontDescription = style->fontDescription();
       
  3313             fontDescription.setGenericFamily(parentFontDescription.genericFamily());
       
  3314             fontDescription.setFamily(parentFontDescription.firstFamily());
       
  3315             if (style->setFontDescription(fontDescription))
       
  3316                 fontDirty = true;
       
  3317             return;
       
  3318         }
       
  3319         else if (isInitial) {
       
  3320             FontDescription initialDesc = FontDescription();
       
  3321             FontDescription fontDescription = style->fontDescription();
       
  3322             // We need to adjust the size to account for the generic family change from monospace
       
  3323             // to non-monospace.
       
  3324             if (fontDescription.keywordSize() && fontDescription.genericFamily() == FontDescription::MonospaceFamily)
       
  3325                 setFontSize(fontDescription, fontSizeForKeyword(CSS_VAL_XX_SMALL + fontDescription.keywordSize() - 1, style->htmlHacks(), false));
       
  3326             fontDescription.setGenericFamily(initialDesc.genericFamily());
       
  3327             fontDescription.setFamily(initialDesc.firstFamily());
       
  3328             if (style->setFontDescription(fontDescription))
       
  3329                 fontDirty = true;
       
  3330             return;
       
  3331         }
       
  3332         
       
  3333         if (!value->isValueList()) return;
       
  3334         FontDescription fontDescription = style->fontDescription();
       
  3335         CSSValueList *list = static_cast<CSSValueList*>(value);
       
  3336         int len = list->length();
       
  3337         FontFamily& firstFamily = fontDescription.firstFamily();
       
  3338         FontFamily *currFamily = 0;
       
  3339         
       
  3340         // Before mapping in a new font-family property, we should reset the generic family.
       
  3341         bool oldFamilyIsMonospace = fontDescription.genericFamily() == FontDescription::MonospaceFamily;
       
  3342         fontDescription.setGenericFamily(FontDescription::NoFamily);
       
  3343 
       
  3344         for(int i = 0; i < len; i++) {
       
  3345             CSSValue *item = list->item(i);
       
  3346             if(!item->isPrimitiveValue()) continue;
       
  3347             CSSPrimitiveValue *val = static_cast<CSSPrimitiveValue*>(item);
       
  3348             AtomicString face;
       
  3349             Settings* settings = m_document->settings();
       
  3350             if (val->primitiveType() == CSSPrimitiveValue::CSS_STRING)
       
  3351                 face = static_cast<FontFamilyValue*>(val)->fontName();
       
  3352             else if (val->primitiveType() == CSSPrimitiveValue::CSS_IDENT && settings) {
       
  3353                 switch (val->getIdent()) {
       
  3354                     case CSS_VAL__WEBKIT_BODY:
       
  3355                         face = settings->standardFontFamily();
       
  3356                         break;
       
  3357                     case CSS_VAL_SERIF:
       
  3358                         face = settings->serifFontFamily();
       
  3359                         fontDescription.setGenericFamily(FontDescription::SerifFamily);
       
  3360                         break;
       
  3361                     case CSS_VAL_SANS_SERIF:
       
  3362                         face = settings->sansSerifFontFamily();
       
  3363                         fontDescription.setGenericFamily(FontDescription::SansSerifFamily);
       
  3364                         break;
       
  3365                     case CSS_VAL_CURSIVE:
       
  3366                         face = settings->cursiveFontFamily();
       
  3367                         fontDescription.setGenericFamily(FontDescription::CursiveFamily);
       
  3368                         break;
       
  3369                     case CSS_VAL_FANTASY:
       
  3370                         face = settings->fantasyFontFamily();
       
  3371                         fontDescription.setGenericFamily(FontDescription::FantasyFamily);
       
  3372                         break;
       
  3373                     case CSS_VAL_MONOSPACE:
       
  3374                         face = settings->fixedFontFamily();
       
  3375                         fontDescription.setGenericFamily(FontDescription::MonospaceFamily);
       
  3376                         break;
       
  3377                 }
       
  3378             }
       
  3379     
       
  3380             if (!face.isEmpty()) {
       
  3381                 if (!currFamily) {
       
  3382                     // Filling in the first family.
       
  3383                     firstFamily.setFamily(face);
       
  3384                     currFamily = &firstFamily;
       
  3385                 }
       
  3386                 else {
       
  3387                     FontFamily *newFamily = new FontFamily;
       
  3388                     newFamily->setFamily(face);
       
  3389                     currFamily->appendFamily(newFamily);
       
  3390                     currFamily = newFamily;
       
  3391                 }
       
  3392     
       
  3393                 if (fontDescription.keywordSize() && (fontDescription.genericFamily() == FontDescription::MonospaceFamily) != oldFamilyIsMonospace)
       
  3394                     setFontSize(fontDescription, fontSizeForKeyword(CSS_VAL_XX_SMALL + fontDescription.keywordSize() - 1, style->htmlHacks(), !oldFamilyIsMonospace));
       
  3395             
       
  3396                 if (style->setFontDescription(fontDescription))
       
  3397                     fontDirty = true;
       
  3398             }
       
  3399         }
       
  3400       return;
       
  3401     }
       
  3402     case CSS_PROP_TEXT_DECORATION: {
       
  3403         // list of ident
       
  3404         HANDLE_INHERIT_AND_INITIAL(textDecoration, TextDecoration)
       
  3405         int t = RenderStyle::initialTextDecoration();
       
  3406         if(primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE) {
       
  3407             // do nothing
       
  3408         } else {
       
  3409             if(!value->isValueList()) return;
       
  3410             CSSValueList *list = static_cast<CSSValueList*>(value);
       
  3411             int len = list->length();
       
  3412             for(int i = 0; i < len; i++)
       
  3413             {
       
  3414                 CSSValue *item = list->item(i);
       
  3415                 if(!item->isPrimitiveValue()) continue;
       
  3416                 primitiveValue = static_cast<CSSPrimitiveValue*>(item);
       
  3417                 switch(primitiveValue->getIdent())
       
  3418                 {
       
  3419                     case CSS_VAL_NONE:
       
  3420                         t = TDNONE; break;
       
  3421                     case CSS_VAL_UNDERLINE:
       
  3422                         t |= UNDERLINE; break;
       
  3423                     case CSS_VAL_OVERLINE:
       
  3424                         t |= OVERLINE; break;
       
  3425                     case CSS_VAL_LINE_THROUGH:
       
  3426                         t |= LINE_THROUGH; break;
       
  3427                     case CSS_VAL_BLINK:
       
  3428                         t |= BLINK; break;
       
  3429                     default:
       
  3430                         return;
       
  3431                 }
       
  3432             }
       
  3433         }
       
  3434 
       
  3435         style->setTextDecoration(t);
       
  3436         return;
       
  3437     }
       
  3438 
       
  3439 // shorthand properties
       
  3440     case CSS_PROP_BACKGROUND:
       
  3441         if (isInitial) {
       
  3442             style->clearBackgroundLayers();
       
  3443             style->setBackgroundColor(Color());
       
  3444             return;
       
  3445         }
       
  3446         else if (isInherit) {
       
  3447             style->inheritBackgroundLayers(*parentStyle->backgroundLayers());
       
  3448             style->setBackgroundColor(parentStyle->backgroundColor());
       
  3449         }
       
  3450         return;
       
  3451     case CSS_PROP_BORDER:
       
  3452     case CSS_PROP_BORDER_STYLE:
       
  3453     case CSS_PROP_BORDER_WIDTH:
       
  3454     case CSS_PROP_BORDER_COLOR:
       
  3455         if (id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_COLOR)
       
  3456         {
       
  3457             if (isInherit) {
       
  3458                 style->setBorderTopColor(parentStyle->borderTopColor());
       
  3459                 style->setBorderBottomColor(parentStyle->borderBottomColor());
       
  3460                 style->setBorderLeftColor(parentStyle->borderLeftColor());
       
  3461                 style->setBorderRightColor(parentStyle->borderRightColor());
       
  3462             }
       
  3463             else if (isInitial) {
       
  3464                 style->setBorderTopColor(Color()); // Reset to invalid color so currentColor is used instead.
       
  3465                 style->setBorderBottomColor(Color());
       
  3466                 style->setBorderLeftColor(Color());
       
  3467                 style->setBorderRightColor(Color());
       
  3468             }
       
  3469         }
       
  3470         if (id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_STYLE)
       
  3471         {
       
  3472             if (isInherit) {
       
  3473                 style->setBorderTopStyle(parentStyle->borderTopStyle());
       
  3474                 style->setBorderBottomStyle(parentStyle->borderBottomStyle());
       
  3475                 style->setBorderLeftStyle(parentStyle->borderLeftStyle());
       
  3476                 style->setBorderRightStyle(parentStyle->borderRightStyle());
       
  3477             }
       
  3478             else if (isInitial) {
       
  3479                 style->setBorderTopStyle(RenderStyle::initialBorderStyle());
       
  3480                 style->setBorderBottomStyle(RenderStyle::initialBorderStyle());
       
  3481                 style->setBorderLeftStyle(RenderStyle::initialBorderStyle());
       
  3482                 style->setBorderRightStyle(RenderStyle::initialBorderStyle());
       
  3483             }
       
  3484         }
       
  3485         if (id == CSS_PROP_BORDER || id == CSS_PROP_BORDER_WIDTH)
       
  3486         {
       
  3487             if (isInherit) {
       
  3488                 style->setBorderTopWidth(parentStyle->borderTopWidth());
       
  3489                 style->setBorderBottomWidth(parentStyle->borderBottomWidth());
       
  3490                 style->setBorderLeftWidth(parentStyle->borderLeftWidth());
       
  3491                 style->setBorderRightWidth(parentStyle->borderRightWidth());
       
  3492             }
       
  3493             else if (isInitial) {
       
  3494                 style->setBorderTopWidth(RenderStyle::initialBorderWidth());
       
  3495                 style->setBorderBottomWidth(RenderStyle::initialBorderWidth());
       
  3496                 style->setBorderLeftWidth(RenderStyle::initialBorderWidth());
       
  3497                 style->setBorderRightWidth(RenderStyle::initialBorderWidth());
       
  3498             }
       
  3499         }
       
  3500         return;
       
  3501     case CSS_PROP_BORDER_TOP:
       
  3502         if (isInherit) {
       
  3503             style->setBorderTopColor(parentStyle->borderTopColor());
       
  3504             style->setBorderTopStyle(parentStyle->borderTopStyle());
       
  3505             style->setBorderTopWidth(parentStyle->borderTopWidth());
       
  3506         }
       
  3507         else if (isInitial)
       
  3508             style->resetBorderTop();
       
  3509         return;
       
  3510     case CSS_PROP_BORDER_RIGHT:
       
  3511         if (isInherit) {
       
  3512             style->setBorderRightColor(parentStyle->borderRightColor());
       
  3513             style->setBorderRightStyle(parentStyle->borderRightStyle());
       
  3514             style->setBorderRightWidth(parentStyle->borderRightWidth());
       
  3515         }
       
  3516         else if (isInitial)
       
  3517             style->resetBorderRight();
       
  3518         return;
       
  3519     case CSS_PROP_BORDER_BOTTOM:
       
  3520         if (isInherit) {
       
  3521             style->setBorderBottomColor(parentStyle->borderBottomColor());
       
  3522             style->setBorderBottomStyle(parentStyle->borderBottomStyle());
       
  3523             style->setBorderBottomWidth(parentStyle->borderBottomWidth());
       
  3524         }
       
  3525         else if (isInitial)
       
  3526             style->resetBorderBottom();
       
  3527         return;
       
  3528     case CSS_PROP_BORDER_LEFT:
       
  3529         if (isInherit) {
       
  3530             style->setBorderLeftColor(parentStyle->borderLeftColor());
       
  3531             style->setBorderLeftStyle(parentStyle->borderLeftStyle());
       
  3532             style->setBorderLeftWidth(parentStyle->borderLeftWidth());
       
  3533         }
       
  3534         else if (isInitial)
       
  3535             style->resetBorderLeft();
       
  3536         return;
       
  3537     case CSS_PROP_MARGIN:
       
  3538         if (isInherit) {
       
  3539             style->setMarginTop(parentStyle->marginTop());
       
  3540             style->setMarginBottom(parentStyle->marginBottom());
       
  3541             style->setMarginLeft(parentStyle->marginLeft());
       
  3542             style->setMarginRight(parentStyle->marginRight());
       
  3543         }
       
  3544         else if (isInitial)
       
  3545             style->resetMargin();
       
  3546         return;
       
  3547     case CSS_PROP_PADDING:
       
  3548         if (isInherit) {
       
  3549             style->setPaddingTop(parentStyle->paddingTop());
       
  3550             style->setPaddingBottom(parentStyle->paddingBottom());
       
  3551             style->setPaddingLeft(parentStyle->paddingLeft());
       
  3552             style->setPaddingRight(parentStyle->paddingRight());
       
  3553         }
       
  3554         else if (isInitial)
       
  3555             style->resetPadding();
       
  3556         return;
       
  3557     case CSS_PROP_FONT:
       
  3558         if (isInherit) {
       
  3559             FontDescription fontDescription = parentStyle->fontDescription();
       
  3560             style->setLineHeight(parentStyle->lineHeight());
       
  3561             m_lineHeightValue = 0;
       
  3562             if (style->setFontDescription(fontDescription))
       
  3563                 fontDirty = true;
       
  3564         } else if (isInitial) {
       
  3565             FontDescription fontDescription;
       
  3566             fontDescription.setGenericFamily(FontDescription::StandardFamily);
       
  3567             style->setLineHeight(RenderStyle::initialLineHeight());
       
  3568             m_lineHeightValue = 0;
       
  3569             if (style->setFontDescription(fontDescription))
       
  3570                 fontDirty = true;
       
  3571         } else if (primitiveValue) {
       
  3572             style->setLineHeight(RenderStyle::initialLineHeight());
       
  3573             m_lineHeightValue = 0;
       
  3574             FontDescription fontDescription;
       
  3575             theme()->systemFont(primitiveValue->getIdent(), fontDescription);
       
  3576             // Double-check and see if the theme did anything.  If not, don't bother updating the font.
       
  3577             if (fontDescription.isAbsoluteSize()) {
       
  3578                 // Handle the zoom factor.
       
  3579                 fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(fontDescription.isAbsoluteSize(), fontDescription.specifiedSize()));
       
  3580                 if (style->setFontDescription(fontDescription))
       
  3581                     fontDirty = true;
       
  3582             }
       
  3583         } else if (value->isFontValue()) {
       
  3584             FontValue *font = static_cast<FontValue*>(value);
       
  3585             if (!font->style || !font->variant || !font->weight ||
       
  3586                  !font->size || !font->lineHeight || !font->family)
       
  3587                 return;
       
  3588             applyProperty(CSS_PROP_FONT_STYLE, font->style.get());
       
  3589             applyProperty(CSS_PROP_FONT_VARIANT, font->variant.get());
       
  3590             applyProperty(CSS_PROP_FONT_WEIGHT, font->weight.get());
       
  3591             applyProperty(CSS_PROP_FONT_SIZE, font->size.get());
       
  3592 
       
  3593             m_lineHeightValue = font->lineHeight.get();
       
  3594             applyProperty(CSS_PROP_FONT_FAMILY, font->family.get());
       
  3595         }
       
  3596         return;
       
  3597         
       
  3598     case CSS_PROP_LIST_STYLE:
       
  3599         if (isInherit) {
       
  3600             style->setListStyleType(parentStyle->listStyleType());
       
  3601             style->setListStyleImage(parentStyle->listStyleImage());
       
  3602             style->setListStylePosition(parentStyle->listStylePosition());
       
  3603         }
       
  3604         else if (isInitial) {
       
  3605             style->setListStyleType(RenderStyle::initialListStyleType());
       
  3606             style->setListStyleImage(RenderStyle::initialListStyleImage());
       
  3607             style->setListStylePosition(RenderStyle::initialListStylePosition());
       
  3608         }
       
  3609         return;
       
  3610     case CSS_PROP_OUTLINE:
       
  3611         if (isInherit) {
       
  3612             style->setOutlineWidth(parentStyle->outlineWidth());
       
  3613             style->setOutlineColor(parentStyle->outlineColor());
       
  3614             style->setOutlineStyle(parentStyle->outlineStyle());
       
  3615         }
       
  3616         else if (isInitial)
       
  3617             style->resetOutline();
       
  3618         return;
       
  3619 
       
  3620     // CSS3 Properties
       
  3621     case CSS_PROP__WEBKIT_APPEARANCE: {
       
  3622         HANDLE_INHERIT_AND_INITIAL(appearance, Appearance)
       
  3623         if (!primitiveValue) break;
       
  3624         int id = primitiveValue->getIdent();
       
  3625         EAppearance appearance;
       
  3626         if (id == CSS_VAL_NONE)
       
  3627             appearance = NoAppearance;
       
  3628         else
       
  3629             appearance = EAppearance(id - CSS_VAL_CHECKBOX + 1);
       
  3630         style->setAppearance(appearance);
       
  3631         return;
       
  3632     }
       
  3633     case CSS_PROP__WEBKIT_BINDING: {
       
  3634 #if ENABLE(XBL)
       
  3635         if (isInitial || (primitiveValue && primitiveValue->getIdent() == CSS_VAL_NONE)) {
       
  3636             style->deleteBindingURIs();
       
  3637             return;
       
  3638         }
       
  3639         else if (isInherit) {
       
  3640             if (parentStyle->bindingURIs())
       
  3641                 style->inheritBindingURIs(parentStyle->bindingURIs());
       
  3642             else
       
  3643                 style->deleteBindingURIs();
       
  3644             return;
       
  3645         }
       
  3646 
       
  3647         if (!value->isValueList()) return;
       
  3648         CSSValueList* list = static_cast<CSSValueList*>(value);
       
  3649         bool firstBinding = true;
       
  3650         for (unsigned int i = 0; i < list->length(); i++) {
       
  3651             CSSValue *item = list->item(i);
       
  3652             CSSPrimitiveValue *val = static_cast<CSSPrimitiveValue*>(item);
       
  3653             if (val->primitiveType() == CSSPrimitiveValue::CSS_URI) {
       
  3654                 if (firstBinding) {
       
  3655                     firstBinding = false;
       
  3656                     style->deleteBindingURIs();
       
  3657                 }
       
  3658                 style->addBindingURI(val->getStringValue());
       
  3659             }
       
  3660         }
       
  3661 #endif
       
  3662         return;
       
  3663     }
       
  3664 
       
  3665     case CSS_PROP__WEBKIT_BORDER_IMAGE: {
       
  3666         HANDLE_INHERIT_AND_INITIAL(borderImage, BorderImage)
       
  3667         BorderImage image;
       
  3668         if (primitiveValue) {
       
  3669             if (primitiveValue->getIdent() == CSS_VAL_NONE)
       
  3670                 style->setBorderImage(image);
       
  3671         } else {
       
  3672             // Retrieve the border image value.
       
  3673             CSSBorderImageValue* borderImage = static_cast<CSSBorderImageValue*>(value);
       
  3674             
       
  3675             // Set the image (this kicks off the load).
       
  3676             image.m_image = borderImage->m_image->image(element->document()->docLoader());
       
  3677             
       
  3678             // Set up a length box to represent our image slices.
       
  3679             LengthBox& l = image.m_slices;
       
  3680             Rect* r = borderImage->m_imageSliceRect.get();
       
  3681             if (r->top()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  3682                 l.top = Length(r->top()->getDoubleValue(), Percent);
       
  3683             else
       
  3684                 l.top = Length(r->top()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
       
  3685             if (r->bottom()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  3686                 l.bottom = Length(r->bottom()->getDoubleValue(), Percent);
       
  3687             else
       
  3688                 l.bottom = Length((int)r->bottom()->getFloatValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
       
  3689             if (r->left()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  3690                 l.left = Length(r->left()->getDoubleValue(), Percent);
       
  3691             else
       
  3692                 l.left = Length(r->left()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
       
  3693             if (r->right()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  3694                 l.right = Length(r->right()->getDoubleValue(), Percent);
       
  3695             else
       
  3696                 l.right = Length(r->right()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
       
  3697             
       
  3698             // Set the appropriate rules for stretch/round/repeat of the slices
       
  3699             switch (borderImage->m_horizontalSizeRule) {
       
  3700                 case CSS_VAL_STRETCH:
       
  3701                     image.m_horizontalRule = BI_STRETCH;
       
  3702                     break;
       
  3703                 case CSS_VAL_ROUND:
       
  3704                     image.m_horizontalRule = BI_ROUND;
       
  3705                     break;
       
  3706                 default: // CSS_VAL_REPEAT
       
  3707                     image.m_horizontalRule = BI_REPEAT;
       
  3708                     break;
       
  3709             }
       
  3710 
       
  3711             switch (borderImage->m_verticalSizeRule) {
       
  3712                 case CSS_VAL_STRETCH:
       
  3713                     image.m_verticalRule = BI_STRETCH;
       
  3714                     break;
       
  3715                 case CSS_VAL_ROUND:
       
  3716                     image.m_verticalRule = BI_ROUND;
       
  3717                     break;
       
  3718                 default: // CSS_VAL_REPEAT
       
  3719                     image.m_verticalRule = BI_REPEAT;
       
  3720                     break;
       
  3721             }
       
  3722 
       
  3723             style->setBorderImage(image);
       
  3724         }
       
  3725         return;
       
  3726     }
       
  3727 
       
  3728     case CSS_PROP__WEBKIT_BORDER_RADIUS:
       
  3729         if (isInherit) {
       
  3730             style->setBorderTopLeftRadius(parentStyle->borderTopLeftRadius());
       
  3731             style->setBorderTopRightRadius(parentStyle->borderTopRightRadius());
       
  3732             style->setBorderBottomLeftRadius(parentStyle->borderBottomLeftRadius());
       
  3733             style->setBorderBottomRightRadius(parentStyle->borderBottomRightRadius());
       
  3734             return;
       
  3735         }
       
  3736         if (isInitial) {
       
  3737             style->resetBorderRadius();
       
  3738             return;
       
  3739         }
       
  3740         // Fall through
       
  3741     case CSS_PROP__WEBKIT_BORDER_TOP_LEFT_RADIUS:
       
  3742     case CSS_PROP__WEBKIT_BORDER_TOP_RIGHT_RADIUS:
       
  3743     case CSS_PROP__WEBKIT_BORDER_BOTTOM_LEFT_RADIUS:
       
  3744     case CSS_PROP__WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS: {
       
  3745         if (isInherit) {
       
  3746             HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_BORDER_TOP_LEFT_RADIUS, borderTopLeftRadius, BorderTopLeftRadius)
       
  3747             HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_BORDER_TOP_RIGHT_RADIUS, borderTopRightRadius, BorderTopRightRadius)
       
  3748             HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_BORDER_BOTTOM_LEFT_RADIUS, borderBottomLeftRadius, BorderBottomLeftRadius)
       
  3749             HANDLE_INHERIT_COND(CSS_PROP__WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS, borderBottomRightRadius, BorderBottomRightRadius)
       
  3750             return;
       
  3751         }
       
  3752         
       
  3753         if (isInitial) {
       
  3754             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP__WEBKIT_BORDER_TOP_LEFT_RADIUS, BorderTopLeftRadius, BorderRadius)
       
  3755             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP__WEBKIT_BORDER_TOP_RIGHT_RADIUS, BorderTopRightRadius, BorderRadius)
       
  3756             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP__WEBKIT_BORDER_BOTTOM_LEFT_RADIUS, BorderBottomLeftRadius, BorderRadius)
       
  3757             HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP__WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS, BorderBottomRightRadius, BorderRadius)
       
  3758             return;
       
  3759         }
       
  3760 
       
  3761         if (!primitiveValue)
       
  3762             return;
       
  3763 
       
  3764         Pair* pair = primitiveValue->getPairValue();
       
  3765         if (!pair)
       
  3766             return;
       
  3767 
       
  3768         int width = pair->first()->computeLengthInt(style);
       
  3769         int height = pair->second()->computeLengthInt(style);
       
  3770         if (width < 0 || height < 0)
       
  3771             return;
       
  3772 
       
  3773         if (width == 0)
       
  3774             height = 0; // Null out the other value.
       
  3775         else if (height == 0)
       
  3776             width = 0; // Null out the other value.
       
  3777 
       
  3778         IntSize size(width, height);
       
  3779         switch (id) {
       
  3780             case CSS_PROP__WEBKIT_BORDER_TOP_LEFT_RADIUS:
       
  3781                 style->setBorderTopLeftRadius(size);
       
  3782                 break;
       
  3783             case CSS_PROP__WEBKIT_BORDER_TOP_RIGHT_RADIUS:
       
  3784                 style->setBorderTopRightRadius(size);
       
  3785                 break;
       
  3786             case CSS_PROP__WEBKIT_BORDER_BOTTOM_LEFT_RADIUS:
       
  3787                 style->setBorderBottomLeftRadius(size);
       
  3788                 break;
       
  3789             case CSS_PROP__WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS:
       
  3790                 style->setBorderBottomRightRadius(size);
       
  3791                 break;
       
  3792             default:
       
  3793                 style->setBorderRadius(size);
       
  3794                 break;
       
  3795         }
       
  3796         return;
       
  3797     }
       
  3798 
       
  3799     case CSS_PROP_OUTLINE_OFFSET:
       
  3800         HANDLE_INHERIT_AND_INITIAL(outlineOffset, OutlineOffset)
       
  3801         style->setOutlineOffset(primitiveValue->computeLengthInt(style));
       
  3802         return;
       
  3803 
       
  3804     case CSS_PROP_TEXT_SHADOW:
       
  3805     case CSS_PROP__WEBKIT_BOX_SHADOW: {
       
  3806         if (isInherit) {
       
  3807             if (id == CSS_PROP_TEXT_SHADOW)
       
  3808                 return style->setTextShadow(parentStyle->textShadow() ? new ShadowData(*parentStyle->textShadow()) : 0);
       
  3809             return style->setBoxShadow(parentStyle->boxShadow() ? new ShadowData(*parentStyle->boxShadow()) : 0);
       
  3810         }
       
  3811         if (isInitial || primitiveValue) // initial | none
       
  3812             return id == CSS_PROP_TEXT_SHADOW ? style->setTextShadow(0) : style->setBoxShadow(0);
       
  3813 
       
  3814         if (!value->isValueList())
       
  3815             return;
       
  3816 
       
  3817         CSSValueList *list = static_cast<CSSValueList*>(value);
       
  3818         int len = list->length();
       
  3819         for (int i = 0; i < len; i++) {
       
  3820             ShadowValue* item = static_cast<ShadowValue*>(list->item(i));
       
  3821             int x = item->x->computeLengthInt(style);
       
  3822             int y = item->y->computeLengthInt(style);
       
  3823             int blur = item->blur ? item->blur->computeLengthInt(style) : 0;
       
  3824             Color color;
       
  3825             if (item->color)
       
  3826                 color = getColorFromPrimitiveValue(item->color.get());
       
  3827             ShadowData* shadowData = new ShadowData(x, y, blur, color.isValid() ? color : Color::transparent);
       
  3828             if (id == CSS_PROP_TEXT_SHADOW)
       
  3829                 style->setTextShadow(shadowData, i != 0);
       
  3830             else
       
  3831                 style->setBoxShadow(shadowData, i != 0);
       
  3832         }
       
  3833         return;
       
  3834     }
       
  3835     case CSS_PROP_OPACITY:
       
  3836         HANDLE_INHERIT_AND_INITIAL(opacity, Opacity)
       
  3837         if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
       
  3838             return; // Error case.
       
  3839         // Clamp opacity to the range 0-1
       
  3840         style->setOpacity(min(1.0f, max(0.0f, primitiveValue->getFloatValue())));
       
  3841         return;
       
  3842     case CSS_PROP__WEBKIT_BOX_ALIGN:
       
  3843         HANDLE_INHERIT_AND_INITIAL(boxAlign, BoxAlign)
       
  3844         if (!primitiveValue) return;
       
  3845         switch (primitiveValue->getIdent()) {
       
  3846             case CSS_VAL_STRETCH:
       
  3847                 style->setBoxAlign(BSTRETCH);
       
  3848                 break;
       
  3849             case CSS_VAL_START:
       
  3850                 style->setBoxAlign(BSTART);
       
  3851                 break;
       
  3852             case CSS_VAL_END:
       
  3853                 style->setBoxAlign(BEND);
       
  3854                 break;
       
  3855             case CSS_VAL_CENTER:
       
  3856                 style->setBoxAlign(BCENTER);
       
  3857                 break;
       
  3858             case CSS_VAL_BASELINE:
       
  3859                 style->setBoxAlign(BBASELINE);
       
  3860                 break;
       
  3861             default:
       
  3862                 return;
       
  3863         }
       
  3864         return;        
       
  3865     case CSS_PROP__WEBKIT_BOX_DIRECTION:
       
  3866         HANDLE_INHERIT_AND_INITIAL(boxDirection, BoxDirection)
       
  3867         if (!primitiveValue) return;
       
  3868         if (primitiveValue->getIdent() == CSS_VAL_NORMAL)
       
  3869             style->setBoxDirection(BNORMAL);
       
  3870         else
       
  3871             style->setBoxDirection(BREVERSE);
       
  3872         return;        
       
  3873     case CSS_PROP__WEBKIT_BOX_LINES:
       
  3874         HANDLE_INHERIT_AND_INITIAL(boxLines, BoxLines)
       
  3875         if(!primitiveValue) return;
       
  3876         if (primitiveValue->getIdent() == CSS_VAL_SINGLE)
       
  3877             style->setBoxLines(SINGLE);
       
  3878         else
       
  3879             style->setBoxLines(MULTIPLE);
       
  3880         return;     
       
  3881     case CSS_PROP__WEBKIT_BOX_ORIENT:
       
  3882         HANDLE_INHERIT_AND_INITIAL(boxOrient, BoxOrient)
       
  3883         if (!primitiveValue) return;
       
  3884         if (primitiveValue->getIdent() == CSS_VAL_HORIZONTAL ||
       
  3885             primitiveValue->getIdent() == CSS_VAL_INLINE_AXIS)
       
  3886             style->setBoxOrient(HORIZONTAL);
       
  3887         else
       
  3888             style->setBoxOrient(VERTICAL);
       
  3889         return;     
       
  3890     case CSS_PROP__WEBKIT_BOX_PACK:
       
  3891         HANDLE_INHERIT_AND_INITIAL(boxPack, BoxPack)
       
  3892         if (!primitiveValue) return;
       
  3893         switch (primitiveValue->getIdent()) {
       
  3894             case CSS_VAL_START:
       
  3895                 style->setBoxPack(BSTART);
       
  3896                 break;
       
  3897             case CSS_VAL_END:
       
  3898                 style->setBoxPack(BEND);
       
  3899                 break;
       
  3900             case CSS_VAL_CENTER:
       
  3901                 style->setBoxPack(BCENTER);
       
  3902                 break;
       
  3903             case CSS_VAL_JUSTIFY:
       
  3904                 style->setBoxPack(BJUSTIFY);
       
  3905                 break;
       
  3906             default:
       
  3907                 return;
       
  3908         }
       
  3909         return;        
       
  3910     case CSS_PROP__WEBKIT_BOX_FLEX:
       
  3911         HANDLE_INHERIT_AND_INITIAL(boxFlex, BoxFlex)
       
  3912         if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
       
  3913             return; // Error case.
       
  3914         style->setBoxFlex(primitiveValue->getFloatValue());
       
  3915         return;
       
  3916     case CSS_PROP__WEBKIT_BOX_FLEX_GROUP:
       
  3917         HANDLE_INHERIT_AND_INITIAL(boxFlexGroup, BoxFlexGroup)
       
  3918         if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
       
  3919             return; // Error case.
       
  3920         style->setBoxFlexGroup((unsigned int)(primitiveValue->getDoubleValue()));
       
  3921         return;        
       
  3922     case CSS_PROP__WEBKIT_BOX_ORDINAL_GROUP:
       
  3923         HANDLE_INHERIT_AND_INITIAL(boxOrdinalGroup, BoxOrdinalGroup)
       
  3924         if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
       
  3925             return; // Error case.
       
  3926         style->setBoxOrdinalGroup((unsigned int)(primitiveValue->getDoubleValue()));
       
  3927         return;
       
  3928     case CSS_PROP__WEBKIT_BOX_SIZING:
       
  3929         HANDLE_INHERIT_AND_INITIAL(boxSizing, BoxSizing)
       
  3930         if (!primitiveValue) return;
       
  3931         if (primitiveValue->getIdent() == CSS_VAL_CONTENT_BOX)
       
  3932             style->setBoxSizing(CONTENT_BOX);
       
  3933         else
       
  3934             style->setBoxSizing(BORDER_BOX);
       
  3935         return;
       
  3936     case CSS_PROP__WEBKIT_COLUMN_COUNT: {
       
  3937         if (isInherit) {
       
  3938             if (parentStyle->hasAutoColumnCount())
       
  3939                 style->setHasAutoColumnCount();
       
  3940             else
       
  3941                 style->setColumnCount(parentStyle->columnCount());
       
  3942             return;
       
  3943         } else if (isInitial || primitiveValue->getIdent() == CSS_VAL_AUTO) {
       
  3944             style->setHasAutoColumnCount();
       
  3945             return;
       
  3946         }
       
  3947         style->setColumnCount(static_cast<unsigned short>(primitiveValue->getDoubleValue()));
       
  3948         return;
       
  3949     }
       
  3950     case CSS_PROP__WEBKIT_COLUMN_GAP: {
       
  3951         if (isInherit) {
       
  3952             if (parentStyle->hasNormalColumnGap())
       
  3953                 style->setHasNormalColumnGap();
       
  3954             else
       
  3955                 style->setColumnGap(parentStyle->columnGap());
       
  3956             return;
       
  3957         } else if (isInitial || primitiveValue->getIdent() == CSS_VAL_NORMAL) {
       
  3958             style->setHasNormalColumnGap();
       
  3959             return;
       
  3960         }
       
  3961         style->setColumnGap(primitiveValue->computeLengthFloat(style));
       
  3962         return;
       
  3963     }
       
  3964     case CSS_PROP__WEBKIT_COLUMN_WIDTH: {
       
  3965         if (isInherit) {
       
  3966             if (parentStyle->hasAutoColumnWidth())
       
  3967                 style->setHasAutoColumnWidth();
       
  3968             else
       
  3969                 style->setColumnWidth(parentStyle->columnWidth());
       
  3970             return;
       
  3971         } else if (isInitial || primitiveValue->getIdent() == CSS_VAL_AUTO) {
       
  3972             style->setHasAutoColumnWidth();
       
  3973             return;
       
  3974         }
       
  3975         style->setColumnWidth(primitiveValue->computeLengthFloat(style));
       
  3976         return;
       
  3977     }
       
  3978     case CSS_PROP__WEBKIT_COLUMN_RULE_STYLE:
       
  3979         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(columnRuleStyle, ColumnRuleStyle, BorderStyle)
       
  3980         style->setColumnRuleStyle((EBorderStyle)(primitiveValue->getIdent() - CSS_VAL_NONE));
       
  3981         return;
       
  3982     case CSS_PROP__WEBKIT_COLUMN_BREAK_BEFORE: {
       
  3983         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(columnBreakBefore, ColumnBreakBefore, PageBreak)
       
  3984         switch (primitiveValue->getIdent()) {
       
  3985             case CSS_VAL_AUTO:
       
  3986                 style->setColumnBreakBefore(PBAUTO);
       
  3987                 break;
       
  3988             case CSS_VAL_LEFT:
       
  3989             case CSS_VAL_RIGHT:
       
  3990             case CSS_VAL_ALWAYS:
       
  3991                 style->setColumnBreakBefore(PBALWAYS);
       
  3992                 break;
       
  3993             case CSS_VAL_AVOID:
       
  3994                 style->setColumnBreakBefore(PBAVOID);
       
  3995                 break;
       
  3996         }
       
  3997         return;
       
  3998     }
       
  3999     case CSS_PROP__WEBKIT_COLUMN_BREAK_AFTER: {
       
  4000         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(columnBreakAfter, ColumnBreakAfter, PageBreak)
       
  4001         switch (primitiveValue->getIdent()) {
       
  4002             case CSS_VAL_AUTO:
       
  4003                 style->setColumnBreakAfter(PBAUTO);
       
  4004                 break;
       
  4005             case CSS_VAL_LEFT:
       
  4006             case CSS_VAL_RIGHT:
       
  4007             case CSS_VAL_ALWAYS:
       
  4008                 style->setColumnBreakAfter(PBALWAYS);
       
  4009                 break;
       
  4010             case CSS_VAL_AVOID:
       
  4011                 style->setColumnBreakAfter(PBAVOID);
       
  4012                 break;
       
  4013         }
       
  4014         return;
       
  4015     }
       
  4016     case CSS_PROP__WEBKIT_COLUMN_BREAK_INSIDE: {
       
  4017         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(columnBreakInside, ColumnBreakInside, PageBreak)
       
  4018         if (primitiveValue->getIdent() == CSS_VAL_AUTO)
       
  4019             style->setColumnBreakInside(PBAUTO);
       
  4020         else if (primitiveValue->getIdent() == CSS_VAL_AVOID)
       
  4021             style->setColumnBreakInside(PBAVOID);
       
  4022         return;
       
  4023     }
       
  4024      case CSS_PROP__WEBKIT_COLUMN_RULE:
       
  4025         if (isInherit) {
       
  4026             style->setColumnRuleColor(parentStyle->columnRuleColor());
       
  4027             style->setColumnRuleStyle(parentStyle->columnRuleStyle());
       
  4028             style->setColumnRuleWidth(parentStyle->columnRuleWidth());
       
  4029         }
       
  4030         else if (isInitial)
       
  4031             style->resetColumnRule();
       
  4032         return;
       
  4033     case CSS_PROP__WEBKIT_COLUMNS:
       
  4034         if (isInherit) {
       
  4035             if (parentStyle->hasAutoColumnWidth())
       
  4036                 style->setHasAutoColumnWidth();
       
  4037             else
       
  4038                 style->setColumnWidth(parentStyle->columnWidth());
       
  4039             style->setColumnCount(parentStyle->columnCount());
       
  4040         } else if (isInitial) {
       
  4041             style->setHasAutoColumnWidth();
       
  4042             style->setColumnCount(RenderStyle::initialColumnCount());
       
  4043         }
       
  4044         return;
       
  4045     case CSS_PROP__WEBKIT_MARQUEE:
       
  4046         if (valueType != CSSValue::CSS_INHERIT || !parentNode) return;
       
  4047         style->setMarqueeDirection(parentStyle->marqueeDirection());
       
  4048         style->setMarqueeIncrement(parentStyle->marqueeIncrement());
       
  4049         style->setMarqueeSpeed(parentStyle->marqueeSpeed());
       
  4050         style->setMarqueeLoopCount(parentStyle->marqueeLoopCount());
       
  4051         style->setMarqueeBehavior(parentStyle->marqueeBehavior());
       
  4052         return;
       
  4053 #if PLATFORM(SYMBIAN)
       
  4054     case CSS_PROP__WAP_MARQUEE_LOOP: {
       
  4055         HANDLE_INHERIT_AND_INITIAL(marqueeLoopCount, MarqueeLoopCount)
       
  4056         if (!primitiveValue) {
       
  4057             // invalid value, set loopcount to 1
       
  4058             style->setMarqueeLoopCount(1);
       
  4059             return;
       
  4060         }
       
  4061         if (primitiveValue->getIdent() == CSS_VAL_INFINITE)
       
  4062             style->setMarqueeLoopCount(1); // 1 loop instead of forever
       
  4063         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
       
  4064             style->setMarqueeLoopCount(primitiveValue->getIntValue());
       
  4065         else
       
  4066             style->setMarqueeLoopCount(1);
       
  4067         return;
       
  4068     }
       
  4069 #endif
       
  4070     case CSS_PROP__WEBKIT_MARQUEE_REPETITION: {
       
  4071         HANDLE_INHERIT_AND_INITIAL(marqueeLoopCount, MarqueeLoopCount)
       
  4072         if (!primitiveValue) return;
       
  4073         if (primitiveValue->getIdent() == CSS_VAL_INFINITE)
       
  4074             style->setMarqueeLoopCount(-1); // -1 means repeat forever.
       
  4075         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
       
  4076             style->setMarqueeLoopCount(primitiveValue->getIntValue());
       
  4077         return;
       
  4078     }
       
  4079 #if PLATFORM(SYMBIAN)
       
  4080     case CSS_PROP__WAP_MARQUEE_SPEED: 
       
  4081 #endif
       
  4082     case CSS_PROP__WEBKIT_MARQUEE_SPEED: {
       
  4083         HANDLE_INHERIT_AND_INITIAL(marqueeSpeed, MarqueeSpeed)      
       
  4084         if (!primitiveValue) return;
       
  4085         if (primitiveValue->getIdent()) {
       
  4086             switch (primitiveValue->getIdent())
       
  4087             {
       
  4088                 case CSS_VAL_SLOW:
       
  4089                     style->setMarqueeSpeed(500); // 500 msec.
       
  4090                     break;
       
  4091                 case CSS_VAL_NORMAL:
       
  4092                     style->setMarqueeSpeed(85); // 85msec. The WinIE default.
       
  4093                     break;
       
  4094                 case CSS_VAL_FAST:
       
  4095                     style->setMarqueeSpeed(10); // 10msec. Super fast.
       
  4096                     break;
       
  4097             }
       
  4098         }
       
  4099         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_S)
       
  4100             style->setMarqueeSpeed(1000 * primitiveValue->getIntValue());
       
  4101         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_MS)
       
  4102             style->setMarqueeSpeed(primitiveValue->getIntValue());
       
  4103         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) // For scrollamount support.
       
  4104             style->setMarqueeSpeed(primitiveValue->getIntValue());
       
  4105         return;
       
  4106     }
       
  4107     case CSS_PROP__WEBKIT_MARQUEE_INCREMENT: {
       
  4108         HANDLE_INHERIT_AND_INITIAL(marqueeIncrement, MarqueeIncrement)
       
  4109         if (!primitiveValue) return;
       
  4110         if (primitiveValue->getIdent()) {
       
  4111             switch (primitiveValue->getIdent())
       
  4112             {
       
  4113                 case CSS_VAL_SMALL:
       
  4114                     style->setMarqueeIncrement(Length(1, Fixed)); // 1px.
       
  4115                     break;
       
  4116                 case CSS_VAL_NORMAL:
       
  4117                     style->setMarqueeIncrement(Length(6, Fixed)); // 6px. The WinIE default.
       
  4118                     break;
       
  4119                 case CSS_VAL_LARGE:
       
  4120                     style->setMarqueeIncrement(Length(36, Fixed)); // 36px.
       
  4121                     break;
       
  4122             }
       
  4123         }
       
  4124         else {
       
  4125             bool ok = true;
       
  4126             Length l = convertToLength(primitiveValue, style, &ok);
       
  4127             if (ok)
       
  4128                 style->setMarqueeIncrement(l);
       
  4129         }
       
  4130         return;
       
  4131     }
       
  4132 #if PLATFORM(SYMBIAN)
       
  4133     case CSS_PROP__WAP_MARQUEE_STYLE:
       
  4134 #endif    
       
  4135     case CSS_PROP__WEBKIT_MARQUEE_STYLE: {
       
  4136         HANDLE_INHERIT_AND_INITIAL(marqueeBehavior, MarqueeBehavior)      
       
  4137         if (!primitiveValue || !primitiveValue->getIdent()) return;
       
  4138         switch (primitiveValue->getIdent())
       
  4139         {
       
  4140             case CSS_VAL_NONE:
       
  4141                 style->setMarqueeBehavior(MNONE);
       
  4142                 break;
       
  4143             case CSS_VAL_SCROLL:
       
  4144                 style->setMarqueeBehavior(MSCROLL);
       
  4145                 break;
       
  4146             case CSS_VAL_SLIDE:
       
  4147                 style->setMarqueeBehavior(MSLIDE);
       
  4148                 break;
       
  4149             case CSS_VAL_ALTERNATE:
       
  4150                 style->setMarqueeBehavior(MALTERNATE);
       
  4151                 break;
       
  4152         }
       
  4153         return;
       
  4154     }
       
  4155 #if PLATFORM(SYMBIAN)
       
  4156     case CSS_PROP__WAP_MARQUEE_DIR: {
       
  4157         HANDLE_INHERIT_AND_INITIAL(marqueeDirection, MarqueeDirection)
       
  4158         if (!primitiveValue || !primitiveValue->getIdent()) return;
       
  4159         switch (primitiveValue->getIdent())
       
  4160         {
       
  4161         case CSS_VAL_RTL:
       
  4162             style->setMarqueeDirection(MLEFT);
       
  4163             break;
       
  4164         case CSS_VAL_LTR:
       
  4165             style->setMarqueeDirection(MRIGHT);
       
  4166             break;
       
  4167         }
       
  4168         break;
       
  4169 #endif
       
  4170     case CSS_PROP__WEBKIT_MARQUEE_DIRECTION: {
       
  4171         HANDLE_INHERIT_AND_INITIAL(marqueeDirection, MarqueeDirection)
       
  4172         if (!primitiveValue || !primitiveValue->getIdent()) return;
       
  4173         switch (primitiveValue->getIdent())
       
  4174         {
       
  4175             case CSS_VAL_FORWARDS:
       
  4176                 style->setMarqueeDirection(MFORWARD);
       
  4177                 break;
       
  4178             case CSS_VAL_BACKWARDS:
       
  4179                 style->setMarqueeDirection(MBACKWARD);
       
  4180                 break;
       
  4181             case CSS_VAL_AUTO:
       
  4182                 style->setMarqueeDirection(MAUTO);
       
  4183                 break;
       
  4184             case CSS_VAL_AHEAD:
       
  4185             case CSS_VAL_UP: // We don't support vertical languages, so AHEAD just maps to UP.
       
  4186                 style->setMarqueeDirection(MUP);
       
  4187                 break;
       
  4188             case CSS_VAL_REVERSE:
       
  4189             case CSS_VAL_DOWN: // REVERSE just maps to DOWN, since we don't do vertical text.
       
  4190                 style->setMarqueeDirection(MDOWN);
       
  4191                 break;
       
  4192             case CSS_VAL_LEFT:
       
  4193                 style->setMarqueeDirection(MLEFT);
       
  4194                 break;
       
  4195             case CSS_VAL_RIGHT:
       
  4196                 style->setMarqueeDirection(MRIGHT);
       
  4197                 break;
       
  4198         }
       
  4199         return;
       
  4200     }
       
  4201     case CSS_PROP__WEBKIT_USER_DRAG: {
       
  4202         HANDLE_INHERIT_AND_INITIAL(userDrag, UserDrag)      
       
  4203         if (!primitiveValue || !primitiveValue->getIdent())
       
  4204             return;
       
  4205         switch (primitiveValue->getIdent()) {
       
  4206             case CSS_VAL_AUTO:
       
  4207                 style->setUserDrag(DRAG_AUTO);
       
  4208                 break;
       
  4209             case CSS_VAL_NONE:
       
  4210                 style->setUserDrag(DRAG_NONE);
       
  4211                 break;
       
  4212             case CSS_VAL_ELEMENT:
       
  4213                 style->setUserDrag(DRAG_ELEMENT);
       
  4214             default:
       
  4215                 return;
       
  4216         }
       
  4217         return;
       
  4218     }
       
  4219     case CSS_PROP__WEBKIT_USER_MODIFY: {
       
  4220         HANDLE_INHERIT_AND_INITIAL(userModify, UserModify)      
       
  4221         if (!primitiveValue || !primitiveValue->getIdent())
       
  4222             return;
       
  4223         EUserModify userModify = EUserModify(primitiveValue->getIdent() - CSS_VAL_READ_ONLY);
       
  4224         style->setUserModify(userModify);
       
  4225         return;
       
  4226     }
       
  4227     case CSS_PROP__WEBKIT_USER_SELECT: {
       
  4228         HANDLE_INHERIT_AND_INITIAL(userSelect, UserSelect)      
       
  4229         if (!primitiveValue || !primitiveValue->getIdent())
       
  4230             return;
       
  4231         switch (primitiveValue->getIdent()) {
       
  4232             case CSS_VAL_AUTO:
       
  4233                 style->setUserSelect(SELECT_TEXT);
       
  4234                 break;
       
  4235             case CSS_VAL_NONE:
       
  4236                 style->setUserSelect(SELECT_NONE);
       
  4237                 break;
       
  4238             case CSS_VAL_TEXT:
       
  4239                 style->setUserSelect(SELECT_TEXT);
       
  4240             default:
       
  4241                 return;
       
  4242         }
       
  4243         return;
       
  4244     }
       
  4245     case CSS_PROP_TEXT_OVERFLOW: {
       
  4246         // This property is supported by WinIE, and so we leave off the "-webkit-" in order to
       
  4247         // work with WinIE-specific pages that use the property.
       
  4248         HANDLE_INHERIT_AND_INITIAL(textOverflow, TextOverflow)
       
  4249         if (!primitiveValue || !primitiveValue->getIdent())
       
  4250             return;
       
  4251         style->setTextOverflow(primitiveValue->getIdent() == CSS_VAL_ELLIPSIS);
       
  4252         return;
       
  4253     }
       
  4254     case CSS_PROP__WEBKIT_MARGIN_COLLAPSE: {
       
  4255         if (isInherit) {
       
  4256             style->setMarginTopCollapse(parentStyle->marginTopCollapse());
       
  4257             style->setMarginBottomCollapse(parentStyle->marginBottomCollapse());
       
  4258         }
       
  4259         else if (isInitial) {
       
  4260             style->setMarginTopCollapse(MCOLLAPSE);
       
  4261             style->setMarginBottomCollapse(MCOLLAPSE);
       
  4262         }
       
  4263         return;
       
  4264     }
       
  4265     case CSS_PROP__WEBKIT_MARGIN_TOP_COLLAPSE: {
       
  4266         HANDLE_INHERIT_AND_INITIAL(marginTopCollapse, MarginTopCollapse)
       
  4267         if (!primitiveValue || !primitiveValue->getIdent()) return;
       
  4268         EMarginCollapse val;
       
  4269         switch (primitiveValue->getIdent()) {
       
  4270             case CSS_VAL_SEPARATE:
       
  4271                 val = MSEPARATE;
       
  4272                 break;
       
  4273             case CSS_VAL_DISCARD:
       
  4274                 val = MDISCARD;
       
  4275                 break;
       
  4276             default:
       
  4277                 val = MCOLLAPSE;
       
  4278         }
       
  4279         style->setMarginTopCollapse(val);
       
  4280         return;
       
  4281     }
       
  4282     case CSS_PROP__WEBKIT_MARGIN_BOTTOM_COLLAPSE: {
       
  4283         HANDLE_INHERIT_AND_INITIAL(marginBottomCollapse, MarginBottomCollapse)
       
  4284         if (!primitiveValue || !primitiveValue->getIdent()) return;
       
  4285         EMarginCollapse val;
       
  4286         switch (primitiveValue->getIdent()) {
       
  4287             case CSS_VAL_SEPARATE:
       
  4288                 val = MSEPARATE;
       
  4289                 break;
       
  4290             case CSS_VAL_DISCARD:
       
  4291                 val = MDISCARD;
       
  4292                 break;
       
  4293             default:
       
  4294                 val = MCOLLAPSE;
       
  4295         }
       
  4296         style->setMarginBottomCollapse(val);
       
  4297         return;
       
  4298     }
       
  4299 
       
  4300     // Apple-specific changes.  Do not merge these properties into KHTML.
       
  4301     case CSS_PROP__WEBKIT_LINE_CLAMP: {
       
  4302         HANDLE_INHERIT_AND_INITIAL(lineClamp, LineClamp)
       
  4303         if (!primitiveValue) return;
       
  4304         style->setLineClamp(primitiveValue->getIntValue(CSSPrimitiveValue::CSS_PERCENTAGE));
       
  4305         return;
       
  4306     }
       
  4307     case CSS_PROP__WEBKIT_HIGHLIGHT: {
       
  4308         HANDLE_INHERIT_AND_INITIAL(highlight, Highlight);
       
  4309         if (primitiveValue->getIdent() == CSS_VAL_NONE)
       
  4310             style->setHighlight(nullAtom);
       
  4311         else
       
  4312             style->setHighlight(primitiveValue->getStringValue());
       
  4313         return;
       
  4314     }
       
  4315     case CSS_PROP__WEBKIT_BORDER_FIT: {
       
  4316         HANDLE_INHERIT_AND_INITIAL(borderFit, BorderFit);
       
  4317         if (primitiveValue->getIdent() == CSS_VAL_BORDER)
       
  4318             style->setBorderFit(BorderFitBorder);
       
  4319         else
       
  4320             style->setBorderFit(BorderFitLines);
       
  4321         return;
       
  4322     }
       
  4323     case CSS_PROP__WEBKIT_TEXT_SIZE_ADJUST: {
       
  4324         HANDLE_INHERIT_AND_INITIAL(textSizeAdjust, TextSizeAdjust)
       
  4325         if (!primitiveValue || !primitiveValue->getIdent()) return;
       
  4326         style->setTextSizeAdjust(primitiveValue->getIdent() == CSS_VAL_AUTO);
       
  4327         fontDirty = true;
       
  4328         return;
       
  4329     }
       
  4330     case CSS_PROP__WEBKIT_TEXT_SECURITY: {
       
  4331         HANDLE_INHERIT_AND_INITIAL(textSecurity, TextSecurity)
       
  4332         if (!primitiveValue)
       
  4333             return;
       
  4334         ETextSecurity textSecurity = TSNONE;
       
  4335         switch (primitiveValue->getIdent()) {
       
  4336             case CSS_VAL_DISC:
       
  4337                 textSecurity = TSDISC;
       
  4338                 break;
       
  4339             case CSS_VAL_CIRCLE:
       
  4340                 textSecurity = TSCIRCLE;
       
  4341                 break;
       
  4342             case CSS_VAL_SQUARE:
       
  4343                 textSecurity= TSSQUARE;
       
  4344                 break;
       
  4345         }
       
  4346         style->setTextSecurity(textSecurity);
       
  4347         return;
       
  4348     }
       
  4349     case CSS_PROP__WEBKIT_DASHBOARD_REGION: {
       
  4350         HANDLE_INHERIT_AND_INITIAL(dashboardRegions, DashboardRegions)
       
  4351         if (!primitiveValue)
       
  4352             return;
       
  4353 
       
  4354         if(primitiveValue->getIdent() == CSS_VAL_NONE) {
       
  4355             style->setDashboardRegions(RenderStyle::noneDashboardRegions());
       
  4356             return;
       
  4357         }
       
  4358 
       
  4359         DashboardRegion *region = primitiveValue->getDashboardRegionValue();
       
  4360         if (!region)
       
  4361             return;
       
  4362             
       
  4363         DashboardRegion *first = region;
       
  4364         while (region) {
       
  4365             Length top = convertToLength (region->top(), style);
       
  4366             Length right = convertToLength (region->right(), style);
       
  4367             Length bottom = convertToLength (region->bottom(), style);
       
  4368             Length left = convertToLength (region->left(), style);
       
  4369             if (region->m_isCircle)
       
  4370                 style->setDashboardRegion(StyleDashboardRegion::Circle, region->m_label, top, right, bottom, left, region == first ? false : true);
       
  4371             else if (region->m_isRectangle)
       
  4372                 style->setDashboardRegion(StyleDashboardRegion::Rectangle, region->m_label, top, right, bottom, left, region == first ? false : true);
       
  4373             region = region->m_next.get();
       
  4374         }
       
  4375         
       
  4376         element->document()->setHasDashboardRegions(true);
       
  4377         
       
  4378         return;
       
  4379     }
       
  4380     case CSS_PROP__WEBKIT_RTL_ORDERING:
       
  4381         HANDLE_INHERIT_AND_INITIAL(visuallyOrdered, VisuallyOrdered)
       
  4382         if (!primitiveValue || !primitiveValue->getIdent())
       
  4383             return;
       
  4384         style->setVisuallyOrdered(primitiveValue->getIdent() == CSS_VAL_VISUAL);
       
  4385         return;
       
  4386     case CSS_PROP__WEBKIT_TEXT_STROKE_WIDTH: {
       
  4387         HANDLE_INHERIT_AND_INITIAL(textStrokeWidth, TextStrokeWidth)
       
  4388         float width = 0;
       
  4389         switch (primitiveValue->getIdent()) {
       
  4390             case CSS_VAL_THIN:
       
  4391             case CSS_VAL_MEDIUM:
       
  4392             case CSS_VAL_THICK: {
       
  4393                 double result = 1.0 / 48;
       
  4394                 if (primitiveValue->getIdent() == CSS_VAL_MEDIUM)
       
  4395                     result *= 3;
       
  4396                 else if (primitiveValue->getIdent() == CSS_VAL_THICK)
       
  4397                     result *= 5;
       
  4398                 CSSPrimitiveValue val(result, CSSPrimitiveValue::CSS_EMS);
       
  4399                 width = val.computeLengthFloat(style);
       
  4400                 break;
       
  4401             }
       
  4402             default:
       
  4403                 width = primitiveValue->computeLengthFloat(style);
       
  4404                 break;
       
  4405         }
       
  4406         style->setTextStrokeWidth(width);
       
  4407         return;
       
  4408     }
       
  4409 #if PLATFORM(SYMBIAN)
       
  4410     case CSS_PROP__WAP_INPUT_FORMAT: {
       
  4411         HANDLE_INHERIT_AND_INITIAL(wapInputFormat, WapInputFormat)
       
  4412         if (!primitiveValue) return;
       
  4413         style->setWapInputFormat(primitiveValue->getStringValue());
       
  4414         break;
       
  4415         }
       
  4416     case CSS_PROP__WAP_INPUT_REQUIRED: {
       
  4417         HANDLE_INHERIT_AND_INITIAL(wapInputRequired, WapInputRequired)
       
  4418         if (!primitiveValue) return;
       
  4419         style->setWapInputRequired(primitiveValue->getIdent() == CSS_VAL_TRUE ? true : false);
       
  4420         break;
       
  4421         }
       
  4422     }
       
  4423 #endif
       
  4424     case CSS_PROP_INVALID:
       
  4425         return;
       
  4426     case CSS_PROP_FONT_STRETCH:
       
  4427     case CSS_PROP_PAGE:
       
  4428     case CSS_PROP_QUOTES:
       
  4429     case CSS_PROP_SCROLLBAR_3DLIGHT_COLOR:
       
  4430     case CSS_PROP_SCROLLBAR_ARROW_COLOR:
       
  4431     case CSS_PROP_SCROLLBAR_DARKSHADOW_COLOR:
       
  4432     case CSS_PROP_SCROLLBAR_FACE_COLOR:
       
  4433     case CSS_PROP_SCROLLBAR_HIGHLIGHT_COLOR:
       
  4434     case CSS_PROP_SCROLLBAR_SHADOW_COLOR:
       
  4435     case CSS_PROP_SCROLLBAR_TRACK_COLOR:
       
  4436     case CSS_PROP_SIZE:
       
  4437     case CSS_PROP_TEXT_LINE_THROUGH:
       
  4438     case CSS_PROP_TEXT_LINE_THROUGH_COLOR:
       
  4439     case CSS_PROP_TEXT_LINE_THROUGH_MODE:
       
  4440     case CSS_PROP_TEXT_LINE_THROUGH_STYLE:
       
  4441     case CSS_PROP_TEXT_LINE_THROUGH_WIDTH:
       
  4442     case CSS_PROP_TEXT_OVERLINE:
       
  4443     case CSS_PROP_TEXT_OVERLINE_COLOR:
       
  4444     case CSS_PROP_TEXT_OVERLINE_MODE:
       
  4445     case CSS_PROP_TEXT_OVERLINE_STYLE:
       
  4446     case CSS_PROP_TEXT_OVERLINE_WIDTH:
       
  4447     case CSS_PROP_TEXT_UNDERLINE:
       
  4448     case CSS_PROP_TEXT_UNDERLINE_COLOR:
       
  4449     case CSS_PROP_TEXT_UNDERLINE_MODE:
       
  4450     case CSS_PROP_TEXT_UNDERLINE_STYLE:
       
  4451     case CSS_PROP_TEXT_UNDERLINE_WIDTH:
       
  4452     case CSS_PROP__WEBKIT_FONT_SIZE_DELTA:
       
  4453     case CSS_PROP__WEBKIT_MARGIN_START:
       
  4454     case CSS_PROP__WEBKIT_PADDING_START:
       
  4455     case CSS_PROP__WEBKIT_TEXT_DECORATIONS_IN_EFFECT:
       
  4456     case CSS_PROP__WEBKIT_TEXT_STROKE:
       
  4457         return;
       
  4458     }
       
  4459 #if ENABLE(SVG)
       
  4460     // Try the SVG properties
       
  4461     applySVGProperty(id, value);
       
  4462 #endif
       
  4463 }
       
  4464 
       
  4465 void CSSStyleSelector::mapBackgroundAttachment(BackgroundLayer* layer, CSSValue* value)
       
  4466 {
       
  4467     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  4468         layer->setBackgroundAttachment(RenderStyle::initialBackgroundAttachment());
       
  4469         return;
       
  4470     }
       
  4471 
       
  4472     if (!value->isPrimitiveValue()) return;
       
  4473     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  4474     switch (primitiveValue->getIdent()) {
       
  4475         case CSS_VAL_FIXED:
       
  4476             layer->setBackgroundAttachment(false);
       
  4477             break;
       
  4478         case CSS_VAL_SCROLL:
       
  4479             layer->setBackgroundAttachment(true);
       
  4480             break;
       
  4481         default:
       
  4482             return;
       
  4483     }
       
  4484 }
       
  4485 
       
  4486 void CSSStyleSelector::mapBackgroundClip(BackgroundLayer* layer, CSSValue* value)
       
  4487 {
       
  4488     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  4489         layer->setBackgroundClip(RenderStyle::initialBackgroundClip());
       
  4490         return;
       
  4491     }
       
  4492 
       
  4493     if (!value->isPrimitiveValue()) return;
       
  4494     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  4495     switch (primitiveValue->getIdent()) {
       
  4496         case CSS_VAL_BORDER:
       
  4497             layer->setBackgroundClip(BGBORDER);
       
  4498             break;
       
  4499         case CSS_VAL_PADDING:
       
  4500             layer->setBackgroundClip(BGPADDING);
       
  4501             break;
       
  4502         default: // CSS_VAL_CONTENT
       
  4503             layer->setBackgroundClip(BGCONTENT);
       
  4504             break;
       
  4505     }
       
  4506 }
       
  4507 
       
  4508 void CSSStyleSelector::mapBackgroundComposite(BackgroundLayer* layer, CSSValue* value)
       
  4509 {
       
  4510     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  4511         layer->setBackgroundComposite(RenderStyle::initialBackgroundComposite());
       
  4512         return;
       
  4513     }
       
  4514     
       
  4515     if (!value->isPrimitiveValue())
       
  4516         return;
       
  4517     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  4518     switch(primitiveValue->getIdent()) {
       
  4519         case CSS_VAL_CLEAR:
       
  4520             layer->setBackgroundComposite(CompositeClear);
       
  4521             break;
       
  4522         case CSS_VAL_COPY:
       
  4523             layer->setBackgroundComposite(CompositeCopy);
       
  4524             break;
       
  4525         case CSS_VAL_SOURCE_OVER:
       
  4526             layer->setBackgroundComposite(CompositeSourceOver);
       
  4527             break;
       
  4528         case CSS_VAL_SOURCE_IN:
       
  4529             layer->setBackgroundComposite(CompositeSourceIn);
       
  4530             break;
       
  4531         case CSS_VAL_SOURCE_OUT:
       
  4532             layer->setBackgroundComposite(CompositeSourceOut);
       
  4533             break;
       
  4534         case CSS_VAL_SOURCE_ATOP:
       
  4535             layer->setBackgroundComposite(CompositeSourceAtop);
       
  4536             break;
       
  4537         case CSS_VAL_DESTINATION_OVER:
       
  4538             layer->setBackgroundComposite(CompositeDestinationOver);
       
  4539             break;
       
  4540         case CSS_VAL_DESTINATION_IN:
       
  4541             layer->setBackgroundComposite(CompositeDestinationIn);
       
  4542             break;
       
  4543         case CSS_VAL_DESTINATION_OUT:
       
  4544             layer->setBackgroundComposite(CompositeDestinationOut);
       
  4545             break;
       
  4546         case CSS_VAL_DESTINATION_ATOP:
       
  4547             layer->setBackgroundComposite(CompositeDestinationAtop);
       
  4548             break;
       
  4549         case CSS_VAL_XOR:
       
  4550             layer->setBackgroundComposite(CompositeXOR);
       
  4551             break;
       
  4552         case CSS_VAL_PLUS_DARKER:
       
  4553             layer->setBackgroundComposite(CompositePlusDarker);
       
  4554             break;
       
  4555         case CSS_VAL_HIGHLIGHT:
       
  4556             layer->setBackgroundComposite(CompositeHighlight);
       
  4557             break;
       
  4558         case CSS_VAL_PLUS_LIGHTER:
       
  4559             layer->setBackgroundComposite(CompositePlusLighter);
       
  4560             break;
       
  4561         default:
       
  4562             return;
       
  4563     }
       
  4564 }
       
  4565 
       
  4566 void CSSStyleSelector::mapBackgroundOrigin(BackgroundLayer* layer, CSSValue* value)
       
  4567 {
       
  4568     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  4569         layer->setBackgroundOrigin(RenderStyle::initialBackgroundOrigin());
       
  4570         return;
       
  4571     }
       
  4572 
       
  4573     if (!value->isPrimitiveValue()) return;
       
  4574     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  4575     switch (primitiveValue->getIdent()) {
       
  4576         case CSS_VAL_BORDER:
       
  4577             layer->setBackgroundOrigin(BGBORDER);
       
  4578             break;
       
  4579         case CSS_VAL_PADDING:
       
  4580             layer->setBackgroundOrigin(BGPADDING);
       
  4581             break;
       
  4582         default: // CSS_VAL_CONTENT
       
  4583             layer->setBackgroundOrigin(BGCONTENT);
       
  4584             break;
       
  4585     }
       
  4586 }
       
  4587 
       
  4588 void CSSStyleSelector::mapBackgroundImage(BackgroundLayer* layer, CSSValue* value)
       
  4589 {
       
  4590     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  4591         layer->setBackgroundImage(RenderStyle::initialBackgroundImage());
       
  4592         return;
       
  4593     }
       
  4594     
       
  4595     if (!value->isPrimitiveValue()) return;
       
  4596     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  4597     layer->setBackgroundImage(static_cast<CSSImageValue*>(primitiveValue)->image(element->document()->docLoader()));
       
  4598 }
       
  4599 
       
  4600 void CSSStyleSelector::mapBackgroundRepeat(BackgroundLayer* layer, CSSValue* value)
       
  4601 {
       
  4602     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  4603         layer->setBackgroundRepeat(RenderStyle::initialBackgroundRepeat());
       
  4604         return;
       
  4605     }
       
  4606     
       
  4607     if (!value->isPrimitiveValue())
       
  4608         return;
       
  4609     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  4610     switch(primitiveValue->getIdent()) {
       
  4611         case CSS_VAL_REPEAT:
       
  4612             layer->setBackgroundRepeat(REPEAT);
       
  4613             break;
       
  4614         case CSS_VAL_REPEAT_X:
       
  4615             layer->setBackgroundRepeat(REPEAT_X);
       
  4616             break;
       
  4617         case CSS_VAL_REPEAT_Y:
       
  4618             layer->setBackgroundRepeat(REPEAT_Y);
       
  4619             break;
       
  4620         case CSS_VAL_NO_REPEAT:
       
  4621             layer->setBackgroundRepeat(NO_REPEAT);
       
  4622             break;
       
  4623         default:
       
  4624             return;
       
  4625     }
       
  4626 }
       
  4627 
       
  4628 void CSSStyleSelector::mapBackgroundSize(BackgroundLayer* layer, CSSValue* value)
       
  4629 {
       
  4630     LengthSize b = RenderStyle::initialBackgroundSize();
       
  4631     
       
  4632     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  4633         layer->setBackgroundSize(b);
       
  4634         return;
       
  4635     }
       
  4636     
       
  4637     if (!value->isPrimitiveValue())
       
  4638         return;
       
  4639         
       
  4640     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  4641     Pair* pair = primitiveValue->getPairValue();
       
  4642     if (!pair)
       
  4643         return;
       
  4644     
       
  4645     CSSPrimitiveValue* first = static_cast<CSSPrimitiveValue*>(pair->first());
       
  4646     CSSPrimitiveValue* second = static_cast<CSSPrimitiveValue*>(pair->second());
       
  4647     
       
  4648     if (!first || !second)
       
  4649         return;
       
  4650         
       
  4651     Length firstLength, secondLength;
       
  4652     int firstType = first->primitiveType();
       
  4653     int secondType = second->primitiveType();
       
  4654     
       
  4655     if (firstType == CSSPrimitiveValue::CSS_UNKNOWN)
       
  4656         firstLength = Length(Auto);
       
  4657     else if (firstType > CSSPrimitiveValue::CSS_PERCENTAGE && firstType < CSSPrimitiveValue::CSS_DEG)
       
  4658         firstLength = Length(first->computeLengthIntForLength(style), Fixed);
       
  4659     else if (firstType == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  4660         firstLength = Length(first->getDoubleValue(), Percent);
       
  4661     else
       
  4662         return;
       
  4663 
       
  4664     if (secondType == CSSPrimitiveValue::CSS_UNKNOWN)
       
  4665         secondLength = Length(Auto);
       
  4666     else if (secondType > CSSPrimitiveValue::CSS_PERCENTAGE && secondType < CSSPrimitiveValue::CSS_DEG)
       
  4667         secondLength = Length(second->computeLengthIntForLength(style), Fixed);
       
  4668     else if (secondType == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  4669         secondLength = Length(second->getDoubleValue(), Percent);
       
  4670     else
       
  4671         return;
       
  4672     
       
  4673     b.width = firstLength;
       
  4674     b.height = secondLength;
       
  4675     layer->setBackgroundSize(b);
       
  4676 }
       
  4677 
       
  4678 void CSSStyleSelector::mapBackgroundXPosition(BackgroundLayer* layer, CSSValue* value)
       
  4679 {
       
  4680     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  4681         layer->setBackgroundXPosition(RenderStyle::initialBackgroundXPosition());
       
  4682         return;
       
  4683     }
       
  4684     
       
  4685     if (!value->isPrimitiveValue())
       
  4686         return;
       
  4687     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  4688     Length l;
       
  4689     int type = primitiveValue->primitiveType();
       
  4690     if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
       
  4691         l = Length(primitiveValue->computeLengthIntForLength(style), Fixed);
       
  4692     else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  4693         l = Length(primitiveValue->getDoubleValue(), Percent);
       
  4694     else
       
  4695         return;
       
  4696     layer->setBackgroundXPosition(l);
       
  4697 }
       
  4698 
       
  4699 void CSSStyleSelector::mapBackgroundYPosition(BackgroundLayer* layer, CSSValue* value)
       
  4700 {
       
  4701     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  4702         layer->setBackgroundYPosition(RenderStyle::initialBackgroundYPosition());
       
  4703         return;
       
  4704     }
       
  4705     
       
  4706     if (!value->isPrimitiveValue())
       
  4707         return;
       
  4708     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  4709     Length l;
       
  4710     int type = primitiveValue->primitiveType();
       
  4711     if(type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
       
  4712         l = Length(primitiveValue->computeLengthIntForLength(style), Fixed);
       
  4713     else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  4714         l = Length(primitiveValue->getDoubleValue(), Percent);
       
  4715     else
       
  4716         return;
       
  4717     layer->setBackgroundYPosition(l);
       
  4718 }
       
  4719 
       
  4720 void CSSStyleSelector::checkForTextSizeAdjust()
       
  4721 {
       
  4722     if (style->textSizeAdjust())
       
  4723         return;
       
  4724  
       
  4725     FontDescription newFontDescription(style->fontDescription());
       
  4726     newFontDescription.setComputedSize(newFontDescription.specifiedSize());
       
  4727     style->setFontDescription(newFontDescription);
       
  4728 }
       
  4729 
       
  4730 void CSSStyleSelector::checkForGenericFamilyChange(RenderStyle* style, RenderStyle* parentStyle)
       
  4731 {
       
  4732     const FontDescription& childFont = style->fontDescription();
       
  4733   
       
  4734     if (childFont.isAbsoluteSize() || !parentStyle)
       
  4735         return;
       
  4736 
       
  4737     const FontDescription& parentFont = parentStyle->fontDescription();
       
  4738 
       
  4739     if (childFont.genericFamily() == parentFont.genericFamily())
       
  4740         return;
       
  4741 
       
  4742     // For now, lump all families but monospace together.
       
  4743     if (childFont.genericFamily() != FontDescription::MonospaceFamily &&
       
  4744         parentFont.genericFamily() != FontDescription::MonospaceFamily)
       
  4745         return;
       
  4746 
       
  4747     // We know the parent is monospace or the child is monospace, and that font
       
  4748     // size was unspecified.  We want to scale our font size as appropriate.
       
  4749     // If the font uses a keyword size, then we refetch from the table rather than
       
  4750     // multiplying by our scale factor.
       
  4751     float size;
       
  4752     if (childFont.keywordSize()) {
       
  4753         size = fontSizeForKeyword(CSS_VAL_XX_SMALL + childFont.keywordSize() - 1, style->htmlHacks(),
       
  4754                                   childFont.genericFamily() == FontDescription::MonospaceFamily);
       
  4755     } else {
       
  4756         Settings* settings = m_document->settings();
       
  4757         float fixedScaleFactor = settings
       
  4758             ? static_cast<float>(settings->defaultFixedFontSize()) / settings->defaultFontSize()
       
  4759             : 1;
       
  4760         size = (parentFont.genericFamily() == FontDescription::MonospaceFamily) ? 
       
  4761                 childFont.specifiedSize()/fixedScaleFactor :
       
  4762                 childFont.specifiedSize()*fixedScaleFactor;
       
  4763     }
       
  4764 
       
  4765     FontDescription newFontDescription(childFont);
       
  4766     setFontSize(newFontDescription, size);
       
  4767     style->setFontDescription(newFontDescription);
       
  4768 }
       
  4769 
       
  4770 void CSSStyleSelector::setFontSize(FontDescription& fontDescription, float size)
       
  4771 {
       
  4772     fontDescription.setSpecifiedSize(size);
       
  4773     fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(fontDescription.isAbsoluteSize(), size));
       
  4774 }
       
  4775 
       
  4776 float CSSStyleSelector::getComputedSizeFromSpecifiedSize(bool isAbsoluteSize, float specifiedSize)
       
  4777 {
       
  4778     // We support two types of minimum font size.  The first is a hard override that applies to
       
  4779     // all fonts.  This is "minSize."  The second type of minimum font size is a "smart minimum"
       
  4780     // that is applied only when the Web page can't know what size it really asked for, e.g.,
       
  4781     // when it uses logical sizes like "small" or expresses the font-size as a percentage of
       
  4782     // the user's default font setting.
       
  4783 
       
  4784     // With the smart minimum, we never want to get smaller than the minimum font size to keep fonts readable.
       
  4785     // However we always allow the page to set an explicit pixel size that is smaller,
       
  4786     // since sites will mis-render otherwise (e.g., http://www.gamespot.com with a 9px minimum).
       
  4787     
       
  4788     Settings* settings = m_document->settings();
       
  4789     if (!settings)
       
  4790         return 1.0f;
       
  4791 
       
  4792     int minSize = settings->minimumFontSize();
       
  4793     int minLogicalSize = settings->minimumLogicalFontSize();
       
  4794 
       
  4795     float zoomPercent = m_document->frame() ? m_document->frame()->zoomFactor() / 100.0f : 1.0f;
       
  4796     float zoomedSize = specifiedSize * zoomPercent;
       
  4797 
       
  4798 #if PLATFORM(SYMBIAN)
       
  4799     if( !isAbsoluteSize )
       
  4800         zoomedSize *= m_document ? m_document->frame()->bridge()->textZoomPercent() / 100.0f : 1.0f;
       
  4801 #endif
       
  4802 
       
  4803     // Apply the hard minimum first.  We only apply the hard minimum if after zooming we're still too small.
       
  4804     if (zoomedSize < minSize)
       
  4805         zoomedSize = minSize;
       
  4806 
       
  4807     // Now apply the "smart minimum."  This minimum is also only applied if we're still too small
       
  4808     // after zooming.  The font size must either be relative to the user default or the original size
       
  4809     // must have been acceptable.  In other words, we only apply the smart minimum whenever we're positive
       
  4810     // doing so won't disrupt the layout.
       
  4811     if (zoomedSize < minLogicalSize && (specifiedSize >= minLogicalSize || !isAbsoluteSize))
       
  4812         zoomedSize = minLogicalSize;
       
  4813     
       
  4814     // Also clamp to a reasonable maximum to prevent insane font sizes from causing crashes on various
       
  4815     // platforms (I'm looking at you, Windows.)
       
  4816     return min(1000000.0f, max(zoomedSize, 1.0f));
       
  4817 }
       
  4818 
       
  4819 const int fontSizeTableMax = 16;
       
  4820 const int fontSizeTableMin = 9;
       
  4821 const int totalKeywords = 8;
       
  4822 
       
  4823 // WinIE/Nav4 table for font sizes.  Designed to match the legacy font mapping system of HTML.
       
  4824 static const int quirksFontSizeTable[fontSizeTableMax - fontSizeTableMin + 1][totalKeywords] =
       
  4825 {
       
  4826       { 9,    9,     9,     9,    11,    14,    18,    28 },
       
  4827       { 9,    9,     9,    10,    12,    15,    20,    31 },
       
  4828       { 9,    9,     9,    11,    13,    17,    22,    34 },
       
  4829       { 9,    9,    10,    12,    14,    18,    24,    37 },
       
  4830       { 9,    9,    10,    13,    16,    20,    26,    40 }, // fixed font default (13)
       
  4831       { 9,    9,    11,    14,    17,    21,    28,    42 },
       
  4832       { 9,   10,    12,    15,    17,    23,    30,    45 },
       
  4833       { 9,   10,    13,    16,    18,    24,    32,    48 }  // proportional font default (16)
       
  4834 };
       
  4835 // HTML       1      2      3      4      5      6      7
       
  4836 // CSS  xxs   xs     s      m      l     xl     xxl
       
  4837 //                          |
       
  4838 //                      user pref
       
  4839 
       
  4840 // Strict mode table matches MacIE and Mozilla's settings exactly.
       
  4841 static const int strictFontSizeTable[fontSizeTableMax - fontSizeTableMin + 1][totalKeywords] =
       
  4842 {
       
  4843       { 9,    9,     9,     9,    11,    14,    18,    27 },
       
  4844       { 9,    9,     9,    10,    12,    15,    20,    30 },
       
  4845       { 9,    9,    10,    11,    13,    17,    22,    33 },
       
  4846       { 9,    9,    10,    12,    14,    18,    24,    36 },
       
  4847       { 9,   10,    12,    13,    16,    20,    26,    39 }, // fixed font default (13)
       
  4848       { 9,   10,    12,    14,    17,    21,    28,    42 },
       
  4849       { 9,   10,    13,    15,    18,    23,    30,    45 },
       
  4850       { 9,   10,    13,    16,    18,    24,    32,    48 }  // proportional font default (16)
       
  4851 };
       
  4852 // HTML       1      2      3      4      5      6      7
       
  4853 // CSS  xxs   xs     s      m      l     xl     xxl
       
  4854 //                          |
       
  4855 //                      user pref
       
  4856 
       
  4857 // For values outside the range of the table, we use Todd Fahrner's suggested scale
       
  4858 // factors for each keyword value.
       
  4859 static const float fontSizeFactors[totalKeywords] = { 0.60f, 0.75f, 0.89f, 1.0f, 1.2f, 1.5f, 2.0f, 3.0f };
       
  4860 
       
  4861 float CSSStyleSelector::fontSizeForKeyword(int keyword, bool quirksMode, bool fixed) const
       
  4862 {
       
  4863     Settings* settings = m_document->settings();
       
  4864     if (!settings)
       
  4865         return 1.0f;
       
  4866 
       
  4867     int mediumSize = fixed ? settings->defaultFixedFontSize() : settings->defaultFontSize();
       
  4868     if (mediumSize >= fontSizeTableMin && mediumSize <= fontSizeTableMax) {
       
  4869         // Look up the entry in the table.
       
  4870         int row = mediumSize - fontSizeTableMin;
       
  4871         int col = (keyword - CSS_VAL_XX_SMALL);
       
  4872         return quirksMode ? quirksFontSizeTable[row][col] : strictFontSizeTable[row][col];
       
  4873     }
       
  4874     
       
  4875     // Value is outside the range of the table. Apply the scale factor instead.
       
  4876     float minLogicalSize = max(settings->minimumLogicalFontSize(), 1);
       
  4877     return max(fontSizeFactors[keyword - CSS_VAL_XX_SMALL]*mediumSize, minLogicalSize);
       
  4878 }
       
  4879 
       
  4880 float CSSStyleSelector::largerFontSize(float size, bool quirksMode) const
       
  4881 {
       
  4882     // FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large) and scale up to
       
  4883     // the next size level.  
       
  4884     return size * 1.2f;
       
  4885 }
       
  4886 
       
  4887 float CSSStyleSelector::smallerFontSize(float size, bool quirksMode) const
       
  4888 {
       
  4889     // FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large) and scale down to
       
  4890     // the next size level. 
       
  4891     return size / 1.2f;
       
  4892 }
       
  4893 
       
  4894 // color mapping code
       
  4895 struct ColorValue {
       
  4896     int css_value;
       
  4897     RGBA32 color;
       
  4898 };
       
  4899 
       
  4900 static const ColorValue colorValues[] = {
       
  4901     { CSS_VAL_AQUA, 0xFF00FFFF },
       
  4902     { CSS_VAL_BLACK, 0xFF000000 },
       
  4903     { CSS_VAL_BLUE, 0xFF0000FF },
       
  4904     { CSS_VAL_FUCHSIA, 0xFFFF00FF },
       
  4905     { CSS_VAL_GRAY, 0xFF808080 },
       
  4906     { CSS_VAL_GREEN, 0xFF008000  },
       
  4907     { CSS_VAL_LIME, 0xFF00FF00 },
       
  4908     { CSS_VAL_MAROON, 0xFF800000 },
       
  4909     { CSS_VAL_NAVY, 0xFF000080 },
       
  4910     { CSS_VAL_OLIVE, 0xFF808000  },
       
  4911     { CSS_VAL_ORANGE, 0xFFFFA500 },
       
  4912     { CSS_VAL_PURPLE, 0xFF800080 },
       
  4913     { CSS_VAL_RED, 0xFFFF0000 },
       
  4914     { CSS_VAL_SILVER, 0xFFC0C0C0 },
       
  4915     { CSS_VAL_TEAL, 0xFF008080  },
       
  4916     { CSS_VAL_WHITE, 0xFFFFFFFF },
       
  4917     { CSS_VAL_YELLOW, 0xFFFFFF00 },
       
  4918     { CSS_VAL_TRANSPARENT, 0x00000000 },
       
  4919     { CSS_VAL_GREY, 0xFF808080 },
       
  4920     { CSS_VAL_ACTIVEBORDER, 0xFFFFFFFF },
       
  4921     { CSS_VAL_ACTIVECAPTION, 0xFFCCCCCC },
       
  4922     { CSS_VAL_APPWORKSPACE, 0xFFFFFFFF },
       
  4923     { CSS_VAL_BUTTONFACE, 0xFFC0C0C0 },
       
  4924     { CSS_VAL_BUTTONHIGHLIGHT, 0xFFDDDDDD },
       
  4925     { CSS_VAL_BUTTONSHADOW, 0xFF888888 },
       
  4926     { CSS_VAL_BUTTONTEXT, 0xFF000000 },
       
  4927     { CSS_VAL_CAPTIONTEXT, 0xFF000000 },
       
  4928     { CSS_VAL_GRAYTEXT, 0xFF808080 },
       
  4929     { CSS_VAL_HIGHLIGHT, 0xFFB5D5FF },
       
  4930     { CSS_VAL_HIGHLIGHTTEXT, 0xFF000000 },
       
  4931     { CSS_VAL_INACTIVEBORDER, 0xFFFFFFFF },
       
  4932     { CSS_VAL_INACTIVECAPTION, 0xFFFFFFFF },
       
  4933     { CSS_VAL_INACTIVECAPTIONTEXT, 0xFF7F7F7F },
       
  4934     { CSS_VAL_INFOBACKGROUND, 0xFFFBFCC5 },
       
  4935     { CSS_VAL_INFOTEXT, 0xFF000000 },
       
  4936     { CSS_VAL_MENU, 0xFFC0C0C0 },
       
  4937     { CSS_VAL_MENUTEXT, 0xFF000000 },
       
  4938     { CSS_VAL_SCROLLBAR, 0xFFFFFFFF },
       
  4939     { CSS_VAL_TEXT, 0xFF000000 },
       
  4940     { CSS_VAL_THREEDDARKSHADOW, 0xFF666666 },
       
  4941     { CSS_VAL_THREEDFACE, 0xFFC0C0C0 },
       
  4942     { CSS_VAL_THREEDHIGHLIGHT, 0xFFDDDDDD },
       
  4943     { CSS_VAL_THREEDLIGHTSHADOW, 0xFFC0C0C0 },
       
  4944     { CSS_VAL_THREEDSHADOW, 0xFF888888 },
       
  4945     { CSS_VAL_WINDOW, 0xFFFFFFFF },
       
  4946     { CSS_VAL_WINDOWFRAME, 0xFFCCCCCC },
       
  4947     { CSS_VAL_WINDOWTEXT, 0xFF000000 },
       
  4948     { 0, 0 }
       
  4949 };
       
  4950 
       
  4951 
       
  4952 static Color colorForCSSValue(int css_value)
       
  4953 {
       
  4954     for (const ColorValue* col = colorValues; col->css_value; ++col)
       
  4955         if (col->css_value == css_value)
       
  4956             return col->color;
       
  4957     return Color();
       
  4958 }
       
  4959 
       
  4960 Color CSSStyleSelector::getColorFromPrimitiveValue(CSSPrimitiveValue* primitiveValue)
       
  4961 {
       
  4962     Color col;
       
  4963     int ident = primitiveValue->getIdent();
       
  4964     if (ident) {
       
  4965         if (ident == CSS_VAL__WEBKIT_TEXT)
       
  4966             col = element->document()->textColor();
       
  4967         else if (ident == CSS_VAL__WEBKIT_LINK) {
       
  4968             Color linkColor = element->document()->linkColor();
       
  4969             Color visitedColor = element->document()->visitedLinkColor();
       
  4970             if (linkColor == visitedColor)
       
  4971                 col = linkColor;
       
  4972             else {
       
  4973                 if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink)
       
  4974                     checkPseudoState(element);
       
  4975                 col = (pseudoState == PseudoLink) ? linkColor : visitedColor;
       
  4976             }
       
  4977         } else if (ident == CSS_VAL__WEBKIT_ACTIVELINK)
       
  4978             col = element->document()->activeLinkColor();
       
  4979         else if (ident == CSS_VAL__WEBKIT_FOCUS_RING_COLOR)
       
  4980             col = focusRingColor();
       
  4981         else
       
  4982             col = colorForCSSValue(ident);
       
  4983     } else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RGBCOLOR)
       
  4984         col.setRGB(primitiveValue->getRGBColorValue());
       
  4985     return col;
       
  4986 }
       
  4987 
       
  4988 bool CSSStyleSelector::hasSelectorForAttribute(const AtomicString &attrname)
       
  4989 {
       
  4990     return m_selectorAttrs.contains(attrname.impl());
       
  4991 }
       
  4992 
       
  4993 } // namespace WebCore