WebCore/css/CSSStyleSelector.cpp
changeset 0 4f2f89ce4247
child 2 303757a437d3
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
       
     3  *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
       
     4  * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
       
     5  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
       
     6  * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
       
     7  * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
       
     8  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
       
     9  *
       
    10  * This library is free software; you can redistribute it and/or
       
    11  * modify it under the terms of the GNU Library General Public
       
    12  * License as published by the Free Software Foundation; either
       
    13  * version 2 of the License, or (at your option) any later version.
       
    14  *
       
    15  * This library is distributed in the hope that it will be useful,
       
    16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    18  * Library General Public License for more details.
       
    19  *
       
    20  * You should have received a copy of the GNU Library General Public License
       
    21  * along with this library; see the file COPYING.LIB.  If not, write to
       
    22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    23  * Boston, MA 02110-1301, USA.
       
    24  */
       
    25 
       
    26 #include "config.h"
       
    27 #include "CSSStyleSelector.h"
       
    28 
       
    29 #include "Attribute.h"
       
    30 #include "CSSBorderImageValue.h"
       
    31 #include "CSSCursorImageValue.h"
       
    32 #include "CSSFontFaceRule.h"
       
    33 #include "CSSImportRule.h"
       
    34 #include "CSSMediaRule.h"
       
    35 #include "CSSPageRule.h"
       
    36 #include "CSSParser.h"
       
    37 #include "CSSPrimitiveValueMappings.h"
       
    38 #include "CSSPropertyNames.h"
       
    39 #include "CSSReflectValue.h"
       
    40 #include "CSSRuleList.h"
       
    41 #include "CSSSelector.h"
       
    42 #include "CSSSelectorList.h"
       
    43 #include "CSSStyleRule.h"
       
    44 #include "CSSStyleSheet.h"
       
    45 #include "CSSTimingFunctionValue.h"
       
    46 #include "CSSValueList.h"
       
    47 #include "CSSVariableDependentValue.h"
       
    48 #include "CSSVariablesDeclaration.h"
       
    49 #include "CSSVariablesRule.h"
       
    50 #include "CachedImage.h"
       
    51 #include "Counter.h"
       
    52 #include "CounterContent.h"
       
    53 #include "FocusController.h"
       
    54 #include "FontFamilyValue.h"
       
    55 #include "FontValue.h"
       
    56 #include "Frame.h"
       
    57 #include "FrameView.h"
       
    58 #include "HTMLDocument.h"
       
    59 #include "HTMLElement.h"
       
    60 #include "HTMLInputElement.h"
       
    61 #include "HTMLNames.h"
       
    62 #include "HTMLTextAreaElement.h"
       
    63 #include "KeyframeList.h"
       
    64 #include "LinkHash.h"
       
    65 #include "Matrix3DTransformOperation.h"
       
    66 #include "MatrixTransformOperation.h"
       
    67 #include "MediaList.h"
       
    68 #include "MediaQueryEvaluator.h"
       
    69 #include "NodeRenderStyle.h"
       
    70 #include "Page.h"
       
    71 #include "PageGroup.h"
       
    72 #include "Pair.h"
       
    73 #include "PerspectiveTransformOperation.h"
       
    74 #include "Rect.h"
       
    75 #include "RenderScrollbar.h"
       
    76 #include "RenderScrollbarTheme.h"
       
    77 #include "RenderStyleConstants.h"
       
    78 #include "RenderTheme.h"
       
    79 #include "RotateTransformOperation.h"
       
    80 #include "ScaleTransformOperation.h"
       
    81 #include "SelectionController.h"
       
    82 #include "Settings.h"
       
    83 #include "ShadowValue.h"
       
    84 #include "SkewTransformOperation.h"
       
    85 #include "StyleCachedImage.h"
       
    86 #include "StyleGeneratedImage.h"
       
    87 #include "StyleSheetList.h"
       
    88 #include "Text.h"
       
    89 #include "TransformationMatrix.h"
       
    90 #include "TranslateTransformOperation.h"
       
    91 #include "UserAgentStyleSheets.h"
       
    92 #include "WebKitCSSKeyframeRule.h"
       
    93 #include "WebKitCSSKeyframesRule.h"
       
    94 #include "WebKitCSSTransformValue.h"
       
    95 #include "XMLNames.h"
       
    96 #include "loader.h"
       
    97 #include <wtf/StdLibExtras.h>
       
    98 #include <wtf/Vector.h>
       
    99 
       
   100 #if ENABLE(DASHBOARD_SUPPORT)
       
   101 #include "DashboardRegion.h"
       
   102 #endif
       
   103 
       
   104 #if ENABLE(SVG)
       
   105 #include "XLinkNames.h"
       
   106 #include "SVGNames.h"
       
   107 #endif
       
   108 
       
   109 #if ENABLE(WML)
       
   110 #include "WMLNames.h"
       
   111 #endif
       
   112 
       
   113 #if PLATFORM(QT)
       
   114 #include <qwebhistoryinterface.h>
       
   115 #endif
       
   116 
       
   117 using namespace std;
       
   118 
       
   119 namespace WebCore {
       
   120 
       
   121 using namespace HTMLNames;
       
   122 
       
   123 // #define STYLE_SHARING_STATS 1
       
   124 
       
   125 #define HANDLE_INHERIT(prop, Prop) \
       
   126 if (isInherit) { \
       
   127     m_style->set##Prop(m_parentStyle->prop()); \
       
   128     return; \
       
   129 }
       
   130 
       
   131 #define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
       
   132 HANDLE_INHERIT(prop, Prop) \
       
   133 if (isInitial) { \
       
   134     m_style->set##Prop(RenderStyle::initial##Prop()); \
       
   135     return; \
       
   136 }
       
   137 
       
   138 #define HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(prop, Prop, Value) \
       
   139 HANDLE_INHERIT(prop, Prop) \
       
   140 if (isInitial) { \
       
   141     m_style->set##Prop(RenderStyle::initial##Value());\
       
   142     return;\
       
   143 }
       
   144 
       
   145 #define HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(prop, Prop) \
       
   146 HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
       
   147 if (primitiveValue) \
       
   148     m_style->set##Prop(*primitiveValue);
       
   149 
       
   150 #define HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(prop, Prop, Value) \
       
   151 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(prop, Prop, Value) \
       
   152 if (primitiveValue) \
       
   153     m_style->set##Prop(*primitiveValue);
       
   154 
       
   155 #define HANDLE_FILL_LAYER_INHERIT_AND_INITIAL(layerType, LayerType, prop, Prop) \
       
   156 if (isInherit) { \
       
   157     FillLayer* currChild = m_style->access##LayerType##Layers(); \
       
   158     FillLayer* prevChild = 0; \
       
   159     const FillLayer* currParent = m_parentStyle->layerType##Layers(); \
       
   160     while (currParent && currParent->is##Prop##Set()) { \
       
   161         if (!currChild) { \
       
   162             /* Need to make a new layer.*/ \
       
   163             currChild = new FillLayer(LayerType##FillLayer); \
       
   164             prevChild->setNext(currChild); \
       
   165         } \
       
   166         currChild->set##Prop(currParent->prop()); \
       
   167         prevChild = currChild; \
       
   168         currChild = prevChild->next(); \
       
   169         currParent = currParent->next(); \
       
   170     } \
       
   171     \
       
   172     while (currChild) { \
       
   173         /* Reset any remaining layers to not have the property set. */ \
       
   174         currChild->clear##Prop(); \
       
   175         currChild = currChild->next(); \
       
   176     } \
       
   177 } else if (isInitial) { \
       
   178     FillLayer* currChild = m_style->access##LayerType##Layers(); \
       
   179     currChild->set##Prop(FillLayer::initialFill##Prop(LayerType##FillLayer)); \
       
   180     for (currChild = currChild->next(); currChild; currChild = currChild->next()) \
       
   181         currChild->clear##Prop(); \
       
   182 }
       
   183 
       
   184 #define HANDLE_FILL_LAYER_VALUE(layerType, LayerType, prop, Prop, value) { \
       
   185 HANDLE_FILL_LAYER_INHERIT_AND_INITIAL(layerType, LayerType, prop, Prop) \
       
   186 if (isInherit || isInitial) \
       
   187     return; \
       
   188 FillLayer* currChild = m_style->access##LayerType##Layers(); \
       
   189 FillLayer* prevChild = 0; \
       
   190 if (value->isValueList()) { \
       
   191     /* Walk each value and put it into a layer, creating new layers as needed. */ \
       
   192     CSSValueList* valueList = static_cast<CSSValueList*>(value); \
       
   193     for (unsigned int i = 0; i < valueList->length(); i++) { \
       
   194         if (!currChild) { \
       
   195             /* Need to make a new layer to hold this value */ \
       
   196             currChild = new FillLayer(LayerType##FillLayer); \
       
   197             prevChild->setNext(currChild); \
       
   198         } \
       
   199         mapFill##Prop(currChild, valueList->itemWithoutBoundsCheck(i)); \
       
   200         prevChild = currChild; \
       
   201         currChild = currChild->next(); \
       
   202     } \
       
   203 } else { \
       
   204     mapFill##Prop(currChild, value); \
       
   205     currChild = currChild->next(); \
       
   206 } \
       
   207 while (currChild) { \
       
   208     /* Reset all remaining layers to not have the property set. */ \
       
   209     currChild->clear##Prop(); \
       
   210     currChild = currChild->next(); \
       
   211 } }
       
   212 
       
   213 #define HANDLE_BACKGROUND_INHERIT_AND_INITIAL(prop, Prop) \
       
   214 HANDLE_FILL_LAYER_INHERIT_AND_INITIAL(background, Background, prop, Prop)
       
   215 
       
   216 #define HANDLE_BACKGROUND_VALUE(prop, Prop, value) \
       
   217 HANDLE_FILL_LAYER_VALUE(background, Background, prop, Prop, value)
       
   218 
       
   219 #define HANDLE_MASK_INHERIT_AND_INITIAL(prop, Prop) \
       
   220 HANDLE_FILL_LAYER_INHERIT_AND_INITIAL(mask, Mask, prop, Prop)
       
   221 
       
   222 #define HANDLE_MASK_VALUE(prop, Prop, value) \
       
   223 HANDLE_FILL_LAYER_VALUE(mask, Mask, prop, Prop, value)
       
   224 
       
   225 #define HANDLE_ANIMATION_INHERIT_AND_INITIAL(prop, Prop) \
       
   226 if (isInherit) { \
       
   227     AnimationList* list = m_style->accessAnimations(); \
       
   228     const AnimationList* parentList = m_parentStyle->animations(); \
       
   229     size_t i = 0, parentSize = parentList ? parentList->size() : 0; \
       
   230     for ( ; i < parentSize && parentList->animation(i)->is##Prop##Set(); ++i) { \
       
   231         if (list->size() <= i) \
       
   232             list->append(Animation::create()); \
       
   233         list->animation(i)->set##Prop(parentList->animation(i)->prop()); \
       
   234     } \
       
   235     \
       
   236     /* Reset any remaining animations to not have the property set. */ \
       
   237     for ( ; i < list->size(); ++i) \
       
   238         list->animation(i)->clear##Prop(); \
       
   239 } else if (isInitial) { \
       
   240     AnimationList* list = m_style->accessAnimations(); \
       
   241     if (list->isEmpty()) \
       
   242         list->append(Animation::create()); \
       
   243     list->animation(0)->set##Prop(Animation::initialAnimation##Prop()); \
       
   244     for (size_t i = 1; i < list->size(); ++i) \
       
   245         list->animation(0)->clear##Prop(); \
       
   246 }
       
   247 
       
   248 #define HANDLE_ANIMATION_VALUE(prop, Prop, value) { \
       
   249 HANDLE_ANIMATION_INHERIT_AND_INITIAL(prop, Prop) \
       
   250 if (isInherit || isInitial) \
       
   251     return; \
       
   252 AnimationList* list = m_style->accessAnimations(); \
       
   253 size_t childIndex = 0; \
       
   254 if (value->isValueList()) { \
       
   255     /* Walk each value and put it into an animation, creating new animations as needed. */ \
       
   256     CSSValueList* valueList = static_cast<CSSValueList*>(value); \
       
   257     for (unsigned int i = 0; i < valueList->length(); i++) { \
       
   258         if (childIndex <= list->size()) \
       
   259             list->append(Animation::create()); \
       
   260         mapAnimation##Prop(list->animation(childIndex), valueList->itemWithoutBoundsCheck(i)); \
       
   261         ++childIndex; \
       
   262     } \
       
   263 } else { \
       
   264     if (list->isEmpty()) \
       
   265         list->append(Animation::create()); \
       
   266     mapAnimation##Prop(list->animation(childIndex), value); \
       
   267     childIndex = 1; \
       
   268 } \
       
   269 for ( ; childIndex < list->size(); ++childIndex) { \
       
   270     /* Reset all remaining animations to not have the property set. */ \
       
   271     list->animation(childIndex)->clear##Prop(); \
       
   272 } \
       
   273 }
       
   274 
       
   275 #define HANDLE_TRANSITION_INHERIT_AND_INITIAL(prop, Prop) \
       
   276 if (isInherit) { \
       
   277     AnimationList* list = m_style->accessTransitions(); \
       
   278     const AnimationList* parentList = m_parentStyle->transitions(); \
       
   279     size_t i = 0, parentSize = parentList ? parentList->size() : 0; \
       
   280     for ( ; i < parentSize && parentList->animation(i)->is##Prop##Set(); ++i) { \
       
   281         if (list->size() <= i) \
       
   282             list->append(Animation::create()); \
       
   283         list->animation(i)->set##Prop(parentList->animation(i)->prop()); \
       
   284     } \
       
   285     \
       
   286     /* Reset any remaining transitions to not have the property set. */ \
       
   287     for ( ; i < list->size(); ++i) \
       
   288         list->animation(i)->clear##Prop(); \
       
   289 } else if (isInitial) { \
       
   290     AnimationList* list = m_style->accessTransitions(); \
       
   291     if (list->isEmpty()) \
       
   292         list->append(Animation::create()); \
       
   293     list->animation(0)->set##Prop(Animation::initialAnimation##Prop()); \
       
   294     for (size_t i = 1; i < list->size(); ++i) \
       
   295         list->animation(0)->clear##Prop(); \
       
   296 }
       
   297 
       
   298 #define HANDLE_TRANSITION_VALUE(prop, Prop, value) { \
       
   299 HANDLE_TRANSITION_INHERIT_AND_INITIAL(prop, Prop) \
       
   300 if (isInherit || isInitial) \
       
   301     return; \
       
   302 AnimationList* list = m_style->accessTransitions(); \
       
   303 size_t childIndex = 0; \
       
   304 if (value->isValueList()) { \
       
   305     /* Walk each value and put it into a transition, creating new animations as needed. */ \
       
   306     CSSValueList* valueList = static_cast<CSSValueList*>(value); \
       
   307     for (unsigned int i = 0; i < valueList->length(); i++) { \
       
   308         if (childIndex <= list->size()) \
       
   309             list->append(Animation::create()); \
       
   310         mapAnimation##Prop(list->animation(childIndex), valueList->itemWithoutBoundsCheck(i)); \
       
   311         ++childIndex; \
       
   312     } \
       
   313 } else { \
       
   314     if (list->isEmpty()) \
       
   315         list->append(Animation::create()); \
       
   316     mapAnimation##Prop(list->animation(childIndex), value); \
       
   317     childIndex = 1; \
       
   318 } \
       
   319 for ( ; childIndex < list->size(); ++childIndex) { \
       
   320     /* Reset all remaining transitions to not have the property set. */ \
       
   321     list->animation(childIndex)->clear##Prop(); \
       
   322 } \
       
   323 }
       
   324 
       
   325 #define HANDLE_INHERIT_COND(propID, prop, Prop) \
       
   326 if (id == propID) { \
       
   327     m_style->set##Prop(m_parentStyle->prop()); \
       
   328     return; \
       
   329 }
       
   330     
       
   331 #define HANDLE_INHERIT_COND_WITH_BACKUP(propID, prop, propAlt, Prop) \
       
   332 if (id == propID) { \
       
   333     if (m_parentStyle->prop().isValid()) \
       
   334         m_style->set##Prop(m_parentStyle->prop()); \
       
   335     else \
       
   336         m_style->set##Prop(m_parentStyle->propAlt()); \
       
   337     return; \
       
   338 }
       
   339 
       
   340 #define HANDLE_INITIAL_COND(propID, Prop) \
       
   341 if (id == propID) { \
       
   342     m_style->set##Prop(RenderStyle::initial##Prop()); \
       
   343     return; \
       
   344 }
       
   345 
       
   346 #define HANDLE_INITIAL_COND_WITH_VALUE(propID, Prop, Value) \
       
   347 if (id == propID) { \
       
   348     m_style->set##Prop(RenderStyle::initial##Value()); \
       
   349     return; \
       
   350 }
       
   351 
       
   352 class CSSRuleSet : public Noncopyable {
       
   353 public:
       
   354     CSSRuleSet();
       
   355     ~CSSRuleSet();
       
   356     
       
   357     typedef HashMap<AtomicStringImpl*, CSSRuleDataList*> AtomRuleMap;
       
   358     
       
   359     void addRulesFromSheet(CSSStyleSheet*, const MediaQueryEvaluator&, CSSStyleSelector* = 0);
       
   360 
       
   361     void addStyleRule(StyleBase* item);
       
   362     void addRule(CSSStyleRule* rule, CSSSelector* sel);
       
   363     void addPageRule(CSSStyleRule* rule, CSSSelector* sel);
       
   364     void addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map,
       
   365                       CSSStyleRule* rule, CSSSelector* sel);
       
   366     
       
   367     CSSRuleDataList* getIDRules(AtomicStringImpl* key) { return m_idRules.get(key); }
       
   368     CSSRuleDataList* getClassRules(AtomicStringImpl* key) { return m_classRules.get(key); }
       
   369     CSSRuleDataList* getTagRules(AtomicStringImpl* key) { return m_tagRules.get(key); }
       
   370     CSSRuleDataList* getUniversalRules() { return m_universalRules; }
       
   371     CSSRuleDataList* getPageRules() { return m_pageRules; }
       
   372     
       
   373 public:
       
   374     AtomRuleMap m_idRules;
       
   375     AtomRuleMap m_classRules;
       
   376     AtomRuleMap m_tagRules;
       
   377     CSSRuleDataList* m_universalRules;
       
   378     CSSRuleDataList* m_pageRules;
       
   379     unsigned m_ruleCount;
       
   380     unsigned m_pageRuleCount;
       
   381 };
       
   382 
       
   383 static CSSRuleSet* defaultStyle;
       
   384 static CSSRuleSet* defaultQuirksStyle;
       
   385 static CSSRuleSet* defaultPrintStyle;
       
   386 static CSSRuleSet* defaultViewSourceStyle;
       
   387 static CSSStyleSheet* simpleDefaultStyleSheet;
       
   388 
       
   389 RenderStyle* CSSStyleSelector::s_styleNotYetAvailable;
       
   390 
       
   391 static void loadFullDefaultStyle();
       
   392 static void loadSimpleDefaultStyle();
       
   393 // FIXME: It would be nice to use some mechanism that guarantees this is in sync with the real UA stylesheet.
       
   394 static const char* simpleUserAgentStyleSheet = "html,body,div{display:block}body{margin:8px}div:focus,span:focus{outline:auto 5px -webkit-focus-ring-color}a:-webkit-any-link{color:-webkit-link;text-decoration:underline}a:-webkit-any-link:active{color:-webkit-activelink}";
       
   395 
       
   396 static bool elementCanUseSimpleDefaultStyle(Element* e)
       
   397 {
       
   398     return e->hasTagName(htmlTag) || e->hasTagName(bodyTag) || e->hasTagName(divTag) || e->hasTagName(spanTag) || e->hasTagName(brTag) || e->hasTagName(aTag);
       
   399 }
       
   400 
       
   401 static const MediaQueryEvaluator& screenEval()
       
   402 {
       
   403     DEFINE_STATIC_LOCAL(const MediaQueryEvaluator, staticScreenEval, ("screen"));
       
   404     return staticScreenEval;
       
   405 }
       
   406 
       
   407 static const MediaQueryEvaluator& printEval()
       
   408 {
       
   409     DEFINE_STATIC_LOCAL(const MediaQueryEvaluator, staticPrintEval, ("print"));
       
   410     return staticPrintEval;
       
   411 }
       
   412 
       
   413 CSSStyleSelector::CSSStyleSelector(Document* doc, StyleSheetList* styleSheets, CSSStyleSheet* mappedElementSheet,
       
   414                                    CSSStyleSheet* pageUserSheet, const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets,
       
   415                                    bool strictParsing, bool matchAuthorAndUserStyles)
       
   416     : m_backgroundData(BackgroundFillLayer)
       
   417     , m_checker(doc, strictParsing)
       
   418     , m_element(0)
       
   419     , m_styledElement(0)
       
   420     , m_elementLinkState(NotInsideLink)
       
   421     , m_fontSelector(CSSFontSelector::create(doc))
       
   422 {
       
   423     init();
       
   424         
       
   425     m_matchAuthorAndUserStyles = matchAuthorAndUserStyles;
       
   426     
       
   427     Element* root = doc->documentElement();
       
   428 
       
   429     if (!defaultStyle) {
       
   430         if (!root || elementCanUseSimpleDefaultStyle(root))
       
   431             loadSimpleDefaultStyle();
       
   432         else
       
   433             loadFullDefaultStyle();
       
   434     }
       
   435 
       
   436     m_userStyle = 0;
       
   437 
       
   438     // construct document root element default style. this is needed
       
   439     // to evaluate media queries that contain relative constraints, like "screen and (max-width: 10em)"
       
   440     // This is here instead of constructor, because when constructor is run,
       
   441     // document doesn't have documentElement
       
   442     // NOTE: this assumes that element that gets passed to styleForElement -call
       
   443     // is always from the document that owns the style selector
       
   444     FrameView* view = doc->view();
       
   445     if (view)
       
   446         m_medium = new MediaQueryEvaluator(view->mediaType());
       
   447     else
       
   448         m_medium = new MediaQueryEvaluator("all");
       
   449 
       
   450     if (root)
       
   451         m_rootDefaultStyle = styleForElement(root, 0, false, true); // don't ref, because the RenderStyle is allocated from global heap
       
   452 
       
   453     if (m_rootDefaultStyle && view) {
       
   454         delete m_medium;
       
   455         m_medium = new MediaQueryEvaluator(view->mediaType(), view->frame(), m_rootDefaultStyle.get());
       
   456     }
       
   457 
       
   458     // FIXME: This sucks! The user sheet is reparsed every time!
       
   459     if (pageUserSheet || pageGroupUserSheets) {
       
   460         m_userStyle = new CSSRuleSet();
       
   461         if (pageUserSheet)
       
   462             m_userStyle->addRulesFromSheet(pageUserSheet, *m_medium, this);
       
   463         if (pageGroupUserSheets) {
       
   464             unsigned length = pageGroupUserSheets->size();
       
   465             for (unsigned i = 0; i < length; i++)
       
   466                 m_userStyle->addRulesFromSheet(pageGroupUserSheets->at(i).get(), *m_medium, this);
       
   467         }
       
   468     }
       
   469 
       
   470     // add stylesheets from document
       
   471     m_authorStyle = new CSSRuleSet();
       
   472     
       
   473     // Add rules from elements like SVG's <font-face>
       
   474     if (mappedElementSheet)
       
   475         m_authorStyle->addRulesFromSheet(mappedElementSheet, *m_medium, this);
       
   476 
       
   477     unsigned length = styleSheets->length();
       
   478     for (unsigned i = 0; i < length; i++) {
       
   479         StyleSheet* sheet = styleSheets->item(i);
       
   480         if (sheet->isCSSStyleSheet() && !sheet->disabled())
       
   481             m_authorStyle->addRulesFromSheet(static_cast<CSSStyleSheet*>(sheet), *m_medium, this);
       
   482     }
       
   483     
       
   484     if (doc->renderer() && doc->renderer()->style())
       
   485         doc->renderer()->style()->font().update(fontSelector());
       
   486 }
       
   487 
       
   488 // This is a simplified style setting function for keyframe styles
       
   489 void CSSStyleSelector::addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule> rule)
       
   490 {
       
   491     AtomicString s(rule->name());
       
   492     m_keyframesRuleMap.add(s.impl(), rule);
       
   493 }
       
   494 
       
   495 void CSSStyleSelector::init()
       
   496 {
       
   497     initElement(0);
       
   498     m_matchedDecls.clear();
       
   499     m_ruleList = 0;
       
   500     m_rootDefaultStyle = 0;
       
   501     m_medium = 0;
       
   502 }
       
   503 
       
   504 CSSStyleSelector::~CSSStyleSelector()
       
   505 {
       
   506     m_fontSelector->clearDocument();
       
   507     delete m_medium;
       
   508     delete m_authorStyle;
       
   509     delete m_userStyle;
       
   510     deleteAllValues(m_viewportDependentMediaQueryResults);
       
   511     m_keyframesRuleMap.clear();
       
   512 }
       
   513 
       
   514 static CSSStyleSheet* parseUASheet(const String& str)
       
   515 {
       
   516     CSSStyleSheet* sheet = CSSStyleSheet::create().releaseRef(); // leak the sheet on purpose
       
   517     sheet->parseString(str);
       
   518     return sheet;
       
   519 }
       
   520 
       
   521 static CSSStyleSheet* parseUASheet(const char* characters, unsigned size)
       
   522 {
       
   523     return parseUASheet(String(characters, size));
       
   524 }
       
   525 
       
   526 static void loadFullDefaultStyle()
       
   527 {
       
   528     if (simpleDefaultStyleSheet) {
       
   529         ASSERT(defaultStyle);
       
   530         delete defaultStyle;
       
   531         simpleDefaultStyleSheet->deref();
       
   532         defaultStyle = new CSSRuleSet;
       
   533         simpleDefaultStyleSheet = 0;
       
   534     } else {
       
   535         ASSERT(!defaultStyle);
       
   536         defaultStyle = new CSSRuleSet;
       
   537         defaultPrintStyle = new CSSRuleSet;
       
   538         defaultQuirksStyle = new CSSRuleSet;
       
   539     }
       
   540 
       
   541     // Strict-mode rules.
       
   542     String defaultRules = String(htmlUserAgentStyleSheet, sizeof(htmlUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraDefaultStyleSheet();
       
   543     CSSStyleSheet* defaultSheet = parseUASheet(defaultRules);
       
   544     defaultStyle->addRulesFromSheet(defaultSheet, screenEval());
       
   545     defaultPrintStyle->addRulesFromSheet(defaultSheet, printEval());
       
   546 
       
   547     // Quirks-mode rules.
       
   548     String quirksRules = String(quirksUserAgentStyleSheet, sizeof(quirksUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraQuirksStyleSheet();
       
   549     CSSStyleSheet* quirksSheet = parseUASheet(quirksRules);
       
   550     defaultQuirksStyle->addRulesFromSheet(quirksSheet, screenEval());
       
   551 }
       
   552 
       
   553 static void loadSimpleDefaultStyle()
       
   554 {
       
   555     ASSERT(!defaultStyle);
       
   556     ASSERT(!simpleDefaultStyleSheet);
       
   557     
       
   558     defaultStyle = new CSSRuleSet;
       
   559     defaultPrintStyle = new CSSRuleSet;
       
   560     defaultQuirksStyle = new CSSRuleSet;
       
   561 
       
   562     simpleDefaultStyleSheet = parseUASheet(simpleUserAgentStyleSheet, strlen(simpleUserAgentStyleSheet));
       
   563     defaultStyle->addRulesFromSheet(simpleDefaultStyleSheet, screenEval());
       
   564     
       
   565     // No need to initialize quirks sheet yet as there are no quirk rules for elements allowed in simple default style.
       
   566 }
       
   567     
       
   568 static void loadViewSourceStyle()
       
   569 {
       
   570     ASSERT(!defaultViewSourceStyle);
       
   571     defaultViewSourceStyle = new CSSRuleSet;
       
   572     defaultViewSourceStyle->addRulesFromSheet(parseUASheet(sourceUserAgentStyleSheet, sizeof(sourceUserAgentStyleSheet)), screenEval());
       
   573 }
       
   574 
       
   575 void CSSStyleSelector::addMatchedDeclaration(CSSMutableStyleDeclaration* decl)
       
   576 {
       
   577     if (!decl->hasVariableDependentValue()) {
       
   578         m_matchedDecls.append(decl);
       
   579         return;
       
   580     }
       
   581 
       
   582     // See if we have already resolved the variables in this declaration.
       
   583     CSSMutableStyleDeclaration* resolvedDecl = m_resolvedVariablesDeclarations.get(decl).get();
       
   584     if (resolvedDecl) {
       
   585         m_matchedDecls.append(resolvedDecl);
       
   586         return;
       
   587     }
       
   588 
       
   589     // If this declaration has any variables in it, then we need to make a cloned
       
   590     // declaration with as many variables resolved as possible for this style selector's media.
       
   591     RefPtr<CSSMutableStyleDeclaration> newDecl = CSSMutableStyleDeclaration::create(decl->parentRule());
       
   592     m_matchedDecls.append(newDecl.get());
       
   593     m_resolvedVariablesDeclarations.set(decl, newDecl);
       
   594 
       
   595     HashSet<String> usedBlockVariables;
       
   596     resolveVariablesForDeclaration(decl, newDecl.get(), usedBlockVariables);
       
   597 }
       
   598 
       
   599 void CSSStyleSelector::resolveVariablesForDeclaration(CSSMutableStyleDeclaration* decl, CSSMutableStyleDeclaration* newDecl, HashSet<String>& usedBlockVariables)
       
   600 {
       
   601     // Now iterate over the properties in the original declaration.  As we resolve variables we'll end up
       
   602     // mutating the new declaration (possibly expanding shorthands).  The new declaration has no m_node
       
   603     // though, so it can't mistakenly call setChanged on anything.
       
   604     CSSMutableStyleDeclaration::const_iterator end = decl->end();
       
   605     for (CSSMutableStyleDeclaration::const_iterator it = decl->begin(); it != end; ++it) {
       
   606         const CSSProperty& current = *it;
       
   607         if (!current.value()->isVariableDependentValue()) {
       
   608             // We can just add the parsed property directly.
       
   609             newDecl->addParsedProperty(current);
       
   610             continue;
       
   611         }
       
   612         CSSValueList* valueList = static_cast<CSSVariableDependentValue*>(current.value())->valueList();
       
   613         if (!valueList)
       
   614             continue;
       
   615         CSSParserValueList resolvedValueList;
       
   616         unsigned s = valueList->length();
       
   617         bool fullyResolved = true;
       
   618         for (unsigned i = 0; i < s; ++i) {
       
   619             CSSValue* val = valueList->item(i);
       
   620             CSSPrimitiveValue* primitiveValue = val->isPrimitiveValue() ? static_cast<CSSPrimitiveValue*>(val) : 0;
       
   621             if (primitiveValue && primitiveValue->isVariable()) {
       
   622                 CSSVariablesRule* rule = m_variablesMap.get(primitiveValue->getStringValue());
       
   623                 if (!rule || !rule->variables()) {
       
   624                     fullyResolved = false;
       
   625                     break;
       
   626                 }
       
   627                 
       
   628                 if (current.id() == CSSPropertyWebkitVariableDeclarationBlock && s == 1) {
       
   629                     fullyResolved = false;
       
   630                     if (!usedBlockVariables.contains(primitiveValue->getStringValue())) {
       
   631                         CSSMutableStyleDeclaration* declBlock = rule->variables()->getParsedVariableDeclarationBlock(primitiveValue->getStringValue());
       
   632                         if (declBlock) {
       
   633                             usedBlockVariables.add(primitiveValue->getStringValue());
       
   634                             resolveVariablesForDeclaration(declBlock, newDecl, usedBlockVariables);
       
   635                         }
       
   636                     }
       
   637                 }
       
   638 
       
   639                 CSSValueList* resolvedVariable = rule->variables()->getParsedVariable(primitiveValue->getStringValue());
       
   640                 if (!resolvedVariable) {
       
   641                     fullyResolved = false;
       
   642                     break;
       
   643                 }
       
   644                 unsigned valueSize = resolvedVariable->length();
       
   645                 for (unsigned j = 0; j < valueSize; ++j)
       
   646                     resolvedValueList.addValue(resolvedVariable->item(j)->parserValue());
       
   647             } else
       
   648                 resolvedValueList.addValue(val->parserValue());
       
   649         }
       
   650         
       
   651         if (!fullyResolved)
       
   652             continue;
       
   653 
       
   654         // We now have a fully resolved new value list.  We want the parser to use this value list
       
   655         // and parse our new declaration.
       
   656         CSSParser(m_checker.m_strictParsing).parsePropertyWithResolvedVariables(current.id(), current.isImportant(), newDecl, &resolvedValueList);
       
   657     }
       
   658 }
       
   659 
       
   660 void CSSStyleSelector::matchRules(CSSRuleSet* rules, int& firstRuleIndex, int& lastRuleIndex)
       
   661 {
       
   662     m_matchedRules.clear();
       
   663 
       
   664     if (!rules || !m_element)
       
   665         return;
       
   666     
       
   667     // We need to collect the rules for id, class, tag, and everything else into a buffer and
       
   668     // then sort the buffer.
       
   669     if (m_element->hasID())
       
   670         matchRulesForList(rules->getIDRules(m_element->idForStyleResolution().impl()), firstRuleIndex, lastRuleIndex);
       
   671     if (m_element->hasClass()) {
       
   672         ASSERT(m_styledElement);
       
   673         const SpaceSplitString& classNames = m_styledElement->classNames();
       
   674         size_t size = classNames.size();
       
   675         for (size_t i = 0; i < size; ++i)
       
   676             matchRulesForList(rules->getClassRules(classNames[i].impl()), firstRuleIndex, lastRuleIndex);
       
   677     }
       
   678     matchRulesForList(rules->getTagRules(m_element->localName().impl()), firstRuleIndex, lastRuleIndex);
       
   679     matchRulesForList(rules->getUniversalRules(), firstRuleIndex, lastRuleIndex);
       
   680     
       
   681     // If we didn't match any rules, we're done.
       
   682     if (m_matchedRules.isEmpty())
       
   683         return;
       
   684     
       
   685     // Sort the set of matched rules.
       
   686     sortMatchedRules(0, m_matchedRules.size());
       
   687     
       
   688     // Now transfer the set of matched rules over to our list of decls.
       
   689     if (!m_checker.m_collectRulesOnly) {
       
   690         for (unsigned i = 0; i < m_matchedRules.size(); i++)
       
   691             addMatchedDeclaration(m_matchedRules[i]->rule()->declaration());
       
   692     } else {
       
   693         for (unsigned i = 0; i < m_matchedRules.size(); i++) {
       
   694             if (!m_ruleList)
       
   695                 m_ruleList = CSSRuleList::create();
       
   696             m_ruleList->append(m_matchedRules[i]->rule());
       
   697         }
       
   698     }
       
   699 }
       
   700 
       
   701 void CSSStyleSelector::matchRulesForList(CSSRuleDataList* rules, int& firstRuleIndex, int& lastRuleIndex)
       
   702 {
       
   703     if (!rules)
       
   704         return;
       
   705 
       
   706     for (CSSRuleData* d = rules->first(); d; d = d->next()) {
       
   707         CSSStyleRule* rule = d->rule();
       
   708         if (checkSelector(d->selector())) {
       
   709             // If the rule has no properties to apply, then ignore it.
       
   710             CSSMutableStyleDeclaration* decl = rule->declaration();
       
   711             if (!decl || !decl->length())
       
   712                 continue;
       
   713             
       
   714             // If we're matching normal rules, set a pseudo bit if 
       
   715             // we really just matched a pseudo-element.
       
   716             if (m_dynamicPseudo != NOPSEUDO && m_checker.m_pseudoStyle == NOPSEUDO) {
       
   717                 if (m_checker.m_collectRulesOnly)
       
   718                     continue;
       
   719                 if (m_dynamicPseudo < FIRST_INTERNAL_PSEUDOID)
       
   720                     m_style->setHasPseudoStyle(m_dynamicPseudo);
       
   721             } else {
       
   722                 // Update our first/last rule indices in the matched rules array.
       
   723                 lastRuleIndex = m_matchedDecls.size() + m_matchedRules.size();
       
   724                 if (firstRuleIndex == -1)
       
   725                     firstRuleIndex = lastRuleIndex;
       
   726 
       
   727                 // Add this rule to our list of matched rules.
       
   728                 addMatchedRule(d);
       
   729             }
       
   730         }
       
   731     }
       
   732 }
       
   733 
       
   734 static bool operator >(CSSRuleData& r1, CSSRuleData& r2)
       
   735 {
       
   736     int spec1 = r1.selector()->specificity();
       
   737     int spec2 = r2.selector()->specificity();
       
   738     return (spec1 == spec2) ? r1.position() > r2.position() : spec1 > spec2; 
       
   739 }
       
   740     
       
   741 static bool operator <=(CSSRuleData& r1, CSSRuleData& r2)
       
   742 {
       
   743     return !(r1 > r2);
       
   744 }
       
   745 
       
   746 void CSSStyleSelector::sortMatchedRules(unsigned start, unsigned end)
       
   747 {
       
   748     if (start >= end || (end - start == 1))
       
   749         return; // Sanity check.
       
   750 
       
   751     if (end - start <= 6) {
       
   752         // Apply a bubble sort for smaller lists.
       
   753         for (unsigned i = end - 1; i > start; i--) {
       
   754             bool sorted = true;
       
   755             for (unsigned j = start; j < i; j++) {
       
   756                 CSSRuleData* elt = m_matchedRules[j];
       
   757                 CSSRuleData* elt2 = m_matchedRules[j + 1];
       
   758                 if (*elt > *elt2) {
       
   759                     sorted = false;
       
   760                     m_matchedRules[j] = elt2;
       
   761                     m_matchedRules[j + 1] = elt;
       
   762                 }
       
   763             }
       
   764             if (sorted)
       
   765                 return;
       
   766         }
       
   767         return;
       
   768     }
       
   769 
       
   770     // Perform a merge sort for larger lists.
       
   771     unsigned mid = (start + end) / 2;
       
   772     sortMatchedRules(start, mid);
       
   773     sortMatchedRules(mid, end);
       
   774     
       
   775     CSSRuleData* elt = m_matchedRules[mid - 1];
       
   776     CSSRuleData* elt2 = m_matchedRules[mid];
       
   777     
       
   778     // Handle the fast common case (of equal specificity).  The list may already
       
   779     // be completely sorted.
       
   780     if (*elt <= *elt2)
       
   781         return;
       
   782     
       
   783     // We have to merge sort.  Ensure our merge buffer is big enough to hold
       
   784     // all the items.
       
   785     Vector<CSSRuleData*> rulesMergeBuffer;
       
   786     rulesMergeBuffer.reserveInitialCapacity(end - start); 
       
   787 
       
   788     unsigned i1 = start;
       
   789     unsigned i2 = mid;
       
   790     
       
   791     elt = m_matchedRules[i1];
       
   792     elt2 = m_matchedRules[i2];
       
   793     
       
   794     while (i1 < mid || i2 < end) {
       
   795         if (i1 < mid && (i2 == end || *elt <= *elt2)) {
       
   796             rulesMergeBuffer.append(elt);
       
   797             if (++i1 < mid)
       
   798                 elt = m_matchedRules[i1];
       
   799         } else {
       
   800             rulesMergeBuffer.append(elt2);
       
   801             if (++i2 < end)
       
   802                 elt2 = m_matchedRules[i2];
       
   803         }
       
   804     }
       
   805     
       
   806     for (unsigned i = start; i < end; i++)
       
   807         m_matchedRules[i] = rulesMergeBuffer[i - start];
       
   808 }
       
   809 
       
   810 inline EInsideLink CSSStyleSelector::SelectorChecker::determineLinkState(Element* element) const
       
   811 {
       
   812     if (!element || !element->isLink())
       
   813         return NotInsideLink;
       
   814     return determineLinkStateSlowCase(element);
       
   815 }
       
   816     
       
   817 inline void CSSStyleSelector::initElement(Element* e)
       
   818 {
       
   819     if (m_element != e) {
       
   820         m_element = e;
       
   821         m_styledElement = m_element && m_element->isStyledElement() ? static_cast<StyledElement*>(m_element) : 0;
       
   822         m_elementLinkState = m_checker.determineLinkState(m_element);
       
   823     }
       
   824 }
       
   825 
       
   826 inline void CSSStyleSelector::initForStyleResolve(Element* e, RenderStyle* parentStyle, PseudoId pseudoID)
       
   827 {
       
   828     m_checker.m_pseudoStyle = pseudoID;
       
   829 
       
   830     m_parentNode = e ? e->parentNode() : 0;
       
   831 
       
   832 #if ENABLE(SVG)
       
   833     if (!m_parentNode && e && e->isSVGElement() && e->isShadowNode())
       
   834         m_parentNode = e->shadowParentNode();
       
   835 #endif
       
   836 
       
   837     if (parentStyle)
       
   838         m_parentStyle = parentStyle;
       
   839     else
       
   840         m_parentStyle = m_parentNode ? m_parentNode->renderStyle() : 0;
       
   841 
       
   842     Node* docElement = e ? e->document()->documentElement() : 0;
       
   843     RenderStyle* docStyle = m_checker.m_document->renderStyle();
       
   844     m_rootElementStyle = docElement && e != docElement ? docElement->renderStyle() : docStyle;
       
   845 
       
   846     m_style = 0;
       
   847 
       
   848     m_matchedDecls.clear();
       
   849 
       
   850     m_ruleList = 0;
       
   851 
       
   852     m_fontDirty = false;
       
   853 }
       
   854 
       
   855 static inline const AtomicString* linkAttribute(Node* node)
       
   856 {
       
   857     if (!node->isLink())
       
   858         return 0;
       
   859 
       
   860     ASSERT(node->isElementNode());
       
   861     Element* element = static_cast<Element*>(node);
       
   862     if (element->isHTMLElement())
       
   863         return &element->fastGetAttribute(hrefAttr);
       
   864 
       
   865 #if ENABLE(WML)
       
   866     if (element->isWMLElement()) {
       
   867         // <anchor> elements don't have href attributes, but we still want to
       
   868         // appear as link, so linkAttribute() has to return a non-null value!
       
   869         if (element->hasTagName(WMLNames::anchorTag))
       
   870             return &emptyAtom;
       
   871 
       
   872         return &element->fastGetAttribute(hrefAttr);
       
   873     }
       
   874 #endif
       
   875 
       
   876 #if ENABLE(SVG)
       
   877     if (element->isSVGElement())
       
   878         return &element->fastGetAttribute(XLinkNames::hrefAttr);
       
   879 #endif
       
   880 
       
   881     return 0;
       
   882 }
       
   883 
       
   884 CSSStyleSelector::SelectorChecker::SelectorChecker(Document* document, bool strictParsing)
       
   885     : m_document(document)
       
   886     , m_strictParsing(strictParsing)
       
   887     , m_collectRulesOnly(false)
       
   888     , m_pseudoStyle(NOPSEUDO)
       
   889     , m_documentIsHTML(document->isHTMLDocument())
       
   890     , m_matchVisitedPseudoClass(false)
       
   891 {
       
   892 }
       
   893 
       
   894 EInsideLink CSSStyleSelector::SelectorChecker::determineLinkStateSlowCase(Element* element) const
       
   895 {
       
   896     ASSERT(element->isLink());
       
   897     
       
   898     const AtomicString* attr = linkAttribute(element);
       
   899     if (!attr || attr->isNull())
       
   900         return NotInsideLink;
       
   901 
       
   902 #if PLATFORM(QT)
       
   903     Vector<UChar, 512> url;
       
   904     visitedURL(m_document->baseURL(), *attr, url);
       
   905     if (url.isEmpty())
       
   906         return InsideUnvisitedLink;
       
   907 
       
   908     // If the Qt4.4 interface for the history is used, we will have to fallback
       
   909     // to the old global history.
       
   910     QWebHistoryInterface* iface = QWebHistoryInterface::defaultInterface();
       
   911     if (iface)
       
   912         return iface->historyContains(QString(reinterpret_cast<QChar*>(url.data()), url.size())) ? InsideVisitedLink : InsideUnvisitedLink;
       
   913 
       
   914     LinkHash hash = visitedLinkHash(url.data(), url.size());
       
   915     if (!hash)
       
   916         return InsideUnvisitedLink;
       
   917 #else
       
   918     LinkHash hash = visitedLinkHash(m_document->baseURL(), *attr);
       
   919     if (!hash)
       
   920         return InsideUnvisitedLink;
       
   921 #endif
       
   922 
       
   923     Frame* frame = m_document->frame();
       
   924     if (!frame)
       
   925         return InsideUnvisitedLink;
       
   926 
       
   927     Page* page = frame->page();
       
   928     if (!page)
       
   929         return InsideUnvisitedLink;
       
   930 
       
   931     m_linksCheckedForVisitedState.add(hash);
       
   932     return page->group().isLinkVisited(hash) ? InsideVisitedLink : InsideUnvisitedLink;
       
   933 }
       
   934 
       
   935 bool CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* element) const
       
   936 {
       
   937     PseudoId dynamicPseudo = NOPSEUDO;
       
   938     return checkSelector(sel, element, 0, dynamicPseudo, false, false) == SelectorMatches;
       
   939 }
       
   940 
       
   941 #ifdef STYLE_SHARING_STATS
       
   942 static int fraction = 0;
       
   943 static int total = 0;
       
   944 #endif
       
   945 
       
   946 static const unsigned cStyleSearchThreshold = 10;
       
   947 
       
   948 Node* CSSStyleSelector::locateCousinList(Element* parent, unsigned depth)
       
   949 {
       
   950     if (parent && parent->isStyledElement()) {
       
   951         StyledElement* p = static_cast<StyledElement*>(parent);
       
   952         if (!p->inlineStyleDecl() && !p->hasID()) {
       
   953             Node* r = p->previousSibling();
       
   954             unsigned subcount = 0;
       
   955             RenderStyle* st = p->renderStyle();
       
   956             while (r) {
       
   957                 if (r->renderStyle() == st)
       
   958                     return r->lastChild();
       
   959                 if (subcount++ == cStyleSearchThreshold)
       
   960                     return 0;
       
   961                 r = r->previousSibling();
       
   962             }
       
   963             if (!r && depth < cStyleSearchThreshold)
       
   964                 r = locateCousinList(parent->parentElement(), depth + 1);
       
   965             while (r) {
       
   966                 if (r->renderStyle() == st)
       
   967                     return r->lastChild();
       
   968                 if (subcount++ == cStyleSearchThreshold)
       
   969                     return 0;
       
   970                 r = r->previousSibling();
       
   971             }
       
   972         }
       
   973     }
       
   974     return 0;
       
   975 }
       
   976 
       
   977 bool CSSStyleSelector::canShareStyleWithElement(Node* n)
       
   978 {
       
   979     if (n->isStyledElement()) {
       
   980         StyledElement* s = static_cast<StyledElement*>(n);
       
   981         RenderStyle* style = s->renderStyle();
       
   982         if (style && !style->unique() &&
       
   983             (s->tagQName() == m_element->tagQName()) && !s->hasID() &&
       
   984             (s->hasClass() == m_element->hasClass()) && !s->inlineStyleDecl() &&
       
   985             (s->hasMappedAttributes() == m_styledElement->hasMappedAttributes()) &&
       
   986             (s->isLink() == m_element->isLink()) && 
       
   987             !style->affectedByAttributeSelectors() &&
       
   988             (s->hovered() == m_element->hovered()) &&
       
   989             (s->active() == m_element->active()) &&
       
   990             (s->focused() == m_element->focused()) &&
       
   991             (s != s->document()->cssTarget() && m_element != m_element->document()->cssTarget()) &&
       
   992             (s->fastGetAttribute(typeAttr) == m_element->fastGetAttribute(typeAttr)) &&
       
   993             (s->fastGetAttribute(XMLNames::langAttr) == m_element->fastGetAttribute(XMLNames::langAttr)) &&
       
   994             (s->fastGetAttribute(langAttr) == m_element->fastGetAttribute(langAttr)) &&
       
   995             (s->fastGetAttribute(readonlyAttr) == m_element->fastGetAttribute(readonlyAttr)) &&
       
   996             (s->fastGetAttribute(cellpaddingAttr) == m_element->fastGetAttribute(cellpaddingAttr))) {
       
   997             bool isControl = s->isFormControlElement();
       
   998             if (isControl != m_element->isFormControlElement())
       
   999                 return false;
       
  1000             if (isControl) {
       
  1001                 InputElement* thisInputElement = toInputElement(s);
       
  1002                 InputElement* otherInputElement = toInputElement(m_element);
       
  1003                 if (thisInputElement && otherInputElement) {
       
  1004                     if ((thisInputElement->isAutofilled() != otherInputElement->isAutofilled()) ||
       
  1005                         (thisInputElement->isChecked() != otherInputElement->isChecked()) ||
       
  1006                         (thisInputElement->isIndeterminate() != otherInputElement->isIndeterminate()))
       
  1007                     return false;
       
  1008                 } else
       
  1009                     return false;
       
  1010 
       
  1011                 if (s->isEnabledFormControl() != m_element->isEnabledFormControl())
       
  1012                     return false;
       
  1013 
       
  1014                 if (s->isDefaultButtonForForm() != m_element->isDefaultButtonForForm())
       
  1015                     return false;
       
  1016                 
       
  1017                 if (!m_element->document()->containsValidityStyleRules())
       
  1018                     return false;
       
  1019                 
       
  1020                 bool willValidate = s->willValidate();
       
  1021                 if (willValidate != m_element->willValidate())
       
  1022                     return false;
       
  1023                 
       
  1024                 if (willValidate && (s->isValidFormControlElement() != m_element->isValidFormControlElement()))
       
  1025                     return false;
       
  1026             }
       
  1027 
       
  1028             if (style->transitions() || style->animations())
       
  1029                 return false;
       
  1030 
       
  1031             bool classesMatch = true;
       
  1032             if (s->hasClass()) {
       
  1033                 const AtomicString& class1 = m_element->fastGetAttribute(classAttr);
       
  1034                 const AtomicString& class2 = s->fastGetAttribute(classAttr);
       
  1035                 classesMatch = (class1 == class2);
       
  1036             }
       
  1037             
       
  1038             if (classesMatch) {
       
  1039                 bool mappedAttrsMatch = true;
       
  1040                 if (s->hasMappedAttributes())
       
  1041                     mappedAttrsMatch = s->attributeMap()->mappedMapsEquivalent(m_styledElement->attributeMap());
       
  1042                 if (mappedAttrsMatch) {
       
  1043                     if (s->isLink()) {
       
  1044                         if (m_elementLinkState != style->insideLink())
       
  1045                             return false;
       
  1046                     }
       
  1047                     return true;
       
  1048                 }
       
  1049             }
       
  1050         }
       
  1051     }
       
  1052     return false;
       
  1053 }
       
  1054 
       
  1055 ALWAYS_INLINE RenderStyle* CSSStyleSelector::locateSharedStyle()
       
  1056 {
       
  1057     if (m_styledElement && !m_styledElement->inlineStyleDecl() && !m_styledElement->hasID() && !m_styledElement->document()->usesSiblingRules()) {
       
  1058         // Check previous siblings.
       
  1059         unsigned count = 0;
       
  1060         Node* n;
       
  1061         for (n = m_element->previousSibling(); n && !n->isElementNode(); n = n->previousSibling()) { }
       
  1062         while (n) {
       
  1063             if (canShareStyleWithElement(n))
       
  1064                 return n->renderStyle();
       
  1065             if (count++ == cStyleSearchThreshold)
       
  1066                 return 0;
       
  1067             for (n = n->previousSibling(); n && !n->isElementNode(); n = n->previousSibling()) { }
       
  1068         }
       
  1069         if (!n) 
       
  1070             n = locateCousinList(m_element->parentElement());
       
  1071         while (n) {
       
  1072             if (canShareStyleWithElement(n))
       
  1073                 return n->renderStyle();
       
  1074             if (count++ == cStyleSearchThreshold)
       
  1075                 return 0;
       
  1076             for (n = n->previousSibling(); n && !n->isElementNode(); n = n->previousSibling()) { }
       
  1077         }        
       
  1078     }
       
  1079     return 0;
       
  1080 }
       
  1081 
       
  1082 void CSSStyleSelector::matchUARules(int& firstUARule, int& lastUARule)
       
  1083 {
       
  1084     // First we match rules from the user agent sheet.
       
  1085     CSSRuleSet* userAgentStyleSheet = m_medium->mediaTypeMatchSpecific("print")
       
  1086         ? defaultPrintStyle : defaultStyle;
       
  1087     matchRules(userAgentStyleSheet, firstUARule, lastUARule);
       
  1088 
       
  1089     // In quirks mode, we match rules from the quirks user agent sheet.
       
  1090     if (!m_checker.m_strictParsing)
       
  1091         matchRules(defaultQuirksStyle, firstUARule, lastUARule);
       
  1092         
       
  1093     // If we're in view source mode, then we match rules from the view source style sheet.
       
  1094     if (m_checker.m_document->frame() && m_checker.m_document->frame()->inViewSourceMode()) {
       
  1095         if (!defaultViewSourceStyle)
       
  1096             loadViewSourceStyle();
       
  1097         matchRules(defaultViewSourceStyle, firstUARule, lastUARule);
       
  1098     }
       
  1099 }
       
  1100 
       
  1101 PassRefPtr<RenderStyle> CSSStyleSelector::styleForDocument(Document* document)
       
  1102 {
       
  1103     FrameView* view = document->view();
       
  1104 
       
  1105     RefPtr<RenderStyle> documentStyle = RenderStyle::create();
       
  1106     documentStyle->setDisplay(BLOCK);
       
  1107     documentStyle->setVisuallyOrdered(document->visuallyOrdered());
       
  1108     documentStyle->setZoom(view ? view->pageZoomFactor() : 1);
       
  1109     
       
  1110     FontDescription fontDescription;
       
  1111     fontDescription.setUsePrinterFont(document->printing());
       
  1112     if (Settings* settings = document->settings()) {
       
  1113         fontDescription.setRenderingMode(settings->fontRenderingMode());
       
  1114         if (document->printing() && !settings->shouldPrintBackgrounds())
       
  1115             documentStyle->setForceBackgroundsToWhite(true);
       
  1116         const AtomicString& stdfont = settings->standardFontFamily();
       
  1117         if (!stdfont.isEmpty()) {
       
  1118             fontDescription.firstFamily().setFamily(stdfont);
       
  1119             fontDescription.firstFamily().appendFamily(0);
       
  1120         }
       
  1121         fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
       
  1122         int size = CSSStyleSelector::fontSizeForKeyword(document, CSSValueMedium, false);
       
  1123         fontDescription.setSpecifiedSize(size);
       
  1124         bool useSVGZoomRules = document->isSVGDocument();
       
  1125         fontDescription.setComputedSize(CSSStyleSelector::getComputedSizeFromSpecifiedSize(document, documentStyle.get(), fontDescription.isAbsoluteSize(), size, useSVGZoomRules));
       
  1126     }
       
  1127 
       
  1128     documentStyle->setFontDescription(fontDescription);
       
  1129     documentStyle->font().update(0);
       
  1130     if (document->inCompatMode())
       
  1131         documentStyle->setHtmlHacks(true); // enable html specific rendering tricks
       
  1132         
       
  1133     return documentStyle.release();
       
  1134 }
       
  1135 
       
  1136 // If resolveForRootDefault is true, style based on user agent style sheet only. This is used in media queries, where
       
  1137 // relative units are interpreted according to document root element style, styled only with UA stylesheet
       
  1138 
       
  1139 PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* e, RenderStyle* defaultParent, bool allowSharing, bool resolveForRootDefault, bool matchVisitedPseudoClass)
       
  1140 {
       
  1141     // Once an element has a renderer, we don't try to destroy it, since otherwise the renderer
       
  1142     // will vanish if a style recalc happens during loading.
       
  1143     if (allowSharing && !e->document()->haveStylesheetsLoaded() && !e->renderer()) {
       
  1144         if (!s_styleNotYetAvailable) {
       
  1145             s_styleNotYetAvailable = RenderStyle::create().releaseRef();
       
  1146             s_styleNotYetAvailable->ref();
       
  1147             s_styleNotYetAvailable->setDisplay(NONE);
       
  1148             s_styleNotYetAvailable->font().update(m_fontSelector);
       
  1149         }
       
  1150         s_styleNotYetAvailable->ref();
       
  1151         e->document()->setHasNodesWithPlaceholderStyle();
       
  1152         return s_styleNotYetAvailable;
       
  1153     }
       
  1154 
       
  1155     initElement(e);
       
  1156     if (allowSharing) {
       
  1157         RenderStyle* sharedStyle = locateSharedStyle();
       
  1158         if (sharedStyle)
       
  1159             return sharedStyle;
       
  1160     }
       
  1161     initForStyleResolve(e, defaultParent);
       
  1162 
       
  1163     // Compute our style allowing :visited to match first.
       
  1164     RefPtr<RenderStyle> visitedStyle;
       
  1165     if (!matchVisitedPseudoClass && m_parentStyle && (m_parentStyle->insideLink() || e->isLink()) && e->document()->usesLinkRules()) {
       
  1166         // Fetch our parent style.
       
  1167         RenderStyle* parentStyle = m_parentStyle;
       
  1168         if (!e->isLink()) {
       
  1169             // Use the parent's visited style if one exists.
       
  1170             RenderStyle* parentVisitedStyle = m_parentStyle->getCachedPseudoStyle(VISITED_LINK);
       
  1171             if (parentVisitedStyle)
       
  1172                 parentStyle = parentVisitedStyle;
       
  1173         }
       
  1174         visitedStyle = styleForElement(e, parentStyle, false, false, true);
       
  1175         if (visitedStyle) {
       
  1176             if (m_elementLinkState == InsideUnvisitedLink)
       
  1177                 visitedStyle = 0;  // We made the style to avoid timing attacks. Just throw it away now that we did that, since we don't need it.
       
  1178             else
       
  1179                 visitedStyle->setStyleType(VISITED_LINK);
       
  1180         }
       
  1181         initForStyleResolve(e, defaultParent);
       
  1182     }
       
  1183 
       
  1184     m_checker.m_matchVisitedPseudoClass = matchVisitedPseudoClass;
       
  1185 
       
  1186     m_style = RenderStyle::create();
       
  1187 
       
  1188     if (m_parentStyle)
       
  1189         m_style->inheritFrom(m_parentStyle);
       
  1190     else
       
  1191         m_parentStyle = style();
       
  1192 
       
  1193     if (e->isLink()) {
       
  1194         m_style->setIsLink(true);
       
  1195         m_style->setInsideLink(m_elementLinkState);
       
  1196     }
       
  1197     
       
  1198     if (simpleDefaultStyleSheet && !elementCanUseSimpleDefaultStyle(e))
       
  1199         loadFullDefaultStyle();
       
  1200 
       
  1201 #if ENABLE(SVG)
       
  1202     static bool loadedSVGUserAgentSheet;
       
  1203     if (e->isSVGElement() && !loadedSVGUserAgentSheet) {
       
  1204         // SVG rules.
       
  1205         loadedSVGUserAgentSheet = true;
       
  1206         CSSStyleSheet* svgSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet));
       
  1207         defaultStyle->addRulesFromSheet(svgSheet, screenEval());
       
  1208         defaultPrintStyle->addRulesFromSheet(svgSheet, printEval());
       
  1209     }
       
  1210 #endif
       
  1211 
       
  1212 #if ENABLE(MATHML)
       
  1213     static bool loadedMathMLUserAgentSheet;
       
  1214     if (e->isMathMLElement() && !loadedMathMLUserAgentSheet) {
       
  1215         // MathML rules.
       
  1216         loadedMathMLUserAgentSheet = true;
       
  1217         CSSStyleSheet* mathMLSheet = parseUASheet(mathmlUserAgentStyleSheet, sizeof(mathmlUserAgentStyleSheet));
       
  1218         defaultStyle->addRulesFromSheet(mathMLSheet, screenEval());
       
  1219         defaultPrintStyle->addRulesFromSheet(mathMLSheet, printEval());
       
  1220     }
       
  1221 #endif
       
  1222 
       
  1223 #if ENABLE(WML)
       
  1224     static bool loadedWMLUserAgentSheet;
       
  1225     if (e->isWMLElement() && !loadedWMLUserAgentSheet) {
       
  1226         // WML rules.
       
  1227         loadedWMLUserAgentSheet = true;
       
  1228         CSSStyleSheet* wmlSheet = parseUASheet(wmlUserAgentStyleSheet, sizeof(wmlUserAgentStyleSheet));
       
  1229         defaultStyle->addRulesFromSheet(wmlSheet, screenEval());
       
  1230         defaultPrintStyle->addRulesFromSheet(wmlSheet, printEval());
       
  1231     }
       
  1232 #endif
       
  1233 
       
  1234 #if ENABLE(VIDEO)
       
  1235     static bool loadedMediaStyleSheet;
       
  1236     if (!loadedMediaStyleSheet && (e->hasTagName(videoTag) || e->hasTagName(audioTag))) {
       
  1237         loadedMediaStyleSheet = true;
       
  1238         String mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraMediaControlsStyleSheet();
       
  1239         CSSStyleSheet* mediaControlsSheet = parseUASheet(mediaRules);
       
  1240         defaultStyle->addRulesFromSheet(mediaControlsSheet, screenEval());
       
  1241         defaultPrintStyle->addRulesFromSheet(mediaControlsSheet, printEval());
       
  1242     }
       
  1243 #endif
       
  1244 
       
  1245     int firstUARule = -1, lastUARule = -1;
       
  1246     int firstUserRule = -1, lastUserRule = -1;
       
  1247     int firstAuthorRule = -1, lastAuthorRule = -1;
       
  1248     matchUARules(firstUARule, lastUARule);
       
  1249 
       
  1250     if (!resolveForRootDefault) {
       
  1251         // 4. Now we check user sheet rules.
       
  1252         if (m_matchAuthorAndUserStyles)
       
  1253             matchRules(m_userStyle, firstUserRule, lastUserRule);
       
  1254 
       
  1255         // 5. Now check author rules, beginning first with presentational attributes
       
  1256         // mapped from HTML.
       
  1257         if (m_styledElement) {
       
  1258             // Ask if the HTML element has mapped attributes.
       
  1259             if (m_styledElement->hasMappedAttributes()) {
       
  1260                 // Walk our attribute list and add in each decl.
       
  1261                 const NamedNodeMap* map = m_styledElement->attributeMap();
       
  1262                 for (unsigned i = 0; i < map->length(); i++) {
       
  1263                     Attribute* attr = map->attributeItem(i);
       
  1264                     if (attr->isMappedAttribute() && attr->decl()) {
       
  1265                         lastAuthorRule = m_matchedDecls.size();
       
  1266                         if (firstAuthorRule == -1)
       
  1267                             firstAuthorRule = lastAuthorRule;
       
  1268                         addMatchedDeclaration(attr->decl());
       
  1269                     }
       
  1270                 }
       
  1271             }
       
  1272 
       
  1273             // Now we check additional mapped declarations.
       
  1274             // Tables and table cells share an additional mapped rule that must be applied
       
  1275             // after all attributes, since their mapped style depends on the values of multiple attributes.
       
  1276             if (m_styledElement->canHaveAdditionalAttributeStyleDecls()) {
       
  1277                 m_additionalAttributeStyleDecls.clear();
       
  1278                 m_styledElement->additionalAttributeStyleDecls(m_additionalAttributeStyleDecls);
       
  1279                 if (!m_additionalAttributeStyleDecls.isEmpty()) {
       
  1280                     unsigned additionalDeclsSize = m_additionalAttributeStyleDecls.size();
       
  1281                     if (firstAuthorRule == -1)
       
  1282                         firstAuthorRule = m_matchedDecls.size();
       
  1283                     lastAuthorRule = m_matchedDecls.size() + additionalDeclsSize - 1;
       
  1284                     for (unsigned i = 0; i < additionalDeclsSize; i++)
       
  1285                         addMatchedDeclaration(m_additionalAttributeStyleDecls[i]);
       
  1286                 }
       
  1287             }
       
  1288         }
       
  1289     
       
  1290         // 6. Check the rules in author sheets next.
       
  1291         if (m_matchAuthorAndUserStyles)
       
  1292             matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);
       
  1293 
       
  1294         // 7. Now check our inline style attribute.
       
  1295         if (m_matchAuthorAndUserStyles && m_styledElement) {
       
  1296             CSSMutableStyleDeclaration* inlineDecl = m_styledElement->inlineStyleDecl();
       
  1297             if (inlineDecl) {
       
  1298                 lastAuthorRule = m_matchedDecls.size();
       
  1299                 if (firstAuthorRule == -1)
       
  1300                     firstAuthorRule = lastAuthorRule;
       
  1301                 addMatchedDeclaration(inlineDecl);
       
  1302             }
       
  1303         }
       
  1304     }
       
  1305 
       
  1306     // Reset the value back before applying properties, so that -webkit-link knows what color to use.
       
  1307     m_checker.m_matchVisitedPseudoClass = matchVisitedPseudoClass;
       
  1308     
       
  1309     // Now we have all of the matched rules in the appropriate order.  Walk the rules and apply
       
  1310     // high-priority properties first, i.e., those properties that other properties depend on.
       
  1311     // The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
       
  1312     // and (4) normal important.
       
  1313     m_lineHeightValue = 0;
       
  1314     applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
       
  1315     if (!resolveForRootDefault) {
       
  1316         applyDeclarations<true>(true, firstAuthorRule, lastAuthorRule);
       
  1317         applyDeclarations<true>(true, firstUserRule, lastUserRule);
       
  1318     }
       
  1319     applyDeclarations<true>(true, firstUARule, lastUARule);
       
  1320     
       
  1321     // If our font got dirtied, go ahead and update it now.
       
  1322     if (m_fontDirty)
       
  1323         updateFont();
       
  1324 
       
  1325     // Line-height is set when we are sure we decided on the font-size
       
  1326     if (m_lineHeightValue)
       
  1327         applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
       
  1328 
       
  1329     // Now do the normal priority UA properties.
       
  1330     applyDeclarations<false>(false, firstUARule, lastUARule);
       
  1331     
       
  1332     // Cache our border and background so that we can examine them later.
       
  1333     cacheBorderAndBackground();
       
  1334     
       
  1335     // Now do the author and user normal priority properties and all the !important properties.
       
  1336     if (!resolveForRootDefault) {
       
  1337         applyDeclarations<false>(false, lastUARule + 1, m_matchedDecls.size() - 1);
       
  1338         applyDeclarations<false>(true, firstAuthorRule, lastAuthorRule);
       
  1339         applyDeclarations<false>(true, firstUserRule, lastUserRule);
       
  1340     }
       
  1341     applyDeclarations<false>(true, firstUARule, lastUARule);
       
  1342     
       
  1343     // If our font got dirtied by one of the non-essential font props, 
       
  1344     // go ahead and update it a second time.
       
  1345     if (m_fontDirty)
       
  1346         updateFont();
       
  1347     
       
  1348     // Clean up our style object's display and text decorations (among other fixups).
       
  1349     adjustRenderStyle(style(), e);
       
  1350 
       
  1351     // If we have first-letter pseudo style, do not share this style
       
  1352     if (m_style->hasPseudoStyle(FIRST_LETTER))
       
  1353         m_style->setUnique();
       
  1354 
       
  1355     if (visitedStyle) {
       
  1356         // Copy any pseudo bits that the visited style has to the primary style so that
       
  1357         // pseudo element styles will continue to work for pseudo elements inside :visited
       
  1358         // links.
       
  1359         for (unsigned pseudo = FIRST_PUBLIC_PSEUDOID; pseudo < FIRST_INTERNAL_PSEUDOID; ++pseudo) {
       
  1360             if (visitedStyle->hasPseudoStyle(static_cast<PseudoId>(pseudo)))
       
  1361                 m_style->setHasPseudoStyle(static_cast<PseudoId>(pseudo));
       
  1362         }
       
  1363         
       
  1364         // Add the visited style off the main style.
       
  1365         m_style->addCachedPseudoStyle(visitedStyle.release());
       
  1366     }
       
  1367 
       
  1368     if (!matchVisitedPseudoClass)
       
  1369         initElement(0); // Clear out for the next resolve.
       
  1370 
       
  1371     // Now return the style.
       
  1372     return m_style.release();
       
  1373 }
       
  1374 
       
  1375 PassRefPtr<RenderStyle> CSSStyleSelector::styleForKeyframe(const RenderStyle* elementStyle, const WebKitCSSKeyframeRule* keyframeRule, KeyframeList& list)
       
  1376 {
       
  1377     if (keyframeRule->style())
       
  1378         addMatchedDeclaration(keyframeRule->style());
       
  1379 
       
  1380     ASSERT(!m_style);
       
  1381 
       
  1382     // Create the style
       
  1383     m_style = RenderStyle::clone(elementStyle);
       
  1384 
       
  1385     m_lineHeightValue = 0;
       
  1386 
       
  1387     // We don't need to bother with !important. Since there is only ever one
       
  1388     // decl, there's nothing to override. So just add the first properties.
       
  1389     if (keyframeRule->style())
       
  1390         applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
       
  1391 
       
  1392     // If our font got dirtied, go ahead and update it now.
       
  1393     if (m_fontDirty)
       
  1394         updateFont();
       
  1395 
       
  1396     // Line-height is set when we are sure we decided on the font-size
       
  1397     if (m_lineHeightValue)
       
  1398         applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
       
  1399 
       
  1400     // Now do rest of the properties.
       
  1401     if (keyframeRule->style())
       
  1402         applyDeclarations<false>(false, 0, m_matchedDecls.size() - 1);
       
  1403 
       
  1404     // If our font got dirtied by one of the non-essential font props,
       
  1405     // go ahead and update it a second time.
       
  1406     if (m_fontDirty)
       
  1407         updateFont();
       
  1408 
       
  1409     // Add all the animating properties to the list
       
  1410     if (keyframeRule->style()) {
       
  1411         CSSMutableStyleDeclaration::const_iterator end = keyframeRule->style()->end();
       
  1412         for (CSSMutableStyleDeclaration::const_iterator it = keyframeRule->style()->begin(); it != end; ++it) {
       
  1413             int property = (*it).id();
       
  1414             // Timing-function within keyframes is special, because it is not animated; it just
       
  1415             // describes the timing function between this keyframe and the next.
       
  1416             if (property != CSSPropertyWebkitAnimationTimingFunction)
       
  1417                 list.addProperty(property);
       
  1418         }
       
  1419     }
       
  1420 
       
  1421     return m_style.release();
       
  1422 }
       
  1423 
       
  1424 void CSSStyleSelector::keyframeStylesForAnimation(Element* e, const RenderStyle* elementStyle, KeyframeList& list)
       
  1425 {
       
  1426     list.clear();
       
  1427     
       
  1428     // Get the keyframesRule for this name
       
  1429     if (!e || list.animationName().isEmpty())
       
  1430         return;
       
  1431 
       
  1432     m_keyframesRuleMap.checkConsistency();
       
  1433    
       
  1434     if (!m_keyframesRuleMap.contains(list.animationName().impl()))
       
  1435         return;
       
  1436         
       
  1437     const WebKitCSSKeyframesRule* rule = m_keyframesRuleMap.find(list.animationName().impl()).get()->second.get();
       
  1438     RefPtr<RenderStyle> keyframeStyle;
       
  1439     
       
  1440     // Construct and populate the style for each keyframe
       
  1441     for (unsigned i = 0; i < rule->length(); ++i) {
       
  1442         // Apply the declaration to the style. This is a simplified version of the logic in styleForElement
       
  1443         initElement(e);
       
  1444         initForStyleResolve(e);
       
  1445         
       
  1446         const WebKitCSSKeyframeRule* keyframeRule = rule->item(i);
       
  1447         
       
  1448         keyframeStyle = styleForKeyframe(elementStyle, keyframeRule, list);
       
  1449 
       
  1450         // Add this keyframe style to all the indicated key times
       
  1451         Vector<float> keys;
       
  1452         keyframeRule->getKeys(keys);
       
  1453         for (size_t keyIndex = 0; keyIndex < keys.size(); ++keyIndex) {
       
  1454             float key = keys[keyIndex];
       
  1455             list.insert(key, keyframeStyle.get());
       
  1456         }
       
  1457         keyframeStyle.release();
       
  1458     }
       
  1459     
       
  1460     // If the 0% keyframe is missing, create it (but only if there is at least one other keyframe)
       
  1461     int initialListSize = list.size();
       
  1462     if (initialListSize > 0 && list.beginKeyframes()->key() != 0) {
       
  1463         RefPtr<WebKitCSSKeyframeRule> keyframe = WebKitCSSKeyframeRule::create();
       
  1464         keyframe->setKeyText("0%");
       
  1465         keyframeStyle = styleForKeyframe(elementStyle, keyframe.get(), list);
       
  1466         list.insert(0, keyframeStyle.release());
       
  1467     }
       
  1468 
       
  1469     // If the 100% keyframe is missing, create it (but only if there is at least one other keyframe)
       
  1470     if (initialListSize > 0 && (list.endKeyframes() - 1)->key() != 1) {
       
  1471         RefPtr<WebKitCSSKeyframeRule> keyframe = WebKitCSSKeyframeRule::create();
       
  1472         keyframe->setKeyText("100%");
       
  1473         keyframeStyle = styleForKeyframe(elementStyle, keyframe.get(), list);
       
  1474         list.insert(1, keyframeStyle.release());
       
  1475     }
       
  1476 }
       
  1477 
       
  1478 PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(PseudoId pseudo, Element* e, RenderStyle* parentStyle, bool matchVisitedPseudoClass)
       
  1479 {
       
  1480     if (!e)
       
  1481         return 0;
       
  1482 
       
  1483     initElement(e);
       
  1484 
       
  1485     // Compute our :visited style first, so that we know whether or not we'll need to create a normal style just to hang it
       
  1486     // off of.
       
  1487     RefPtr<RenderStyle> visitedStyle;
       
  1488     if (!matchVisitedPseudoClass && parentStyle && parentStyle->insideLink()) {
       
  1489         // Fetch our parent style with :visited in effect.
       
  1490         RenderStyle* parentVisitedStyle = parentStyle->getCachedPseudoStyle(VISITED_LINK);
       
  1491         visitedStyle = pseudoStyleForElement(pseudo, e, parentVisitedStyle ? parentVisitedStyle : parentStyle, true);
       
  1492         if (visitedStyle) {
       
  1493             if (m_elementLinkState == InsideUnvisitedLink)
       
  1494                 visitedStyle = 0;  // We made the style to avoid timing attacks. Just throw it away now that we did that.
       
  1495             else
       
  1496                 visitedStyle->setStyleType(VISITED_LINK);
       
  1497         }
       
  1498     }
       
  1499 
       
  1500     initForStyleResolve(e, parentStyle, pseudo);
       
  1501     m_style = parentStyle;
       
  1502     
       
  1503     m_checker.m_matchVisitedPseudoClass = matchVisitedPseudoClass;
       
  1504 
       
  1505     // Since we don't use pseudo-elements in any of our quirk/print user agent rules, don't waste time walking
       
  1506     // those rules.
       
  1507     
       
  1508     // Check UA, user and author rules.
       
  1509     int firstUARule = -1, lastUARule = -1, firstUserRule = -1, lastUserRule = -1, firstAuthorRule = -1, lastAuthorRule = -1;
       
  1510     matchUARules(firstUARule, lastUARule);
       
  1511 
       
  1512     if (m_matchAuthorAndUserStyles) {
       
  1513         matchRules(m_userStyle, firstUserRule, lastUserRule);
       
  1514         matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);
       
  1515     }
       
  1516 
       
  1517     if (m_matchedDecls.isEmpty() && !visitedStyle)
       
  1518         return 0;
       
  1519 
       
  1520     m_style = RenderStyle::create();
       
  1521     if (parentStyle)
       
  1522         m_style->inheritFrom(parentStyle);
       
  1523 
       
  1524     m_style->setStyleType(pseudo);
       
  1525     
       
  1526     m_lineHeightValue = 0;
       
  1527     
       
  1528     // Reset the value back before applying properties, so that -webkit-link knows what color to use.
       
  1529     m_checker.m_matchVisitedPseudoClass = matchVisitedPseudoClass;
       
  1530 
       
  1531     // High-priority properties.
       
  1532     applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
       
  1533     applyDeclarations<true>(true, firstAuthorRule, lastAuthorRule);
       
  1534     applyDeclarations<true>(true, firstUserRule, lastUserRule);
       
  1535     applyDeclarations<true>(true, firstUARule, lastUARule);
       
  1536     
       
  1537     // If our font got dirtied, go ahead and update it now.
       
  1538     if (m_fontDirty)
       
  1539         updateFont();
       
  1540 
       
  1541     // Line-height is set when we are sure we decided on the font-size
       
  1542     if (m_lineHeightValue)
       
  1543         applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
       
  1544     
       
  1545     // Now do the normal priority properties.
       
  1546     applyDeclarations<false>(false, firstUARule, lastUARule);
       
  1547     
       
  1548     // Cache our border and background so that we can examine them later.
       
  1549     cacheBorderAndBackground();
       
  1550     
       
  1551     applyDeclarations<false>(false, lastUARule + 1, m_matchedDecls.size() - 1);
       
  1552     applyDeclarations<false>(true, firstAuthorRule, lastAuthorRule);
       
  1553     applyDeclarations<false>(true, firstUserRule, lastUserRule);
       
  1554     applyDeclarations<false>(true, firstUARule, lastUARule);
       
  1555     
       
  1556     // If our font got dirtied by one of the non-essential font props, 
       
  1557     // go ahead and update it a second time.
       
  1558     if (m_fontDirty)
       
  1559         updateFont();
       
  1560 
       
  1561     // Clean up our style object's display and text decorations (among other fixups).
       
  1562     adjustRenderStyle(style(), 0);
       
  1563 
       
  1564     // Hang our visited style off m_style.
       
  1565     if (visitedStyle)
       
  1566         m_style->addCachedPseudoStyle(visitedStyle.release());
       
  1567         
       
  1568     // Now return the style.
       
  1569     return m_style.release();
       
  1570 }
       
  1571 
       
  1572 PassRefPtr<RenderStyle> CSSStyleSelector::styleForPage(int pageIndex)
       
  1573 {
       
  1574     initForStyleResolve(m_checker.m_document->body());
       
  1575 
       
  1576     m_style = RenderStyle::create();
       
  1577     m_style->inheritFrom(m_rootElementStyle);
       
  1578 
       
  1579     const bool isLeft = isLeftPage(pageIndex);
       
  1580     const bool isFirst = isFirstPage(pageIndex);
       
  1581     const String page = pageName(pageIndex);
       
  1582     matchPageRules(defaultPrintStyle, isLeft, isFirst, page);
       
  1583     matchPageRules(m_userStyle, isLeft, isFirst, page);
       
  1584     matchPageRules(m_authorStyle, isLeft, isFirst, page);
       
  1585     m_lineHeightValue = 0;
       
  1586     applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
       
  1587 
       
  1588     // If our font got dirtied, go ahead and update it now.
       
  1589     if (m_fontDirty)
       
  1590         updateFont();
       
  1591 
       
  1592     // Line-height is set when we are sure we decided on the font-size
       
  1593     if (m_lineHeightValue)
       
  1594         applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
       
  1595 
       
  1596     applyDeclarations<false>(false, 0, m_matchedDecls.size() - 1);
       
  1597 
       
  1598     // Now return the style.
       
  1599     return m_style.release();
       
  1600 }
       
  1601 
       
  1602 #if ENABLE(DATAGRID)
       
  1603 
       
  1604 PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForDataGridColumn(DataGridColumn*, RenderStyle*)
       
  1605 {
       
  1606     // FIXME: Implement
       
  1607     return 0;
       
  1608 }
       
  1609 
       
  1610 PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForDataGridColumnHeader(DataGridColumn*, RenderStyle*)
       
  1611 {
       
  1612     // FIXME: Implement
       
  1613     return 0;
       
  1614 }
       
  1615 
       
  1616 #endif
       
  1617 
       
  1618 static void addIntrinsicMargins(RenderStyle* style)
       
  1619 {
       
  1620     // Intrinsic margin value.
       
  1621     const int intrinsicMargin = 2 * style->effectiveZoom();
       
  1622     
       
  1623     // FIXME: Using width/height alone and not also dealing with min-width/max-width is flawed.
       
  1624     // FIXME: Using "quirk" to decide the margin wasn't set is kind of lame.
       
  1625     if (style->width().isIntrinsicOrAuto()) {
       
  1626         if (style->marginLeft().quirk())
       
  1627             style->setMarginLeft(Length(intrinsicMargin, Fixed));
       
  1628         if (style->marginRight().quirk())
       
  1629             style->setMarginRight(Length(intrinsicMargin, Fixed));
       
  1630     }
       
  1631 
       
  1632     if (style->height().isAuto()) {
       
  1633         if (style->marginTop().quirk())
       
  1634             style->setMarginTop(Length(intrinsicMargin, Fixed));
       
  1635         if (style->marginBottom().quirk())
       
  1636             style->setMarginBottom(Length(intrinsicMargin, Fixed));
       
  1637     }
       
  1638 }
       
  1639 
       
  1640 void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, Element *e)
       
  1641 {
       
  1642     // Cache our original display.
       
  1643     style->setOriginalDisplay(style->display());
       
  1644 
       
  1645     if (style->display() != NONE) {
       
  1646         // If we have a <td> that specifies a float property, in quirks mode we just drop the float
       
  1647         // property.
       
  1648         // Sites also commonly use display:inline/block on <td>s and <table>s.  In quirks mode we force
       
  1649         // these tags to retain their display types.
       
  1650         if (!m_checker.m_strictParsing && e) {
       
  1651             if (e->hasTagName(tdTag)) {
       
  1652                 style->setDisplay(TABLE_CELL);
       
  1653                 style->setFloating(FNONE);
       
  1654             }
       
  1655             else if (e->hasTagName(tableTag))
       
  1656                 style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE);
       
  1657         }
       
  1658 
       
  1659         if (e && (e->hasTagName(tdTag) || e->hasTagName(thTag))) {
       
  1660             if (style->whiteSpace() == KHTML_NOWRAP) {
       
  1661                 // Figure out if we are really nowrapping or if we should just
       
  1662                 // use normal instead.  If the width of the cell is fixed, then
       
  1663                 // we don't actually use NOWRAP.
       
  1664                 if (style->width().isFixed())
       
  1665                     style->setWhiteSpace(NORMAL);
       
  1666                 else
       
  1667                     style->setWhiteSpace(NOWRAP);
       
  1668             }
       
  1669         }
       
  1670 
       
  1671         // Tables never support the -webkit-* values for text-align and will reset back to the default.
       
  1672         if (e && e->hasTagName(tableTag) && (style->textAlign() == WEBKIT_LEFT || style->textAlign() == WEBKIT_CENTER || style->textAlign() == WEBKIT_RIGHT))
       
  1673             style->setTextAlign(TAAUTO);
       
  1674 
       
  1675         // Frames and framesets never honor position:relative or position:absolute.  This is necessary to
       
  1676         // fix a crash where a site tries to position these objects.  They also never honor display.
       
  1677         if (e && (e->hasTagName(frameTag) || e->hasTagName(framesetTag))) {
       
  1678             style->setPosition(StaticPosition);
       
  1679             style->setDisplay(BLOCK);
       
  1680         }
       
  1681 
       
  1682         // Table headers with a text-align of auto will change the text-align to center.
       
  1683         if (e && e->hasTagName(thTag) && style->textAlign() == TAAUTO)
       
  1684             style->setTextAlign(CENTER);
       
  1685 
       
  1686         if (e && e->hasTagName(legendTag))
       
  1687             style->setDisplay(BLOCK);
       
  1688 
       
  1689         // Mutate the display to BLOCK or TABLE for certain cases, e.g., if someone attempts to
       
  1690         // position or float an inline, compact, or run-in.  Cache the original display, since it
       
  1691         // may be needed for positioned elements that have to compute their static normal flow
       
  1692         // positions.  We also force inline-level roots to be block-level.
       
  1693         if (style->display() != BLOCK && style->display() != TABLE && style->display() != BOX &&
       
  1694             (style->position() == AbsolutePosition || style->position() == FixedPosition || style->floating() != FNONE ||
       
  1695              (e && e->document()->documentElement() == e))) {
       
  1696             if (style->display() == INLINE_TABLE)
       
  1697                 style->setDisplay(TABLE);
       
  1698             else if (style->display() == INLINE_BOX)
       
  1699                 style->setDisplay(BOX);
       
  1700             else if (style->display() == LIST_ITEM) {
       
  1701                 // It is a WinIE bug that floated list items lose their bullets, so we'll emulate the quirk,
       
  1702                 // but only in quirks mode.
       
  1703                 if (!m_checker.m_strictParsing && style->floating() != FNONE)
       
  1704                     style->setDisplay(BLOCK);
       
  1705             }
       
  1706             else
       
  1707                 style->setDisplay(BLOCK);
       
  1708         }
       
  1709         
       
  1710         // After performing the display mutation, check table rows.  We do not honor position:relative on
       
  1711         // table rows or cells.  This has been established in CSS2.1 (and caused a crash in containingBlock()
       
  1712         // on some sites).
       
  1713         if ((style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW_GROUP ||
       
  1714              style->display() == TABLE_FOOTER_GROUP || style->display() == TABLE_ROW || style->display() == TABLE_CELL) &&
       
  1715              style->position() == RelativePosition)
       
  1716             style->setPosition(StaticPosition);
       
  1717     }
       
  1718 
       
  1719     // Make sure our z-index value is only applied if the object is positioned.
       
  1720     if (style->position() == StaticPosition)
       
  1721         style->setHasAutoZIndex();
       
  1722 
       
  1723     // Auto z-index becomes 0 for the root element and transparent objects.  This prevents
       
  1724     // cases where objects that should be blended as a single unit end up with a non-transparent
       
  1725     // object wedged in between them.  Auto z-index also becomes 0 for objects that specify transforms/masks/reflections.
       
  1726     if (style->hasAutoZIndex() && ((e && e->document()->documentElement() == e) || style->opacity() < 1.0f || 
       
  1727         style->hasTransformRelatedProperty() || style->hasMask() || style->boxReflect()))
       
  1728         style->setZIndex(0);
       
  1729     
       
  1730     // Button, legend, input, select and textarea all consider width values of 'auto' to be 'intrinsic'.
       
  1731     // This will be important when we use block flows for all form controls.
       
  1732     if (e && (e->hasTagName(legendTag) || e->hasTagName(buttonTag) || e->hasTagName(inputTag) ||
       
  1733               e->hasTagName(selectTag) || e->hasTagName(textareaTag) || e->hasTagName(datagridTag)
       
  1734 #if ENABLE(WML)
       
  1735               || e->hasTagName(WMLNames::insertedLegendTag)
       
  1736               || e->hasTagName(WMLNames::inputTag)
       
  1737 #endif
       
  1738        )) {
       
  1739         if (style->width().isAuto())
       
  1740             style->setWidth(Length(Intrinsic));
       
  1741 
       
  1742         // Textarea considers overflow visible as auto.
       
  1743         if (e && e->hasTagName(textareaTag)) {
       
  1744             style->setOverflowX(style->overflowX() == OVISIBLE ? OAUTO : style->overflowX());
       
  1745             style->setOverflowY(style->overflowY() == OVISIBLE ? OAUTO : style->overflowY());
       
  1746         }
       
  1747     }
       
  1748 
       
  1749     // Finally update our text decorations in effect, but don't allow text-decoration to percolate through
       
  1750     // tables, inline blocks, inline tables, or run-ins.
       
  1751     if (style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN
       
  1752         || style->display() == INLINE_BLOCK || style->display() == INLINE_BOX)
       
  1753         style->setTextDecorationsInEffect(style->textDecoration());
       
  1754     else
       
  1755         style->addToTextDecorationsInEffect(style->textDecoration());
       
  1756     
       
  1757     // If either overflow value is not visible, change to auto.
       
  1758     if (style->overflowX() == OMARQUEE && style->overflowY() != OMARQUEE)
       
  1759         style->setOverflowY(OMARQUEE);
       
  1760     else if (style->overflowY() == OMARQUEE && style->overflowX() != OMARQUEE)
       
  1761         style->setOverflowX(OMARQUEE);
       
  1762     else if (style->overflowX() == OVISIBLE && style->overflowY() != OVISIBLE)
       
  1763         style->setOverflowX(OAUTO);
       
  1764     else if (style->overflowY() == OVISIBLE && style->overflowX() != OVISIBLE)
       
  1765         style->setOverflowY(OAUTO);
       
  1766 
       
  1767     // Table rows, sections and the table itself will support overflow:hidden and will ignore scroll/auto.
       
  1768     // FIXME: Eventually table sections will support auto and scroll.
       
  1769     if (style->display() == TABLE || style->display() == INLINE_TABLE ||
       
  1770         style->display() == TABLE_ROW_GROUP || style->display() == TABLE_ROW) {
       
  1771         if (style->overflowX() != OVISIBLE && style->overflowX() != OHIDDEN) 
       
  1772             style->setOverflowX(OVISIBLE);
       
  1773         if (style->overflowY() != OVISIBLE && style->overflowY() != OHIDDEN) 
       
  1774             style->setOverflowY(OVISIBLE);
       
  1775     }
       
  1776 
       
  1777     // Menulists should have visible overflow
       
  1778     if (style->appearance() == MenulistPart) {
       
  1779         style->setOverflowX(OVISIBLE);
       
  1780         style->setOverflowY(OVISIBLE);
       
  1781     }
       
  1782 
       
  1783     // Cull out any useless layers and also repeat patterns into additional layers.
       
  1784     style->adjustBackgroundLayers();
       
  1785     style->adjustMaskLayers();
       
  1786 
       
  1787     // Do the same for animations and transitions.
       
  1788     style->adjustAnimations();
       
  1789     style->adjustTransitions();
       
  1790 
       
  1791     // Important: Intrinsic margins get added to controls before the theme has adjusted the style, since the theme will
       
  1792     // alter fonts and heights/widths.
       
  1793     if (e && e->isFormControlElement() && style->fontSize() >= 11) {
       
  1794         // Don't apply intrinsic margins to image buttons.  The designer knows how big the images are,
       
  1795         // so we have to treat all image buttons as though they were explicitly sized.
       
  1796         if (!e->hasTagName(inputTag) || static_cast<HTMLInputElement*>(e)->inputType() != HTMLInputElement::IMAGE)
       
  1797             addIntrinsicMargins(style);
       
  1798     }
       
  1799 
       
  1800     // Let the theme also have a crack at adjusting the style.
       
  1801     if (style->hasAppearance())
       
  1802         RenderTheme::defaultTheme()->adjustStyle(this, style, e, m_hasUAAppearance, m_borderData, m_backgroundData, m_backgroundColor);
       
  1803 
       
  1804 #if ENABLE(SVG)
       
  1805     if (e && e->isSVGElement()) {
       
  1806         // Spec: http://www.w3.org/TR/SVG/masking.html#OverflowProperty
       
  1807         if (style->overflowY() == OSCROLL)
       
  1808             style->setOverflowY(OHIDDEN);
       
  1809         else if (style->overflowY() == OAUTO)
       
  1810             style->setOverflowY(OVISIBLE);
       
  1811 
       
  1812         if (style->overflowX() == OSCROLL)
       
  1813             style->setOverflowX(OHIDDEN);
       
  1814         else if (style->overflowX() == OAUTO)
       
  1815             style->setOverflowX(OVISIBLE);
       
  1816 
       
  1817         // Only the root <svg> element in an SVG document fragment tree honors css position
       
  1818         if (!(e->hasTagName(SVGNames::svgTag) && e->parentNode() && !e->parentNode()->isSVGElement()))
       
  1819             style->setPosition(RenderStyle::initialPosition());
       
  1820     }
       
  1821 #endif
       
  1822 }
       
  1823 
       
  1824 void CSSStyleSelector::updateFont()
       
  1825 {
       
  1826     checkForTextSizeAdjust();
       
  1827     checkForGenericFamilyChange(style(), m_parentStyle);
       
  1828     checkForZoomChange(style(), m_parentStyle);
       
  1829     m_style->font().update(m_fontSelector);
       
  1830     m_fontDirty = false;
       
  1831 }
       
  1832 
       
  1833 void CSSStyleSelector::cacheBorderAndBackground()
       
  1834 {
       
  1835     m_hasUAAppearance = m_style->hasAppearance();
       
  1836     if (m_hasUAAppearance) {
       
  1837         m_borderData = m_style->border();
       
  1838         m_backgroundData = *m_style->backgroundLayers();
       
  1839         m_backgroundColor = m_style->backgroundColor();
       
  1840     }
       
  1841 }
       
  1842 
       
  1843 PassRefPtr<CSSRuleList> CSSStyleSelector::styleRulesForElement(Element* e, bool authorOnly)
       
  1844 {
       
  1845     return pseudoStyleRulesForElement(e, NOPSEUDO, authorOnly);
       
  1846 }
       
  1847 
       
  1848 PassRefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element* e, PseudoId pseudoId, bool authorOnly)
       
  1849 {
       
  1850     if (!e || !e->document()->haveStylesheetsLoaded())
       
  1851         return 0;
       
  1852 
       
  1853     m_checker.m_collectRulesOnly = true;
       
  1854 
       
  1855     initElement(e);
       
  1856     initForStyleResolve(e, 0, pseudoId);
       
  1857 
       
  1858     if (!authorOnly) {
       
  1859         int firstUARule = -1, lastUARule = -1;
       
  1860         // First we match rules from the user agent sheet.
       
  1861         matchUARules(firstUARule, lastUARule);
       
  1862 
       
  1863         // Now we check user sheet rules.
       
  1864         if (m_matchAuthorAndUserStyles) {
       
  1865             int firstUserRule = -1, lastUserRule = -1;
       
  1866             matchRules(m_userStyle, firstUserRule, lastUserRule);
       
  1867         }
       
  1868     }
       
  1869 
       
  1870     if (m_matchAuthorAndUserStyles) {
       
  1871         // Check the rules in author sheets.
       
  1872         int firstAuthorRule = -1, lastAuthorRule = -1;
       
  1873         matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);
       
  1874     }
       
  1875 
       
  1876     m_checker.m_collectRulesOnly = false;
       
  1877     
       
  1878     return m_ruleList.release();
       
  1879 }
       
  1880 
       
  1881 bool CSSStyleSelector::checkSelector(CSSSelector* sel)
       
  1882 {
       
  1883     m_dynamicPseudo = NOPSEUDO;
       
  1884 
       
  1885     // Check the selector
       
  1886     SelectorMatch match = m_checker.checkSelector(sel, m_element, &m_selectorAttrs, m_dynamicPseudo, false, false, style(), m_parentStyle);
       
  1887     if (match != SelectorMatches)
       
  1888         return false;
       
  1889 
       
  1890     if (m_checker.m_pseudoStyle != NOPSEUDO && m_checker.m_pseudoStyle != m_dynamicPseudo)
       
  1891         return false;
       
  1892 
       
  1893     return true;
       
  1894 }
       
  1895 
       
  1896 // Recursive check of selectors and combinators
       
  1897 // It can return 3 different values:
       
  1898 // * SelectorMatches         - the selector matches the element e
       
  1899 // * SelectorFailsLocally    - the selector fails for the element e
       
  1900 // * SelectorFailsCompletely - the selector fails for e and any sibling or ancestor of e
       
  1901 CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
       
  1902 {
       
  1903 #if ENABLE(SVG)
       
  1904     // Spec: CSS2 selectors cannot be applied to the (conceptually) cloned DOM tree
       
  1905     // because its contents are not part of the formal document structure.
       
  1906     if (e->isSVGElement() && e->isShadowNode())
       
  1907         return SelectorFailsCompletely;
       
  1908 #endif
       
  1909 
       
  1910     // first selector has to match
       
  1911     if (!checkOneSelector(sel, e, selectorAttrs, dynamicPseudo, isSubSelector, elementStyle, elementParentStyle))
       
  1912         return SelectorFailsLocally;
       
  1913 
       
  1914     // The rest of the selectors has to match
       
  1915     CSSSelector::Relation relation = sel->relation();
       
  1916 
       
  1917     // Prepare next sel
       
  1918     sel = sel->tagHistory();
       
  1919     if (!sel)
       
  1920         return SelectorMatches;
       
  1921 
       
  1922     if (relation != CSSSelector::SubSelector)
       
  1923         // Bail-out if this selector is irrelevant for the pseudoStyle
       
  1924         if (m_pseudoStyle != NOPSEUDO && m_pseudoStyle != dynamicPseudo)
       
  1925             return SelectorFailsCompletely;
       
  1926 
       
  1927     // Check for nested links.
       
  1928     if (m_matchVisitedPseudoClass && !isSubSelector) {
       
  1929         RenderStyle* currentStyle = elementStyle ? elementStyle : e->renderStyle();
       
  1930         if (currentStyle && currentStyle->insideLink() && e->isLink()) {
       
  1931             if (encounteredLink)
       
  1932                 m_matchVisitedPseudoClass = false; // This link is not relevant to the style being resolved, so disable matching.
       
  1933             else
       
  1934                 encounteredLink = true;
       
  1935         }
       
  1936     }
       
  1937 
       
  1938     switch (relation) {
       
  1939         case CSSSelector::Descendant:
       
  1940             while (true) {
       
  1941                 Node* n = e->parentNode();
       
  1942                 if (!n || !n->isElementNode())
       
  1943                     return SelectorFailsCompletely;
       
  1944                 e = static_cast<Element*>(n);
       
  1945                 SelectorMatch match = checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
       
  1946                 if (match != SelectorFailsLocally)
       
  1947                     return match;
       
  1948             }
       
  1949             break;
       
  1950         case CSSSelector::Child:
       
  1951         {
       
  1952             Node* n = e->parentNode();
       
  1953             if (!n || !n->isElementNode())
       
  1954                 return SelectorFailsCompletely;
       
  1955             e = static_cast<Element*>(n);
       
  1956             return checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
       
  1957         }
       
  1958         case CSSSelector::DirectAdjacent:
       
  1959         {
       
  1960             if (!m_collectRulesOnly && e->parentNode() && e->parentNode()->isElementNode()) {
       
  1961                 RenderStyle* parentStyle = elementStyle ? elementParentStyle : e->parentNode()->renderStyle();
       
  1962                 if (parentStyle)
       
  1963                     parentStyle->setChildrenAffectedByDirectAdjacentRules();
       
  1964             }
       
  1965             Node* n = e->previousSibling();
       
  1966             while (n && !n->isElementNode())
       
  1967                 n = n->previousSibling();
       
  1968             if (!n)
       
  1969                 return SelectorFailsLocally;
       
  1970             e = static_cast<Element*>(n);
       
  1971             m_matchVisitedPseudoClass = false;
       
  1972             return checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink); 
       
  1973         }
       
  1974         case CSSSelector::IndirectAdjacent:
       
  1975             if (!m_collectRulesOnly && e->parentNode() && e->parentNode()->isElementNode()) {
       
  1976                 RenderStyle* parentStyle = elementStyle ? elementParentStyle : e->parentNode()->renderStyle();
       
  1977                 if (parentStyle)
       
  1978                     parentStyle->setChildrenAffectedByForwardPositionalRules();
       
  1979             }
       
  1980             while (true) {
       
  1981                 Node* n = e->previousSibling();
       
  1982                 while (n && !n->isElementNode())
       
  1983                     n = n->previousSibling();
       
  1984                 if (!n)
       
  1985                     return SelectorFailsLocally;
       
  1986                 e = static_cast<Element*>(n);
       
  1987                 m_matchVisitedPseudoClass = false;
       
  1988                 SelectorMatch match = checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
       
  1989                 if (match != SelectorFailsLocally)
       
  1990                     return match;
       
  1991             };
       
  1992             break;
       
  1993         case CSSSelector::SubSelector:
       
  1994             // a selector is invalid if something follows a pseudo-element
       
  1995             // We make an exception for scrollbar pseudo elements and allow a set of pseudo classes (but nothing else)
       
  1996             // to follow the pseudo elements.
       
  1997             if ((elementStyle || m_collectRulesOnly) && dynamicPseudo != NOPSEUDO && dynamicPseudo != SELECTION &&
       
  1998                 !((RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER) && sel->m_match == CSSSelector::PseudoClass))
       
  1999                 return SelectorFailsCompletely;
       
  2000             return checkSelector(sel, e, selectorAttrs, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle);
       
  2001     }
       
  2002 
       
  2003     return SelectorFailsCompletely;
       
  2004 }
       
  2005 
       
  2006 static void addLocalNameToSet(HashSet<AtomicStringImpl*>* set, const QualifiedName& qName)
       
  2007 {
       
  2008     set->add(qName.localName().impl());
       
  2009 }
       
  2010 
       
  2011 static HashSet<AtomicStringImpl*>* createHtmlCaseInsensitiveAttributesSet()
       
  2012 {
       
  2013     // This is the list of attributes in HTML 4.01 with values marked as "[CI]" or case-insensitive
       
  2014     // Mozilla treats all other values as case-sensitive, thus so do we.
       
  2015     HashSet<AtomicStringImpl*>* attrSet = new HashSet<AtomicStringImpl*>;
       
  2016 
       
  2017     addLocalNameToSet(attrSet, accept_charsetAttr);
       
  2018     addLocalNameToSet(attrSet, acceptAttr);
       
  2019     addLocalNameToSet(attrSet, alignAttr);
       
  2020     addLocalNameToSet(attrSet, alinkAttr);
       
  2021     addLocalNameToSet(attrSet, axisAttr);
       
  2022     addLocalNameToSet(attrSet, bgcolorAttr);
       
  2023     addLocalNameToSet(attrSet, charsetAttr);
       
  2024     addLocalNameToSet(attrSet, checkedAttr);
       
  2025     addLocalNameToSet(attrSet, clearAttr);
       
  2026     addLocalNameToSet(attrSet, codetypeAttr);
       
  2027     addLocalNameToSet(attrSet, colorAttr);
       
  2028     addLocalNameToSet(attrSet, compactAttr);
       
  2029     addLocalNameToSet(attrSet, declareAttr);
       
  2030     addLocalNameToSet(attrSet, deferAttr);
       
  2031     addLocalNameToSet(attrSet, dirAttr);
       
  2032     addLocalNameToSet(attrSet, disabledAttr);
       
  2033     addLocalNameToSet(attrSet, enctypeAttr);
       
  2034     addLocalNameToSet(attrSet, faceAttr);
       
  2035     addLocalNameToSet(attrSet, frameAttr);
       
  2036     addLocalNameToSet(attrSet, hreflangAttr);
       
  2037     addLocalNameToSet(attrSet, http_equivAttr);
       
  2038     addLocalNameToSet(attrSet, langAttr);
       
  2039     addLocalNameToSet(attrSet, languageAttr);
       
  2040     addLocalNameToSet(attrSet, linkAttr);
       
  2041     addLocalNameToSet(attrSet, mediaAttr);
       
  2042     addLocalNameToSet(attrSet, methodAttr);
       
  2043     addLocalNameToSet(attrSet, multipleAttr);
       
  2044     addLocalNameToSet(attrSet, nohrefAttr);
       
  2045     addLocalNameToSet(attrSet, noresizeAttr);
       
  2046     addLocalNameToSet(attrSet, noshadeAttr);
       
  2047     addLocalNameToSet(attrSet, nowrapAttr);
       
  2048     addLocalNameToSet(attrSet, readonlyAttr);
       
  2049     addLocalNameToSet(attrSet, relAttr);
       
  2050     addLocalNameToSet(attrSet, revAttr);
       
  2051     addLocalNameToSet(attrSet, rulesAttr);
       
  2052     addLocalNameToSet(attrSet, scopeAttr);
       
  2053     addLocalNameToSet(attrSet, scrollingAttr);
       
  2054     addLocalNameToSet(attrSet, selectedAttr);
       
  2055     addLocalNameToSet(attrSet, shapeAttr);
       
  2056     addLocalNameToSet(attrSet, targetAttr);
       
  2057     addLocalNameToSet(attrSet, textAttr);
       
  2058     addLocalNameToSet(attrSet, typeAttr);
       
  2059     addLocalNameToSet(attrSet, valignAttr);
       
  2060     addLocalNameToSet(attrSet, valuetypeAttr);
       
  2061     addLocalNameToSet(attrSet, vlinkAttr);
       
  2062 
       
  2063     return attrSet;
       
  2064 }
       
  2065 
       
  2066 static bool htmlAttributeHasCaseInsensitiveValue(const QualifiedName& attr)
       
  2067 {
       
  2068     static HashSet<AtomicStringImpl*>* htmlCaseInsensitiveAttributesSet = createHtmlCaseInsensitiveAttributesSet();
       
  2069     bool isPossibleHTMLAttr = !attr.hasPrefix() && (attr.namespaceURI() == nullAtom);
       
  2070     return isPossibleHTMLAttr && htmlCaseInsensitiveAttributesSet->contains(attr.localName().impl());
       
  2071 }
       
  2072 
       
  2073 bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
       
  2074 {
       
  2075     if (!e)
       
  2076         return false;
       
  2077 
       
  2078     if (sel->hasTag()) {
       
  2079         const AtomicString& selLocalName = sel->m_tag.localName();
       
  2080         if (selLocalName != starAtom && selLocalName != e->localName())
       
  2081             return false;
       
  2082         const AtomicString& selNS = sel->m_tag.namespaceURI();
       
  2083         if (selNS != starAtom && selNS != e->namespaceURI())
       
  2084             return false;
       
  2085     }
       
  2086 
       
  2087     if (sel->hasAttribute()) {
       
  2088         if (sel->m_match == CSSSelector::Class)
       
  2089             return e->hasClass() && static_cast<StyledElement*>(e)->classNames().contains(sel->m_value);
       
  2090 
       
  2091         if (sel->m_match == CSSSelector::Id)
       
  2092             return e->hasID() && e->idForStyleResolution() == sel->m_value;
       
  2093         
       
  2094         const QualifiedName& attr = sel->attribute();
       
  2095 
       
  2096         // FIXME: Handle the case were elementStyle is 0.
       
  2097         if (elementStyle && (!e->isStyledElement() || (!static_cast<StyledElement*>(e)->isMappedAttribute(attr) && attr != typeAttr && attr != readonlyAttr))) {
       
  2098             elementStyle->setAffectedByAttributeSelectors(); // Special-case the "type" and "readonly" attributes so input form controls can share style.
       
  2099             if (selectorAttrs)
       
  2100                 selectorAttrs->add(attr.localName().impl());
       
  2101         }
       
  2102 
       
  2103         const AtomicString& value = e->getAttribute(attr);
       
  2104         if (value.isNull())
       
  2105             return false; // attribute is not set
       
  2106 
       
  2107         bool caseSensitive = !m_documentIsHTML || !htmlAttributeHasCaseInsensitiveValue(attr);
       
  2108 
       
  2109         switch (sel->m_match) {
       
  2110         case CSSSelector::Exact:
       
  2111             if (caseSensitive ? sel->m_value != value : !equalIgnoringCase(sel->m_value, value))
       
  2112                 return false;
       
  2113             break;
       
  2114         case CSSSelector::List:
       
  2115         {
       
  2116             // Ignore empty selectors or selectors containing spaces
       
  2117             if (sel->m_value.contains(' ') || sel->m_value.isEmpty())
       
  2118                 return false;
       
  2119 
       
  2120             int startSearchAt = 0;
       
  2121             while (true) {
       
  2122                 int foundPos = value.find(sel->m_value, startSearchAt, caseSensitive);
       
  2123                 if (foundPos == -1)
       
  2124                     return false;
       
  2125                 if (foundPos == 0 || value[foundPos-1] == ' ') {
       
  2126                     unsigned endStr = foundPos + sel->m_value.length();
       
  2127                     if (endStr == value.length() || value[endStr] == ' ')
       
  2128                         break; // We found a match.
       
  2129                 }
       
  2130                 
       
  2131                 // No match.  Keep looking.
       
  2132                 startSearchAt = foundPos + 1;
       
  2133             }
       
  2134             break;
       
  2135         }
       
  2136         case CSSSelector::Contain:
       
  2137             if (!value.contains(sel->m_value, caseSensitive) || sel->m_value.isEmpty())
       
  2138                 return false;
       
  2139             break;
       
  2140         case CSSSelector::Begin:
       
  2141             if (!value.startsWith(sel->m_value, caseSensitive) || sel->m_value.isEmpty())
       
  2142                 return false;
       
  2143             break;
       
  2144         case CSSSelector::End:
       
  2145             if (!value.endsWith(sel->m_value, caseSensitive) || sel->m_value.isEmpty())
       
  2146                 return false;
       
  2147             break;
       
  2148         case CSSSelector::Hyphen:
       
  2149             if (value.length() < sel->m_value.length())
       
  2150                 return false;
       
  2151             if (!value.startsWith(sel->m_value, caseSensitive))
       
  2152                 return false;
       
  2153             // It they start the same, check for exact match or following '-':
       
  2154             if (value.length() != sel->m_value.length() && value[sel->m_value.length()] != '-')
       
  2155                 return false;
       
  2156             break;
       
  2157         case CSSSelector::PseudoClass:
       
  2158         case CSSSelector::PseudoElement:
       
  2159         default:
       
  2160             break;
       
  2161         }
       
  2162     }
       
  2163     
       
  2164     if (sel->m_match == CSSSelector::PseudoClass) {
       
  2165         // Handle :not up front.
       
  2166         if (sel->pseudoType() == CSSSelector::PseudoNot) {
       
  2167             // check the simple selector
       
  2168             for (CSSSelector* subSel = sel->simpleSelector(); subSel; subSel = subSel->tagHistory()) {
       
  2169                 // :not cannot nest. I don't really know why this is a
       
  2170                 // restriction in CSS3, but it is, so let's honor it.
       
  2171                 // the parser enforces that this never occurs
       
  2172                 ASSERT(!subSel->simpleSelector());
       
  2173 
       
  2174                 if (!checkOneSelector(subSel, e, selectorAttrs, dynamicPseudo, true, elementStyle, elementParentStyle))
       
  2175                     return true;
       
  2176             }
       
  2177         } else if (dynamicPseudo != NOPSEUDO && (RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER)) {
       
  2178             // CSS scrollbars match a specific subset of pseudo classes, and they have specialized rules for each
       
  2179             // (since there are no elements involved).
       
  2180             return checkScrollbarPseudoClass(sel, dynamicPseudo);
       
  2181         } else if (dynamicPseudo == SELECTION) {
       
  2182             if (sel->pseudoType() == CSSSelector::PseudoWindowInactive)
       
  2183                 return !m_document->page()->focusController()->isActive();
       
  2184         }
       
  2185         
       
  2186         // Normal element pseudo class checking.
       
  2187         switch (sel->pseudoType()) {
       
  2188             // Pseudo classes:
       
  2189             case CSSSelector::PseudoNot:
       
  2190                 break; // Already handled up above.
       
  2191             case CSSSelector::PseudoEmpty: {
       
  2192                 bool result = true;
       
  2193                 for (Node* n = e->firstChild(); n; n = n->nextSibling()) {
       
  2194                     if (n->isElementNode()) {
       
  2195                         result = false;
       
  2196                         break;
       
  2197                     } else if (n->isTextNode()) {
       
  2198                         Text* textNode = static_cast<Text*>(n);
       
  2199                         if (!textNode->data().isEmpty()) {
       
  2200                             result = false;
       
  2201                             break;
       
  2202                         }
       
  2203                     }
       
  2204                 }
       
  2205                 if (!m_collectRulesOnly) {
       
  2206                     if (elementStyle)
       
  2207                         elementStyle->setEmptyState(result);
       
  2208                     else if (e->renderStyle() && (e->document()->usesSiblingRules() || e->renderStyle()->unique()))
       
  2209                         e->renderStyle()->setEmptyState(result);
       
  2210                 }
       
  2211                 return result;
       
  2212             }
       
  2213             case CSSSelector::PseudoFirstChild: {
       
  2214                 // first-child matches the first child that is an element
       
  2215                 if (e->parentNode() && e->parentNode()->isElementNode()) {
       
  2216                     bool result = false;
       
  2217                     Node* n = e->previousSibling();
       
  2218                     while (n && !n->isElementNode())
       
  2219                         n = n->previousSibling();
       
  2220                     if (!n)
       
  2221                         result = true;
       
  2222                     if (!m_collectRulesOnly) {
       
  2223                         RenderStyle* childStyle = elementStyle ? elementStyle : e->renderStyle();
       
  2224                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : e->parentNode()->renderStyle();
       
  2225                         if (parentStyle)
       
  2226                             parentStyle->setChildrenAffectedByFirstChildRules();
       
  2227                         if (result && childStyle)
       
  2228                             childStyle->setFirstChildState();
       
  2229                     }
       
  2230                     return result;
       
  2231                 }
       
  2232                 break;
       
  2233             }
       
  2234             case CSSSelector::PseudoFirstOfType: {
       
  2235                 // first-of-type matches the first element of its type
       
  2236                 if (e->parentNode() && e->parentNode()->isElementNode()) {
       
  2237                     bool result = false;
       
  2238                     const QualifiedName& type = e->tagQName();
       
  2239                     Node* n = e->previousSibling();
       
  2240                     while (n) {
       
  2241                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
       
  2242                             break;
       
  2243                         n = n->previousSibling();
       
  2244                     }
       
  2245                     if (!n)
       
  2246                         result = true;
       
  2247                     if (!m_collectRulesOnly) {
       
  2248                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : e->parentNode()->renderStyle();
       
  2249                         if (parentStyle)
       
  2250                             parentStyle->setChildrenAffectedByForwardPositionalRules();
       
  2251                     }
       
  2252                     return result;
       
  2253                 }
       
  2254                 break;
       
  2255             }
       
  2256             case CSSSelector::PseudoLastChild: {
       
  2257                 // last-child matches the last child that is an element
       
  2258                 if (Element* parentElement = e->parentElement()) {
       
  2259                     bool result = false;
       
  2260                     if (parentElement->isFinishedParsingChildren()) {
       
  2261                         Node* n = e->nextSibling();
       
  2262                         while (n && !n->isElementNode())
       
  2263                             n = n->nextSibling();
       
  2264                         if (!n)
       
  2265                             result = true;
       
  2266                     }
       
  2267                     if (!m_collectRulesOnly) {
       
  2268                         RenderStyle* childStyle = elementStyle ? elementStyle : e->renderStyle();
       
  2269                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
       
  2270                         if (parentStyle)
       
  2271                             parentStyle->setChildrenAffectedByLastChildRules();
       
  2272                         if (result && childStyle)
       
  2273                             childStyle->setLastChildState();
       
  2274                     }
       
  2275                     return result;
       
  2276                 }
       
  2277                 break;
       
  2278             }
       
  2279             case CSSSelector::PseudoLastOfType: {
       
  2280                 // last-of-type matches the last element of its type
       
  2281                 if (Element* parentElement = e->parentElement()) {
       
  2282                     if (!m_collectRulesOnly) {
       
  2283                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
       
  2284                         if (parentStyle)
       
  2285                             parentStyle->setChildrenAffectedByBackwardPositionalRules();
       
  2286                     }
       
  2287                     if (!parentElement->isFinishedParsingChildren())
       
  2288                         return false;
       
  2289                     bool result = false;
       
  2290                     const QualifiedName& type = e->tagQName();
       
  2291                     Node* n = e->nextSibling();
       
  2292                     while (n) {
       
  2293                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
       
  2294                             break;
       
  2295                         n = n->nextSibling();
       
  2296                     }
       
  2297                     if (!n)
       
  2298                         result = true;
       
  2299                     return result;
       
  2300                 }
       
  2301                 break;
       
  2302             }
       
  2303             case CSSSelector::PseudoOnlyChild: {
       
  2304                 if (Element* parentElement = e->parentElement()) {
       
  2305                     bool firstChild = false;
       
  2306                     bool lastChild = false;
       
  2307                     
       
  2308                     Node* n = e->previousSibling();
       
  2309                     while (n && !n->isElementNode())
       
  2310                         n = n->previousSibling();
       
  2311                     if (!n)
       
  2312                         firstChild = true;
       
  2313                     if (firstChild && parentElement->isFinishedParsingChildren()) {
       
  2314                         n = e->nextSibling();
       
  2315                         while (n && !n->isElementNode())
       
  2316                             n = n->nextSibling();
       
  2317                         if (!n)
       
  2318                             lastChild = true;
       
  2319                     }
       
  2320                     if (!m_collectRulesOnly) {
       
  2321                         RenderStyle* childStyle = elementStyle ? elementStyle : e->renderStyle();
       
  2322                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
       
  2323                         if (parentStyle) {
       
  2324                             parentStyle->setChildrenAffectedByFirstChildRules();
       
  2325                             parentStyle->setChildrenAffectedByLastChildRules();
       
  2326                         }
       
  2327                         if (firstChild && childStyle)
       
  2328                             childStyle->setFirstChildState();
       
  2329                         if (lastChild && childStyle)
       
  2330                             childStyle->setLastChildState();
       
  2331                     }
       
  2332                     return firstChild && lastChild;
       
  2333                 }
       
  2334                 break;
       
  2335             }
       
  2336             case CSSSelector::PseudoOnlyOfType: {
       
  2337                 // FIXME: This selector is very slow.
       
  2338                 if (Element* parentElement = e->parentElement()) {
       
  2339                     if (!m_collectRulesOnly) {
       
  2340                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
       
  2341                         if (parentStyle) {
       
  2342                             parentStyle->setChildrenAffectedByForwardPositionalRules();
       
  2343                             parentStyle->setChildrenAffectedByBackwardPositionalRules();
       
  2344                         }
       
  2345                     }
       
  2346                     if (!parentElement->isFinishedParsingChildren())
       
  2347                         return false;
       
  2348                     bool firstChild = false;
       
  2349                     bool lastChild = false;
       
  2350                     const QualifiedName& type = e->tagQName();
       
  2351                     Node* n = e->previousSibling();
       
  2352                     while (n) {
       
  2353                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
       
  2354                             break;
       
  2355                         n = n->previousSibling();
       
  2356                     }
       
  2357                     if (!n)
       
  2358                         firstChild = true;
       
  2359                     if (firstChild) {
       
  2360                         n = e->nextSibling();
       
  2361                         while (n) {
       
  2362                             if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
       
  2363                                 break;
       
  2364                             n = n->nextSibling();
       
  2365                         }
       
  2366                         if (!n)
       
  2367                             lastChild = true;
       
  2368                     }
       
  2369                     return firstChild && lastChild;
       
  2370                 }
       
  2371                 break;
       
  2372             }
       
  2373             case CSSSelector::PseudoNthChild: {
       
  2374                 if (!sel->parseNth())
       
  2375                     break;
       
  2376                 if (Element* parentElement = e->parentElement()) {
       
  2377                     int count = 1;
       
  2378                     Node* n = e->previousSibling();
       
  2379                     while (n) {
       
  2380                         if (n->isElementNode()) {
       
  2381                             RenderStyle* s = n->renderStyle();
       
  2382                             unsigned index = s ? s->childIndex() : 0;
       
  2383                             if (index) {
       
  2384                                 count += index;
       
  2385                                 break;
       
  2386                             }
       
  2387                             count++;
       
  2388                         }
       
  2389                         n = n->previousSibling();
       
  2390                     }
       
  2391                     
       
  2392                     if (!m_collectRulesOnly) {
       
  2393                         RenderStyle* childStyle = elementStyle ? elementStyle : e->renderStyle();
       
  2394                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
       
  2395                         if (childStyle)
       
  2396                             childStyle->setChildIndex(count);
       
  2397                         if (parentStyle)
       
  2398                             parentStyle->setChildrenAffectedByForwardPositionalRules();
       
  2399                     }
       
  2400                     
       
  2401                     if (sel->matchNth(count))
       
  2402                         return true;
       
  2403                 }
       
  2404                 break;
       
  2405             }
       
  2406             case CSSSelector::PseudoNthOfType: {
       
  2407                 if (!sel->parseNth())
       
  2408                     break;
       
  2409                 if (Element* parentElement = e->parentElement()) {
       
  2410                     int count = 1;
       
  2411                     const QualifiedName& type = e->tagQName();
       
  2412                     Node* n = e->previousSibling();
       
  2413                     while (n) {
       
  2414                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
       
  2415                             count++;
       
  2416                         n = n->previousSibling();
       
  2417                     }
       
  2418                     
       
  2419                     if (!m_collectRulesOnly) {
       
  2420                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
       
  2421                         if (parentStyle)
       
  2422                             parentStyle->setChildrenAffectedByForwardPositionalRules();
       
  2423                     }
       
  2424 
       
  2425                     if (sel->matchNth(count))
       
  2426                         return true;
       
  2427                 }
       
  2428                 break;
       
  2429             }
       
  2430             case CSSSelector::PseudoNthLastChild: {
       
  2431                 if (!sel->parseNth())
       
  2432                     break;
       
  2433                 if (Element* parentElement = e->parentElement()) {
       
  2434                     if (!m_collectRulesOnly) {
       
  2435                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
       
  2436                         if (parentStyle)
       
  2437                             parentStyle->setChildrenAffectedByBackwardPositionalRules();
       
  2438                     }
       
  2439                     if (!parentElement->isFinishedParsingChildren())
       
  2440                         return false;
       
  2441                     int count = 1;
       
  2442                     Node* n = e->nextSibling();
       
  2443                     while (n) {
       
  2444                         if (n->isElementNode())
       
  2445                             count++;
       
  2446                         n = n->nextSibling();
       
  2447                     }
       
  2448                     if (sel->matchNth(count))
       
  2449                         return true;
       
  2450                 }
       
  2451                 break;
       
  2452             }
       
  2453             case CSSSelector::PseudoNthLastOfType: {
       
  2454                 if (!sel->parseNth())
       
  2455                     break;
       
  2456                 if (Element* parentElement = e->parentElement()) {
       
  2457                     if (!m_collectRulesOnly) {
       
  2458                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
       
  2459                         if (parentStyle)
       
  2460                             parentStyle->setChildrenAffectedByBackwardPositionalRules();
       
  2461                     }
       
  2462                     if (!parentElement->isFinishedParsingChildren())
       
  2463                         return false;
       
  2464                     int count = 1;
       
  2465                     const QualifiedName& type = e->tagQName();
       
  2466                     Node* n = e->nextSibling();
       
  2467                     while (n) {
       
  2468                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
       
  2469                             count++;
       
  2470                         n = n->nextSibling();
       
  2471                     }
       
  2472                     if (sel->matchNth(count))
       
  2473                         return true;
       
  2474                 }
       
  2475                 break;
       
  2476             }
       
  2477             case CSSSelector::PseudoTarget:
       
  2478                 if (e == e->document()->cssTarget())
       
  2479                     return true;
       
  2480                 break;
       
  2481             case CSSSelector::PseudoAnyLink:
       
  2482                 if (e && e->isLink())
       
  2483                     return true;
       
  2484                 break;
       
  2485             case CSSSelector::PseudoAutofill: {
       
  2486                 if (!e || !e->isFormControlElement())
       
  2487                     break;
       
  2488                 if (InputElement* inputElement = toInputElement(e))
       
  2489                     return inputElement->isAutofilled();
       
  2490                 break;
       
  2491             }
       
  2492             case CSSSelector::PseudoLink:
       
  2493                 if (e && e->isLink())
       
  2494                     return !m_matchVisitedPseudoClass;
       
  2495                 break;
       
  2496             case CSSSelector::PseudoVisited:
       
  2497                 if (e && e->isLink())
       
  2498                     return m_matchVisitedPseudoClass;
       
  2499                 break;
       
  2500             case CSSSelector::PseudoDrag: {
       
  2501                 if (elementStyle)
       
  2502                     elementStyle->setAffectedByDragRules(true);
       
  2503                 else if (e->renderStyle())
       
  2504                     e->renderStyle()->setAffectedByDragRules(true);
       
  2505                 if (e->renderer() && e->renderer()->isDragging())
       
  2506                     return true;
       
  2507                 break;
       
  2508             }
       
  2509             case CSSSelector::PseudoFocus:
       
  2510                 if (e && e->focused() && e->document()->frame()->selection()->isFocusedAndActive())
       
  2511                     return true;
       
  2512                 break;
       
  2513             case CSSSelector::PseudoHover: {
       
  2514                 // If we're in quirks mode, then hover should never match anchors with no
       
  2515                 // href and *:hover should not match anything.  This is important for sites like wsj.com.
       
  2516                 if (m_strictParsing || isSubSelector || (sel->hasTag() && !e->hasTagName(aTag)) || e->isLink()) {
       
  2517                     if (elementStyle)
       
  2518                         elementStyle->setAffectedByHoverRules(true);
       
  2519                     else if (e->renderStyle())
       
  2520                         e->renderStyle()->setAffectedByHoverRules(true);
       
  2521                     if (e->hovered())
       
  2522                         return true;
       
  2523                 }
       
  2524                 break;
       
  2525             }
       
  2526             case CSSSelector::PseudoActive:
       
  2527                 // If we're in quirks mode, then :active should never match anchors with no
       
  2528                 // href and *:active should not match anything. 
       
  2529                 if (m_strictParsing || isSubSelector || (sel->hasTag() && !e->hasTagName(aTag)) || e->isLink()) {
       
  2530                     if (elementStyle)
       
  2531                         elementStyle->setAffectedByActiveRules(true);
       
  2532                     else if (e->renderStyle())
       
  2533                         e->renderStyle()->setAffectedByActiveRules(true);
       
  2534                     if (e->active())
       
  2535                         return true;
       
  2536                 }
       
  2537                 break;
       
  2538             case CSSSelector::PseudoEnabled:
       
  2539                 if (e && e->isFormControlElement())
       
  2540                     return e->isEnabledFormControl();
       
  2541                 break;
       
  2542             case CSSSelector::PseudoFullPageMedia:
       
  2543                 return e && e->document() && e->document()->isMediaDocument();
       
  2544                 break;
       
  2545             case CSSSelector::PseudoDefault:
       
  2546                 return e && e->isDefaultButtonForForm();
       
  2547             case CSSSelector::PseudoDisabled:
       
  2548                 if (e && e->isFormControlElement())
       
  2549                     return !e->isEnabledFormControl();
       
  2550                 break;
       
  2551             case CSSSelector::PseudoReadOnly: {
       
  2552                 if (!e || !e->isFormControlElement())
       
  2553                     return false;
       
  2554                 return e->isTextFormControl() && e->isReadOnlyFormControl();
       
  2555             }
       
  2556             case CSSSelector::PseudoReadWrite: {
       
  2557                 if (!e || !e->isFormControlElement())
       
  2558                     return false;
       
  2559                 return e->isTextFormControl() && !e->isReadOnlyFormControl();
       
  2560             }
       
  2561             case CSSSelector::PseudoOptional:
       
  2562                 return e && e->isOptionalFormControl();
       
  2563             case CSSSelector::PseudoRequired:
       
  2564                 return e && e->isRequiredFormControl();
       
  2565             case CSSSelector::PseudoValid: {
       
  2566                 if (!e)
       
  2567                     return false;
       
  2568                 e->document()->setContainsValidityStyleRules();
       
  2569                 return e->willValidate() && e->isValidFormControlElement();
       
  2570             } case CSSSelector::PseudoInvalid: {
       
  2571                 if (!e)
       
  2572                     return false;
       
  2573                 e->document()->setContainsValidityStyleRules();
       
  2574                 return e->willValidate() && !e->isValidFormControlElement();
       
  2575             } case CSSSelector::PseudoChecked: {
       
  2576                 if (!e || !e->isFormControlElement())
       
  2577                     break;
       
  2578                 // Even though WinIE allows checked and indeterminate to co-exist, the CSS selector spec says that
       
  2579                 // you can't be both checked and indeterminate.  We will behave like WinIE behind the scenes and just
       
  2580                 // obey the CSS spec here in the test for matching the pseudo.
       
  2581                 InputElement* inputElement = toInputElement(e);
       
  2582                 if (inputElement && inputElement->isChecked() && !inputElement->isIndeterminate())
       
  2583                     return true;
       
  2584                 break;
       
  2585             }
       
  2586             case CSSSelector::PseudoIndeterminate: {
       
  2587                 if (!e || !e->isFormControlElement())
       
  2588                     break;
       
  2589                 InputElement* inputElement = toInputElement(e);
       
  2590                 if (inputElement && inputElement->isIndeterminate())
       
  2591                     return true;
       
  2592                 break;
       
  2593             }
       
  2594             case CSSSelector::PseudoRoot:
       
  2595                 if (e == e->document()->documentElement())
       
  2596                     return true;
       
  2597                 break;
       
  2598             case CSSSelector::PseudoLang: {
       
  2599                 Node* n = e;
       
  2600                 AtomicString value;
       
  2601                 // The language property is inherited, so we iterate over the parents
       
  2602                 // to find the first language.
       
  2603                 while (n && value.isNull()) {
       
  2604                     if (n->isElementNode()) {
       
  2605                         // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
       
  2606                         value = static_cast<Element*>(n)->fastGetAttribute(XMLNames::langAttr);
       
  2607                         if (value.isNull())
       
  2608                             value = static_cast<Element*>(n)->fastGetAttribute(langAttr);
       
  2609                     } else if (n->isDocumentNode())
       
  2610                         // checking the MIME content-language
       
  2611                         value = static_cast<Document*>(n)->contentLanguage();
       
  2612 
       
  2613                     n = n->parent();
       
  2614                 }
       
  2615                 const AtomicString& argument = sel->argument();
       
  2616                 if (value.isNull() || !value.startsWith(argument, false))
       
  2617                     break;
       
  2618                 if (value.length() != argument.length() && value[argument.length()] != '-')
       
  2619                     break;
       
  2620                 return true;
       
  2621             }
       
  2622             case CSSSelector::PseudoUnknown:
       
  2623             case CSSSelector::PseudoNotParsed:
       
  2624             default:
       
  2625                 ASSERT_NOT_REACHED();
       
  2626                 break;
       
  2627         }
       
  2628         return false;
       
  2629     }
       
  2630     if (sel->m_match == CSSSelector::PseudoElement) {
       
  2631         if (!elementStyle && !m_collectRulesOnly)
       
  2632             return false;
       
  2633 
       
  2634         PseudoId pseudoId = CSSSelector::pseudoId(sel->pseudoType());
       
  2635         if (pseudoId == FIRST_LETTER) {
       
  2636             if (Document* document = e->document())
       
  2637                 document->setUsesFirstLetterRules(true);
       
  2638         }
       
  2639         if (pseudoId != NOPSEUDO) {
       
  2640             dynamicPseudo = pseudoId;
       
  2641             return true;
       
  2642         }
       
  2643         ASSERT_NOT_REACHED();
       
  2644         return false;
       
  2645     }
       
  2646     // ### add the rest of the checks...
       
  2647     return true;
       
  2648 }
       
  2649 
       
  2650 bool CSSStyleSelector::SelectorChecker::checkScrollbarPseudoClass(CSSSelector* sel, PseudoId&) const
       
  2651 {
       
  2652     RenderScrollbar* scrollbar = RenderScrollbar::scrollbarForStyleResolve();
       
  2653     ScrollbarPart part = RenderScrollbar::partForStyleResolve();
       
  2654 
       
  2655     // FIXME: This is a temporary hack for resizers and scrollbar corners.  Eventually :window-inactive should become a real
       
  2656     // pseudo class and just apply to everything.
       
  2657     if (sel->pseudoType() == CSSSelector::PseudoWindowInactive)
       
  2658         return !m_document->page()->focusController()->isActive();
       
  2659     
       
  2660     if (!scrollbar)
       
  2661         return false;
       
  2662         
       
  2663     ASSERT(sel->m_match == CSSSelector::PseudoClass);
       
  2664     switch (sel->pseudoType()) {
       
  2665         case CSSSelector::PseudoEnabled:
       
  2666             return scrollbar->enabled();
       
  2667         case CSSSelector::PseudoDisabled:
       
  2668             return !scrollbar->enabled();
       
  2669         case CSSSelector::PseudoHover: {
       
  2670             ScrollbarPart hoveredPart = scrollbar->hoveredPart();
       
  2671             if (part == ScrollbarBGPart)
       
  2672                 return hoveredPart != NoPart;
       
  2673             if (part == TrackBGPart)
       
  2674                 return hoveredPart == BackTrackPart || hoveredPart == ForwardTrackPart || hoveredPart == ThumbPart;
       
  2675             return part == hoveredPart;
       
  2676         }
       
  2677         case CSSSelector::PseudoActive: {
       
  2678             ScrollbarPart pressedPart = scrollbar->pressedPart();
       
  2679             if (part == ScrollbarBGPart)
       
  2680                 return pressedPart != NoPart;
       
  2681             if (part == TrackBGPart)
       
  2682                 return pressedPart == BackTrackPart || pressedPart == ForwardTrackPart || pressedPart == ThumbPart;
       
  2683             return part == pressedPart;
       
  2684         }
       
  2685         case CSSSelector::PseudoHorizontal:
       
  2686             return scrollbar->orientation() == HorizontalScrollbar;
       
  2687         case CSSSelector::PseudoVertical:
       
  2688             return scrollbar->orientation() == VerticalScrollbar;
       
  2689         case CSSSelector::PseudoDecrement:
       
  2690             return part == BackButtonStartPart || part == BackButtonEndPart || part == BackTrackPart;
       
  2691         case CSSSelector::PseudoIncrement:
       
  2692             return part == ForwardButtonStartPart || part == ForwardButtonEndPart || part == ForwardTrackPart;
       
  2693         case CSSSelector::PseudoStart:
       
  2694             return part == BackButtonStartPart || part == ForwardButtonStartPart || part == BackTrackPart;
       
  2695         case CSSSelector::PseudoEnd:
       
  2696             return part == BackButtonEndPart || part == ForwardButtonEndPart || part == ForwardTrackPart;
       
  2697         case CSSSelector::PseudoDoubleButton: {
       
  2698             ScrollbarButtonsPlacement buttonsPlacement = scrollbar->theme()->buttonsPlacement();
       
  2699             if (part == BackButtonStartPart || part == ForwardButtonStartPart || part == BackTrackPart)
       
  2700                 return buttonsPlacement == ScrollbarButtonsDoubleStart || buttonsPlacement == ScrollbarButtonsDoubleBoth;
       
  2701             if (part == BackButtonEndPart || part == ForwardButtonEndPart || part == ForwardTrackPart)
       
  2702                 return buttonsPlacement == ScrollbarButtonsDoubleEnd || buttonsPlacement == ScrollbarButtonsDoubleBoth;
       
  2703             return false;
       
  2704         } 
       
  2705         case CSSSelector::PseudoSingleButton: {
       
  2706             ScrollbarButtonsPlacement buttonsPlacement = scrollbar->theme()->buttonsPlacement();
       
  2707             if (part == BackButtonStartPart || part == ForwardButtonEndPart || part == BackTrackPart || part == ForwardTrackPart)
       
  2708                 return buttonsPlacement == ScrollbarButtonsSingle;
       
  2709             return false;
       
  2710         }
       
  2711         case CSSSelector::PseudoNoButton: {
       
  2712             ScrollbarButtonsPlacement buttonsPlacement = scrollbar->theme()->buttonsPlacement();
       
  2713             if (part == BackTrackPart)
       
  2714                 return buttonsPlacement == ScrollbarButtonsNone || buttonsPlacement == ScrollbarButtonsDoubleEnd;
       
  2715             if (part == ForwardTrackPart)
       
  2716                 return buttonsPlacement == ScrollbarButtonsNone || buttonsPlacement == ScrollbarButtonsDoubleStart;
       
  2717             return false;
       
  2718         }
       
  2719         case CSSSelector::PseudoCornerPresent:
       
  2720             return scrollbar->client()->scrollbarCornerPresent();
       
  2721         default:
       
  2722             return false;
       
  2723     }
       
  2724 }
       
  2725 
       
  2726 void CSSStyleSelector::addVariables(CSSVariablesRule* variables)
       
  2727 {
       
  2728     CSSVariablesDeclaration* decl = variables->variables();
       
  2729     if (!decl)
       
  2730         return;
       
  2731     unsigned size = decl->length();
       
  2732     for (unsigned i = 0; i < size; ++i) {
       
  2733         String name = decl->item(i);
       
  2734         m_variablesMap.set(name, variables);
       
  2735     }
       
  2736 }
       
  2737 
       
  2738 CSSValue* CSSStyleSelector::resolveVariableDependentValue(CSSVariableDependentValue*)
       
  2739 {
       
  2740     return 0;
       
  2741 }
       
  2742 
       
  2743 // -----------------------------------------------------------------
       
  2744 
       
  2745 CSSRuleSet::CSSRuleSet()
       
  2746 {
       
  2747     m_universalRules = 0;
       
  2748     m_pageRules = 0;
       
  2749     m_ruleCount = 0;
       
  2750     m_pageRuleCount = 0;
       
  2751 }
       
  2752 
       
  2753 CSSRuleSet::~CSSRuleSet()
       
  2754 { 
       
  2755     deleteAllValues(m_idRules);
       
  2756     deleteAllValues(m_classRules);
       
  2757     deleteAllValues(m_tagRules);
       
  2758 
       
  2759     delete m_universalRules; 
       
  2760     delete m_pageRules;
       
  2761 }
       
  2762 
       
  2763 
       
  2764 void CSSRuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map,
       
  2765                               CSSStyleRule* rule, CSSSelector* sel)
       
  2766 {
       
  2767     if (!key) return;
       
  2768     CSSRuleDataList* rules = map.get(key);
       
  2769     if (!rules) {
       
  2770         rules = new CSSRuleDataList(m_ruleCount++, rule, sel);
       
  2771         map.set(key, rules);
       
  2772     } else
       
  2773         rules->append(m_ruleCount++, rule, sel);
       
  2774 }
       
  2775 
       
  2776 void CSSRuleSet::addRule(CSSStyleRule* rule, CSSSelector* sel)
       
  2777 {
       
  2778     if (sel->m_match == CSSSelector::Id) {
       
  2779         addToRuleSet(sel->m_value.impl(), m_idRules, rule, sel);
       
  2780         return;
       
  2781     }
       
  2782     if (sel->m_match == CSSSelector::Class) {
       
  2783         addToRuleSet(sel->m_value.impl(), m_classRules, rule, sel);
       
  2784         return;
       
  2785     }
       
  2786      
       
  2787     const AtomicString& localName = sel->m_tag.localName();
       
  2788     if (localName != starAtom) {
       
  2789         addToRuleSet(localName.impl(), m_tagRules, rule, sel);
       
  2790         return;
       
  2791     }
       
  2792     
       
  2793     // Just put it in the universal rule set.
       
  2794     if (!m_universalRules)
       
  2795         m_universalRules = new CSSRuleDataList(m_ruleCount++, rule, sel);
       
  2796     else
       
  2797         m_universalRules->append(m_ruleCount++, rule, sel);
       
  2798 }
       
  2799 
       
  2800 void CSSRuleSet::addPageRule(CSSStyleRule* rule, CSSSelector* sel)
       
  2801 {
       
  2802     if (!m_pageRules)
       
  2803         m_pageRules = new CSSRuleDataList(m_pageRuleCount++, rule, sel);
       
  2804     else
       
  2805         m_pageRules->append(m_pageRuleCount++, rule, sel);
       
  2806 }
       
  2807 
       
  2808 void CSSRuleSet::addRulesFromSheet(CSSStyleSheet* sheet, const MediaQueryEvaluator& medium, CSSStyleSelector* styleSelector)
       
  2809 {
       
  2810     if (!sheet)
       
  2811         return;
       
  2812 
       
  2813     // No media implies "all", but if a media list exists it must
       
  2814     // contain our current medium
       
  2815     if (sheet->media() && !medium.eval(sheet->media(), styleSelector))
       
  2816         return; // the style sheet doesn't apply
       
  2817 
       
  2818     int len = sheet->length();
       
  2819 
       
  2820     for (int i = 0; i < len; i++) {
       
  2821         StyleBase* item = sheet->item(i);
       
  2822         if (item->isStyleRule()) {
       
  2823             addStyleRule(item);
       
  2824         }
       
  2825         else if (item->isImportRule()) {
       
  2826             CSSImportRule* import = static_cast<CSSImportRule*>(item);
       
  2827             if (!import->media() || medium.eval(import->media(), styleSelector))
       
  2828                 addRulesFromSheet(import->styleSheet(), medium, styleSelector);
       
  2829         }
       
  2830         else if (item->isMediaRule()) {
       
  2831             CSSMediaRule* r = static_cast<CSSMediaRule*>(item);
       
  2832             CSSRuleList* rules = r->cssRules();
       
  2833 
       
  2834             if ((!r->media() || medium.eval(r->media(), styleSelector)) && rules) {
       
  2835                 // Traverse child elements of the @media rule.
       
  2836                 for (unsigned j = 0; j < rules->length(); j++) {
       
  2837                     CSSRule *childItem = rules->item(j);
       
  2838                     if (childItem->isStyleRule()) {
       
  2839                         // It is a StyleRule, so append it to our list
       
  2840                         addStyleRule(childItem);
       
  2841                     } else if (childItem->isFontFaceRule() && styleSelector) {
       
  2842                         // Add this font face to our set.
       
  2843                         const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(childItem);
       
  2844                         styleSelector->fontSelector()->addFontFaceRule(fontFaceRule);
       
  2845                     } else if (childItem->isKeyframesRule() && styleSelector) {
       
  2846                         // Add this keyframe rule to our set.
       
  2847                         styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(childItem));
       
  2848                     }
       
  2849                 }   // for rules
       
  2850             }   // if rules
       
  2851         } else if (item->isFontFaceRule() && styleSelector) {
       
  2852             // Add this font face to our set.
       
  2853             const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(item);
       
  2854             styleSelector->fontSelector()->addFontFaceRule(fontFaceRule);
       
  2855         } else if (item->isVariablesRule()) {
       
  2856             // Evaluate the media query and make sure it matches.
       
  2857             CSSVariablesRule* variables = static_cast<CSSVariablesRule*>(item);
       
  2858             if (!variables->media() || medium.eval(variables->media(), styleSelector))
       
  2859                 styleSelector->addVariables(variables);
       
  2860         } else if (item->isKeyframesRule())
       
  2861             styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(item));
       
  2862     }
       
  2863 }
       
  2864 
       
  2865 void CSSRuleSet::addStyleRule(StyleBase* item)
       
  2866 {
       
  2867     if (item->isPageRule()) {
       
  2868         CSSPageRule* pageRule = static_cast<CSSPageRule*>(item);
       
  2869         addPageRule(pageRule, pageRule->selectorList().first());
       
  2870     } else {
       
  2871         CSSStyleRule* rule = static_cast<CSSStyleRule*>(item);
       
  2872         for (CSSSelector* s = rule->selectorList().first(); s; s = CSSSelectorList::next(s))
       
  2873             addRule(rule, s);
       
  2874     }
       
  2875 }
       
  2876 
       
  2877 // -------------------------------------------------------------------------------------
       
  2878 // this is mostly boring stuff on how to apply a certain rule to the renderstyle...
       
  2879 
       
  2880 static Length convertToLength(CSSPrimitiveValue* primitiveValue, RenderStyle* style, RenderStyle* rootStyle, double multiplier = 1, bool *ok = 0)
       
  2881 {
       
  2882     // This function is tolerant of a null style value. The only place style is used is in
       
  2883     // length measurements, like 'ems' and 'px'. And in those cases style is only used
       
  2884     // when the units are EMS or EXS. So we will just fail in those cases.
       
  2885     Length l;
       
  2886     if (!primitiveValue) {
       
  2887         if (ok)
       
  2888             *ok = false;
       
  2889     } else {
       
  2890         int type = primitiveValue->primitiveType();
       
  2891         
       
  2892         if (!style && (type == CSSPrimitiveValue::CSS_EMS || type == CSSPrimitiveValue::CSS_EXS || type == CSSPrimitiveValue::CSS_REMS)) {
       
  2893             if (ok)
       
  2894                 *ok = false;
       
  2895         } else if (CSSPrimitiveValue::isUnitTypeLength(type))
       
  2896             l = Length(primitiveValue->computeLengthIntForLength(style, rootStyle, multiplier), Fixed);
       
  2897         else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  2898             l = Length(primitiveValue->getDoubleValue(), Percent);
       
  2899         else if (type == CSSPrimitiveValue::CSS_NUMBER)
       
  2900             l = Length(primitiveValue->getDoubleValue() * 100.0, Percent);
       
  2901         else if (ok)
       
  2902             *ok = false;
       
  2903     }
       
  2904     return l;
       
  2905 }
       
  2906 
       
  2907 template <bool applyFirst>
       
  2908 void CSSStyleSelector::applyDeclarations(bool isImportant, int startIndex, int endIndex)
       
  2909 {
       
  2910     if (startIndex == -1)
       
  2911         return;
       
  2912 
       
  2913     for (int i = startIndex; i <= endIndex; i++) {
       
  2914         CSSMutableStyleDeclaration* decl = m_matchedDecls[i];
       
  2915         CSSMutableStyleDeclaration::const_iterator end = decl->end();
       
  2916         for (CSSMutableStyleDeclaration::const_iterator it = decl->begin(); it != end; ++it) {
       
  2917             const CSSProperty& current = *it;
       
  2918             if (isImportant == current.isImportant()) {
       
  2919                 int property = current.id();
       
  2920 
       
  2921                 if (applyFirst) {
       
  2922                     COMPILE_ASSERT(firstCSSProperty == CSSPropertyColor, CSS_color_is_first_property);
       
  2923                     COMPILE_ASSERT(CSSPropertyZoom == CSSPropertyColor + 11, CSS_zoom_is_end_of_first_prop_range);
       
  2924                     COMPILE_ASSERT(CSSPropertyLineHeight == CSSPropertyZoom + 1, CSS_line_height_is_after_zoom);
       
  2925 
       
  2926                     // give special priority to font-xxx, color properties, etc
       
  2927                     if (property <= CSSPropertyLineHeight) {
       
  2928                         // we apply line-height later
       
  2929                         if (property == CSSPropertyLineHeight)
       
  2930                             m_lineHeightValue = current.value(); 
       
  2931                         else 
       
  2932                             applyProperty(current.id(), current.value());
       
  2933                     }
       
  2934                 } else {
       
  2935                     if (property > CSSPropertyLineHeight)
       
  2936                         applyProperty(current.id(), current.value());
       
  2937                 }
       
  2938             }
       
  2939         }
       
  2940     }
       
  2941 }
       
  2942 
       
  2943 void CSSStyleSelector::matchPageRules(CSSRuleSet* rules, bool isLeftPage, bool isFirstPage, const String& pageName)
       
  2944 {
       
  2945     m_matchedRules.clear();
       
  2946 
       
  2947     if (!rules)
       
  2948         return;
       
  2949 
       
  2950     matchPageRulesForList(rules->getPageRules(), isLeftPage, isFirstPage, pageName);
       
  2951 
       
  2952     // If we didn't match any rules, we're done.
       
  2953     if (m_matchedRules.isEmpty())
       
  2954         return;
       
  2955 
       
  2956     // Sort the set of matched rules.
       
  2957     sortMatchedRules(0, m_matchedRules.size());
       
  2958 
       
  2959     // Now transfer the set of matched rules over to our list of decls.
       
  2960     for (unsigned i = 0; i < m_matchedRules.size(); i++)
       
  2961         addMatchedDeclaration(m_matchedRules[i]->rule()->declaration());
       
  2962 }
       
  2963 
       
  2964 void CSSStyleSelector::matchPageRulesForList(CSSRuleDataList* rules, bool isLeftPage, bool isFirstPage, const String& pageName)
       
  2965 {
       
  2966     if (!rules)
       
  2967         return;
       
  2968 
       
  2969     for (CSSRuleData* d = rules->first(); d; d = d->next()) {
       
  2970         CSSStyleRule* rule = d->rule();
       
  2971         const AtomicString& selectorLocalName = d->selector()->m_tag.localName();
       
  2972         if (selectorLocalName != starAtom && selectorLocalName != pageName)
       
  2973             continue;
       
  2974         CSSSelector::PseudoType pseudoType = d->selector()->pseudoType();
       
  2975         if ((pseudoType == CSSSelector::PseudoLeftPage && !isLeftPage)
       
  2976             || (pseudoType == CSSSelector::PseudoRightPage && isLeftPage)
       
  2977             || (pseudoType == CSSSelector::PseudoFirstPage && !isFirstPage))
       
  2978             continue;
       
  2979 
       
  2980         // If the rule has no properties to apply, then ignore it.
       
  2981         CSSMutableStyleDeclaration* decl = rule->declaration();
       
  2982         if (!decl || !decl->length())
       
  2983             continue;
       
  2984 
       
  2985         // Add this rule to our list of matched rules.
       
  2986         addMatchedRule(d);
       
  2987     }
       
  2988 }
       
  2989 
       
  2990 bool CSSStyleSelector::isLeftPage(int pageIndex) const
       
  2991 {
       
  2992     bool isFirstPageLeft = false;
       
  2993     if (m_rootElementStyle->direction() == RTL)
       
  2994         isFirstPageLeft = true;
       
  2995 
       
  2996     return (pageIndex + (isFirstPageLeft ? 1 : 0)) % 2;
       
  2997 }
       
  2998 
       
  2999 bool CSSStyleSelector::isFirstPage(int pageIndex) const
       
  3000 {
       
  3001     // FIXME: In case of forced left/right page, page at index 1 (not 0) can be the first page.
       
  3002     return (!pageIndex);
       
  3003 }
       
  3004 
       
  3005 String CSSStyleSelector::pageName(int /* pageIndex */) const
       
  3006 {
       
  3007     // FIXME: Implement page index to page name mapping.
       
  3008     return "";
       
  3009 }
       
  3010 
       
  3011 static void applyCounterList(RenderStyle* style, CSSValueList* list, bool isReset)
       
  3012 {
       
  3013     CounterDirectiveMap& map = style->accessCounterDirectives();
       
  3014     typedef CounterDirectiveMap::iterator Iterator;
       
  3015 
       
  3016     Iterator end = map.end();
       
  3017     for (Iterator it = map.begin(); it != end; ++it)
       
  3018         if (isReset)
       
  3019             it->second.m_reset = false;
       
  3020         else
       
  3021             it->second.m_increment = false;
       
  3022 
       
  3023     int length = list ? list->length() : 0;
       
  3024     for (int i = 0; i < length; ++i) {
       
  3025         Pair* pair = static_cast<CSSPrimitiveValue*>(list->itemWithoutBoundsCheck(i))->getPairValue();
       
  3026         AtomicString identifier = static_cast<CSSPrimitiveValue*>(pair->first())->getStringValue();
       
  3027         // FIXME: What about overflow?
       
  3028         int value = static_cast<CSSPrimitiveValue*>(pair->second())->getIntValue();
       
  3029         CounterDirectives& directives = map.add(identifier.impl(), CounterDirectives()).first->second;
       
  3030         if (isReset) {
       
  3031             directives.m_reset = true;
       
  3032             directives.m_resetValue = value;
       
  3033         } else {
       
  3034             if (directives.m_increment)
       
  3035                 directives.m_incrementValue += value;
       
  3036             else {
       
  3037                 directives.m_increment = true;
       
  3038                 directives.m_incrementValue = value;
       
  3039             }
       
  3040         }
       
  3041     }
       
  3042 }
       
  3043 
       
  3044 void CSSStyleSelector::applyPropertyToStyle(int id, CSSValue *value, RenderStyle* style)
       
  3045 {
       
  3046     initElement(0);
       
  3047     initForStyleResolve(0, style);
       
  3048     m_style = style;
       
  3049     applyProperty(id, value);
       
  3050 }
       
  3051 
       
  3052 inline bool isValidVisitedLinkProperty(int id)
       
  3053 {
       
  3054     switch(static_cast<CSSPropertyID>(id)) {
       
  3055         case CSSPropertyBackgroundColor:
       
  3056         case CSSPropertyBorderLeftColor:
       
  3057         case CSSPropertyBorderRightColor:
       
  3058         case CSSPropertyBorderTopColor:
       
  3059         case CSSPropertyBorderBottomColor:
       
  3060         case CSSPropertyColor:
       
  3061         case CSSPropertyOutlineColor:
       
  3062         case CSSPropertyWebkitColumnRuleColor:
       
  3063         case CSSPropertyWebkitTextFillColor:
       
  3064         case CSSPropertyWebkitTextStrokeColor:
       
  3065         // Also allow shorthands so that inherit/initial still work.
       
  3066         case CSSPropertyBackground:
       
  3067         case CSSPropertyBorderLeft:
       
  3068         case CSSPropertyBorderRight:
       
  3069         case CSSPropertyBorderTop:
       
  3070         case CSSPropertyBorderBottom:
       
  3071         case CSSPropertyOutline:
       
  3072         case CSSPropertyWebkitColumnRule:
       
  3073 #if ENABLE(SVG)
       
  3074         case CSSPropertyFill:
       
  3075         case CSSPropertyStroke:
       
  3076 #endif
       
  3077             return true;
       
  3078         default:
       
  3079             break;
       
  3080     }
       
  3081 
       
  3082     return false;
       
  3083 }
       
  3084 
       
  3085 void CSSStyleSelector::applyProperty(int id, CSSValue *value)
       
  3086 {
       
  3087     CSSPrimitiveValue* primitiveValue = 0;
       
  3088     if (value->isPrimitiveValue())
       
  3089         primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  3090 
       
  3091     float zoomFactor = m_style->effectiveZoom();
       
  3092 
       
  3093     // SVG handles zooming in a different way compared to CSS. The whole document is scaled instead
       
  3094     // of each individual length value in the render style / tree. CSSPrimitiveValue::computeLength*()
       
  3095     // multiplies each resolved length with the zoom multiplier - so for SVG we need to disable that.
       
  3096     // Though all CSS values that can be applied to outermost <svg> elements (width/height/border/padding...)
       
  3097     // need to respect the scaling. RenderBox (the parent class of RenderSVGRoot) grabs values like
       
  3098     // width/height/border/padding/... from the RenderStyle -> for SVG these values would never scale,
       
  3099     // if we'd pass a 1.0 zoom factor everyhwere. So we only pass a zoom factor of 1.0 for specific
       
  3100     // properties that are NOT allowed to scale within a zoomed SVG document (letter/word-spacing/font-size).
       
  3101     bool useSVGZoomRules = m_element && m_element->isSVGElement();
       
  3102 
       
  3103     Length l;
       
  3104     bool apply = false;
       
  3105 
       
  3106     unsigned short valueType = value->cssValueType();
       
  3107 
       
  3108     bool isInherit = m_parentNode && valueType == CSSValue::CSS_INHERIT;
       
  3109     bool isInitial = valueType == CSSValue::CSS_INITIAL || (!m_parentNode && valueType == CSSValue::CSS_INHERIT);
       
  3110     
       
  3111     id = CSSProperty::resolveDirectionAwareProperty(id, m_style->direction());
       
  3112 
       
  3113     if (m_checker.m_matchVisitedPseudoClass && !isValidVisitedLinkProperty(id)) {
       
  3114         // Limit the properties that can be applied to only the ones honored by :visited.
       
  3115         return;
       
  3116     }
       
  3117     
       
  3118     // What follows is a list that maps the CSS properties into their corresponding front-end
       
  3119     // RenderStyle values.  Shorthands (e.g. border, background) occur in this list as well and
       
  3120     // are only hit when mapping "inherit" or "initial" into front-end values.
       
  3121     switch (static_cast<CSSPropertyID>(id)) {
       
  3122 // ident only properties
       
  3123     case CSSPropertyBackgroundAttachment:
       
  3124         HANDLE_BACKGROUND_VALUE(attachment, Attachment, value)
       
  3125         return;
       
  3126     case CSSPropertyBackgroundClip:
       
  3127     case CSSPropertyWebkitBackgroundClip:
       
  3128         HANDLE_BACKGROUND_VALUE(clip, Clip, value)
       
  3129         return;
       
  3130     case CSSPropertyWebkitBackgroundComposite:
       
  3131         HANDLE_BACKGROUND_VALUE(composite, Composite, value)
       
  3132         return;
       
  3133     case CSSPropertyBackgroundOrigin:
       
  3134     case CSSPropertyWebkitBackgroundOrigin:
       
  3135         HANDLE_BACKGROUND_VALUE(origin, Origin, value)
       
  3136         return;
       
  3137     case CSSPropertyBackgroundSize:
       
  3138     case CSSPropertyWebkitBackgroundSize:
       
  3139         HANDLE_BACKGROUND_VALUE(size, Size, value)
       
  3140         return;
       
  3141     case CSSPropertyWebkitMaskAttachment:
       
  3142         HANDLE_MASK_VALUE(attachment, Attachment, value)
       
  3143         return;
       
  3144     case CSSPropertyWebkitMaskClip:
       
  3145         HANDLE_MASK_VALUE(clip, Clip, value)
       
  3146         return;
       
  3147     case CSSPropertyWebkitMaskComposite:
       
  3148         HANDLE_MASK_VALUE(composite, Composite, value)
       
  3149         return;
       
  3150     case CSSPropertyWebkitMaskOrigin:
       
  3151         HANDLE_MASK_VALUE(origin, Origin, value)
       
  3152         return;
       
  3153     case CSSPropertyWebkitMaskSize:
       
  3154         HANDLE_MASK_VALUE(size, Size, value)
       
  3155         return;
       
  3156     case CSSPropertyBorderCollapse:
       
  3157         HANDLE_INHERIT_AND_INITIAL(borderCollapse, BorderCollapse)
       
  3158         if (!primitiveValue)
       
  3159             return;
       
  3160         switch (primitiveValue->getIdent()) {
       
  3161             case CSSValueCollapse:
       
  3162                 m_style->setBorderCollapse(true);
       
  3163                 break;
       
  3164             case CSSValueSeparate:
       
  3165                 m_style->setBorderCollapse(false);
       
  3166                 break;
       
  3167             default:
       
  3168                 return;
       
  3169         }
       
  3170         return;
       
  3171     case CSSPropertyBorderTopStyle:
       
  3172         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(borderTopStyle, BorderTopStyle, BorderStyle)
       
  3173         return;
       
  3174     case CSSPropertyBorderRightStyle:
       
  3175         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(borderRightStyle, BorderRightStyle, BorderStyle)
       
  3176         return;
       
  3177     case CSSPropertyBorderBottomStyle:
       
  3178         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(borderBottomStyle, BorderBottomStyle, BorderStyle)
       
  3179         return;
       
  3180     case CSSPropertyBorderLeftStyle:
       
  3181         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(borderLeftStyle, BorderLeftStyle, BorderStyle)
       
  3182         return;
       
  3183     case CSSPropertyOutlineStyle:
       
  3184         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(outlineStyle, OutlineStyle, BorderStyle)
       
  3185         if (primitiveValue) {
       
  3186             if (primitiveValue->getIdent() == CSSValueAuto)
       
  3187                 m_style->setOutlineStyle(DOTTED, true);
       
  3188             else
       
  3189                 m_style->setOutlineStyle(*primitiveValue);
       
  3190         }
       
  3191         return;
       
  3192     case CSSPropertyCaptionSide:
       
  3193         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(captionSide, CaptionSide)
       
  3194         return;
       
  3195     case CSSPropertyClear:
       
  3196         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(clear, Clear)
       
  3197         return;
       
  3198     case CSSPropertyDirection:
       
  3199         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(direction, Direction)
       
  3200         return;
       
  3201     case CSSPropertyDisplay:
       
  3202         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(display, Display)
       
  3203 #if ENABLE(WCSS)
       
  3204         if (primitiveValue) {
       
  3205             if (primitiveValue->getIdent() == CSSValueWapMarquee) {
       
  3206                 // Initialize WAP Marquee style
       
  3207                 m_style->setOverflowX(OMARQUEE);
       
  3208                 m_style->setOverflowY(OMARQUEE);
       
  3209                 m_style->setWhiteSpace(NOWRAP);
       
  3210                 m_style->setMarqueeDirection(MLEFT);
       
  3211                 m_style->setMarqueeSpeed(85); // Normal speed
       
  3212                 m_style->setMarqueeLoopCount(1);
       
  3213                 m_style->setMarqueeBehavior(MSCROLL);
       
  3214 
       
  3215                 if (m_parentStyle)
       
  3216                     m_style->setDisplay(m_parentStyle->display());
       
  3217                 else
       
  3218                     m_style->setDisplay(*primitiveValue);
       
  3219             } else
       
  3220                 m_style->setDisplay(*primitiveValue);
       
  3221         }
       
  3222 #endif
       
  3223         return;
       
  3224     case CSSPropertyEmptyCells:
       
  3225         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(emptyCells, EmptyCells)
       
  3226         return;
       
  3227     case CSSPropertyFloat:
       
  3228         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(floating, Floating)
       
  3229         return;
       
  3230     case CSSPropertyFontStyle:
       
  3231     {
       
  3232         FontDescription fontDescription = m_style->fontDescription();
       
  3233         if (isInherit)
       
  3234             fontDescription.setItalic(m_parentStyle->fontDescription().italic());
       
  3235         else if (isInitial)
       
  3236             fontDescription.setItalic(false);
       
  3237         else {
       
  3238             if (!primitiveValue)
       
  3239                 return;
       
  3240             switch (primitiveValue->getIdent()) {
       
  3241                 case CSSValueOblique:
       
  3242                 // FIXME: oblique is the same as italic for the moment...
       
  3243                 case CSSValueItalic:
       
  3244                     fontDescription.setItalic(true);
       
  3245                     break;
       
  3246                 case CSSValueNormal:
       
  3247                     fontDescription.setItalic(false);
       
  3248                     break;
       
  3249                 default:
       
  3250                     return;
       
  3251             }
       
  3252         }
       
  3253         if (m_style->setFontDescription(fontDescription))
       
  3254             m_fontDirty = true;
       
  3255         return;
       
  3256     }
       
  3257 
       
  3258     case CSSPropertyFontVariant:
       
  3259     {
       
  3260         FontDescription fontDescription = m_style->fontDescription();
       
  3261         if (isInherit) 
       
  3262             fontDescription.setSmallCaps(m_parentStyle->fontDescription().smallCaps());
       
  3263         else if (isInitial)
       
  3264             fontDescription.setSmallCaps(false);
       
  3265         else {
       
  3266             if (!primitiveValue)
       
  3267                 return;
       
  3268             int id = primitiveValue->getIdent();
       
  3269             if (id == CSSValueNormal)
       
  3270                 fontDescription.setSmallCaps(false);
       
  3271             else if (id == CSSValueSmallCaps)
       
  3272                 fontDescription.setSmallCaps(true);
       
  3273             else
       
  3274                 return;
       
  3275         }
       
  3276         if (m_style->setFontDescription(fontDescription))
       
  3277             m_fontDirty = true;
       
  3278         return;
       
  3279     }
       
  3280 
       
  3281     case CSSPropertyFontWeight:
       
  3282     {
       
  3283         FontDescription fontDescription = m_style->fontDescription();
       
  3284         if (isInherit)
       
  3285             fontDescription.setWeight(m_parentStyle->fontDescription().weight());
       
  3286         else if (isInitial)
       
  3287             fontDescription.setWeight(FontWeightNormal);
       
  3288         else {
       
  3289             if (!primitiveValue)
       
  3290                 return;
       
  3291             if (primitiveValue->getIdent()) {
       
  3292                 switch (primitiveValue->getIdent()) {
       
  3293                     case CSSValueBolder:
       
  3294                         fontDescription.setWeight(fontDescription.bolderWeight());
       
  3295                         break;
       
  3296                     case CSSValueLighter:
       
  3297                         fontDescription.setWeight(fontDescription.lighterWeight());
       
  3298                         break;
       
  3299                     case CSSValueBold:
       
  3300                     case CSSValue700:
       
  3301                         fontDescription.setWeight(FontWeightBold);
       
  3302                         break;
       
  3303                     case CSSValueNormal:
       
  3304                     case CSSValue400:
       
  3305                         fontDescription.setWeight(FontWeightNormal);
       
  3306                         break;
       
  3307                     case CSSValue900:
       
  3308                         fontDescription.setWeight(FontWeight900);
       
  3309                         break;
       
  3310                     case CSSValue800:
       
  3311                         fontDescription.setWeight(FontWeight800);
       
  3312                         break;
       
  3313                     case CSSValue600:
       
  3314                         fontDescription.setWeight(FontWeight600);
       
  3315                         break;
       
  3316                     case CSSValue500:
       
  3317                         fontDescription.setWeight(FontWeight500);
       
  3318                         break;
       
  3319                     case CSSValue300:
       
  3320                         fontDescription.setWeight(FontWeight300);
       
  3321                         break;
       
  3322                     case CSSValue200:
       
  3323                         fontDescription.setWeight(FontWeight200);
       
  3324                         break;
       
  3325                     case CSSValue100:
       
  3326                         fontDescription.setWeight(FontWeight100);
       
  3327                         break;
       
  3328                     default:
       
  3329                         return;
       
  3330                 }
       
  3331             } else
       
  3332                 ASSERT_NOT_REACHED();
       
  3333         }
       
  3334         if (m_style->setFontDescription(fontDescription))
       
  3335             m_fontDirty = true;
       
  3336         return;
       
  3337     }
       
  3338         
       
  3339     case CSSPropertyListStylePosition:
       
  3340         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(listStylePosition, ListStylePosition)
       
  3341         return;
       
  3342     case CSSPropertyListStyleType:
       
  3343         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(listStyleType, ListStyleType)
       
  3344         return;
       
  3345     case CSSPropertyOverflow:
       
  3346     {
       
  3347         if (isInherit) {
       
  3348             m_style->setOverflowX(m_parentStyle->overflowX());
       
  3349             m_style->setOverflowY(m_parentStyle->overflowY());
       
  3350             return;
       
  3351         }
       
  3352         
       
  3353         if (isInitial) {
       
  3354             m_style->setOverflowX(RenderStyle::initialOverflowX());
       
  3355             m_style->setOverflowY(RenderStyle::initialOverflowY());
       
  3356             return;
       
  3357         }
       
  3358             
       
  3359         EOverflow o = *primitiveValue;
       
  3360 
       
  3361         m_style->setOverflowX(o);
       
  3362         m_style->setOverflowY(o);
       
  3363         return;
       
  3364     }
       
  3365 
       
  3366     case CSSPropertyOverflowX:
       
  3367         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(overflowX, OverflowX)
       
  3368         return;
       
  3369     case CSSPropertyOverflowY:
       
  3370         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(overflowY, OverflowY)
       
  3371         return;
       
  3372     case CSSPropertyPageBreakBefore:
       
  3373         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(pageBreakBefore, PageBreakBefore, PageBreak)
       
  3374         return;
       
  3375     case CSSPropertyPageBreakAfter:
       
  3376         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(pageBreakAfter, PageBreakAfter, PageBreak)
       
  3377         return;
       
  3378     case CSSPropertyPageBreakInside: {
       
  3379         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(pageBreakInside, PageBreakInside, PageBreak)
       
  3380         if (!primitiveValue)
       
  3381             return;
       
  3382         EPageBreak pageBreak = *primitiveValue;
       
  3383         if (pageBreak != PBALWAYS)
       
  3384             m_style->setPageBreakInside(pageBreak);
       
  3385         return;
       
  3386     }
       
  3387         
       
  3388     case CSSPropertyPosition:
       
  3389         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(position, Position)
       
  3390         return;
       
  3391     case CSSPropertyTableLayout: {
       
  3392         HANDLE_INHERIT_AND_INITIAL(tableLayout, TableLayout)
       
  3393 
       
  3394         ETableLayout l = *primitiveValue;
       
  3395         if (l == TAUTO)
       
  3396             l = RenderStyle::initialTableLayout();
       
  3397 
       
  3398         m_style->setTableLayout(l);
       
  3399         return;
       
  3400     }
       
  3401         
       
  3402     case CSSPropertyUnicodeBidi: 
       
  3403         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(unicodeBidi, UnicodeBidi)
       
  3404         return;
       
  3405     case CSSPropertyTextTransform: 
       
  3406         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(textTransform, TextTransform)
       
  3407         return;
       
  3408     case CSSPropertyVisibility:
       
  3409         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(visibility, Visibility)
       
  3410         return;
       
  3411     case CSSPropertyWhiteSpace:
       
  3412         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(whiteSpace, WhiteSpace)
       
  3413         return;
       
  3414 
       
  3415     case CSSPropertyBackgroundPosition:
       
  3416         HANDLE_BACKGROUND_INHERIT_AND_INITIAL(xPosition, XPosition);
       
  3417         HANDLE_BACKGROUND_INHERIT_AND_INITIAL(yPosition, YPosition);
       
  3418         return;
       
  3419     case CSSPropertyBackgroundPositionX: {
       
  3420         HANDLE_BACKGROUND_VALUE(xPosition, XPosition, value)
       
  3421         return;
       
  3422     }
       
  3423     case CSSPropertyBackgroundPositionY: {
       
  3424         HANDLE_BACKGROUND_VALUE(yPosition, YPosition, value)
       
  3425         return;
       
  3426     }
       
  3427     case CSSPropertyWebkitMaskPosition:
       
  3428         HANDLE_MASK_INHERIT_AND_INITIAL(xPosition, XPosition);
       
  3429         HANDLE_MASK_INHERIT_AND_INITIAL(yPosition, YPosition);
       
  3430         return;
       
  3431     case CSSPropertyWebkitMaskPositionX: {
       
  3432         HANDLE_MASK_VALUE(xPosition, XPosition, value)
       
  3433         return;
       
  3434     }
       
  3435     case CSSPropertyWebkitMaskPositionY: {
       
  3436         HANDLE_MASK_VALUE(yPosition, YPosition, value)
       
  3437         return;
       
  3438     }
       
  3439     case CSSPropertyBackgroundRepeat:
       
  3440         HANDLE_BACKGROUND_INHERIT_AND_INITIAL(repeatX, RepeatX);
       
  3441         HANDLE_BACKGROUND_INHERIT_AND_INITIAL(repeatY, RepeatY);
       
  3442         return;
       
  3443     case CSSPropertyBackgroundRepeatX:
       
  3444         HANDLE_BACKGROUND_VALUE(repeatX, RepeatX, value)
       
  3445         return;
       
  3446     case CSSPropertyBackgroundRepeatY:
       
  3447         HANDLE_BACKGROUND_VALUE(repeatY, RepeatY, value)
       
  3448         return;
       
  3449     case CSSPropertyWebkitMaskRepeat:
       
  3450         HANDLE_MASK_INHERIT_AND_INITIAL(repeatX, RepeatX);
       
  3451         HANDLE_MASK_INHERIT_AND_INITIAL(repeatY, RepeatY);
       
  3452         return;
       
  3453     case CSSPropertyWebkitMaskRepeatX:
       
  3454         HANDLE_MASK_VALUE(repeatX, RepeatX, value)
       
  3455         return;
       
  3456     case CSSPropertyWebkitMaskRepeatY:
       
  3457         HANDLE_MASK_VALUE(repeatY, RepeatY, value)
       
  3458         return;
       
  3459     case CSSPropertyBorderSpacing: {
       
  3460         if (isInherit) {
       
  3461             m_style->setHorizontalBorderSpacing(m_parentStyle->horizontalBorderSpacing());
       
  3462             m_style->setVerticalBorderSpacing(m_parentStyle->verticalBorderSpacing());
       
  3463         }
       
  3464         else if (isInitial) {
       
  3465             m_style->setHorizontalBorderSpacing(0);
       
  3466             m_style->setVerticalBorderSpacing(0);
       
  3467         }
       
  3468         return;
       
  3469     }
       
  3470     case CSSPropertyWebkitBorderHorizontalSpacing: {
       
  3471         HANDLE_INHERIT_AND_INITIAL(horizontalBorderSpacing, HorizontalBorderSpacing)
       
  3472         if (!primitiveValue)
       
  3473             return;
       
  3474         short spacing = primitiveValue->computeLengthShort(style(), m_rootElementStyle, zoomFactor);
       
  3475         m_style->setHorizontalBorderSpacing(spacing);
       
  3476         return;
       
  3477     }
       
  3478     case CSSPropertyWebkitBorderVerticalSpacing: {
       
  3479         HANDLE_INHERIT_AND_INITIAL(verticalBorderSpacing, VerticalBorderSpacing)
       
  3480         if (!primitiveValue)
       
  3481             return;
       
  3482         short spacing = primitiveValue->computeLengthShort(style(), m_rootElementStyle, zoomFactor);
       
  3483         m_style->setVerticalBorderSpacing(spacing);
       
  3484         return;
       
  3485     }
       
  3486     case CSSPropertyCursor:
       
  3487         if (isInherit) {
       
  3488             m_style->setCursor(m_parentStyle->cursor());
       
  3489             m_style->setCursorList(m_parentStyle->cursors());
       
  3490             return;
       
  3491         }
       
  3492         m_style->clearCursorList();
       
  3493         if (isInitial) {
       
  3494             m_style->setCursor(RenderStyle::initialCursor());
       
  3495             return;
       
  3496         }
       
  3497         if (value->isValueList()) {
       
  3498             CSSValueList* list = static_cast<CSSValueList*>(value);
       
  3499             int len = list->length();
       
  3500             m_style->setCursor(CURSOR_AUTO);
       
  3501             for (int i = 0; i < len; i++) {
       
  3502                 CSSValue* item = list->itemWithoutBoundsCheck(i);
       
  3503                 if (!item->isPrimitiveValue())
       
  3504                     continue;
       
  3505                 primitiveValue = static_cast<CSSPrimitiveValue*>(item);
       
  3506                 int type = primitiveValue->primitiveType();
       
  3507                 if (type == CSSPrimitiveValue::CSS_URI) {
       
  3508                     CSSCursorImageValue* image = static_cast<CSSCursorImageValue*>(primitiveValue);
       
  3509                     if (image->updateIfSVGCursorIsUsed(m_element)) // Elements with SVG cursors are not allowed to share style.
       
  3510                         m_style->setUnique();
       
  3511                     // FIXME: Temporary clumsiness to pass off a CachedImage to an API that will eventually convert to using
       
  3512                     // StyleImage.
       
  3513                     RefPtr<StyleCachedImage> styleCachedImage(image->cachedImage(m_element->document()->docLoader()));
       
  3514                     if (styleCachedImage)
       
  3515                         m_style->addCursor(styleCachedImage->cachedImage(), image->hotSpot());
       
  3516                 } else if (type == CSSPrimitiveValue::CSS_IDENT)
       
  3517                     m_style->setCursor(*primitiveValue);
       
  3518             }
       
  3519         } else if (primitiveValue) {
       
  3520             int type = primitiveValue->primitiveType();
       
  3521             if (type == CSSPrimitiveValue::CSS_IDENT && m_style->cursor() != ECursor(*primitiveValue))
       
  3522                 m_style->setCursor(*primitiveValue);
       
  3523         }
       
  3524         return;
       
  3525 // colors || inherit
       
  3526     case CSSPropertyColor:
       
  3527         // If the 'currentColor' keyword is set on the 'color' property itself,
       
  3528         // it is treated as 'color:inherit' at parse time
       
  3529         if (primitiveValue && primitiveValue->getIdent() == CSSValueCurrentcolor)
       
  3530             isInherit = true;
       
  3531     case CSSPropertyBackgroundColor:
       
  3532     case CSSPropertyBorderTopColor:
       
  3533     case CSSPropertyBorderRightColor:
       
  3534     case CSSPropertyBorderBottomColor:
       
  3535     case CSSPropertyBorderLeftColor:
       
  3536     case CSSPropertyOutlineColor:
       
  3537     case CSSPropertyWebkitColumnRuleColor:
       
  3538     case CSSPropertyWebkitTextStrokeColor:
       
  3539     case CSSPropertyWebkitTextFillColor: {
       
  3540         Color col;
       
  3541         if (isInherit) {
       
  3542             HANDLE_INHERIT_COND(CSSPropertyBackgroundColor, backgroundColor, BackgroundColor)
       
  3543             HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyBorderTopColor, borderTopColor, color, BorderTopColor)
       
  3544             HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyBorderBottomColor, borderBottomColor, color, BorderBottomColor)
       
  3545             HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyBorderRightColor, borderRightColor, color, BorderRightColor)
       
  3546             HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyBorderLeftColor, borderLeftColor, color, BorderLeftColor)
       
  3547             HANDLE_INHERIT_COND(CSSPropertyColor, color, Color)
       
  3548             HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyOutlineColor, outlineColor, color, OutlineColor)
       
  3549             HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyWebkitColumnRuleColor, columnRuleColor, color, ColumnRuleColor)
       
  3550             HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyWebkitTextStrokeColor, textStrokeColor, color, TextStrokeColor)
       
  3551             HANDLE_INHERIT_COND_WITH_BACKUP(CSSPropertyWebkitTextFillColor, textFillColor, color, TextFillColor)
       
  3552             return;
       
  3553         }
       
  3554         if (isInitial) {
       
  3555             // The border/outline colors will just map to the invalid color |col| above.  This will have the
       
  3556             // effect of forcing the use of the currentColor when it comes time to draw the borders (and of
       
  3557             // not painting the background since the color won't be valid).
       
  3558             if (id == CSSPropertyColor)
       
  3559                 col = RenderStyle::initialColor();
       
  3560         } else {
       
  3561             if (!primitiveValue)
       
  3562                 return;
       
  3563             col = getColorFromPrimitiveValue(primitiveValue);
       
  3564         }
       
  3565 
       
  3566         switch (id) {
       
  3567         case CSSPropertyBackgroundColor:
       
  3568             m_style->setBackgroundColor(col);
       
  3569             break;
       
  3570         case CSSPropertyBorderTopColor:
       
  3571             m_style->setBorderTopColor(col);
       
  3572             break;
       
  3573         case CSSPropertyBorderRightColor:
       
  3574             m_style->setBorderRightColor(col);
       
  3575             break;
       
  3576         case CSSPropertyBorderBottomColor:
       
  3577             m_style->setBorderBottomColor(col);
       
  3578             break;
       
  3579         case CSSPropertyBorderLeftColor:
       
  3580             m_style->setBorderLeftColor(col);
       
  3581             break;
       
  3582         case CSSPropertyColor:
       
  3583             m_style->setColor(col);
       
  3584             break;
       
  3585         case CSSPropertyOutlineColor:
       
  3586             m_style->setOutlineColor(col);
       
  3587             break;
       
  3588         case CSSPropertyWebkitColumnRuleColor:
       
  3589             m_style->setColumnRuleColor(col);
       
  3590             break;
       
  3591         case CSSPropertyWebkitTextStrokeColor:
       
  3592             m_style->setTextStrokeColor(col);
       
  3593             break;
       
  3594         case CSSPropertyWebkitTextFillColor:
       
  3595             m_style->setTextFillColor(col);
       
  3596             break;
       
  3597         }
       
  3598         
       
  3599         return;
       
  3600     }
       
  3601     
       
  3602 // uri || inherit
       
  3603     case CSSPropertyBackgroundImage:
       
  3604         HANDLE_BACKGROUND_VALUE(image, Image, value)
       
  3605         return;
       
  3606     case CSSPropertyWebkitMaskImage:
       
  3607         HANDLE_MASK_VALUE(image, Image, value)
       
  3608         return;
       
  3609     case CSSPropertyListStyleImage:
       
  3610     {
       
  3611         HANDLE_INHERIT_AND_INITIAL(listStyleImage, ListStyleImage)
       
  3612         m_style->setListStyleImage(styleImage(value));
       
  3613         return;
       
  3614     }
       
  3615 
       
  3616 // length
       
  3617     case CSSPropertyBorderTopWidth:
       
  3618     case CSSPropertyBorderRightWidth:
       
  3619     case CSSPropertyBorderBottomWidth:
       
  3620     case CSSPropertyBorderLeftWidth:
       
  3621     case CSSPropertyOutlineWidth:
       
  3622     case CSSPropertyWebkitColumnRuleWidth:
       
  3623     {
       
  3624         if (isInherit) {
       
  3625             HANDLE_INHERIT_COND(CSSPropertyBorderTopWidth, borderTopWidth, BorderTopWidth)
       
  3626             HANDLE_INHERIT_COND(CSSPropertyBorderRightWidth, borderRightWidth, BorderRightWidth)
       
  3627             HANDLE_INHERIT_COND(CSSPropertyBorderBottomWidth, borderBottomWidth, BorderBottomWidth)
       
  3628             HANDLE_INHERIT_COND(CSSPropertyBorderLeftWidth, borderLeftWidth, BorderLeftWidth)
       
  3629             HANDLE_INHERIT_COND(CSSPropertyOutlineWidth, outlineWidth, OutlineWidth)
       
  3630             HANDLE_INHERIT_COND(CSSPropertyWebkitColumnRuleWidth, columnRuleWidth, ColumnRuleWidth)
       
  3631             return;
       
  3632         }
       
  3633         else if (isInitial) {
       
  3634             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyBorderTopWidth, BorderTopWidth, BorderWidth)
       
  3635             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyBorderRightWidth, BorderRightWidth, BorderWidth)
       
  3636             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyBorderBottomWidth, BorderBottomWidth, BorderWidth)
       
  3637             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyBorderLeftWidth, BorderLeftWidth, BorderWidth)
       
  3638             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyOutlineWidth, OutlineWidth, BorderWidth)
       
  3639             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyWebkitColumnRuleWidth, ColumnRuleWidth, BorderWidth)
       
  3640             return;
       
  3641         }
       
  3642 
       
  3643         if (!primitiveValue)
       
  3644             return;
       
  3645         short width = 3;
       
  3646         switch (primitiveValue->getIdent()) {
       
  3647         case CSSValueThin:
       
  3648             width = 1;
       
  3649             break;
       
  3650         case CSSValueMedium:
       
  3651             width = 3;
       
  3652             break;
       
  3653         case CSSValueThick:
       
  3654             width = 5;
       
  3655             break;
       
  3656         case CSSValueInvalid:
       
  3657             width = primitiveValue->computeLengthShort(style(), m_rootElementStyle, zoomFactor);
       
  3658             break;
       
  3659         default:
       
  3660             return;
       
  3661         }
       
  3662 
       
  3663         if (width < 0) return;
       
  3664         switch (id) {
       
  3665         case CSSPropertyBorderTopWidth:
       
  3666             m_style->setBorderTopWidth(width);
       
  3667             break;
       
  3668         case CSSPropertyBorderRightWidth:
       
  3669             m_style->setBorderRightWidth(width);
       
  3670             break;
       
  3671         case CSSPropertyBorderBottomWidth:
       
  3672             m_style->setBorderBottomWidth(width);
       
  3673             break;
       
  3674         case CSSPropertyBorderLeftWidth:
       
  3675             m_style->setBorderLeftWidth(width);
       
  3676             break;
       
  3677         case CSSPropertyOutlineWidth:
       
  3678             m_style->setOutlineWidth(width);
       
  3679             break;
       
  3680         case CSSPropertyWebkitColumnRuleWidth:
       
  3681             m_style->setColumnRuleWidth(width);
       
  3682             break;
       
  3683         default:
       
  3684             return;
       
  3685         }
       
  3686         return;
       
  3687     }
       
  3688 
       
  3689     case CSSPropertyWebkitFontSmoothing: {
       
  3690         FontDescription fontDescription = m_style->fontDescription();
       
  3691         if (isInherit) 
       
  3692             fontDescription.setFontSmoothing(m_parentStyle->fontDescription().fontSmoothing());
       
  3693         else if (isInitial)
       
  3694             fontDescription.setFontSmoothing(AutoSmoothing);
       
  3695         else {
       
  3696             if (!primitiveValue)
       
  3697                 return;
       
  3698             int id = primitiveValue->getIdent();
       
  3699             FontSmoothingMode smoothing;
       
  3700             switch (id) {
       
  3701                 case CSSValueAuto:
       
  3702                     smoothing = AutoSmoothing;
       
  3703                     break;
       
  3704                 case CSSValueNone:
       
  3705                     smoothing = NoSmoothing;
       
  3706                     break;
       
  3707                 case CSSValueAntialiased:
       
  3708                     smoothing = Antialiased;
       
  3709                     break;
       
  3710                 case CSSValueSubpixelAntialiased:
       
  3711                     smoothing = SubpixelAntialiased;
       
  3712                     break;
       
  3713                 default:
       
  3714                     ASSERT_NOT_REACHED();
       
  3715                     smoothing = AutoSmoothing;
       
  3716             }
       
  3717             fontDescription.setFontSmoothing(smoothing);
       
  3718         }
       
  3719         if (m_style->setFontDescription(fontDescription))
       
  3720             m_fontDirty = true;
       
  3721         return;
       
  3722     }
       
  3723 
       
  3724     case CSSPropertyLetterSpacing:
       
  3725     case CSSPropertyWordSpacing:
       
  3726     {
       
  3727         
       
  3728         if (isInherit) {
       
  3729             HANDLE_INHERIT_COND(CSSPropertyLetterSpacing, letterSpacing, LetterSpacing)
       
  3730             HANDLE_INHERIT_COND(CSSPropertyWordSpacing, wordSpacing, WordSpacing)
       
  3731             return;
       
  3732         }
       
  3733         else if (isInitial) {
       
  3734             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyLetterSpacing, LetterSpacing, LetterWordSpacing)
       
  3735             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyWordSpacing, WordSpacing, LetterWordSpacing)
       
  3736             return;
       
  3737         }
       
  3738         
       
  3739         int width = 0;
       
  3740         if (primitiveValue && primitiveValue->getIdent() == CSSValueNormal) {
       
  3741             width = 0;
       
  3742         } else {
       
  3743             if (!primitiveValue)
       
  3744                 return;
       
  3745             width = primitiveValue->computeLengthInt(style(), m_rootElementStyle, useSVGZoomRules ? 1.0f : zoomFactor);
       
  3746         }
       
  3747         switch (id) {
       
  3748         case CSSPropertyLetterSpacing:
       
  3749             m_style->setLetterSpacing(width);
       
  3750             break;
       
  3751         case CSSPropertyWordSpacing:
       
  3752             m_style->setWordSpacing(width);
       
  3753             break;
       
  3754             // ### needs the definitions in renderstyle
       
  3755         default: break;
       
  3756         }
       
  3757         return;
       
  3758     }
       
  3759 
       
  3760     case CSSPropertyWordBreak:
       
  3761         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(wordBreak, WordBreak)
       
  3762         return;
       
  3763     case CSSPropertyWordWrap:
       
  3764         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(wordWrap, WordWrap)
       
  3765         return;
       
  3766     case CSSPropertyWebkitNbspMode:
       
  3767         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(nbspMode, NBSPMode)
       
  3768         return;
       
  3769     case CSSPropertyWebkitLineBreak:
       
  3770         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(khtmlLineBreak, KHTMLLineBreak)
       
  3771         return;
       
  3772     case CSSPropertyWebkitMatchNearestMailBlockquoteColor:
       
  3773         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(matchNearestMailBlockquoteColor, MatchNearestMailBlockquoteColor)
       
  3774         return;
       
  3775 
       
  3776     case CSSPropertyResize:
       
  3777     {
       
  3778         HANDLE_INHERIT_AND_INITIAL(resize, Resize)
       
  3779 
       
  3780         if (!primitiveValue->getIdent())
       
  3781             return;
       
  3782 
       
  3783         EResize r = RESIZE_NONE;
       
  3784         if (primitiveValue->getIdent() == CSSValueAuto) {
       
  3785             if (Settings* settings = m_checker.m_document->settings())
       
  3786                 r = settings->textAreasAreResizable() ? RESIZE_BOTH : RESIZE_NONE;
       
  3787         } else
       
  3788             r = *primitiveValue;
       
  3789             
       
  3790         m_style->setResize(r);
       
  3791         return;
       
  3792     }
       
  3793     
       
  3794     // length, percent
       
  3795     case CSSPropertyMaxWidth:
       
  3796         // +none +inherit
       
  3797         if (primitiveValue && primitiveValue->getIdent() == CSSValueNone)
       
  3798             apply = true;
       
  3799     case CSSPropertyTop:
       
  3800     case CSSPropertyLeft:
       
  3801     case CSSPropertyRight:
       
  3802     case CSSPropertyBottom:
       
  3803     case CSSPropertyWidth:
       
  3804     case CSSPropertyMinWidth:
       
  3805     case CSSPropertyMarginTop:
       
  3806     case CSSPropertyMarginRight:
       
  3807     case CSSPropertyMarginBottom:
       
  3808     case CSSPropertyMarginLeft:
       
  3809         // +inherit +auto
       
  3810         if (id == CSSPropertyWidth || id == CSSPropertyMinWidth || id == CSSPropertyMaxWidth) {
       
  3811             if (primitiveValue && primitiveValue->getIdent() == CSSValueIntrinsic) {
       
  3812                 l = Length(Intrinsic);
       
  3813                 apply = true;
       
  3814             }
       
  3815             else if (primitiveValue && primitiveValue->getIdent() == CSSValueMinIntrinsic) {
       
  3816                 l = Length(MinIntrinsic);
       
  3817                 apply = true;
       
  3818             }
       
  3819         }
       
  3820         if (id != CSSPropertyMaxWidth && primitiveValue && primitiveValue->getIdent() == CSSValueAuto)
       
  3821             apply = true;
       
  3822     case CSSPropertyPaddingTop:
       
  3823     case CSSPropertyPaddingRight:
       
  3824     case CSSPropertyPaddingBottom:
       
  3825     case CSSPropertyPaddingLeft:
       
  3826     case CSSPropertyTextIndent:
       
  3827         // +inherit
       
  3828     {
       
  3829         if (isInherit) {
       
  3830             HANDLE_INHERIT_COND(CSSPropertyMaxWidth, maxWidth, MaxWidth)
       
  3831             HANDLE_INHERIT_COND(CSSPropertyBottom, bottom, Bottom)
       
  3832             HANDLE_INHERIT_COND(CSSPropertyTop, top, Top)
       
  3833             HANDLE_INHERIT_COND(CSSPropertyLeft, left, Left)
       
  3834             HANDLE_INHERIT_COND(CSSPropertyRight, right, Right)
       
  3835             HANDLE_INHERIT_COND(CSSPropertyWidth, width, Width)
       
  3836             HANDLE_INHERIT_COND(CSSPropertyMinWidth, minWidth, MinWidth)
       
  3837             HANDLE_INHERIT_COND(CSSPropertyPaddingTop, paddingTop, PaddingTop)
       
  3838             HANDLE_INHERIT_COND(CSSPropertyPaddingRight, paddingRight, PaddingRight)
       
  3839             HANDLE_INHERIT_COND(CSSPropertyPaddingBottom, paddingBottom, PaddingBottom)
       
  3840             HANDLE_INHERIT_COND(CSSPropertyPaddingLeft, paddingLeft, PaddingLeft)
       
  3841             HANDLE_INHERIT_COND(CSSPropertyMarginTop, marginTop, MarginTop)
       
  3842             HANDLE_INHERIT_COND(CSSPropertyMarginRight, marginRight, MarginRight)
       
  3843             HANDLE_INHERIT_COND(CSSPropertyMarginBottom, marginBottom, MarginBottom)
       
  3844             HANDLE_INHERIT_COND(CSSPropertyMarginLeft, marginLeft, MarginLeft)
       
  3845             HANDLE_INHERIT_COND(CSSPropertyTextIndent, textIndent, TextIndent)
       
  3846             return;
       
  3847         }
       
  3848         else if (isInitial) {
       
  3849             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMaxWidth, MaxWidth, MaxSize)
       
  3850             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyBottom, Bottom, Offset)
       
  3851             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyTop, Top, Offset)
       
  3852             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyLeft, Left, Offset)
       
  3853             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyRight, Right, Offset)
       
  3854             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyWidth, Width, Size)
       
  3855             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMinWidth, MinWidth, MinSize)
       
  3856             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyPaddingTop, PaddingTop, Padding)
       
  3857             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyPaddingRight, PaddingRight, Padding)
       
  3858             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyPaddingBottom, PaddingBottom, Padding)
       
  3859             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyPaddingLeft, PaddingLeft, Padding)
       
  3860             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMarginTop, MarginTop, Margin)
       
  3861             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMarginRight, MarginRight, Margin)
       
  3862             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMarginBottom, MarginBottom, Margin)
       
  3863             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMarginLeft, MarginLeft, Margin)
       
  3864             HANDLE_INITIAL_COND(CSSPropertyTextIndent, TextIndent)
       
  3865             return;
       
  3866         } 
       
  3867 
       
  3868         if (primitiveValue && !apply) {
       
  3869             int type = primitiveValue->primitiveType();
       
  3870             if (CSSPrimitiveValue::isUnitTypeLength(type))
       
  3871                 // Handle our quirky margin units if we have them.
       
  3872                 l = Length(primitiveValue->computeLengthIntForLength(style(), m_rootElementStyle, zoomFactor), Fixed, 
       
  3873                            primitiveValue->isQuirkValue());
       
  3874             else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  3875                 l = Length(primitiveValue->getDoubleValue(), Percent);
       
  3876             else
       
  3877                 return;
       
  3878             apply = true;
       
  3879         }
       
  3880         if (!apply) return;
       
  3881         switch (id) {
       
  3882             case CSSPropertyMaxWidth:
       
  3883                 m_style->setMaxWidth(l);
       
  3884                 break;
       
  3885             case CSSPropertyBottom:
       
  3886                 m_style->setBottom(l);
       
  3887                 break;
       
  3888             case CSSPropertyTop:
       
  3889                 m_style->setTop(l);
       
  3890                 break;
       
  3891             case CSSPropertyLeft:
       
  3892                 m_style->setLeft(l);
       
  3893                 break;
       
  3894             case CSSPropertyRight:
       
  3895                 m_style->setRight(l);
       
  3896                 break;
       
  3897             case CSSPropertyWidth:
       
  3898                 m_style->setWidth(l);
       
  3899                 break;
       
  3900             case CSSPropertyMinWidth:
       
  3901                 m_style->setMinWidth(l);
       
  3902                 break;
       
  3903             case CSSPropertyPaddingTop:
       
  3904                 m_style->setPaddingTop(l);
       
  3905                 break;
       
  3906             case CSSPropertyPaddingRight:
       
  3907                 m_style->setPaddingRight(l);
       
  3908                 break;
       
  3909             case CSSPropertyPaddingBottom:
       
  3910                 m_style->setPaddingBottom(l);
       
  3911                 break;
       
  3912             case CSSPropertyPaddingLeft:
       
  3913                 m_style->setPaddingLeft(l);
       
  3914                 break;
       
  3915             case CSSPropertyMarginTop:
       
  3916                 m_style->setMarginTop(l);
       
  3917                 break;
       
  3918             case CSSPropertyMarginRight:
       
  3919                 m_style->setMarginRight(l);
       
  3920                 break;
       
  3921             case CSSPropertyMarginBottom:
       
  3922                 m_style->setMarginBottom(l);
       
  3923                 break;
       
  3924             case CSSPropertyMarginLeft:
       
  3925                 m_style->setMarginLeft(l);
       
  3926                 break;
       
  3927             case CSSPropertyTextIndent:
       
  3928                 m_style->setTextIndent(l);
       
  3929                 break;
       
  3930             default:
       
  3931                 break;
       
  3932             }
       
  3933         return;
       
  3934     }
       
  3935 
       
  3936     case CSSPropertyMaxHeight:
       
  3937         if (primitiveValue && primitiveValue->getIdent() == CSSValueNone) {
       
  3938             l = Length(undefinedLength, Fixed);
       
  3939             apply = true;
       
  3940         }
       
  3941     case CSSPropertyHeight:
       
  3942     case CSSPropertyMinHeight:
       
  3943         if (primitiveValue && primitiveValue->getIdent() == CSSValueIntrinsic) {
       
  3944             l = Length(Intrinsic);
       
  3945             apply = true;
       
  3946         } else if (primitiveValue && primitiveValue->getIdent() == CSSValueMinIntrinsic) {
       
  3947             l = Length(MinIntrinsic);
       
  3948             apply = true;
       
  3949         } else if (id != CSSPropertyMaxHeight && primitiveValue && primitiveValue->getIdent() == CSSValueAuto)
       
  3950             apply = true;
       
  3951         if (isInherit) {
       
  3952             HANDLE_INHERIT_COND(CSSPropertyMaxHeight, maxHeight, MaxHeight)
       
  3953             HANDLE_INHERIT_COND(CSSPropertyHeight, height, Height)
       
  3954             HANDLE_INHERIT_COND(CSSPropertyMinHeight, minHeight, MinHeight)
       
  3955             return;
       
  3956         }
       
  3957         if (isInitial) {
       
  3958             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMaxHeight, MaxHeight, MaxSize)
       
  3959             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyHeight, Height, Size)
       
  3960             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyMinHeight, MinHeight, MinSize)
       
  3961             return;
       
  3962         }
       
  3963 
       
  3964         if (primitiveValue && !apply) {
       
  3965             unsigned short type = primitiveValue->primitiveType();
       
  3966             if (CSSPrimitiveValue::isUnitTypeLength(type))
       
  3967                 l = Length(primitiveValue->computeLengthIntForLength(style(), m_rootElementStyle, zoomFactor), Fixed);
       
  3968             else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  3969                 l = Length(primitiveValue->getDoubleValue(), Percent);
       
  3970             else
       
  3971                 return;
       
  3972             apply = true;
       
  3973         }
       
  3974         if (apply)
       
  3975             switch (id) {
       
  3976                 case CSSPropertyMaxHeight:
       
  3977                     m_style->setMaxHeight(l);
       
  3978                     break;
       
  3979                 case CSSPropertyHeight:
       
  3980                     m_style->setHeight(l);
       
  3981                     break;
       
  3982                 case CSSPropertyMinHeight:
       
  3983                     m_style->setMinHeight(l);
       
  3984                     break;
       
  3985             }
       
  3986         return;
       
  3987 
       
  3988     case CSSPropertyVerticalAlign:
       
  3989         HANDLE_INHERIT_AND_INITIAL(verticalAlign, VerticalAlign)
       
  3990         if (!primitiveValue)
       
  3991             return;
       
  3992         if (primitiveValue->getIdent()) {
       
  3993           EVerticalAlign align;
       
  3994 
       
  3995           switch (primitiveValue->getIdent()) {
       
  3996                 case CSSValueTop:
       
  3997                     align = TOP; break;
       
  3998                 case CSSValueBottom:
       
  3999                     align = BOTTOM; break;
       
  4000                 case CSSValueMiddle:
       
  4001                     align = MIDDLE; break;
       
  4002                 case CSSValueBaseline:
       
  4003                     align = BASELINE; break;
       
  4004                 case CSSValueTextBottom:
       
  4005                     align = TEXT_BOTTOM; break;
       
  4006                 case CSSValueTextTop:
       
  4007                     align = TEXT_TOP; break;
       
  4008                 case CSSValueSub:
       
  4009                     align = SUB; break;
       
  4010                 case CSSValueSuper:
       
  4011                     align = SUPER; break;
       
  4012                 case CSSValueWebkitBaselineMiddle:
       
  4013                     align = BASELINE_MIDDLE; break;
       
  4014                 default:
       
  4015                     return;
       
  4016             }
       
  4017           m_style->setVerticalAlign(align);
       
  4018           return;
       
  4019         } else {
       
  4020           int type = primitiveValue->primitiveType();
       
  4021           Length l;
       
  4022           if (CSSPrimitiveValue::isUnitTypeLength(type))
       
  4023             l = Length(primitiveValue->computeLengthIntForLength(style(), m_rootElementStyle, zoomFactor), Fixed);
       
  4024           else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  4025             l = Length(primitiveValue->getDoubleValue(), Percent);
       
  4026 
       
  4027           m_style->setVerticalAlign(LENGTH);
       
  4028           m_style->setVerticalAlignLength(l);
       
  4029         }
       
  4030         return;
       
  4031 
       
  4032     case CSSPropertyFontSize:
       
  4033     {
       
  4034         FontDescription fontDescription = m_style->fontDescription();
       
  4035         fontDescription.setKeywordSize(0);
       
  4036         float oldSize = 0;
       
  4037         float size = 0;
       
  4038         
       
  4039         bool parentIsAbsoluteSize = false;
       
  4040         if (m_parentNode) {
       
  4041             oldSize = m_parentStyle->fontDescription().specifiedSize();
       
  4042             parentIsAbsoluteSize = m_parentStyle->fontDescription().isAbsoluteSize();
       
  4043         }
       
  4044 
       
  4045         if (isInherit) {
       
  4046             size = oldSize;
       
  4047             if (m_parentNode)
       
  4048                 fontDescription.setKeywordSize(m_parentStyle->fontDescription().keywordSize());
       
  4049         } else if (isInitial) {
       
  4050             size = fontSizeForKeyword(m_checker.m_document, CSSValueMedium, fontDescription.useFixedDefaultSize());
       
  4051             fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
       
  4052         } else if (primitiveValue->getIdent()) {
       
  4053             // Keywords are being used.
       
  4054             switch (primitiveValue->getIdent()) {
       
  4055                 case CSSValueXxSmall:
       
  4056                 case CSSValueXSmall:
       
  4057                 case CSSValueSmall:
       
  4058                 case CSSValueMedium:
       
  4059                 case CSSValueLarge:
       
  4060                 case CSSValueXLarge:
       
  4061                 case CSSValueXxLarge:
       
  4062                 case CSSValueWebkitXxxLarge:
       
  4063                     size = fontSizeForKeyword(m_checker.m_document, primitiveValue->getIdent(), fontDescription.useFixedDefaultSize());
       
  4064                     fontDescription.setKeywordSize(primitiveValue->getIdent() - CSSValueXxSmall + 1);
       
  4065                     break;
       
  4066                 case CSSValueLarger:
       
  4067                     size = largerFontSize(oldSize, m_style->htmlHacks());
       
  4068                     break;
       
  4069                 case CSSValueSmaller:
       
  4070                     size = smallerFontSize(oldSize, m_style->htmlHacks());
       
  4071                     break;
       
  4072                 default:
       
  4073                     return;
       
  4074             }
       
  4075 
       
  4076             fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize && 
       
  4077                                               (primitiveValue->getIdent() == CSSValueLarger ||
       
  4078                                                primitiveValue->getIdent() == CSSValueSmaller));
       
  4079         } else {
       
  4080             int type = primitiveValue->primitiveType();
       
  4081             fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize ||
       
  4082                                               (type != CSSPrimitiveValue::CSS_PERCENTAGE &&
       
  4083                                                type != CSSPrimitiveValue::CSS_EMS && 
       
  4084                                                type != CSSPrimitiveValue::CSS_EXS &&
       
  4085                                                type != CSSPrimitiveValue::CSS_REMS));
       
  4086             if (CSSPrimitiveValue::isUnitTypeLength(type))
       
  4087                 size = primitiveValue->computeLengthFloat(m_parentStyle, m_rootElementStyle, true);
       
  4088             else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  4089                 size = (primitiveValue->getFloatValue() * oldSize) / 100.0f;
       
  4090             else
       
  4091                 return;
       
  4092         }
       
  4093 
       
  4094         if (size < 0)
       
  4095             return;
       
  4096 
       
  4097         setFontSize(fontDescription, size);
       
  4098         if (m_style->setFontDescription(fontDescription))
       
  4099             m_fontDirty = true;
       
  4100         return;
       
  4101     }
       
  4102 
       
  4103     case CSSPropertyZIndex: {
       
  4104         if (isInherit) {
       
  4105             if (m_parentStyle->hasAutoZIndex())
       
  4106                 m_style->setHasAutoZIndex();
       
  4107             else
       
  4108                 m_style->setZIndex(m_parentStyle->zIndex());
       
  4109             return;
       
  4110         } else if (isInitial || primitiveValue->getIdent() == CSSValueAuto) {
       
  4111             m_style->setHasAutoZIndex();
       
  4112             return;
       
  4113         }
       
  4114         
       
  4115         // FIXME: Should clamp all sorts of other integer properties too.
       
  4116         const double minIntAsDouble = INT_MIN;
       
  4117         const double maxIntAsDouble = INT_MAX;
       
  4118         m_style->setZIndex(static_cast<int>(max(minIntAsDouble, min(primitiveValue->getDoubleValue(), maxIntAsDouble))));
       
  4119         return;
       
  4120     }
       
  4121     case CSSPropertyWidows:
       
  4122     {
       
  4123         HANDLE_INHERIT_AND_INITIAL(widows, Widows)
       
  4124         if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
       
  4125             return;
       
  4126         m_style->setWidows(primitiveValue->getIntValue());
       
  4127         return;
       
  4128     }
       
  4129         
       
  4130     case CSSPropertyOrphans:
       
  4131     {
       
  4132         HANDLE_INHERIT_AND_INITIAL(orphans, Orphans)
       
  4133         if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
       
  4134             return;
       
  4135         m_style->setOrphans(primitiveValue->getIntValue());
       
  4136         return;
       
  4137     }        
       
  4138 
       
  4139 // length, percent, number
       
  4140     case CSSPropertyLineHeight:
       
  4141     {
       
  4142         HANDLE_INHERIT_AND_INITIAL(lineHeight, LineHeight)
       
  4143         if (!primitiveValue)
       
  4144             return;
       
  4145         Length lineHeight;
       
  4146         int type = primitiveValue->primitiveType();
       
  4147         if (primitiveValue->getIdent() == CSSValueNormal)
       
  4148             lineHeight = Length(-100.0, Percent);
       
  4149         else if (CSSPrimitiveValue::isUnitTypeLength(type)) {
       
  4150             double multiplier = zoomFactor;
       
  4151             if (m_style->textSizeAdjust()) {
       
  4152                 if (FrameView* view = m_checker.m_document->view()) {
       
  4153                     if (view->shouldApplyTextZoom())
       
  4154                         multiplier *= view->textZoomFactor();
       
  4155                 }
       
  4156             }
       
  4157             lineHeight = Length(primitiveValue->computeLengthIntForLength(style(), m_rootElementStyle,  multiplier), Fixed);
       
  4158         } else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  4159             lineHeight = Length((m_style->fontSize() * primitiveValue->getIntValue()) / 100, Fixed);
       
  4160         else if (type == CSSPrimitiveValue::CSS_NUMBER)
       
  4161             lineHeight = Length(primitiveValue->getDoubleValue() * 100.0, Percent);
       
  4162         else
       
  4163             return;
       
  4164         m_style->setLineHeight(lineHeight);
       
  4165         return;
       
  4166     }
       
  4167 
       
  4168 // string
       
  4169     case CSSPropertyTextAlign:
       
  4170     {
       
  4171         HANDLE_INHERIT_AND_INITIAL(textAlign, TextAlign)
       
  4172         if (!primitiveValue)
       
  4173             return;
       
  4174         int id = primitiveValue->getIdent();
       
  4175         if (id == CSSValueStart)
       
  4176             m_style->setTextAlign(m_style->direction() == LTR ? LEFT : RIGHT);
       
  4177         else if (id == CSSValueEnd)
       
  4178             m_style->setTextAlign(m_style->direction() == LTR ? RIGHT : LEFT);
       
  4179         else
       
  4180             m_style->setTextAlign(*primitiveValue);
       
  4181         return;
       
  4182     }
       
  4183 
       
  4184 // rect
       
  4185     case CSSPropertyClip:
       
  4186     {
       
  4187         Length top;
       
  4188         Length right;
       
  4189         Length bottom;
       
  4190         Length left;
       
  4191         bool hasClip = true;
       
  4192         if (isInherit) {
       
  4193             if (m_parentStyle->hasClip()) {
       
  4194                 top = m_parentStyle->clipTop();
       
  4195                 right = m_parentStyle->clipRight();
       
  4196                 bottom = m_parentStyle->clipBottom();
       
  4197                 left = m_parentStyle->clipLeft();
       
  4198             } else {
       
  4199                 hasClip = false;
       
  4200                 top = right = bottom = left = Length();
       
  4201             }
       
  4202         } else if (isInitial) {
       
  4203             hasClip = false;
       
  4204             top = right = bottom = left = Length();
       
  4205         } else if (!primitiveValue) {
       
  4206             return;
       
  4207         } else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RECT) {
       
  4208             Rect* rect = primitiveValue->getRectValue();
       
  4209             if (!rect)
       
  4210                 return;
       
  4211             top = convertToLength(rect->top(), style(), m_rootElementStyle, zoomFactor);
       
  4212             right = convertToLength(rect->right(), style(), m_rootElementStyle, zoomFactor);
       
  4213             bottom = convertToLength(rect->bottom(), style(), m_rootElementStyle, zoomFactor);
       
  4214             left = convertToLength(rect->left(), style(), m_rootElementStyle, zoomFactor);
       
  4215         } else if (primitiveValue->getIdent() != CSSValueAuto) {
       
  4216             return;
       
  4217         }
       
  4218         m_style->setClip(top, right, bottom, left);
       
  4219         m_style->setHasClip(hasClip);
       
  4220     
       
  4221         // rect, ident
       
  4222         return;
       
  4223     }
       
  4224 
       
  4225 // lists
       
  4226     case CSSPropertyContent:
       
  4227         // list of string, uri, counter, attr, i
       
  4228     {
       
  4229         // FIXME: In CSS3, it will be possible to inherit content.  In CSS2 it is not.  This
       
  4230         // note is a reminder that eventually "inherit" needs to be supported.
       
  4231 
       
  4232         if (isInitial) {
       
  4233             m_style->clearContent();
       
  4234             return;
       
  4235         }
       
  4236         
       
  4237         if (!value->isValueList())
       
  4238             return;
       
  4239 
       
  4240         CSSValueList* list = static_cast<CSSValueList*>(value);
       
  4241         int len = list->length();
       
  4242 
       
  4243         bool didSet = false;
       
  4244         for (int i = 0; i < len; i++) {
       
  4245             CSSValue* item = list->itemWithoutBoundsCheck(i);
       
  4246             if (item->isImageGeneratorValue()) {
       
  4247                 m_style->setContent(static_cast<CSSImageGeneratorValue*>(item)->generatedImage(), didSet);
       
  4248                 didSet = true;
       
  4249             }
       
  4250             
       
  4251             if (!item->isPrimitiveValue())
       
  4252                 continue;
       
  4253             
       
  4254             CSSPrimitiveValue* val = static_cast<CSSPrimitiveValue*>(item);
       
  4255             switch (val->primitiveType()) {
       
  4256                 case CSSPrimitiveValue::CSS_STRING:
       
  4257                     m_style->setContent(val->getStringValue().impl(), didSet);
       
  4258                     didSet = true;
       
  4259                     break;
       
  4260                 case CSSPrimitiveValue::CSS_ATTR: {
       
  4261                     // FIXME: Can a namespace be specified for an attr(foo)?
       
  4262                     if (m_style->styleType() == NOPSEUDO)
       
  4263                         m_style->setUnique();
       
  4264                     else
       
  4265                         m_parentStyle->setUnique();
       
  4266                     QualifiedName attr(nullAtom, val->getStringValue().impl(), nullAtom);
       
  4267                     m_style->setContent(m_element->getAttribute(attr).impl(), didSet);
       
  4268                     didSet = true;
       
  4269                     // register the fact that the attribute value affects the style
       
  4270                     m_selectorAttrs.add(attr.localName().impl());
       
  4271                     break;
       
  4272                 }
       
  4273                 case CSSPrimitiveValue::CSS_URI: {
       
  4274                     CSSImageValue* image = static_cast<CSSImageValue*>(val);
       
  4275                     m_style->setContent(image->cachedImage(m_element->document()->docLoader()), didSet);
       
  4276                     didSet = true;
       
  4277                     break;
       
  4278                 }
       
  4279                 case CSSPrimitiveValue::CSS_COUNTER: {
       
  4280                     Counter* counterValue = val->getCounterValue();
       
  4281                     CounterContent* counter = new CounterContent(counterValue->identifier(),
       
  4282                         (EListStyleType)counterValue->listStyleNumber(), counterValue->separator());
       
  4283                     m_style->setContent(counter, didSet);
       
  4284                     didSet = true;
       
  4285                 }
       
  4286             }
       
  4287         }
       
  4288         if (!didSet)
       
  4289             m_style->clearContent();
       
  4290         return;
       
  4291     }
       
  4292 
       
  4293     case CSSPropertyCounterIncrement:
       
  4294         applyCounterList(style(), value->isValueList() ? static_cast<CSSValueList*>(value) : 0, false);
       
  4295         return;
       
  4296     case CSSPropertyCounterReset:
       
  4297         applyCounterList(style(), value->isValueList() ? static_cast<CSSValueList*>(value) : 0, true);
       
  4298         return;
       
  4299 
       
  4300     case CSSPropertyFontFamily: {
       
  4301         // list of strings and ids
       
  4302         if (isInherit) {
       
  4303             FontDescription parentFontDescription = m_parentStyle->fontDescription();
       
  4304             FontDescription fontDescription = m_style->fontDescription();
       
  4305             fontDescription.setGenericFamily(parentFontDescription.genericFamily());
       
  4306             fontDescription.setFamily(parentFontDescription.firstFamily());
       
  4307             if (m_style->setFontDescription(fontDescription))
       
  4308                 m_fontDirty = true;
       
  4309             return;
       
  4310         } else if (isInitial) {
       
  4311             FontDescription initialDesc = FontDescription();
       
  4312             FontDescription fontDescription = m_style->fontDescription();
       
  4313             // We need to adjust the size to account for the generic family change from monospace
       
  4314             // to non-monospace.
       
  4315             if (fontDescription.keywordSize() && fontDescription.useFixedDefaultSize())
       
  4316                 setFontSize(fontDescription, fontSizeForKeyword(m_checker.m_document, CSSValueXxSmall + fontDescription.keywordSize() - 1, false));
       
  4317             fontDescription.setGenericFamily(initialDesc.genericFamily());
       
  4318             if (!initialDesc.firstFamily().familyIsEmpty())
       
  4319                 fontDescription.setFamily(initialDesc.firstFamily());
       
  4320             if (m_style->setFontDescription(fontDescription))
       
  4321                 m_fontDirty = true;
       
  4322             return;
       
  4323         }
       
  4324         
       
  4325         if (!value->isValueList())
       
  4326             return;
       
  4327         FontDescription fontDescription = m_style->fontDescription();
       
  4328         CSSValueList* list = static_cast<CSSValueList*>(value);
       
  4329         int len = list->length();
       
  4330         FontFamily& firstFamily = fontDescription.firstFamily();
       
  4331         FontFamily* currFamily = 0;
       
  4332         
       
  4333         // Before mapping in a new font-family property, we should reset the generic family.
       
  4334         bool oldFamilyUsedFixedDefaultSize = fontDescription.useFixedDefaultSize();
       
  4335         fontDescription.setGenericFamily(FontDescription::NoFamily);
       
  4336 
       
  4337         for (int i = 0; i < len; i++) {
       
  4338             CSSValue* item = list->itemWithoutBoundsCheck(i);
       
  4339             if (!item->isPrimitiveValue())
       
  4340                 continue;
       
  4341             CSSPrimitiveValue* val = static_cast<CSSPrimitiveValue*>(item);
       
  4342             AtomicString face;
       
  4343             Settings* settings = m_checker.m_document->settings();
       
  4344             if (val->primitiveType() == CSSPrimitiveValue::CSS_STRING)
       
  4345                 face = static_cast<FontFamilyValue*>(val)->familyName();
       
  4346             else if (val->primitiveType() == CSSPrimitiveValue::CSS_IDENT && settings) {
       
  4347                 switch (val->getIdent()) {
       
  4348                     case CSSValueWebkitBody:
       
  4349                         face = settings->standardFontFamily();
       
  4350                         break;
       
  4351                     case CSSValueSerif:
       
  4352                         face = "-webkit-serif";
       
  4353                         fontDescription.setGenericFamily(FontDescription::SerifFamily);
       
  4354                         break;
       
  4355                     case CSSValueSansSerif:
       
  4356                         face = "-webkit-sans-serif";
       
  4357                         fontDescription.setGenericFamily(FontDescription::SansSerifFamily);
       
  4358                         break;
       
  4359                     case CSSValueCursive:
       
  4360                         face = "-webkit-cursive";
       
  4361                         fontDescription.setGenericFamily(FontDescription::CursiveFamily);
       
  4362                         break;
       
  4363                     case CSSValueFantasy:
       
  4364                         face = "-webkit-fantasy";
       
  4365                         fontDescription.setGenericFamily(FontDescription::FantasyFamily);
       
  4366                         break;
       
  4367                     case CSSValueMonospace:
       
  4368                         face = "-webkit-monospace";
       
  4369                         fontDescription.setGenericFamily(FontDescription::MonospaceFamily);
       
  4370                         break;
       
  4371                 }
       
  4372             }
       
  4373 
       
  4374             if (!face.isEmpty()) {
       
  4375                 if (!currFamily) {
       
  4376                     // Filling in the first family.
       
  4377                     firstFamily.setFamily(face);
       
  4378                     firstFamily.appendFamily(0); // Remove any inherited family-fallback list.
       
  4379                     currFamily = &firstFamily;
       
  4380                 } else {
       
  4381                     RefPtr<SharedFontFamily> newFamily = SharedFontFamily::create();
       
  4382                     newFamily->setFamily(face);
       
  4383                     currFamily->appendFamily(newFamily);
       
  4384                     currFamily = newFamily.get();
       
  4385                 }
       
  4386             }
       
  4387         }
       
  4388 
       
  4389         // We can't call useFixedDefaultSize() until all new font families have been added
       
  4390         // If currFamily is non-zero then we set at least one family on this description.
       
  4391         if (currFamily) {
       
  4392             if (fontDescription.keywordSize() && fontDescription.useFixedDefaultSize() != oldFamilyUsedFixedDefaultSize)
       
  4393                 setFontSize(fontDescription, fontSizeForKeyword(m_checker.m_document, CSSValueXxSmall + fontDescription.keywordSize() - 1, !oldFamilyUsedFixedDefaultSize));
       
  4394 
       
  4395             if (m_style->setFontDescription(fontDescription))
       
  4396                 m_fontDirty = true;
       
  4397         }
       
  4398         return;
       
  4399     }
       
  4400     case CSSPropertyTextDecoration: {
       
  4401         // list of ident
       
  4402         HANDLE_INHERIT_AND_INITIAL(textDecoration, TextDecoration)
       
  4403         int t = RenderStyle::initialTextDecoration();
       
  4404         if (primitiveValue && primitiveValue->getIdent() == CSSValueNone) {
       
  4405             // do nothing
       
  4406         } else {
       
  4407             if (!value->isValueList()) return;
       
  4408             CSSValueList *list = static_cast<CSSValueList*>(value);
       
  4409             int len = list->length();
       
  4410             for (int i = 0; i < len; i++)
       
  4411             {
       
  4412                 CSSValue *item = list->itemWithoutBoundsCheck(i);
       
  4413                 if (!item->isPrimitiveValue()) continue;
       
  4414                 primitiveValue = static_cast<CSSPrimitiveValue*>(item);
       
  4415                 switch (primitiveValue->getIdent()) {
       
  4416                     case CSSValueNone:
       
  4417                         t = TDNONE; break;
       
  4418                     case CSSValueUnderline:
       
  4419                         t |= UNDERLINE; break;
       
  4420                     case CSSValueOverline:
       
  4421                         t |= OVERLINE; break;
       
  4422                     case CSSValueLineThrough:
       
  4423                         t |= LINE_THROUGH; break;
       
  4424                     case CSSValueBlink:
       
  4425                         t |= BLINK; break;
       
  4426                     default:
       
  4427                         return;
       
  4428                 }
       
  4429             }
       
  4430         }
       
  4431 
       
  4432         m_style->setTextDecoration(t);
       
  4433         return;
       
  4434     }
       
  4435 
       
  4436     case CSSPropertyZoom:
       
  4437     {
       
  4438         // Reset the zoom in effect before we do anything.  This allows the setZoom method to accurately compute a new
       
  4439         // zoom in effect.
       
  4440         m_style->setEffectiveZoom(m_parentStyle ? m_parentStyle->effectiveZoom() : RenderStyle::initialZoom());
       
  4441         
       
  4442         // Now we can handle inherit and initial.
       
  4443         HANDLE_INHERIT_AND_INITIAL(zoom, Zoom)
       
  4444         
       
  4445         // Handle normal/reset, numbers and percentages.
       
  4446         int type = primitiveValue->primitiveType();
       
  4447         if (primitiveValue->getIdent() == CSSValueNormal)
       
  4448             m_style->setZoom(RenderStyle::initialZoom());
       
  4449         else if (primitiveValue->getIdent() == CSSValueReset) {
       
  4450             m_style->setEffectiveZoom(RenderStyle::initialZoom());
       
  4451             m_style->setZoom(RenderStyle::initialZoom());
       
  4452         } else if (primitiveValue->getIdent() == CSSValueDocument) {
       
  4453             float docZoom = m_checker.m_document->renderer()->style()->zoom();
       
  4454             m_style->setEffectiveZoom(docZoom);
       
  4455             m_style->setZoom(docZoom);
       
  4456         } else if (type == CSSPrimitiveValue::CSS_PERCENTAGE) {
       
  4457             if (primitiveValue->getFloatValue())
       
  4458                 m_style->setZoom(primitiveValue->getFloatValue() / 100.0f);
       
  4459         } else if (type == CSSPrimitiveValue::CSS_NUMBER) {
       
  4460             if (primitiveValue->getFloatValue())
       
  4461                 m_style->setZoom(primitiveValue->getFloatValue());
       
  4462         }
       
  4463         
       
  4464         m_fontDirty = true;
       
  4465         return;
       
  4466     }
       
  4467 // shorthand properties
       
  4468     case CSSPropertyBackground:
       
  4469         if (isInitial) {
       
  4470             m_style->clearBackgroundLayers();
       
  4471             m_style->setBackgroundColor(Color());
       
  4472         }
       
  4473         else if (isInherit) {
       
  4474             m_style->inheritBackgroundLayers(*m_parentStyle->backgroundLayers());
       
  4475             m_style->setBackgroundColor(m_parentStyle->backgroundColor());
       
  4476         }
       
  4477         return;
       
  4478     case CSSPropertyWebkitMask:
       
  4479         if (isInitial)
       
  4480             m_style->clearMaskLayers();
       
  4481         else if (isInherit)
       
  4482             m_style->inheritMaskLayers(*m_parentStyle->maskLayers());
       
  4483         return;
       
  4484 
       
  4485     case CSSPropertyBorder:
       
  4486     case CSSPropertyBorderStyle:
       
  4487     case CSSPropertyBorderWidth:
       
  4488     case CSSPropertyBorderColor:
       
  4489         if (id == CSSPropertyBorder || id == CSSPropertyBorderColor)
       
  4490         {
       
  4491             if (isInherit) {
       
  4492                 m_style->setBorderTopColor(m_parentStyle->borderTopColor().isValid() ? m_parentStyle->borderTopColor() : m_parentStyle->color());
       
  4493                 m_style->setBorderBottomColor(m_parentStyle->borderBottomColor().isValid() ? m_parentStyle->borderBottomColor() : m_parentStyle->color());
       
  4494                 m_style->setBorderLeftColor(m_parentStyle->borderLeftColor().isValid() ? m_parentStyle->borderLeftColor() : m_parentStyle->color());
       
  4495                 m_style->setBorderRightColor(m_parentStyle->borderRightColor().isValid() ? m_parentStyle->borderRightColor(): m_parentStyle->color());
       
  4496             }
       
  4497             else if (isInitial) {
       
  4498                 m_style->setBorderTopColor(Color()); // Reset to invalid color so currentColor is used instead.
       
  4499                 m_style->setBorderBottomColor(Color());
       
  4500                 m_style->setBorderLeftColor(Color());
       
  4501                 m_style->setBorderRightColor(Color());
       
  4502             }
       
  4503         }
       
  4504         if (id == CSSPropertyBorder || id == CSSPropertyBorderStyle)
       
  4505         {
       
  4506             if (isInherit) {
       
  4507                 m_style->setBorderTopStyle(m_parentStyle->borderTopStyle());
       
  4508                 m_style->setBorderBottomStyle(m_parentStyle->borderBottomStyle());
       
  4509                 m_style->setBorderLeftStyle(m_parentStyle->borderLeftStyle());
       
  4510                 m_style->setBorderRightStyle(m_parentStyle->borderRightStyle());
       
  4511             }
       
  4512             else if (isInitial) {
       
  4513                 m_style->setBorderTopStyle(RenderStyle::initialBorderStyle());
       
  4514                 m_style->setBorderBottomStyle(RenderStyle::initialBorderStyle());
       
  4515                 m_style->setBorderLeftStyle(RenderStyle::initialBorderStyle());
       
  4516                 m_style->setBorderRightStyle(RenderStyle::initialBorderStyle());
       
  4517             }
       
  4518         }
       
  4519         if (id == CSSPropertyBorder || id == CSSPropertyBorderWidth)
       
  4520         {
       
  4521             if (isInherit) {
       
  4522                 m_style->setBorderTopWidth(m_parentStyle->borderTopWidth());
       
  4523                 m_style->setBorderBottomWidth(m_parentStyle->borderBottomWidth());
       
  4524                 m_style->setBorderLeftWidth(m_parentStyle->borderLeftWidth());
       
  4525                 m_style->setBorderRightWidth(m_parentStyle->borderRightWidth());
       
  4526             }
       
  4527             else if (isInitial) {
       
  4528                 m_style->setBorderTopWidth(RenderStyle::initialBorderWidth());
       
  4529                 m_style->setBorderBottomWidth(RenderStyle::initialBorderWidth());
       
  4530                 m_style->setBorderLeftWidth(RenderStyle::initialBorderWidth());
       
  4531                 m_style->setBorderRightWidth(RenderStyle::initialBorderWidth());
       
  4532             }
       
  4533         }
       
  4534         return;
       
  4535     case CSSPropertyBorderTop:
       
  4536         if (isInherit) {
       
  4537             m_style->setBorderTopColor(m_parentStyle->borderTopColor().isValid() ? m_parentStyle->borderTopColor() : m_parentStyle->color());
       
  4538             m_style->setBorderTopStyle(m_parentStyle->borderTopStyle());
       
  4539             m_style->setBorderTopWidth(m_parentStyle->borderTopWidth());
       
  4540         }
       
  4541         else if (isInitial)
       
  4542             m_style->resetBorderTop();
       
  4543         return;
       
  4544     case CSSPropertyBorderRight:
       
  4545         if (isInherit) {
       
  4546             m_style->setBorderRightColor(m_parentStyle->borderRightColor().isValid() ? m_parentStyle->borderRightColor() : m_parentStyle->color());
       
  4547             m_style->setBorderRightStyle(m_parentStyle->borderRightStyle());
       
  4548             m_style->setBorderRightWidth(m_parentStyle->borderRightWidth());
       
  4549         }
       
  4550         else if (isInitial)
       
  4551             m_style->resetBorderRight();
       
  4552         return;
       
  4553     case CSSPropertyBorderBottom:
       
  4554         if (isInherit) {
       
  4555             m_style->setBorderBottomColor(m_parentStyle->borderBottomColor().isValid() ? m_parentStyle->borderBottomColor() : m_parentStyle->color());
       
  4556             m_style->setBorderBottomStyle(m_parentStyle->borderBottomStyle());
       
  4557             m_style->setBorderBottomWidth(m_parentStyle->borderBottomWidth());
       
  4558         }
       
  4559         else if (isInitial)
       
  4560             m_style->resetBorderBottom();
       
  4561         return;
       
  4562     case CSSPropertyBorderLeft:
       
  4563         if (isInherit) {
       
  4564             m_style->setBorderLeftColor(m_parentStyle->borderLeftColor().isValid() ? m_parentStyle->borderLeftColor() : m_parentStyle->color());
       
  4565             m_style->setBorderLeftStyle(m_parentStyle->borderLeftStyle());
       
  4566             m_style->setBorderLeftWidth(m_parentStyle->borderLeftWidth());
       
  4567         }
       
  4568         else if (isInitial)
       
  4569             m_style->resetBorderLeft();
       
  4570         return;
       
  4571     case CSSPropertyMargin:
       
  4572         if (isInherit) {
       
  4573             m_style->setMarginTop(m_parentStyle->marginTop());
       
  4574             m_style->setMarginBottom(m_parentStyle->marginBottom());
       
  4575             m_style->setMarginLeft(m_parentStyle->marginLeft());
       
  4576             m_style->setMarginRight(m_parentStyle->marginRight());
       
  4577         }
       
  4578         else if (isInitial)
       
  4579             m_style->resetMargin();
       
  4580         return;
       
  4581     case CSSPropertyPadding:
       
  4582         if (isInherit) {
       
  4583             m_style->setPaddingTop(m_parentStyle->paddingTop());
       
  4584             m_style->setPaddingBottom(m_parentStyle->paddingBottom());
       
  4585             m_style->setPaddingLeft(m_parentStyle->paddingLeft());
       
  4586             m_style->setPaddingRight(m_parentStyle->paddingRight());
       
  4587         }
       
  4588         else if (isInitial)
       
  4589             m_style->resetPadding();
       
  4590         return;
       
  4591     case CSSPropertyFont:
       
  4592         if (isInherit) {
       
  4593             FontDescription fontDescription = m_parentStyle->fontDescription();
       
  4594             m_style->setLineHeight(m_parentStyle->lineHeight());
       
  4595             m_lineHeightValue = 0;
       
  4596             if (m_style->setFontDescription(fontDescription))
       
  4597                 m_fontDirty = true;
       
  4598         } else if (isInitial) {
       
  4599             Settings* settings = m_checker.m_document->settings();
       
  4600             ASSERT(settings); // If we're doing style resolution, this document should always be in a frame and thus have settings
       
  4601             if (!settings)
       
  4602                 return;
       
  4603             FontDescription fontDescription;
       
  4604             fontDescription.setGenericFamily(FontDescription::StandardFamily);
       
  4605             fontDescription.setRenderingMode(settings->fontRenderingMode());
       
  4606             fontDescription.setUsePrinterFont(m_checker.m_document->printing());
       
  4607             const AtomicString& standardFontFamily = m_checker.m_document->settings()->standardFontFamily();
       
  4608             if (!standardFontFamily.isEmpty()) {
       
  4609                 fontDescription.firstFamily().setFamily(standardFontFamily);
       
  4610                 fontDescription.firstFamily().appendFamily(0);
       
  4611             }
       
  4612             fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
       
  4613             setFontSize(fontDescription, fontSizeForKeyword(m_checker.m_document, CSSValueMedium, false));
       
  4614             m_style->setLineHeight(RenderStyle::initialLineHeight());
       
  4615             m_lineHeightValue = 0;
       
  4616             if (m_style->setFontDescription(fontDescription))
       
  4617                 m_fontDirty = true;
       
  4618         } else if (primitiveValue) {
       
  4619             m_style->setLineHeight(RenderStyle::initialLineHeight());
       
  4620             m_lineHeightValue = 0;
       
  4621             
       
  4622             FontDescription fontDescription;
       
  4623             RenderTheme::defaultTheme()->systemFont(primitiveValue->getIdent(), fontDescription);
       
  4624  
       
  4625             // Double-check and see if the theme did anything.  If not, don't bother updating the font.
       
  4626             if (fontDescription.isAbsoluteSize()) {
       
  4627                 // Make sure the rendering mode and printer font settings are updated.
       
  4628                 Settings* settings = m_checker.m_document->settings();
       
  4629                 ASSERT(settings); // If we're doing style resolution, this document should always be in a frame and thus have settings
       
  4630                 if (!settings)
       
  4631                     return;
       
  4632                 fontDescription.setRenderingMode(settings->fontRenderingMode());
       
  4633                 fontDescription.setUsePrinterFont(m_checker.m_document->printing());
       
  4634            
       
  4635                 // Handle the zoom factor.
       
  4636                 fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(m_checker.m_document, m_style.get(), fontDescription.isAbsoluteSize(), fontDescription.specifiedSize(), useSVGZoomRules));
       
  4637                 if (m_style->setFontDescription(fontDescription))
       
  4638                     m_fontDirty = true;
       
  4639             }
       
  4640         } else if (value->isFontValue()) {
       
  4641             FontValue *font = static_cast<FontValue*>(value);
       
  4642             if (!font->style || !font->variant || !font->weight ||
       
  4643                  !font->size || !font->lineHeight || !font->family)
       
  4644                 return;
       
  4645             applyProperty(CSSPropertyFontStyle, font->style.get());
       
  4646             applyProperty(CSSPropertyFontVariant, font->variant.get());
       
  4647             applyProperty(CSSPropertyFontWeight, font->weight.get());
       
  4648             applyProperty(CSSPropertyFontSize, font->size.get());
       
  4649 
       
  4650             m_lineHeightValue = font->lineHeight.get();
       
  4651 
       
  4652             applyProperty(CSSPropertyFontFamily, font->family.get());
       
  4653         }
       
  4654         return;
       
  4655         
       
  4656     case CSSPropertyListStyle:
       
  4657         if (isInherit) {
       
  4658             m_style->setListStyleType(m_parentStyle->listStyleType());
       
  4659             m_style->setListStyleImage(m_parentStyle->listStyleImage());
       
  4660             m_style->setListStylePosition(m_parentStyle->listStylePosition());
       
  4661         }
       
  4662         else if (isInitial) {
       
  4663             m_style->setListStyleType(RenderStyle::initialListStyleType());
       
  4664             m_style->setListStyleImage(RenderStyle::initialListStyleImage());
       
  4665             m_style->setListStylePosition(RenderStyle::initialListStylePosition());
       
  4666         }
       
  4667         return;
       
  4668     case CSSPropertyOutline:
       
  4669         if (isInherit) {
       
  4670             m_style->setOutlineWidth(m_parentStyle->outlineWidth());
       
  4671             m_style->setOutlineColor(m_parentStyle->outlineColor().isValid() ? m_parentStyle->outlineColor() : m_parentStyle->color());
       
  4672             m_style->setOutlineStyle(m_parentStyle->outlineStyle());
       
  4673         }
       
  4674         else if (isInitial)
       
  4675             m_style->resetOutline();
       
  4676         return;
       
  4677 
       
  4678     // CSS3 Properties
       
  4679     case CSSPropertyWebkitAppearance: {
       
  4680         HANDLE_INHERIT_AND_INITIAL(appearance, Appearance)
       
  4681         if (!primitiveValue)
       
  4682             return;
       
  4683         m_style->setAppearance(*primitiveValue);
       
  4684         return;
       
  4685     }
       
  4686     case CSSPropertyWebkitBinding: {
       
  4687 #if ENABLE(XBL)
       
  4688         if (isInitial || (primitiveValue && primitiveValue->getIdent() == CSSValueNone)) {
       
  4689             m_style->deleteBindingURIs();
       
  4690             return;
       
  4691         }
       
  4692         else if (isInherit) {
       
  4693             if (m_parentStyle->bindingURIs())
       
  4694                 m_style->inheritBindingURIs(m_parentStyle->bindingURIs());
       
  4695             else
       
  4696                 m_style->deleteBindingURIs();
       
  4697             return;
       
  4698         }
       
  4699 
       
  4700         if (!value->isValueList()) return;
       
  4701         CSSValueList* list = static_cast<CSSValueList*>(value);
       
  4702         bool firstBinding = true;
       
  4703         for (unsigned int i = 0; i < list->length(); i++) {
       
  4704             CSSValue *item = list->itemWithoutBoundsCheck(i);
       
  4705             CSSPrimitiveValue *val = static_cast<CSSPrimitiveValue*>(item);
       
  4706             if (val->primitiveType() == CSSPrimitiveValue::CSS_URI) {
       
  4707                 if (firstBinding) {
       
  4708                     firstBinding = false;
       
  4709                     m_style->deleteBindingURIs();
       
  4710                 }
       
  4711                 m_style->addBindingURI(val->getStringValue());
       
  4712             }
       
  4713         }
       
  4714 #endif
       
  4715         return;
       
  4716     }
       
  4717 
       
  4718     case CSSPropertyWebkitBorderImage:
       
  4719     case CSSPropertyWebkitMaskBoxImage: {
       
  4720         if (isInherit) {
       
  4721             HANDLE_INHERIT_COND(CSSPropertyWebkitBorderImage, borderImage, BorderImage)
       
  4722             HANDLE_INHERIT_COND(CSSPropertyWebkitMaskBoxImage, maskBoxImage, MaskBoxImage)
       
  4723             return;
       
  4724         } else if (isInitial) {
       
  4725             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyWebkitBorderImage, BorderImage, NinePieceImage)
       
  4726             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyWebkitMaskBoxImage, MaskBoxImage, NinePieceImage)
       
  4727             return;
       
  4728         }
       
  4729 
       
  4730         NinePieceImage image;
       
  4731         mapNinePieceImage(value, image);
       
  4732         
       
  4733         if (id == CSSPropertyWebkitBorderImage)
       
  4734             m_style->setBorderImage(image);
       
  4735         else
       
  4736             m_style->setMaskBoxImage(image);
       
  4737         return;
       
  4738     }
       
  4739 
       
  4740     case CSSPropertyBorderRadius:
       
  4741     case CSSPropertyWebkitBorderRadius:
       
  4742         if (isInherit) {
       
  4743             m_style->setBorderTopLeftRadius(m_parentStyle->borderTopLeftRadius());
       
  4744             m_style->setBorderTopRightRadius(m_parentStyle->borderTopRightRadius());
       
  4745             m_style->setBorderBottomLeftRadius(m_parentStyle->borderBottomLeftRadius());
       
  4746             m_style->setBorderBottomRightRadius(m_parentStyle->borderBottomRightRadius());
       
  4747             return;
       
  4748         }
       
  4749         if (isInitial) {
       
  4750             m_style->resetBorderRadius();
       
  4751             return;
       
  4752         }
       
  4753         // Fall through
       
  4754     case CSSPropertyBorderTopLeftRadius:
       
  4755     case CSSPropertyBorderTopRightRadius:
       
  4756     case CSSPropertyBorderBottomLeftRadius:
       
  4757     case CSSPropertyBorderBottomRightRadius: {
       
  4758         if (isInherit) {
       
  4759             HANDLE_INHERIT_COND(CSSPropertyBorderTopLeftRadius, borderTopLeftRadius, BorderTopLeftRadius)
       
  4760             HANDLE_INHERIT_COND(CSSPropertyBorderTopRightRadius, borderTopRightRadius, BorderTopRightRadius)
       
  4761             HANDLE_INHERIT_COND(CSSPropertyBorderBottomLeftRadius, borderBottomLeftRadius, BorderBottomLeftRadius)
       
  4762             HANDLE_INHERIT_COND(CSSPropertyBorderBottomRightRadius, borderBottomRightRadius, BorderBottomRightRadius)
       
  4763             return;
       
  4764         }
       
  4765         
       
  4766         if (isInitial) {
       
  4767             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyBorderTopLeftRadius, BorderTopLeftRadius, BorderRadius)
       
  4768             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyBorderTopRightRadius, BorderTopRightRadius, BorderRadius)
       
  4769             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyBorderBottomLeftRadius, BorderBottomLeftRadius, BorderRadius)
       
  4770             HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyBorderBottomRightRadius, BorderBottomRightRadius, BorderRadius)
       
  4771             return;
       
  4772         }
       
  4773 
       
  4774         if (!primitiveValue)
       
  4775             return;
       
  4776 
       
  4777         Pair* pair = primitiveValue->getPairValue();
       
  4778         if (!pair)
       
  4779             return;
       
  4780 
       
  4781         int width = pair->first()->computeLengthInt(style(), m_rootElementStyle, zoomFactor);
       
  4782         int height = pair->second()->computeLengthInt(style(), m_rootElementStyle,  zoomFactor);
       
  4783         if (width < 0 || height < 0)
       
  4784             return;
       
  4785 
       
  4786         if (width == 0)
       
  4787             height = 0; // Null out the other value.
       
  4788         else if (height == 0)
       
  4789             width = 0; // Null out the other value.
       
  4790 
       
  4791         IntSize size(width, height);
       
  4792         switch (id) {
       
  4793             case CSSPropertyBorderTopLeftRadius:
       
  4794                 m_style->setBorderTopLeftRadius(size);
       
  4795                 break;
       
  4796             case CSSPropertyBorderTopRightRadius:
       
  4797                 m_style->setBorderTopRightRadius(size);
       
  4798                 break;
       
  4799             case CSSPropertyBorderBottomLeftRadius:
       
  4800                 m_style->setBorderBottomLeftRadius(size);
       
  4801                 break;
       
  4802             case CSSPropertyBorderBottomRightRadius:
       
  4803                 m_style->setBorderBottomRightRadius(size);
       
  4804                 break;
       
  4805             default:
       
  4806                 m_style->setBorderRadius(size);
       
  4807                 break;
       
  4808         }
       
  4809         return;
       
  4810     }
       
  4811 
       
  4812     case CSSPropertyOutlineOffset:
       
  4813         HANDLE_INHERIT_AND_INITIAL(outlineOffset, OutlineOffset)
       
  4814         m_style->setOutlineOffset(primitiveValue->computeLengthInt(style(), m_rootElementStyle, zoomFactor));
       
  4815         return;
       
  4816     case CSSPropertyTextRendering: {
       
  4817         FontDescription fontDescription = m_style->fontDescription();
       
  4818         if (isInherit) 
       
  4819             fontDescription.setTextRenderingMode(m_parentStyle->fontDescription().textRenderingMode());
       
  4820         else if (isInitial)
       
  4821             fontDescription.setTextRenderingMode(AutoTextRendering);
       
  4822         else {
       
  4823             if (!primitiveValue)
       
  4824                 return;
       
  4825             fontDescription.setTextRenderingMode(*primitiveValue);
       
  4826         }
       
  4827         if (m_style->setFontDescription(fontDescription))
       
  4828             m_fontDirty = true;
       
  4829         return;
       
  4830     }
       
  4831     case CSSPropertyTextShadow:
       
  4832     case CSSPropertyWebkitBoxShadow: {
       
  4833         if (isInherit) {
       
  4834             if (id == CSSPropertyTextShadow)
       
  4835                 return m_style->setTextShadow(m_parentStyle->textShadow() ? new ShadowData(*m_parentStyle->textShadow()) : 0);
       
  4836             return m_style->setBoxShadow(m_parentStyle->boxShadow() ? new ShadowData(*m_parentStyle->boxShadow()) : 0);
       
  4837         }
       
  4838         if (isInitial || primitiveValue) // initial | none
       
  4839             return id == CSSPropertyTextShadow ? m_style->setTextShadow(0) : m_style->setBoxShadow(0);
       
  4840 
       
  4841         if (!value->isValueList())
       
  4842             return;
       
  4843 
       
  4844         CSSValueList *list = static_cast<CSSValueList*>(value);
       
  4845         int len = list->length();
       
  4846         for (int i = 0; i < len; i++) {
       
  4847             ShadowValue* item = static_cast<ShadowValue*>(list->itemWithoutBoundsCheck(i));
       
  4848             int x = item->x->computeLengthInt(style(), m_rootElementStyle, zoomFactor);
       
  4849             int y = item->y->computeLengthInt(style(), m_rootElementStyle, zoomFactor);
       
  4850             int blur = item->blur ? item->blur->computeLengthInt(style(), m_rootElementStyle, zoomFactor) : 0;
       
  4851             int spread = item->spread ? item->spread->computeLengthInt(style(), m_rootElementStyle, zoomFactor) : 0;
       
  4852             ShadowStyle shadowStyle = item->style && item->style->getIdent() == CSSValueInset ? Inset : Normal;
       
  4853             Color color;
       
  4854             if (item->color)
       
  4855                 color = getColorFromPrimitiveValue(item->color.get());
       
  4856             ShadowData* shadowData = new ShadowData(x, y, blur, spread, shadowStyle, color.isValid() ? color : Color::transparent);
       
  4857             if (id == CSSPropertyTextShadow)
       
  4858                 m_style->setTextShadow(shadowData, i != 0);
       
  4859             else
       
  4860                 m_style->setBoxShadow(shadowData, i != 0);
       
  4861         }
       
  4862         return;
       
  4863     }
       
  4864     case CSSPropertyWebkitBoxReflect: {
       
  4865         HANDLE_INHERIT_AND_INITIAL(boxReflect, BoxReflect)
       
  4866         if (primitiveValue) {
       
  4867             m_style->setBoxReflect(RenderStyle::initialBoxReflect());
       
  4868             return;
       
  4869         }
       
  4870         CSSReflectValue* reflectValue = static_cast<CSSReflectValue*>(value);
       
  4871         RefPtr<StyleReflection> reflection = StyleReflection::create();
       
  4872         reflection->setDirection(reflectValue->direction());
       
  4873         if (reflectValue->offset()) {
       
  4874             int type = reflectValue->offset()->primitiveType();
       
  4875             if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  4876                 reflection->setOffset(Length(reflectValue->offset()->getDoubleValue(), Percent));
       
  4877             else
       
  4878                 reflection->setOffset(Length(reflectValue->offset()->computeLengthIntForLength(style(), m_rootElementStyle, zoomFactor), Fixed));
       
  4879         }
       
  4880         NinePieceImage mask;
       
  4881         mapNinePieceImage(reflectValue->mask(), mask);
       
  4882         reflection->setMask(mask);
       
  4883         
       
  4884         m_style->setBoxReflect(reflection.release());
       
  4885         return;
       
  4886     }
       
  4887     case CSSPropertyOpacity:
       
  4888         HANDLE_INHERIT_AND_INITIAL(opacity, Opacity)
       
  4889         if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
       
  4890             return; // Error case.
       
  4891         // Clamp opacity to the range 0-1
       
  4892         m_style->setOpacity(min(1.0f, max(0.0f, primitiveValue->getFloatValue())));
       
  4893         return;
       
  4894     case CSSPropertyWebkitBoxAlign:
       
  4895     {
       
  4896         HANDLE_INHERIT_AND_INITIAL(boxAlign, BoxAlign)
       
  4897         if (!primitiveValue)
       
  4898             return;
       
  4899         EBoxAlignment boxAlignment = *primitiveValue;
       
  4900         if (boxAlignment != BJUSTIFY)
       
  4901             m_style->setBoxAlign(boxAlignment);
       
  4902         return;
       
  4903     }
       
  4904     case CSSPropertySrc: // Only used in @font-face rules.
       
  4905         return;
       
  4906     case CSSPropertyUnicodeRange: // Only used in @font-face rules.
       
  4907         return;
       
  4908     case CSSPropertyWebkitBackfaceVisibility:
       
  4909         HANDLE_INHERIT_AND_INITIAL(backfaceVisibility, BackfaceVisibility)
       
  4910         if (primitiveValue)
       
  4911             m_style->setBackfaceVisibility((primitiveValue->getIdent() == CSSValueVisible) ? BackfaceVisibilityVisible : BackfaceVisibilityHidden);
       
  4912         return;
       
  4913     case CSSPropertyWebkitBoxDirection:
       
  4914         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(boxDirection, BoxDirection)
       
  4915         return;
       
  4916     case CSSPropertyWebkitBoxLines:
       
  4917         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(boxLines, BoxLines)
       
  4918         return;
       
  4919     case CSSPropertyWebkitBoxOrient:
       
  4920         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(boxOrient, BoxOrient)
       
  4921         return;
       
  4922     case CSSPropertyWebkitBoxPack:
       
  4923     {
       
  4924         HANDLE_INHERIT_AND_INITIAL(boxPack, BoxPack)
       
  4925         if (!primitiveValue)
       
  4926             return;
       
  4927         EBoxAlignment boxPack = *primitiveValue;
       
  4928         if (boxPack != BSTRETCH && boxPack != BBASELINE)
       
  4929             m_style->setBoxPack(boxPack);
       
  4930         return;
       
  4931     }
       
  4932     case CSSPropertyWebkitBoxFlex:
       
  4933         HANDLE_INHERIT_AND_INITIAL(boxFlex, BoxFlex)
       
  4934         if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
       
  4935             return; // Error case.
       
  4936         m_style->setBoxFlex(primitiveValue->getFloatValue());
       
  4937         return;
       
  4938     case CSSPropertyWebkitBoxFlexGroup:
       
  4939         HANDLE_INHERIT_AND_INITIAL(boxFlexGroup, BoxFlexGroup)
       
  4940         if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
       
  4941             return; // Error case.
       
  4942         m_style->setBoxFlexGroup((unsigned int)(primitiveValue->getDoubleValue()));
       
  4943         return;
       
  4944     case CSSPropertyWebkitBoxOrdinalGroup:
       
  4945         HANDLE_INHERIT_AND_INITIAL(boxOrdinalGroup, BoxOrdinalGroup)
       
  4946         if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
       
  4947             return; // Error case.
       
  4948         m_style->setBoxOrdinalGroup((unsigned int)(primitiveValue->getDoubleValue()));
       
  4949         return;
       
  4950     case CSSPropertyWebkitBoxSizing:
       
  4951         HANDLE_INHERIT_AND_INITIAL(boxSizing, BoxSizing)
       
  4952         if (!primitiveValue)
       
  4953             return;
       
  4954         if (primitiveValue->getIdent() == CSSValueContentBox)
       
  4955             m_style->setBoxSizing(CONTENT_BOX);
       
  4956         else
       
  4957             m_style->setBoxSizing(BORDER_BOX);
       
  4958         return;
       
  4959     case CSSPropertyWebkitColumnCount: {
       
  4960         if (isInherit) {
       
  4961             if (m_parentStyle->hasAutoColumnCount())
       
  4962                 m_style->setHasAutoColumnCount();
       
  4963             else
       
  4964                 m_style->setColumnCount(m_parentStyle->columnCount());
       
  4965             return;
       
  4966         } else if (isInitial || primitiveValue->getIdent() == CSSValueAuto) {
       
  4967             m_style->setHasAutoColumnCount();
       
  4968             return;
       
  4969         }
       
  4970         m_style->setColumnCount(static_cast<unsigned short>(primitiveValue->getDoubleValue()));
       
  4971         return;
       
  4972     }
       
  4973     case CSSPropertyWebkitColumnGap: {
       
  4974         if (isInherit) {
       
  4975             if (m_parentStyle->hasNormalColumnGap())
       
  4976                 m_style->setHasNormalColumnGap();
       
  4977             else
       
  4978                 m_style->setColumnGap(m_parentStyle->columnGap());
       
  4979             return;
       
  4980         } else if (isInitial || primitiveValue->getIdent() == CSSValueNormal) {
       
  4981             m_style->setHasNormalColumnGap();
       
  4982             return;
       
  4983         }
       
  4984         m_style->setColumnGap(primitiveValue->computeLengthFloat(style(), m_rootElementStyle, zoomFactor));
       
  4985         return;
       
  4986     }
       
  4987     case CSSPropertyWebkitColumnSpan: {
       
  4988         HANDLE_INHERIT_AND_INITIAL(columnSpan, ColumnSpan)
       
  4989         m_style->setColumnSpan(primitiveValue->getIdent() == CSSValueAll);
       
  4990         return;
       
  4991     }
       
  4992     case CSSPropertyWebkitColumnWidth: {
       
  4993         if (isInherit) {
       
  4994             if (m_parentStyle->hasAutoColumnWidth())
       
  4995                 m_style->setHasAutoColumnWidth();
       
  4996             else
       
  4997                 m_style->setColumnWidth(m_parentStyle->columnWidth());
       
  4998             return;
       
  4999         } else if (isInitial || primitiveValue->getIdent() == CSSValueAuto) {
       
  5000             m_style->setHasAutoColumnWidth();
       
  5001             return;
       
  5002         }
       
  5003         m_style->setColumnWidth(primitiveValue->computeLengthFloat(style(), m_rootElementStyle, zoomFactor));
       
  5004         return;
       
  5005     }
       
  5006     case CSSPropertyWebkitColumnRuleStyle:
       
  5007         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(columnRuleStyle, ColumnRuleStyle, BorderStyle)
       
  5008         return;
       
  5009     case CSSPropertyWebkitColumnBreakBefore:
       
  5010         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(columnBreakBefore, ColumnBreakBefore, PageBreak)
       
  5011         return;
       
  5012     case CSSPropertyWebkitColumnBreakAfter:
       
  5013         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(columnBreakAfter, ColumnBreakAfter, PageBreak)
       
  5014         return;
       
  5015     case CSSPropertyWebkitColumnBreakInside: {
       
  5016         HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(columnBreakInside, ColumnBreakInside, PageBreak)
       
  5017         EPageBreak pb = *primitiveValue;
       
  5018         if (pb != PBALWAYS)
       
  5019             m_style->setColumnBreakInside(pb);
       
  5020         return;
       
  5021     }
       
  5022      case CSSPropertyWebkitColumnRule:
       
  5023         if (isInherit) {
       
  5024             m_style->setColumnRuleColor(m_parentStyle->columnRuleColor().isValid() ? m_parentStyle->columnRuleColor() : m_parentStyle->color());
       
  5025             m_style->setColumnRuleStyle(m_parentStyle->columnRuleStyle());
       
  5026             m_style->setColumnRuleWidth(m_parentStyle->columnRuleWidth());
       
  5027         }
       
  5028         else if (isInitial)
       
  5029             m_style->resetColumnRule();
       
  5030         return;
       
  5031     case CSSPropertyWebkitColumns:
       
  5032         if (isInherit) {
       
  5033             if (m_parentStyle->hasAutoColumnWidth())
       
  5034                 m_style->setHasAutoColumnWidth();
       
  5035             else
       
  5036                 m_style->setColumnWidth(m_parentStyle->columnWidth());
       
  5037             m_style->setColumnCount(m_parentStyle->columnCount());
       
  5038         } else if (isInitial) {
       
  5039             m_style->setHasAutoColumnWidth();
       
  5040             m_style->setColumnCount(RenderStyle::initialColumnCount());
       
  5041         }
       
  5042         return;
       
  5043     case CSSPropertyWebkitMarquee:
       
  5044         if (valueType != CSSValue::CSS_INHERIT || !m_parentNode) return;
       
  5045         m_style->setMarqueeDirection(m_parentStyle->marqueeDirection());
       
  5046         m_style->setMarqueeIncrement(m_parentStyle->marqueeIncrement());
       
  5047         m_style->setMarqueeSpeed(m_parentStyle->marqueeSpeed());
       
  5048         m_style->setMarqueeLoopCount(m_parentStyle->marqueeLoopCount());
       
  5049         m_style->setMarqueeBehavior(m_parentStyle->marqueeBehavior());
       
  5050         return;
       
  5051 #if ENABLE(WCSS)
       
  5052     case CSSPropertyWapMarqueeLoop:
       
  5053 #endif
       
  5054     case CSSPropertyWebkitMarqueeRepetition: {
       
  5055         HANDLE_INHERIT_AND_INITIAL(marqueeLoopCount, MarqueeLoopCount)
       
  5056         if (!primitiveValue)
       
  5057             return;
       
  5058         if (primitiveValue->getIdent() == CSSValueInfinite)
       
  5059             m_style->setMarqueeLoopCount(-1); // -1 means repeat forever.
       
  5060         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
       
  5061             m_style->setMarqueeLoopCount(primitiveValue->getIntValue());
       
  5062         return;
       
  5063     }
       
  5064 #if ENABLE(WCSS)
       
  5065     case CSSPropertyWapMarqueeSpeed:
       
  5066 #endif
       
  5067     case CSSPropertyWebkitMarqueeSpeed: {
       
  5068         HANDLE_INHERIT_AND_INITIAL(marqueeSpeed, MarqueeSpeed)      
       
  5069         if (!primitiveValue)
       
  5070             return;
       
  5071         if (primitiveValue->getIdent()) {
       
  5072             switch (primitiveValue->getIdent()) {
       
  5073                 case CSSValueSlow:
       
  5074                     m_style->setMarqueeSpeed(500); // 500 msec.
       
  5075                     break;
       
  5076                 case CSSValueNormal:
       
  5077                     m_style->setMarqueeSpeed(85); // 85msec. The WinIE default.
       
  5078                     break;
       
  5079                 case CSSValueFast:
       
  5080                     m_style->setMarqueeSpeed(10); // 10msec. Super fast.
       
  5081                     break;
       
  5082             }
       
  5083         }
       
  5084         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_S)
       
  5085             m_style->setMarqueeSpeed(1000 * primitiveValue->getIntValue());
       
  5086         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_MS)
       
  5087             m_style->setMarqueeSpeed(primitiveValue->getIntValue());
       
  5088         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) // For scrollamount support.
       
  5089             m_style->setMarqueeSpeed(primitiveValue->getIntValue());
       
  5090         return;
       
  5091     }
       
  5092     case CSSPropertyWebkitMarqueeIncrement: {
       
  5093         HANDLE_INHERIT_AND_INITIAL(marqueeIncrement, MarqueeIncrement)
       
  5094         if (!primitiveValue)
       
  5095             return;
       
  5096         if (primitiveValue->getIdent()) {
       
  5097             switch (primitiveValue->getIdent()) {
       
  5098                 case CSSValueSmall:
       
  5099                     m_style->setMarqueeIncrement(Length(1, Fixed)); // 1px.
       
  5100                     break;
       
  5101                 case CSSValueNormal:
       
  5102                     m_style->setMarqueeIncrement(Length(6, Fixed)); // 6px. The WinIE default.
       
  5103                     break;
       
  5104                 case CSSValueLarge:
       
  5105                     m_style->setMarqueeIncrement(Length(36, Fixed)); // 36px.
       
  5106                     break;
       
  5107             }
       
  5108         }
       
  5109         else {
       
  5110             bool ok = true;
       
  5111             Length l = convertToLength(primitiveValue, style(), m_rootElementStyle, 1, &ok);
       
  5112             if (ok)
       
  5113                 m_style->setMarqueeIncrement(l);
       
  5114         }
       
  5115         return;
       
  5116     }
       
  5117 #if ENABLE(WCSS)
       
  5118     case CSSPropertyWapMarqueeStyle:
       
  5119 #endif
       
  5120     case CSSPropertyWebkitMarqueeStyle:
       
  5121         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(marqueeBehavior, MarqueeBehavior)      
       
  5122         return;
       
  5123 #if ENABLE(WCSS)
       
  5124     case CSSPropertyWapMarqueeDir:
       
  5125         HANDLE_INHERIT_AND_INITIAL(marqueeDirection, MarqueeDirection)
       
  5126         if (primitiveValue && primitiveValue->getIdent()) {
       
  5127             switch (primitiveValue->getIdent()) {
       
  5128             case CSSValueLtr:
       
  5129                 m_style->setMarqueeDirection(MRIGHT);
       
  5130                 break;
       
  5131             case CSSValueRtl:
       
  5132                 m_style->setMarqueeDirection(MLEFT);
       
  5133                 break;
       
  5134             default:
       
  5135                 m_style->setMarqueeDirection(*primitiveValue);
       
  5136                 break;
       
  5137             }
       
  5138         }
       
  5139         return;
       
  5140 #endif
       
  5141     case CSSPropertyWebkitMarqueeDirection:
       
  5142         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(marqueeDirection, MarqueeDirection)
       
  5143         return;
       
  5144     case CSSPropertyWebkitUserDrag:
       
  5145         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(userDrag, UserDrag)      
       
  5146         return;
       
  5147     case CSSPropertyWebkitUserModify:
       
  5148         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(userModify, UserModify)      
       
  5149         return;
       
  5150     case CSSPropertyWebkitUserSelect:
       
  5151         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(userSelect, UserSelect)      
       
  5152         return;
       
  5153 
       
  5154     case CSSPropertyTextOverflow: {
       
  5155         // This property is supported by WinIE, and so we leave off the "-webkit-" in order to
       
  5156         // work with WinIE-specific pages that use the property.
       
  5157         HANDLE_INHERIT_AND_INITIAL(textOverflow, TextOverflow)
       
  5158         if (!primitiveValue || !primitiveValue->getIdent())
       
  5159             return;
       
  5160         m_style->setTextOverflow(primitiveValue->getIdent() == CSSValueEllipsis);
       
  5161         return;
       
  5162     }
       
  5163     case CSSPropertyWebkitMarginCollapse: {
       
  5164         if (isInherit) {
       
  5165             m_style->setMarginTopCollapse(m_parentStyle->marginTopCollapse());
       
  5166             m_style->setMarginBottomCollapse(m_parentStyle->marginBottomCollapse());
       
  5167         }
       
  5168         else if (isInitial) {
       
  5169             m_style->setMarginTopCollapse(MCOLLAPSE);
       
  5170             m_style->setMarginBottomCollapse(MCOLLAPSE);
       
  5171         }
       
  5172         return;
       
  5173     }
       
  5174 
       
  5175     case CSSPropertyWebkitMarginTopCollapse:
       
  5176         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(marginTopCollapse, MarginTopCollapse)
       
  5177         return;
       
  5178     case CSSPropertyWebkitMarginBottomCollapse:
       
  5179         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(marginBottomCollapse, MarginBottomCollapse)
       
  5180         return;
       
  5181     case CSSPropertyWebkitLineClamp: {
       
  5182         HANDLE_INHERIT_AND_INITIAL(lineClamp, LineClamp)
       
  5183         if (!primitiveValue)
       
  5184             return;
       
  5185         int type = primitiveValue->primitiveType();
       
  5186         if (type == CSSPrimitiveValue::CSS_NUMBER)
       
  5187             m_style->setLineClamp(LineClampValue(primitiveValue->getIntValue(CSSPrimitiveValue::CSS_NUMBER), LineClampLineCount));
       
  5188         else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  5189             m_style->setLineClamp(LineClampValue(primitiveValue->getIntValue(CSSPrimitiveValue::CSS_PERCENTAGE), LineClampPercentage));
       
  5190         return;
       
  5191     }
       
  5192     case CSSPropertyWebkitHighlight: {
       
  5193         HANDLE_INHERIT_AND_INITIAL(highlight, Highlight);
       
  5194         if (primitiveValue->getIdent() == CSSValueNone)
       
  5195             m_style->setHighlight(nullAtom);
       
  5196         else
       
  5197             m_style->setHighlight(primitiveValue->getStringValue());
       
  5198         return;
       
  5199     }
       
  5200     case CSSPropertyWebkitHyphens: {
       
  5201         HANDLE_INHERIT_AND_INITIAL(hyphens, Hyphens);
       
  5202         m_style->setHyphens(*primitiveValue);
       
  5203         return;
       
  5204     }
       
  5205     case CSSPropertyWebkitHyphenateCharacter: {
       
  5206         HANDLE_INHERIT_AND_INITIAL(hyphenateCharacter, HyphenateCharacter);
       
  5207         if (primitiveValue->getIdent() == CSSValueAuto)
       
  5208             m_style->setHyphenateCharacter(nullAtom);
       
  5209         else
       
  5210             m_style->setHyphenateCharacter(primitiveValue->getStringValue());
       
  5211         return;
       
  5212     }
       
  5213     case CSSPropertyWebkitBorderFit: {
       
  5214         HANDLE_INHERIT_AND_INITIAL(borderFit, BorderFit);
       
  5215         if (primitiveValue->getIdent() == CSSValueBorder)
       
  5216             m_style->setBorderFit(BorderFitBorder);
       
  5217         else
       
  5218             m_style->setBorderFit(BorderFitLines);
       
  5219         return;
       
  5220     }
       
  5221     case CSSPropertyWebkitTextSizeAdjust: {
       
  5222         HANDLE_INHERIT_AND_INITIAL(textSizeAdjust, TextSizeAdjust)
       
  5223         if (!primitiveValue || !primitiveValue->getIdent()) return;
       
  5224         m_style->setTextSizeAdjust(primitiveValue->getIdent() == CSSValueAuto);
       
  5225         m_fontDirty = true;
       
  5226         return;
       
  5227     }
       
  5228     case CSSPropertyWebkitTextSecurity:
       
  5229         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(textSecurity, TextSecurity)
       
  5230         return;
       
  5231 
       
  5232 #if ENABLE(DASHBOARD_SUPPORT)
       
  5233     case CSSPropertyWebkitDashboardRegion: {
       
  5234         HANDLE_INHERIT_AND_INITIAL(dashboardRegions, DashboardRegions)
       
  5235         if (!primitiveValue)
       
  5236             return;
       
  5237 
       
  5238         if (primitiveValue->getIdent() == CSSValueNone) {
       
  5239             m_style->setDashboardRegions(RenderStyle::noneDashboardRegions());
       
  5240             return;
       
  5241         }
       
  5242 
       
  5243         DashboardRegion *region = primitiveValue->getDashboardRegionValue();
       
  5244         if (!region)
       
  5245             return;
       
  5246             
       
  5247         DashboardRegion *first = region;
       
  5248         while (region) {
       
  5249             Length top = convertToLength(region->top(), style(), m_rootElementStyle);
       
  5250             Length right = convertToLength(region->right(), style(), m_rootElementStyle);
       
  5251             Length bottom = convertToLength(region->bottom(), style(), m_rootElementStyle);
       
  5252             Length left = convertToLength(region->left(), style(), m_rootElementStyle);
       
  5253             if (region->m_isCircle)
       
  5254                 m_style->setDashboardRegion(StyleDashboardRegion::Circle, region->m_label, top, right, bottom, left, region == first ? false : true);
       
  5255             else if (region->m_isRectangle)
       
  5256                 m_style->setDashboardRegion(StyleDashboardRegion::Rectangle, region->m_label, top, right, bottom, left, region == first ? false : true);
       
  5257             region = region->m_next.get();
       
  5258         }
       
  5259         
       
  5260         m_element->document()->setHasDashboardRegions(true);
       
  5261         
       
  5262         return;
       
  5263     }
       
  5264 #endif        
       
  5265     case CSSPropertyWebkitRtlOrdering:
       
  5266         HANDLE_INHERIT_AND_INITIAL(visuallyOrdered, VisuallyOrdered)
       
  5267         if (!primitiveValue || !primitiveValue->getIdent())
       
  5268             return;
       
  5269         m_style->setVisuallyOrdered(primitiveValue->getIdent() == CSSValueVisual);
       
  5270         return;
       
  5271     case CSSPropertyWebkitTextStrokeWidth: {
       
  5272         HANDLE_INHERIT_AND_INITIAL(textStrokeWidth, TextStrokeWidth)
       
  5273         float width = 0;
       
  5274         switch (primitiveValue->getIdent()) {
       
  5275             case CSSValueThin:
       
  5276             case CSSValueMedium:
       
  5277             case CSSValueThick: {
       
  5278                 double result = 1.0 / 48;
       
  5279                 if (primitiveValue->getIdent() == CSSValueMedium)
       
  5280                     result *= 3;
       
  5281                 else if (primitiveValue->getIdent() == CSSValueThick)
       
  5282                     result *= 5;
       
  5283                 width = CSSPrimitiveValue::create(result, CSSPrimitiveValue::CSS_EMS)->computeLengthFloat(style(), m_rootElementStyle, zoomFactor);
       
  5284                 break;
       
  5285             }
       
  5286             default:
       
  5287                 width = primitiveValue->computeLengthFloat(style(), m_rootElementStyle, zoomFactor);
       
  5288                 break;
       
  5289         }
       
  5290         m_style->setTextStrokeWidth(width);
       
  5291         return;
       
  5292     }
       
  5293     case CSSPropertyWebkitTransform: {
       
  5294         HANDLE_INHERIT_AND_INITIAL(transform, Transform);
       
  5295         TransformOperations operations;
       
  5296         createTransformOperations(value, style(), m_rootElementStyle, operations);
       
  5297         m_style->setTransform(operations);
       
  5298         return;
       
  5299     }
       
  5300     case CSSPropertyWebkitTransformOrigin:
       
  5301         HANDLE_INHERIT_AND_INITIAL(transformOriginX, TransformOriginX)
       
  5302         HANDLE_INHERIT_AND_INITIAL(transformOriginY, TransformOriginY)
       
  5303         HANDLE_INHERIT_AND_INITIAL(transformOriginZ, TransformOriginZ)
       
  5304         return;
       
  5305     case CSSPropertyWebkitTransformOriginX: {
       
  5306         HANDLE_INHERIT_AND_INITIAL(transformOriginX, TransformOriginX)
       
  5307         CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5308         Length l;
       
  5309         int type = primitiveValue->primitiveType();
       
  5310         if (CSSPrimitiveValue::isUnitTypeLength(type))
       
  5311             l = Length(primitiveValue->computeLengthIntForLength(style(), m_rootElementStyle, zoomFactor), Fixed);
       
  5312         else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  5313             l = Length(primitiveValue->getDoubleValue(), Percent);
       
  5314         else
       
  5315             return;
       
  5316         m_style->setTransformOriginX(l);
       
  5317         break;
       
  5318     }
       
  5319     case CSSPropertyWebkitTransformOriginY: {
       
  5320         HANDLE_INHERIT_AND_INITIAL(transformOriginY, TransformOriginY)
       
  5321         CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5322         Length l;
       
  5323         int type = primitiveValue->primitiveType();
       
  5324         if (CSSPrimitiveValue::isUnitTypeLength(type))
       
  5325             l = Length(primitiveValue->computeLengthIntForLength(style(), m_rootElementStyle, zoomFactor), Fixed);
       
  5326         else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  5327             l = Length(primitiveValue->getDoubleValue(), Percent);
       
  5328         else
       
  5329             return;
       
  5330         m_style->setTransformOriginY(l);
       
  5331         break;
       
  5332     }
       
  5333     case CSSPropertyWebkitTransformOriginZ: {
       
  5334         HANDLE_INHERIT_AND_INITIAL(transformOriginZ, TransformOriginZ)
       
  5335         CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5336         float f;
       
  5337         int type = primitiveValue->primitiveType();
       
  5338         if (CSSPrimitiveValue::isUnitTypeLength(type))
       
  5339             f = static_cast<float>(primitiveValue->computeLengthIntForLength(style(), m_rootElementStyle));
       
  5340         else
       
  5341             return;
       
  5342         m_style->setTransformOriginZ(f);
       
  5343         break;
       
  5344     }
       
  5345     case CSSPropertyWebkitTransformStyle:
       
  5346         HANDLE_INHERIT_AND_INITIAL(transformStyle3D, TransformStyle3D)
       
  5347         if (primitiveValue)
       
  5348             m_style->setTransformStyle3D((primitiveValue->getIdent() == CSSValuePreserve3d) ? TransformStyle3DPreserve3D : TransformStyle3DFlat);
       
  5349         return;
       
  5350     case CSSPropertyWebkitPerspective: {
       
  5351         HANDLE_INHERIT_AND_INITIAL(perspective, Perspective)
       
  5352         if (primitiveValue && primitiveValue->getIdent() == CSSValueNone) {
       
  5353             m_style->setPerspective(0);
       
  5354             return;
       
  5355         }
       
  5356         
       
  5357         float perspectiveValue;
       
  5358         int type = primitiveValue->primitiveType();
       
  5359         if (CSSPrimitiveValue::isUnitTypeLength(type))
       
  5360             perspectiveValue = static_cast<float>(primitiveValue->computeLengthIntForLength(style(), m_rootElementStyle, zoomFactor));
       
  5361         else if (type == CSSPrimitiveValue::CSS_NUMBER) {
       
  5362             // For backward compatibility, treat valueless numbers as px.
       
  5363             perspectiveValue = CSSPrimitiveValue::create(primitiveValue->getDoubleValue(), CSSPrimitiveValue::CSS_PX)->computeLengthFloat(style(), m_rootElementStyle, zoomFactor);
       
  5364         } else
       
  5365             return;
       
  5366 
       
  5367         if (perspectiveValue >= 0.0f)
       
  5368             m_style->setPerspective(perspectiveValue);
       
  5369         return;
       
  5370     }
       
  5371     case CSSPropertyWebkitPerspectiveOrigin:
       
  5372         HANDLE_INHERIT_AND_INITIAL(perspectiveOriginX, PerspectiveOriginX)
       
  5373         HANDLE_INHERIT_AND_INITIAL(perspectiveOriginY, PerspectiveOriginY)
       
  5374         return;
       
  5375     case CSSPropertyWebkitPerspectiveOriginX: {
       
  5376         HANDLE_INHERIT_AND_INITIAL(perspectiveOriginX, PerspectiveOriginX)
       
  5377         CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5378         Length l;
       
  5379         int type = primitiveValue->primitiveType();
       
  5380         if (CSSPrimitiveValue::isUnitTypeLength(type))
       
  5381             l = Length(primitiveValue->computeLengthIntForLength(style(), m_rootElementStyle, zoomFactor), Fixed);
       
  5382         else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  5383             l = Length(primitiveValue->getDoubleValue(), Percent);
       
  5384         else
       
  5385             return;
       
  5386         m_style->setPerspectiveOriginX(l);
       
  5387         return;
       
  5388     }
       
  5389     case CSSPropertyWebkitPerspectiveOriginY: {
       
  5390         HANDLE_INHERIT_AND_INITIAL(perspectiveOriginY, PerspectiveOriginY)
       
  5391         CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5392         Length l;
       
  5393         int type = primitiveValue->primitiveType();
       
  5394         if (CSSPrimitiveValue::isUnitTypeLength(type))
       
  5395             l = Length(primitiveValue->computeLengthIntForLength(style(), m_rootElementStyle, zoomFactor), Fixed);
       
  5396         else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  5397             l = Length(primitiveValue->getDoubleValue(), Percent);
       
  5398         else
       
  5399             return;
       
  5400         m_style->setPerspectiveOriginY(l);
       
  5401         return;
       
  5402     }
       
  5403     case CSSPropertyWebkitAnimation:
       
  5404         if (isInitial)
       
  5405             m_style->clearAnimations();
       
  5406         else if (isInherit)
       
  5407             m_style->inheritAnimations(m_parentStyle->animations());
       
  5408         return;
       
  5409     case CSSPropertyWebkitAnimationDelay:
       
  5410         HANDLE_ANIMATION_VALUE(delay, Delay, value)
       
  5411         return;
       
  5412     case CSSPropertyWebkitAnimationDirection:
       
  5413         HANDLE_ANIMATION_VALUE(direction, Direction, value)
       
  5414         return;
       
  5415     case CSSPropertyWebkitAnimationDuration:
       
  5416         HANDLE_ANIMATION_VALUE(duration, Duration, value)
       
  5417         return;
       
  5418     case CSSPropertyWebkitAnimationFillMode:
       
  5419         HANDLE_ANIMATION_VALUE(fillMode, FillMode, value)
       
  5420         return;
       
  5421     case CSSPropertyWebkitAnimationIterationCount:
       
  5422         HANDLE_ANIMATION_VALUE(iterationCount, IterationCount, value)
       
  5423         return;
       
  5424     case CSSPropertyWebkitAnimationName:
       
  5425         HANDLE_ANIMATION_VALUE(name, Name, value)
       
  5426         return;
       
  5427     case CSSPropertyWebkitAnimationPlayState:
       
  5428         HANDLE_ANIMATION_VALUE(playState, PlayState, value)
       
  5429         return;
       
  5430     case CSSPropertyWebkitAnimationTimingFunction:
       
  5431         HANDLE_ANIMATION_VALUE(timingFunction, TimingFunction, value)
       
  5432         return;
       
  5433     case CSSPropertyWebkitTransition:
       
  5434         if (isInitial)
       
  5435             m_style->clearTransitions();
       
  5436         else if (isInherit)
       
  5437             m_style->inheritTransitions(m_parentStyle->transitions());
       
  5438         return;
       
  5439     case CSSPropertyWebkitTransitionDelay:
       
  5440         HANDLE_TRANSITION_VALUE(delay, Delay, value)
       
  5441         return;
       
  5442     case CSSPropertyWebkitTransitionDuration:
       
  5443         HANDLE_TRANSITION_VALUE(duration, Duration, value)
       
  5444         return;
       
  5445     case CSSPropertyWebkitTransitionProperty:
       
  5446         HANDLE_TRANSITION_VALUE(property, Property, value)
       
  5447         return;
       
  5448     case CSSPropertyWebkitTransitionTimingFunction:
       
  5449         HANDLE_TRANSITION_VALUE(timingFunction, TimingFunction, value)
       
  5450         return;
       
  5451 #if 0 // :HACK:
       
  5452     case CSSPropertyWebkitHapticTapType: {
       
  5453         HANDLE_INHERIT_AND_INITIAL(hapticTapType, HapticTapType)
       
  5454         m_style->setHapticTapType(*primitiveValue);
       
  5455         return;
       
  5456     }
       
  5457     case CSSPropertyWebkitHapticTapStrength: {
       
  5458         HANDLE_INHERIT_AND_INITIAL(hapticTapStrength, HapticTapStrength)
       
  5459         m_style->setHapticTapStrength(*primitiveValue);
       
  5460         return;
       
  5461     }
       
  5462     case CSSPropertyWebkitHapticTap: {
       
  5463         if (isInherit) {
       
  5464             m_style->setHapticTapType(m_parentStyle->hapticTapType());
       
  5465             m_style->setHapticTapStrength(m_parentStyle->hapticTapStrength());
       
  5466         } else if (isInitial) {
       
  5467             m_style->setHapticTapType(RenderStyle::initialHapticTapType());
       
  5468             m_style->setHapticTapStrength(RenderStyle::initialHapticTapStrength());
       
  5469         }
       
  5470         return;
       
  5471     }
       
  5472 #endif // ENABLE(HAPTICS)
       
  5473     case CSSPropertyPointerEvents:
       
  5474     {
       
  5475 #if ENABLE(DASHBOARD_SUPPORT)
       
  5476         // <rdar://problem/6561077> Work around the Stocks widget's misuse of the
       
  5477         // pointer-events property by not applying it in Dashboard.
       
  5478         Settings* settings = m_checker.m_document->settings();
       
  5479         if (settings && settings->usesDashboardBackwardCompatibilityMode())
       
  5480             return;
       
  5481 #endif
       
  5482         HANDLE_INHERIT_AND_INITIAL(pointerEvents, PointerEvents)
       
  5483         if (!primitiveValue)
       
  5484             return;
       
  5485         m_style->setPointerEvents(*primitiveValue);
       
  5486         return;
       
  5487     }
       
  5488     case CSSPropertyWebkitColorCorrection:
       
  5489         if (isInherit) 
       
  5490             m_style->setColorSpace(m_parentStyle->colorSpace());
       
  5491         else if (isInitial)
       
  5492             m_style->setColorSpace(DeviceColorSpace);
       
  5493         else {
       
  5494             if (!primitiveValue)
       
  5495                 return;
       
  5496             m_style->setColorSpace(*primitiveValue);
       
  5497         }
       
  5498         return;
       
  5499     case CSSPropertySize:
       
  5500         applyPageSizeProperty(value);
       
  5501         return;
       
  5502     case CSSPropertyInvalid:
       
  5503         return;
       
  5504 
       
  5505     // Directional properties are resolved by resolveDirectionAwareProperty() before the switch.
       
  5506     case CSSPropertyWebkitBorderEnd:
       
  5507     case CSSPropertyWebkitBorderEndColor:
       
  5508     case CSSPropertyWebkitBorderEndStyle:
       
  5509     case CSSPropertyWebkitBorderEndWidth:
       
  5510     case CSSPropertyWebkitBorderStart:
       
  5511     case CSSPropertyWebkitBorderStartColor:
       
  5512     case CSSPropertyWebkitBorderStartStyle:
       
  5513     case CSSPropertyWebkitBorderStartWidth:
       
  5514     case CSSPropertyWebkitMarginEnd:
       
  5515     case CSSPropertyWebkitMarginStart:
       
  5516     case CSSPropertyWebkitPaddingEnd:
       
  5517     case CSSPropertyWebkitPaddingStart:
       
  5518         ASSERT_NOT_REACHED();
       
  5519         break;
       
  5520 
       
  5521     case CSSPropertyFontStretch:
       
  5522     case CSSPropertyPage:
       
  5523     case CSSPropertyQuotes:
       
  5524     case CSSPropertyTextLineThrough:
       
  5525     case CSSPropertyTextLineThroughColor:
       
  5526     case CSSPropertyTextLineThroughMode:
       
  5527     case CSSPropertyTextLineThroughStyle:
       
  5528     case CSSPropertyTextLineThroughWidth:
       
  5529     case CSSPropertyTextOverline:
       
  5530     case CSSPropertyTextOverlineColor:
       
  5531     case CSSPropertyTextOverlineMode:
       
  5532     case CSSPropertyTextOverlineStyle:
       
  5533     case CSSPropertyTextOverlineWidth:
       
  5534     case CSSPropertyTextUnderline:
       
  5535     case CSSPropertyTextUnderlineColor:
       
  5536     case CSSPropertyTextUnderlineMode:
       
  5537     case CSSPropertyTextUnderlineStyle:
       
  5538     case CSSPropertyTextUnderlineWidth:
       
  5539     case CSSPropertyWebkitFontSizeDelta:
       
  5540     case CSSPropertyWebkitTextDecorationsInEffect:
       
  5541     case CSSPropertyWebkitTextStroke:
       
  5542     case CSSPropertyWebkitVariableDeclarationBlock:
       
  5543         return;
       
  5544 #if ENABLE(WCSS)
       
  5545     case CSSPropertyWapInputFormat:
       
  5546         if (primitiveValue && m_element->hasTagName(WebCore::inputTag)) {
       
  5547             String mask = primitiveValue->getStringValue();
       
  5548             static_cast<HTMLInputElement*>(m_element)->setWapInputFormat(mask);
       
  5549         }
       
  5550         return;
       
  5551 
       
  5552     case CSSPropertyWapInputRequired:
       
  5553         if (primitiveValue && m_element->isFormControlElement()) {
       
  5554             HTMLFormControlElement* element = static_cast<HTMLFormControlElement*>(m_element);
       
  5555             bool required = primitiveValue->getStringValue() == "true";
       
  5556             element->setRequired(required);
       
  5557         }
       
  5558         return;
       
  5559 #endif 
       
  5560 
       
  5561 #if ENABLE(SVG)
       
  5562     default:
       
  5563         // Try the SVG properties
       
  5564         applySVGProperty(id, value);
       
  5565 #endif
       
  5566     }
       
  5567 }
       
  5568 
       
  5569 void CSSStyleSelector::applyPageSizeProperty(CSSValue* value)
       
  5570 {
       
  5571     m_style->resetPageSizeType();
       
  5572     if (!value->isValueList())
       
  5573         return;
       
  5574     CSSValueList* valueList = static_cast<CSSValueList*>(value);
       
  5575     Length width;
       
  5576     Length height;
       
  5577     PageSizeType pageSizeType = PAGE_SIZE_AUTO;
       
  5578     switch (valueList->length()) {
       
  5579     case 2: {
       
  5580         // <length>{2} | <page-size> <orientation>
       
  5581         pageSizeType = PAGE_SIZE_RESOLVED;
       
  5582         if (!valueList->item(0)->isPrimitiveValue() || !valueList->item(1)->isPrimitiveValue())
       
  5583             return;
       
  5584         CSSPrimitiveValue* primitiveValue0 = static_cast<CSSPrimitiveValue*>(valueList->item(0));
       
  5585         CSSPrimitiveValue* primitiveValue1 = static_cast<CSSPrimitiveValue*>(valueList->item(1));
       
  5586         int type0 = primitiveValue0->primitiveType();
       
  5587         int type1 = primitiveValue1->primitiveType();
       
  5588         if (CSSPrimitiveValue::isUnitTypeLength(type0)) {
       
  5589             // <length>{2}
       
  5590             if (!CSSPrimitiveValue::isUnitTypeLength(type1))
       
  5591                 return;
       
  5592             width = Length(primitiveValue0->computeLengthIntForLength(style(), m_rootElementStyle), Fixed);
       
  5593             height = Length(primitiveValue1->computeLengthIntForLength(style(), m_rootElementStyle), Fixed);
       
  5594         } else {
       
  5595             // <page-size> <orientation>
       
  5596             // The value order is guaranteed. See CSSParser::parseSizeParameter.
       
  5597             if (!pageSizeFromName(primitiveValue0, primitiveValue1, width, height))
       
  5598                 return;
       
  5599         }
       
  5600         break;
       
  5601     }
       
  5602     case 1: {
       
  5603         // <length> | auto | <page-size> | [ portrait | landscape]
       
  5604         if (!valueList->item(0)->isPrimitiveValue())
       
  5605             return;
       
  5606         CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(valueList->item(0));
       
  5607         int type = primitiveValue->primitiveType();
       
  5608         if (CSSPrimitiveValue::isUnitTypeLength(type)) {
       
  5609             // <length>
       
  5610             pageSizeType = PAGE_SIZE_RESOLVED;
       
  5611             width = height = Length(primitiveValue->computeLengthIntForLength(style(), m_rootElementStyle), Fixed);
       
  5612         } else {
       
  5613             if (type != CSSPrimitiveValue::CSS_IDENT)
       
  5614                 return;
       
  5615             switch (primitiveValue->getIdent()) {
       
  5616             case CSSValueAuto:
       
  5617                 pageSizeType = PAGE_SIZE_AUTO;
       
  5618                 break;
       
  5619             case CSSValuePortrait:
       
  5620                 pageSizeType = PAGE_SIZE_AUTO_PORTRAIT;
       
  5621                 break;
       
  5622             case CSSValueLandscape:
       
  5623                 pageSizeType = PAGE_SIZE_AUTO_LANDSCAPE;
       
  5624                 break;
       
  5625             default:
       
  5626                 // <page-size>
       
  5627                 pageSizeType = PAGE_SIZE_RESOLVED;
       
  5628                 if (!pageSizeFromName(primitiveValue, 0, width, height))
       
  5629                     return;
       
  5630             }
       
  5631         }
       
  5632         break;
       
  5633     }
       
  5634     default:
       
  5635         return;
       
  5636     }
       
  5637     m_style->setPageSizeType(pageSizeType);
       
  5638     m_style->setPageSize(LengthSize(width, height));
       
  5639     return;
       
  5640 }
       
  5641 
       
  5642 bool CSSStyleSelector::pageSizeFromName(CSSPrimitiveValue* pageSizeName, CSSPrimitiveValue* pageOrientation, Length& width, Length& height)
       
  5643 {
       
  5644     static const Length a5Width = mmLength(148), a5Height = mmLength(210);
       
  5645     static const Length a4Width = mmLength(210), a4Height = mmLength(297);
       
  5646     static const Length a3Width = mmLength(297), a3Height = mmLength(420);
       
  5647     static const Length b5Width = mmLength(176), b5Height = mmLength(250);
       
  5648     static const Length b4Width = mmLength(250), b4Height = mmLength(353);
       
  5649     static const Length letterWidth = inchLength(8.5), letterHeight = inchLength(11);
       
  5650     static const Length legalWidth = inchLength(8.5), legalHeight = inchLength(14);
       
  5651     static const Length ledgerWidth = inchLength(11), ledgerHeight = inchLength(17);
       
  5652 
       
  5653     if (!pageSizeName || pageSizeName->primitiveType() != CSSPrimitiveValue::CSS_IDENT)
       
  5654         return false;
       
  5655 
       
  5656     switch (pageSizeName->getIdent()) {
       
  5657     case CSSValueA5:
       
  5658         width = a5Width;
       
  5659         height = a5Height;
       
  5660         break;
       
  5661     case CSSValueA4:
       
  5662         width = a4Width;
       
  5663         height = a4Height;
       
  5664         break;
       
  5665     case CSSValueA3:
       
  5666         width = a3Width;
       
  5667         height = a3Height;
       
  5668         break;
       
  5669     case CSSValueB5:
       
  5670         width = b5Width;
       
  5671         height = b5Height;
       
  5672         break;
       
  5673     case CSSValueB4:
       
  5674         width = b4Width;
       
  5675         height = b4Height;
       
  5676         break;
       
  5677     case CSSValueLetter:
       
  5678         width = letterWidth;
       
  5679         height = letterHeight;
       
  5680         break;
       
  5681     case CSSValueLegal:
       
  5682         width = legalWidth;
       
  5683         height = legalHeight;
       
  5684         break;
       
  5685     case CSSValueLedger:
       
  5686         width = ledgerWidth;
       
  5687         height = ledgerHeight;
       
  5688         break;
       
  5689     default:
       
  5690         return false;
       
  5691     }
       
  5692 
       
  5693     if (pageOrientation) {
       
  5694         if (pageOrientation->primitiveType() != CSSPrimitiveValue::CSS_IDENT)
       
  5695             return false;
       
  5696         switch (pageOrientation->getIdent()) {
       
  5697         case CSSValueLandscape:
       
  5698             std::swap(width, height);
       
  5699             break;
       
  5700         case CSSValuePortrait:
       
  5701             // Nothing to do.
       
  5702             break;
       
  5703         default:
       
  5704             return false;
       
  5705         }
       
  5706     }
       
  5707     return true;
       
  5708 }
       
  5709 
       
  5710 Length CSSStyleSelector::mmLength(double mm)
       
  5711 {
       
  5712     return Length(CSSPrimitiveValue::create(mm, CSSPrimitiveValue::CSS_MM)->computeLengthIntForLength(style(), m_rootElementStyle), Fixed);
       
  5713 }
       
  5714 
       
  5715 Length CSSStyleSelector::inchLength(double inch)
       
  5716 {
       
  5717     return Length(CSSPrimitiveValue::create(inch, CSSPrimitiveValue::CSS_IN)->computeLengthIntForLength(style(), m_rootElementStyle), Fixed);
       
  5718 }
       
  5719 
       
  5720 void CSSStyleSelector::mapFillAttachment(FillLayer* layer, CSSValue* value)
       
  5721 {
       
  5722     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  5723         layer->setAttachment(FillLayer::initialFillAttachment(layer->type()));
       
  5724         return;
       
  5725     }
       
  5726 
       
  5727     if (!value->isPrimitiveValue())
       
  5728         return;
       
  5729 
       
  5730     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5731     switch (primitiveValue->getIdent()) {
       
  5732         case CSSValueFixed:
       
  5733             layer->setAttachment(FixedBackgroundAttachment);
       
  5734             break;
       
  5735         case CSSValueScroll:
       
  5736             layer->setAttachment(ScrollBackgroundAttachment);
       
  5737             break;
       
  5738         case CSSValueLocal:
       
  5739             layer->setAttachment(LocalBackgroundAttachment);
       
  5740             break;
       
  5741         default:
       
  5742             return;
       
  5743     }
       
  5744 }
       
  5745 
       
  5746 void CSSStyleSelector::mapFillClip(FillLayer* layer, CSSValue* value)
       
  5747 {
       
  5748     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  5749         layer->setClip(FillLayer::initialFillClip(layer->type()));
       
  5750         return;
       
  5751     }
       
  5752 
       
  5753     if (!value->isPrimitiveValue())
       
  5754         return;
       
  5755 
       
  5756     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5757     layer->setClip(*primitiveValue);
       
  5758 }
       
  5759 
       
  5760 void CSSStyleSelector::mapFillComposite(FillLayer* layer, CSSValue* value)
       
  5761 {
       
  5762     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  5763         layer->setComposite(FillLayer::initialFillComposite(layer->type()));
       
  5764         return;
       
  5765     }
       
  5766     
       
  5767     if (!value->isPrimitiveValue())
       
  5768         return;
       
  5769 
       
  5770     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5771     layer->setComposite(*primitiveValue);
       
  5772 }
       
  5773 
       
  5774 void CSSStyleSelector::mapFillOrigin(FillLayer* layer, CSSValue* value)
       
  5775 {
       
  5776     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  5777         layer->setOrigin(FillLayer::initialFillOrigin(layer->type()));
       
  5778         return;
       
  5779     }
       
  5780 
       
  5781     if (!value->isPrimitiveValue())
       
  5782         return;
       
  5783 
       
  5784     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5785     layer->setOrigin(*primitiveValue);
       
  5786 }
       
  5787 
       
  5788 StyleImage* CSSStyleSelector::styleImage(CSSValue* value)
       
  5789 {
       
  5790     if (value->isImageValue())
       
  5791         return static_cast<CSSImageValue*>(value)->cachedImage(m_element->document()->docLoader());
       
  5792     if (value->isImageGeneratorValue())
       
  5793         return static_cast<CSSImageGeneratorValue*>(value)->generatedImage();
       
  5794     return 0;
       
  5795 }
       
  5796 
       
  5797 void CSSStyleSelector::mapFillImage(FillLayer* layer, CSSValue* value)
       
  5798 {
       
  5799     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  5800         layer->setImage(FillLayer::initialFillImage(layer->type()));
       
  5801         return;
       
  5802     }
       
  5803 
       
  5804     layer->setImage(styleImage(value));
       
  5805 }
       
  5806 
       
  5807 void CSSStyleSelector::mapFillRepeatX(FillLayer* layer, CSSValue* value)
       
  5808 {
       
  5809     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  5810         layer->setRepeatX(FillLayer::initialFillRepeatX(layer->type()));
       
  5811         return;
       
  5812     }
       
  5813     
       
  5814     if (!value->isPrimitiveValue())
       
  5815         return;
       
  5816 
       
  5817     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5818     layer->setRepeatX(*primitiveValue);
       
  5819 }
       
  5820 
       
  5821 void CSSStyleSelector::mapFillRepeatY(FillLayer* layer, CSSValue* value)
       
  5822 {
       
  5823     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  5824         layer->setRepeatY(FillLayer::initialFillRepeatY(layer->type()));
       
  5825         return;
       
  5826     }
       
  5827     
       
  5828     if (!value->isPrimitiveValue())
       
  5829         return;
       
  5830 
       
  5831     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5832     layer->setRepeatY(*primitiveValue);
       
  5833 }
       
  5834 
       
  5835 void CSSStyleSelector::mapFillSize(FillLayer* layer, CSSValue* value)
       
  5836 {
       
  5837     if (!value->isPrimitiveValue()) {
       
  5838         layer->setSizeType(SizeNone);
       
  5839         return;
       
  5840     }
       
  5841 
       
  5842     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5843     if (primitiveValue->getIdent() == CSSValueContain)
       
  5844         layer->setSizeType(Contain);
       
  5845     else if (primitiveValue->getIdent() == CSSValueCover)
       
  5846         layer->setSizeType(Cover);
       
  5847     else
       
  5848         layer->setSizeType(SizeLength);
       
  5849     
       
  5850     LengthSize b = FillLayer::initialFillSizeLength(layer->type());
       
  5851     
       
  5852     if (value->cssValueType() == CSSValue::CSS_INITIAL || primitiveValue->getIdent() == CSSValueContain
       
  5853         || primitiveValue->getIdent() == CSSValueCover) {
       
  5854         layer->setSizeLength(b);
       
  5855         return;
       
  5856     }
       
  5857 
       
  5858     Pair* pair = primitiveValue->getPairValue();
       
  5859     if (!pair)
       
  5860         return;
       
  5861     
       
  5862     CSSPrimitiveValue* first = static_cast<CSSPrimitiveValue*>(pair->first());
       
  5863     CSSPrimitiveValue* second = static_cast<CSSPrimitiveValue*>(pair->second());
       
  5864     
       
  5865     if (!first || !second)
       
  5866         return;
       
  5867         
       
  5868     Length firstLength, secondLength;
       
  5869     int firstType = first->primitiveType();
       
  5870     int secondType = second->primitiveType();
       
  5871     
       
  5872     float zoomFactor = m_style->effectiveZoom();
       
  5873 
       
  5874     if (firstType == CSSPrimitiveValue::CSS_UNKNOWN)
       
  5875         firstLength = Length(Auto);
       
  5876     else if (CSSPrimitiveValue::isUnitTypeLength(firstType))
       
  5877         firstLength = Length(first->computeLengthIntForLength(style(), m_rootElementStyle, zoomFactor), Fixed);
       
  5878     else if (firstType == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  5879         firstLength = Length(first->getDoubleValue(), Percent);
       
  5880     else
       
  5881         return;
       
  5882 
       
  5883     if (secondType == CSSPrimitiveValue::CSS_UNKNOWN)
       
  5884         secondLength = Length(Auto);
       
  5885     else if (CSSPrimitiveValue::isUnitTypeLength(secondType))
       
  5886         secondLength = Length(second->computeLengthIntForLength(style(), m_rootElementStyle, zoomFactor), Fixed);
       
  5887     else if (secondType == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  5888         secondLength = Length(second->getDoubleValue(), Percent);
       
  5889     else
       
  5890         return;
       
  5891     
       
  5892     b.setWidth(firstLength);
       
  5893     b.setHeight(secondLength);
       
  5894     layer->setSizeLength(b);
       
  5895 }
       
  5896 
       
  5897 void CSSStyleSelector::mapFillXPosition(FillLayer* layer, CSSValue* value)
       
  5898 {
       
  5899     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  5900         layer->setXPosition(FillLayer::initialFillXPosition(layer->type()));
       
  5901         return;
       
  5902     }
       
  5903     
       
  5904     if (!value->isPrimitiveValue())
       
  5905         return;
       
  5906 
       
  5907     float zoomFactor = m_style->effectiveZoom();
       
  5908 
       
  5909     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5910     Length l;
       
  5911     int type = primitiveValue->primitiveType();
       
  5912     if (CSSPrimitiveValue::isUnitTypeLength(type))
       
  5913         l = Length(primitiveValue->computeLengthIntForLength(style(), m_rootElementStyle, zoomFactor), Fixed);
       
  5914     else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  5915         l = Length(primitiveValue->getDoubleValue(), Percent);
       
  5916     else
       
  5917         return;
       
  5918     layer->setXPosition(l);
       
  5919 }
       
  5920 
       
  5921 void CSSStyleSelector::mapFillYPosition(FillLayer* layer, CSSValue* value)
       
  5922 {
       
  5923     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  5924         layer->setYPosition(FillLayer::initialFillYPosition(layer->type()));
       
  5925         return;
       
  5926     }
       
  5927     
       
  5928     if (!value->isPrimitiveValue())
       
  5929         return;
       
  5930 
       
  5931     float zoomFactor = m_style->effectiveZoom();
       
  5932     
       
  5933     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5934     Length l;
       
  5935     int type = primitiveValue->primitiveType();
       
  5936     if (CSSPrimitiveValue::isUnitTypeLength(type))
       
  5937         l = Length(primitiveValue->computeLengthIntForLength(style(), m_rootElementStyle, zoomFactor), Fixed);
       
  5938     else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  5939         l = Length(primitiveValue->getDoubleValue(), Percent);
       
  5940     else
       
  5941         return;
       
  5942     layer->setYPosition(l);
       
  5943 }
       
  5944 
       
  5945 void CSSStyleSelector::mapAnimationDelay(Animation* animation, CSSValue* value)
       
  5946 {
       
  5947     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  5948         animation->setDelay(Animation::initialAnimationDelay());
       
  5949         return;
       
  5950     }
       
  5951 
       
  5952     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5953     if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_S)
       
  5954         animation->setDelay(primitiveValue->getFloatValue());
       
  5955     else
       
  5956         animation->setDelay(primitiveValue->getFloatValue()/1000.0f);
       
  5957 }
       
  5958 
       
  5959 void CSSStyleSelector::mapAnimationDirection(Animation* layer, CSSValue* value)
       
  5960 {
       
  5961     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  5962         layer->setDirection(Animation::initialAnimationDirection());
       
  5963         return;
       
  5964     }
       
  5965 
       
  5966     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5967     layer->setDirection(primitiveValue->getIdent() == CSSValueAlternate ? Animation::AnimationDirectionAlternate : Animation::AnimationDirectionNormal);
       
  5968 }
       
  5969 
       
  5970 void CSSStyleSelector::mapAnimationDuration(Animation* animation, CSSValue* value)
       
  5971 {
       
  5972     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  5973         animation->setDuration(Animation::initialAnimationDuration());
       
  5974         return;
       
  5975     }
       
  5976 
       
  5977     if (!value->isPrimitiveValue())
       
  5978         return;
       
  5979 
       
  5980     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5981     if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_S)
       
  5982         animation->setDuration(primitiveValue->getFloatValue());
       
  5983     else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_MS)
       
  5984         animation->setDuration(primitiveValue->getFloatValue()/1000.0f);
       
  5985 }
       
  5986 
       
  5987 void CSSStyleSelector::mapAnimationFillMode(Animation* layer, CSSValue* value)
       
  5988 {
       
  5989     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  5990         layer->setFillMode(Animation::initialAnimationFillMode());
       
  5991         return;
       
  5992     }
       
  5993 
       
  5994     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  5995     switch (primitiveValue->getIdent()) {
       
  5996     case CSSValueNone:
       
  5997         layer->setFillMode(AnimationFillModeNone);
       
  5998         break;
       
  5999     case CSSValueForwards:
       
  6000         layer->setFillMode(AnimationFillModeForwards);
       
  6001         break;
       
  6002     case CSSValueBackwards:
       
  6003         layer->setFillMode(AnimationFillModeBackwards);
       
  6004         break;
       
  6005     case CSSValueBoth:
       
  6006         layer->setFillMode(AnimationFillModeBoth);
       
  6007         break;
       
  6008     }
       
  6009 }
       
  6010 
       
  6011 void CSSStyleSelector::mapAnimationIterationCount(Animation* animation, CSSValue* value)
       
  6012 {
       
  6013     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  6014         animation->setIterationCount(Animation::initialAnimationIterationCount());
       
  6015         return;
       
  6016     }
       
  6017 
       
  6018     if (!value->isPrimitiveValue())
       
  6019         return;
       
  6020 
       
  6021     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  6022     if (primitiveValue->getIdent() == CSSValueInfinite)
       
  6023         animation->setIterationCount(-1);
       
  6024     else
       
  6025         animation->setIterationCount(int(primitiveValue->getFloatValue()));
       
  6026 }
       
  6027 
       
  6028 void CSSStyleSelector::mapAnimationName(Animation* layer, CSSValue* value)
       
  6029 {
       
  6030     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  6031         layer->setName(Animation::initialAnimationName());
       
  6032         return;
       
  6033     }
       
  6034 
       
  6035     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  6036     
       
  6037     if (primitiveValue->getIdent() == CSSValueNone)
       
  6038         layer->setIsNoneAnimation(true);
       
  6039     else
       
  6040         layer->setName(primitiveValue->getStringValue());
       
  6041 }
       
  6042 
       
  6043 void CSSStyleSelector::mapAnimationPlayState(Animation* layer, CSSValue* value)
       
  6044 {
       
  6045     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  6046         layer->setPlayState(Animation::initialAnimationPlayState());
       
  6047         return;
       
  6048     }
       
  6049 
       
  6050     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  6051     EAnimPlayState playState = (primitiveValue->getIdent() == CSSValuePaused) ? AnimPlayStatePaused : AnimPlayStatePlaying;
       
  6052     layer->setPlayState(playState);
       
  6053 }
       
  6054 
       
  6055 void CSSStyleSelector::mapAnimationProperty(Animation* animation, CSSValue* value)
       
  6056 {
       
  6057     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  6058         animation->setProperty(Animation::initialAnimationProperty());
       
  6059         return;
       
  6060     }
       
  6061 
       
  6062     if (!value->isPrimitiveValue())
       
  6063         return;
       
  6064 
       
  6065     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  6066     if (primitiveValue->getIdent() == CSSValueAll)
       
  6067         animation->setProperty(cAnimateAll);
       
  6068     else if (primitiveValue->getIdent() == CSSValueNone)
       
  6069         animation->setProperty(cAnimateNone);
       
  6070     else
       
  6071         animation->setProperty(static_cast<CSSPropertyID>(primitiveValue->getIdent()));
       
  6072 }
       
  6073 
       
  6074 void CSSStyleSelector::mapAnimationTimingFunction(Animation* animation, CSSValue* value)
       
  6075 {
       
  6076     if (value->cssValueType() == CSSValue::CSS_INITIAL) {
       
  6077         animation->setTimingFunction(Animation::initialAnimationTimingFunction());
       
  6078         return;
       
  6079     }
       
  6080     
       
  6081     if (value->isPrimitiveValue()) {
       
  6082         CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
       
  6083         switch (primitiveValue->getIdent()) {
       
  6084             case CSSValueLinear:
       
  6085                 animation->setTimingFunction(TimingFunction(LinearTimingFunction, 0.0, 0.0, 1.0, 1.0));
       
  6086                 break;
       
  6087             case CSSValueEase:
       
  6088                 animation->setTimingFunction(TimingFunction());
       
  6089                 break;
       
  6090             case CSSValueEaseIn:
       
  6091                 animation->setTimingFunction(TimingFunction(CubicBezierTimingFunction, 0.42, 0.0, 1.0, 1.0));
       
  6092                 break;
       
  6093             case CSSValueEaseOut:
       
  6094                 animation->setTimingFunction(TimingFunction(CubicBezierTimingFunction, 0.0, 0.0, 0.58, 1.0));
       
  6095                 break;
       
  6096             case CSSValueEaseInOut:
       
  6097                 animation->setTimingFunction(TimingFunction(CubicBezierTimingFunction, 0.42, 0.0, 0.58, 1.0));
       
  6098                 break;
       
  6099         }
       
  6100         return;
       
  6101     }
       
  6102     
       
  6103     if (value->isTimingFunctionValue()) {
       
  6104         CSSTimingFunctionValue* timingFunction = static_cast<CSSTimingFunctionValue*>(value);
       
  6105         animation->setTimingFunction(TimingFunction(CubicBezierTimingFunction, timingFunction->x1(), timingFunction->y1(), timingFunction->x2(), timingFunction->y2()));
       
  6106     }
       
  6107 }
       
  6108 
       
  6109 void CSSStyleSelector::mapNinePieceImage(CSSValue* value, NinePieceImage& image)
       
  6110 {
       
  6111     // If we're a primitive value, then we are "none" and don't need to alter the empty image at all.
       
  6112     if (!value || value->isPrimitiveValue())
       
  6113         return;
       
  6114 
       
  6115     // Retrieve the border image value.
       
  6116     CSSBorderImageValue* borderImage = static_cast<CSSBorderImageValue*>(value);
       
  6117     
       
  6118     // Set the image (this kicks off the load).
       
  6119     image.setImage(styleImage(borderImage->imageValue()));
       
  6120 
       
  6121     // Set up a length box to represent our image slices.
       
  6122     LengthBox l;
       
  6123     Rect* r = borderImage->m_imageSliceRect.get();
       
  6124     if (r->top()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  6125         l.m_top = Length(r->top()->getDoubleValue(), Percent);
       
  6126     else
       
  6127         l.m_top = Length(r->top()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
       
  6128     if (r->bottom()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  6129         l.m_bottom = Length(r->bottom()->getDoubleValue(), Percent);
       
  6130     else
       
  6131         l.m_bottom = Length((int)r->bottom()->getFloatValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
       
  6132     if (r->left()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  6133         l.m_left = Length(r->left()->getDoubleValue(), Percent);
       
  6134     else
       
  6135         l.m_left = Length(r->left()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
       
  6136     if (r->right()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
       
  6137         l.m_right = Length(r->right()->getDoubleValue(), Percent);
       
  6138     else
       
  6139         l.m_right = Length(r->right()->getIntValue(CSSPrimitiveValue::CSS_NUMBER), Fixed);
       
  6140     image.setSlices(l);
       
  6141 
       
  6142     // Set the appropriate rules for stretch/round/repeat of the slices
       
  6143     ENinePieceImageRule horizontalRule;
       
  6144     switch (borderImage->m_horizontalSizeRule) {
       
  6145         case CSSValueStretch:
       
  6146             horizontalRule = StretchImageRule;
       
  6147             break;
       
  6148         case CSSValueRound:
       
  6149             horizontalRule = RoundImageRule;
       
  6150             break;
       
  6151         default: // CSSValueRepeat
       
  6152             horizontalRule = RepeatImageRule;
       
  6153             break;
       
  6154     }
       
  6155     image.setHorizontalRule(horizontalRule);
       
  6156 
       
  6157     ENinePieceImageRule verticalRule;
       
  6158     switch (borderImage->m_verticalSizeRule) {
       
  6159         case CSSValueStretch:
       
  6160             verticalRule = StretchImageRule;
       
  6161             break;
       
  6162         case CSSValueRound:
       
  6163             verticalRule = RoundImageRule;
       
  6164             break;
       
  6165         default: // CSSValueRepeat
       
  6166             verticalRule = RepeatImageRule;
       
  6167             break;
       
  6168     }
       
  6169     image.setVerticalRule(verticalRule);
       
  6170 }
       
  6171 
       
  6172 void CSSStyleSelector::checkForTextSizeAdjust()
       
  6173 {
       
  6174     if (m_style->textSizeAdjust())
       
  6175         return;
       
  6176  
       
  6177     FontDescription newFontDescription(m_style->fontDescription());
       
  6178     newFontDescription.setComputedSize(newFontDescription.specifiedSize());
       
  6179     m_style->setFontDescription(newFontDescription);
       
  6180 }
       
  6181 
       
  6182 void CSSStyleSelector::checkForZoomChange(RenderStyle* style, RenderStyle* parentStyle)
       
  6183 {
       
  6184     if (style->effectiveZoom() == parentStyle->effectiveZoom())
       
  6185         return;
       
  6186     
       
  6187     const FontDescription& childFont = style->fontDescription();
       
  6188     FontDescription newFontDescription(childFont);
       
  6189     setFontSize(newFontDescription, childFont.specifiedSize());
       
  6190     style->setFontDescription(newFontDescription);
       
  6191 }
       
  6192 
       
  6193 void CSSStyleSelector::checkForGenericFamilyChange(RenderStyle* style, RenderStyle* parentStyle)
       
  6194 {
       
  6195     const FontDescription& childFont = style->fontDescription();
       
  6196   
       
  6197     if (childFont.isAbsoluteSize() || !parentStyle)
       
  6198         return;
       
  6199 
       
  6200     const FontDescription& parentFont = parentStyle->fontDescription();
       
  6201     if (childFont.useFixedDefaultSize() == parentFont.useFixedDefaultSize())
       
  6202         return;
       
  6203 
       
  6204     // For now, lump all families but monospace together.
       
  6205     if (childFont.genericFamily() != FontDescription::MonospaceFamily &&
       
  6206         parentFont.genericFamily() != FontDescription::MonospaceFamily)
       
  6207         return;
       
  6208 
       
  6209     // We know the parent is monospace or the child is monospace, and that font
       
  6210     // size was unspecified.  We want to scale our font size as appropriate.
       
  6211     // If the font uses a keyword size, then we refetch from the table rather than
       
  6212     // multiplying by our scale factor.
       
  6213     float size;
       
  6214     if (childFont.keywordSize())
       
  6215         size = fontSizeForKeyword(m_checker.m_document, CSSValueXxSmall + childFont.keywordSize() - 1, childFont.useFixedDefaultSize());
       
  6216     else {
       
  6217         Settings* settings = m_checker.m_document->settings();
       
  6218         float fixedScaleFactor = settings
       
  6219             ? static_cast<float>(settings->defaultFixedFontSize()) / settings->defaultFontSize()
       
  6220             : 1;
       
  6221         size = parentFont.useFixedDefaultSize() ?
       
  6222                 childFont.specifiedSize() / fixedScaleFactor :
       
  6223                 childFont.specifiedSize() * fixedScaleFactor;
       
  6224     }
       
  6225 
       
  6226     FontDescription newFontDescription(childFont);
       
  6227     setFontSize(newFontDescription, size);
       
  6228     style->setFontDescription(newFontDescription);
       
  6229 }
       
  6230 
       
  6231 void CSSStyleSelector::setFontSize(FontDescription& fontDescription, float size)
       
  6232 {
       
  6233     fontDescription.setSpecifiedSize(size);
       
  6234 
       
  6235     bool useSVGZoomRules = m_element && m_element->isSVGElement();
       
  6236     fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(m_checker.m_document, m_style.get(), fontDescription.isAbsoluteSize(), size, useSVGZoomRules)); 
       
  6237 }
       
  6238 
       
  6239 float CSSStyleSelector::getComputedSizeFromSpecifiedSize(Document* document, RenderStyle* style, bool isAbsoluteSize, float specifiedSize, bool useSVGZoomRules)
       
  6240 {
       
  6241     float zoomFactor = 1.0f;
       
  6242     if (!useSVGZoomRules) {
       
  6243         zoomFactor = style->effectiveZoom();
       
  6244         if (document->view() && document->view()->shouldApplyTextZoom())
       
  6245             zoomFactor *= document->view()->textZoomFactor();
       
  6246     }
       
  6247 
       
  6248     // We support two types of minimum font size.  The first is a hard override that applies to
       
  6249     // all fonts.  This is "minSize."  The second type of minimum font size is a "smart minimum"
       
  6250     // that is applied only when the Web page can't know what size it really asked for, e.g.,
       
  6251     // when it uses logical sizes like "small" or expresses the font-size as a percentage of
       
  6252     // the user's default font setting.
       
  6253 
       
  6254     // With the smart minimum, we never want to get smaller than the minimum font size to keep fonts readable.
       
  6255     // However we always allow the page to set an explicit pixel size that is smaller,
       
  6256     // since sites will mis-render otherwise (e.g., http://www.gamespot.com with a 9px minimum).
       
  6257     
       
  6258     Settings* settings = document->settings();
       
  6259     if (!settings)
       
  6260         return 1.0f;
       
  6261 
       
  6262     int minSize = settings->minimumFontSize();
       
  6263     int minLogicalSize = settings->minimumLogicalFontSize();
       
  6264     float zoomedSize = specifiedSize * zoomFactor;
       
  6265 
       
  6266     // Apply the hard minimum first.  We only apply the hard minimum if after zooming we're still too small.
       
  6267     if (zoomedSize < minSize)
       
  6268         zoomedSize = minSize;
       
  6269 
       
  6270     // Now apply the "smart minimum."  This minimum is also only applied if we're still too small
       
  6271     // after zooming.  The font size must either be relative to the user default or the original size
       
  6272     // must have been acceptable.  In other words, we only apply the smart minimum whenever we're positive
       
  6273     // doing so won't disrupt the layout.
       
  6274     if (zoomedSize < minLogicalSize && (specifiedSize >= minLogicalSize || !isAbsoluteSize))
       
  6275         zoomedSize = minLogicalSize;
       
  6276     
       
  6277     // Also clamp to a reasonable maximum to prevent insane font sizes from causing crashes on various
       
  6278     // platforms (I'm looking at you, Windows.)
       
  6279     return min(1000000.0f, max(zoomedSize, 1.0f));
       
  6280 }
       
  6281 
       
  6282 const int fontSizeTableMax = 16;
       
  6283 const int fontSizeTableMin = 9;
       
  6284 const int totalKeywords = 8;
       
  6285 
       
  6286 // WinIE/Nav4 table for font sizes.  Designed to match the legacy font mapping system of HTML.
       
  6287 static const int quirksFontSizeTable[fontSizeTableMax - fontSizeTableMin + 1][totalKeywords] =
       
  6288 {
       
  6289       { 9,    9,     9,     9,    11,    14,    18,    28 },
       
  6290       { 9,    9,     9,    10,    12,    15,    20,    31 },
       
  6291       { 9,    9,     9,    11,    13,    17,    22,    34 },
       
  6292       { 9,    9,    10,    12,    14,    18,    24,    37 },
       
  6293       { 9,    9,    10,    13,    16,    20,    26,    40 }, // fixed font default (13)
       
  6294       { 9,    9,    11,    14,    17,    21,    28,    42 },
       
  6295       { 9,   10,    12,    15,    17,    23,    30,    45 },
       
  6296       { 9,   10,    13,    16,    18,    24,    32,    48 }  // proportional font default (16)
       
  6297 };
       
  6298 // HTML       1      2      3      4      5      6      7
       
  6299 // CSS  xxs   xs     s      m      l     xl     xxl
       
  6300 //                          |
       
  6301 //                      user pref
       
  6302 
       
  6303 // Strict mode table matches MacIE and Mozilla's settings exactly.
       
  6304 static const int strictFontSizeTable[fontSizeTableMax - fontSizeTableMin + 1][totalKeywords] =
       
  6305 {
       
  6306       { 9,    9,     9,     9,    11,    14,    18,    27 },
       
  6307       { 9,    9,     9,    10,    12,    15,    20,    30 },
       
  6308       { 9,    9,    10,    11,    13,    17,    22,    33 },
       
  6309       { 9,    9,    10,    12,    14,    18,    24,    36 },
       
  6310       { 9,   10,    12,    13,    16,    20,    26,    39 }, // fixed font default (13)
       
  6311       { 9,   10,    12,    14,    17,    21,    28,    42 },
       
  6312       { 9,   10,    13,    15,    18,    23,    30,    45 },
       
  6313       { 9,   10,    13,    16,    18,    24,    32,    48 }  // proportional font default (16)
       
  6314 };
       
  6315 // HTML       1      2      3      4      5      6      7
       
  6316 // CSS  xxs   xs     s      m      l     xl     xxl
       
  6317 //                          |
       
  6318 //                      user pref
       
  6319 
       
  6320 // For values outside the range of the table, we use Todd Fahrner's suggested scale
       
  6321 // factors for each keyword value.
       
  6322 static const float fontSizeFactors[totalKeywords] = { 0.60f, 0.75f, 0.89f, 1.0f, 1.2f, 1.5f, 2.0f, 3.0f };
       
  6323 
       
  6324 float CSSStyleSelector::fontSizeForKeyword(Document* document, int keyword, bool fixed)
       
  6325 {
       
  6326     Settings* settings = document->settings();
       
  6327     if (!settings)
       
  6328         return 1.0f;
       
  6329 
       
  6330     bool quirksMode = document->inCompatMode();
       
  6331     int mediumSize = fixed ? settings->defaultFixedFontSize() : settings->defaultFontSize();
       
  6332     if (mediumSize >= fontSizeTableMin && mediumSize <= fontSizeTableMax) {
       
  6333         // Look up the entry in the table.
       
  6334         int row = mediumSize - fontSizeTableMin;
       
  6335         int col = (keyword - CSSValueXxSmall);
       
  6336         return quirksMode ? quirksFontSizeTable[row][col] : strictFontSizeTable[row][col];
       
  6337     }
       
  6338     
       
  6339     // Value is outside the range of the table. Apply the scale factor instead.
       
  6340     float minLogicalSize = max(settings->minimumLogicalFontSize(), 1);
       
  6341     return max(fontSizeFactors[keyword - CSSValueXxSmall]*mediumSize, minLogicalSize);
       
  6342 }
       
  6343 
       
  6344 float CSSStyleSelector::largerFontSize(float size, bool) const
       
  6345 {
       
  6346     // FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large) and scale up to
       
  6347     // the next size level.  
       
  6348     return size * 1.2f;
       
  6349 }
       
  6350 
       
  6351 float CSSStyleSelector::smallerFontSize(float size, bool) const
       
  6352 {
       
  6353     // FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large) and scale down to
       
  6354     // the next size level. 
       
  6355     return size / 1.2f;
       
  6356 }
       
  6357 
       
  6358 static Color colorForCSSValue(int cssValueId)
       
  6359 {
       
  6360     struct ColorValue {
       
  6361         int cssValueId;
       
  6362         RGBA32 color;
       
  6363     };
       
  6364 
       
  6365     static const ColorValue colorValues[] = {
       
  6366         { CSSValueAqua, 0xFF00FFFF },
       
  6367         { CSSValueBlack, 0xFF000000 },
       
  6368         { CSSValueBlue, 0xFF0000FF },
       
  6369         { CSSValueFuchsia, 0xFFFF00FF },
       
  6370         { CSSValueGray, 0xFF808080 },
       
  6371         { CSSValueGreen, 0xFF008000  },
       
  6372         { CSSValueGrey, 0xFF808080 },
       
  6373         { CSSValueLime, 0xFF00FF00 },
       
  6374         { CSSValueMaroon, 0xFF800000 },
       
  6375         { CSSValueNavy, 0xFF000080 },
       
  6376         { CSSValueOlive, 0xFF808000  },
       
  6377         { CSSValueOrange, 0xFFFFA500 },
       
  6378         { CSSValuePurple, 0xFF800080 },
       
  6379         { CSSValueRed, 0xFFFF0000 },
       
  6380         { CSSValueSilver, 0xFFC0C0C0 },
       
  6381         { CSSValueTeal, 0xFF008080  },
       
  6382         { CSSValueTransparent, 0x00000000 },
       
  6383         { CSSValueWhite, 0xFFFFFFFF },
       
  6384         { CSSValueYellow, 0xFFFFFF00 },
       
  6385         { 0, 0 }
       
  6386     };
       
  6387 
       
  6388     for (const ColorValue* col = colorValues; col->cssValueId; ++col) {
       
  6389         if (col->cssValueId == cssValueId)
       
  6390             return col->color;
       
  6391     }
       
  6392     return RenderTheme::defaultTheme()->systemColor(cssValueId);
       
  6393 }
       
  6394 
       
  6395 Color CSSStyleSelector::getColorFromPrimitiveValue(CSSPrimitiveValue* primitiveValue)
       
  6396 {
       
  6397     Color col;
       
  6398     int ident = primitiveValue->getIdent();
       
  6399     if (ident) {
       
  6400         if (ident == CSSValueWebkitText)
       
  6401             col = m_element->document()->textColor();
       
  6402         else if (ident == CSSValueWebkitLink)
       
  6403             col = m_element->isLink() && m_checker.m_matchVisitedPseudoClass ? m_element->document()->visitedLinkColor() : m_element->document()->linkColor();
       
  6404         else if (ident == CSSValueWebkitActivelink)
       
  6405             col = m_element->document()->activeLinkColor();
       
  6406         else if (ident == CSSValueWebkitFocusRingColor)
       
  6407             col = RenderTheme::focusRingColor();
       
  6408         else if (ident == CSSValueCurrentcolor)
       
  6409             col = m_style->color();
       
  6410         else
       
  6411             col = colorForCSSValue(ident);
       
  6412     } else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RGBCOLOR)
       
  6413         col.setRGB(primitiveValue->getRGBA32Value());
       
  6414     return col;
       
  6415 }
       
  6416 
       
  6417 bool CSSStyleSelector::hasSelectorForAttribute(const AtomicString &attrname)
       
  6418 {
       
  6419     return m_selectorAttrs.contains(attrname.impl());
       
  6420 }
       
  6421 
       
  6422 void CSSStyleSelector::addViewportDependentMediaQueryResult(const MediaQueryExp* expr, bool result)
       
  6423 {
       
  6424     m_viewportDependentMediaQueryResults.append(new MediaQueryResult(*expr, result));
       
  6425 }
       
  6426 
       
  6427 bool CSSStyleSelector::affectedByViewportChange() const
       
  6428 {
       
  6429     unsigned s = m_viewportDependentMediaQueryResults.size();
       
  6430     for (unsigned i = 0; i < s; i++) {
       
  6431         if (m_medium->eval(&m_viewportDependentMediaQueryResults[i]->m_expression) != m_viewportDependentMediaQueryResults[i]->m_result)
       
  6432             return true;
       
  6433     }
       
  6434     return false;
       
  6435 }
       
  6436 
       
  6437 void CSSStyleSelector::SelectorChecker::allVisitedStateChanged()
       
  6438 {
       
  6439     if (m_linksCheckedForVisitedState.isEmpty())
       
  6440         return;
       
  6441     for (Node* node = m_document; node; node = node->traverseNextNode()) {
       
  6442         if (node->isLink())
       
  6443             node->setNeedsStyleRecalc();
       
  6444     }
       
  6445 }
       
  6446 
       
  6447 void CSSStyleSelector::SelectorChecker::visitedStateChanged(LinkHash visitedHash)
       
  6448 {
       
  6449     if (!m_linksCheckedForVisitedState.contains(visitedHash))
       
  6450         return;
       
  6451     for (Node* node = m_document; node; node = node->traverseNextNode()) {
       
  6452         const AtomicString* attr = linkAttribute(node);
       
  6453         if (attr && visitedLinkHash(m_document->baseURL(), *attr) == visitedHash)
       
  6454             node->setNeedsStyleRecalc();
       
  6455     }
       
  6456 }
       
  6457 
       
  6458 static TransformOperation::OperationType getTransformOperationType(WebKitCSSTransformValue::TransformOperationType type)
       
  6459 {
       
  6460     switch (type) {
       
  6461         case WebKitCSSTransformValue::ScaleTransformOperation:          return TransformOperation::SCALE;
       
  6462         case WebKitCSSTransformValue::ScaleXTransformOperation:         return TransformOperation::SCALE_X;
       
  6463         case WebKitCSSTransformValue::ScaleYTransformOperation:         return TransformOperation::SCALE_Y;
       
  6464         case WebKitCSSTransformValue::ScaleZTransformOperation:         return TransformOperation::SCALE_Z;
       
  6465         case WebKitCSSTransformValue::Scale3DTransformOperation:        return TransformOperation::SCALE_3D;
       
  6466         case WebKitCSSTransformValue::TranslateTransformOperation:      return TransformOperation::TRANSLATE;
       
  6467         case WebKitCSSTransformValue::TranslateXTransformOperation:     return TransformOperation::TRANSLATE_X;
       
  6468         case WebKitCSSTransformValue::TranslateYTransformOperation:     return TransformOperation::TRANSLATE_Y;
       
  6469         case WebKitCSSTransformValue::TranslateZTransformOperation:     return TransformOperation::TRANSLATE_Z;
       
  6470         case WebKitCSSTransformValue::Translate3DTransformOperation:    return TransformOperation::TRANSLATE_3D;
       
  6471         case WebKitCSSTransformValue::RotateTransformOperation:         return TransformOperation::ROTATE;
       
  6472         case WebKitCSSTransformValue::RotateXTransformOperation:        return TransformOperation::ROTATE_X;
       
  6473         case WebKitCSSTransformValue::RotateYTransformOperation:        return TransformOperation::ROTATE_Y;
       
  6474         case WebKitCSSTransformValue::RotateZTransformOperation:        return TransformOperation::ROTATE_Z;
       
  6475         case WebKitCSSTransformValue::Rotate3DTransformOperation:       return TransformOperation::ROTATE_3D;
       
  6476         case WebKitCSSTransformValue::SkewTransformOperation:           return TransformOperation::SKEW;
       
  6477         case WebKitCSSTransformValue::SkewXTransformOperation:          return TransformOperation::SKEW_X;
       
  6478         case WebKitCSSTransformValue::SkewYTransformOperation:          return TransformOperation::SKEW_Y;
       
  6479         case WebKitCSSTransformValue::MatrixTransformOperation:         return TransformOperation::MATRIX;
       
  6480         case WebKitCSSTransformValue::Matrix3DTransformOperation:       return TransformOperation::MATRIX_3D;
       
  6481         case WebKitCSSTransformValue::PerspectiveTransformOperation:    return TransformOperation::PERSPECTIVE;
       
  6482         case WebKitCSSTransformValue::UnknownTransformOperation:        return TransformOperation::NONE;
       
  6483     }
       
  6484     return TransformOperation::NONE;
       
  6485 }
       
  6486 
       
  6487 bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle* style, RenderStyle* rootStyle, TransformOperations& outOperations)
       
  6488 {
       
  6489     float zoomFactor = style ? style->effectiveZoom() : 1;
       
  6490 
       
  6491     TransformOperations operations;
       
  6492     if (inValue && !inValue->isPrimitiveValue()) {
       
  6493         CSSValueList* list = static_cast<CSSValueList*>(inValue);
       
  6494         unsigned size = list->length();
       
  6495         for (unsigned i = 0; i < size; i++) {
       
  6496             WebKitCSSTransformValue* val = static_cast<WebKitCSSTransformValue*>(list->itemWithoutBoundsCheck(i));
       
  6497             
       
  6498             CSSPrimitiveValue* firstValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(0));
       
  6499              
       
  6500             switch (val->operationType()) {
       
  6501                 case WebKitCSSTransformValue::ScaleTransformOperation:
       
  6502                 case WebKitCSSTransformValue::ScaleXTransformOperation:
       
  6503                 case WebKitCSSTransformValue::ScaleYTransformOperation: {
       
  6504                     double sx = 1.0;
       
  6505                     double sy = 1.0;
       
  6506                     if (val->operationType() == WebKitCSSTransformValue::ScaleYTransformOperation)
       
  6507                         sy = firstValue->getDoubleValue();
       
  6508                     else { 
       
  6509                         sx = firstValue->getDoubleValue();
       
  6510                         if (val->operationType() != WebKitCSSTransformValue::ScaleXTransformOperation) {
       
  6511                             if (val->length() > 1) {
       
  6512                                 CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1));
       
  6513                                 sy = secondValue->getDoubleValue();
       
  6514                             } else 
       
  6515                                 sy = sx;
       
  6516                         }
       
  6517                     }
       
  6518                     operations.operations().append(ScaleTransformOperation::create(sx, sy, 1.0, getTransformOperationType(val->operationType())));
       
  6519                     break;
       
  6520                 }
       
  6521                 case WebKitCSSTransformValue::ScaleZTransformOperation:
       
  6522                 case WebKitCSSTransformValue::Scale3DTransformOperation: {
       
  6523                     double sx = 1.0;
       
  6524                     double sy = 1.0;
       
  6525                     double sz = 1.0;
       
  6526                     if (val->operationType() == WebKitCSSTransformValue::ScaleZTransformOperation)
       
  6527                         sz = firstValue->getDoubleValue();
       
  6528                     else if (val->operationType() == WebKitCSSTransformValue::ScaleYTransformOperation)
       
  6529                         sy = firstValue->getDoubleValue();
       
  6530                     else { 
       
  6531                         sx = firstValue->getDoubleValue();
       
  6532                         if (val->operationType() != WebKitCSSTransformValue::ScaleXTransformOperation) {
       
  6533                             if (val->length() > 2) {
       
  6534                                 CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(2));
       
  6535                                 sz = thirdValue->getDoubleValue();
       
  6536                             }
       
  6537                             if (val->length() > 1) {
       
  6538                                 CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1));
       
  6539                                 sy = secondValue->getDoubleValue();
       
  6540                             } else 
       
  6541                                 sy = sx;
       
  6542                         }
       
  6543                     }
       
  6544                     operations.operations().append(ScaleTransformOperation::create(sx, sy, sz, getTransformOperationType(val->operationType())));
       
  6545                     break;
       
  6546                 }
       
  6547                 case WebKitCSSTransformValue::TranslateTransformOperation:
       
  6548                 case WebKitCSSTransformValue::TranslateXTransformOperation:
       
  6549                 case WebKitCSSTransformValue::TranslateYTransformOperation: {
       
  6550                     bool ok = true;
       
  6551                     Length tx = Length(0, Fixed);
       
  6552                     Length ty = Length(0, Fixed);
       
  6553                     if (val->operationType() == WebKitCSSTransformValue::TranslateYTransformOperation)
       
  6554                         ty = convertToLength(firstValue, style, rootStyle, zoomFactor, &ok);
       
  6555                     else { 
       
  6556                         tx = convertToLength(firstValue, style, rootStyle, zoomFactor, &ok);
       
  6557                         if (val->operationType() != WebKitCSSTransformValue::TranslateXTransformOperation) {
       
  6558                             if (val->length() > 1) {
       
  6559                                 CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1));
       
  6560                                 ty = convertToLength(secondValue, style, rootStyle, zoomFactor, &ok);
       
  6561                             }
       
  6562                         }
       
  6563                     }
       
  6564 
       
  6565                     if (!ok)
       
  6566                         return false;
       
  6567 
       
  6568                     operations.operations().append(TranslateTransformOperation::create(tx, ty, Length(0, Fixed), getTransformOperationType(val->operationType())));
       
  6569                     break;
       
  6570                 }
       
  6571                 case WebKitCSSTransformValue::TranslateZTransformOperation:
       
  6572                 case WebKitCSSTransformValue::Translate3DTransformOperation: {
       
  6573                     bool ok = true;
       
  6574                     Length tx = Length(0, Fixed);
       
  6575                     Length ty = Length(0, Fixed);
       
  6576                     Length tz = Length(0, Fixed);
       
  6577                     if (val->operationType() == WebKitCSSTransformValue::TranslateZTransformOperation)
       
  6578                         tz = convertToLength(firstValue, style, rootStyle, zoomFactor, &ok);
       
  6579                     else if (val->operationType() == WebKitCSSTransformValue::TranslateYTransformOperation)
       
  6580                         ty = convertToLength(firstValue, style, rootStyle, zoomFactor, &ok);
       
  6581                     else { 
       
  6582                         tx = convertToLength(firstValue, style, rootStyle, zoomFactor, &ok);
       
  6583                         if (val->operationType() != WebKitCSSTransformValue::TranslateXTransformOperation) {
       
  6584                             if (val->length() > 2) {
       
  6585                                 CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(2));
       
  6586                                 tz = convertToLength(thirdValue, style, rootStyle, zoomFactor, &ok);
       
  6587                             }
       
  6588                             if (val->length() > 1) {
       
  6589                                 CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1));
       
  6590                                 ty = convertToLength(secondValue, style, rootStyle, zoomFactor, &ok);
       
  6591                             }
       
  6592                         }
       
  6593                     }
       
  6594 
       
  6595                     if (!ok)
       
  6596                         return false;
       
  6597 
       
  6598                     operations.operations().append(TranslateTransformOperation::create(tx, ty, tz, getTransformOperationType(val->operationType())));
       
  6599                     break;
       
  6600                 }
       
  6601                 case WebKitCSSTransformValue::RotateTransformOperation: {
       
  6602                     double angle = firstValue->getDoubleValue();
       
  6603                     if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_RAD)
       
  6604                         angle = rad2deg(angle);
       
  6605                     else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD)
       
  6606                         angle = grad2deg(angle);
       
  6607                     else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_TURN)
       
  6608                         angle = turn2deg(angle);
       
  6609                     
       
  6610                     operations.operations().append(RotateTransformOperation::create(0, 0, 1, angle, getTransformOperationType(val->operationType())));
       
  6611                     break;
       
  6612                 }
       
  6613                 case WebKitCSSTransformValue::RotateXTransformOperation:
       
  6614                 case WebKitCSSTransformValue::RotateYTransformOperation:
       
  6615                 case WebKitCSSTransformValue::RotateZTransformOperation: {
       
  6616                     double x = 0;
       
  6617                     double y = 0;
       
  6618                     double z = 0;
       
  6619                     double angle = firstValue->getDoubleValue();
       
  6620                     if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_RAD)
       
  6621                         angle = rad2deg(angle);
       
  6622                     else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD)
       
  6623                         angle = grad2deg(angle);
       
  6624                     
       
  6625                     if (val->operationType() == WebKitCSSTransformValue::RotateXTransformOperation)
       
  6626                         x = 1;
       
  6627                     else if (val->operationType() == WebKitCSSTransformValue::RotateYTransformOperation)
       
  6628                         y = 1;
       
  6629                     else
       
  6630                         z = 1;
       
  6631                     operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(val->operationType())));
       
  6632                     break;
       
  6633                 }
       
  6634                 case WebKitCSSTransformValue::Rotate3DTransformOperation: {
       
  6635                     CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1));
       
  6636                     CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(2));
       
  6637                     CSSPrimitiveValue* fourthValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(3));
       
  6638                     double x = firstValue->getDoubleValue();
       
  6639                     double y = secondValue->getDoubleValue();
       
  6640                     double z = thirdValue->getDoubleValue();
       
  6641                     double angle = fourthValue->getDoubleValue();
       
  6642                     if (fourthValue->primitiveType() == CSSPrimitiveValue::CSS_RAD)
       
  6643                         angle = rad2deg(angle);
       
  6644                     else if (fourthValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD)
       
  6645                         angle = grad2deg(angle);
       
  6646                     operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(val->operationType())));
       
  6647                     break;
       
  6648                 }
       
  6649                 case WebKitCSSTransformValue::SkewTransformOperation:
       
  6650                 case WebKitCSSTransformValue::SkewXTransformOperation:
       
  6651                 case WebKitCSSTransformValue::SkewYTransformOperation: {
       
  6652                     double angleX = 0;
       
  6653                     double angleY = 0;
       
  6654                     double angle = firstValue->getDoubleValue();
       
  6655                     if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_RAD)
       
  6656                         angle = rad2deg(angle);
       
  6657                     else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD)
       
  6658                         angle = grad2deg(angle);
       
  6659                     else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_TURN)
       
  6660                         angle = turn2deg(angle);
       
  6661                     if (val->operationType() == WebKitCSSTransformValue::SkewYTransformOperation)
       
  6662                         angleY = angle;
       
  6663                     else {
       
  6664                         angleX = angle;
       
  6665                         if (val->operationType() == WebKitCSSTransformValue::SkewTransformOperation) {
       
  6666                             if (val->length() > 1) {
       
  6667                                 CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1));
       
  6668                                 angleY = secondValue->getDoubleValue();
       
  6669                                 if (secondValue->primitiveType() == CSSPrimitiveValue::CSS_RAD)
       
  6670                                     angleY = rad2deg(angleY);
       
  6671                                 else if (secondValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD)
       
  6672                                     angleY = grad2deg(angleY);
       
  6673                                 else if (secondValue->primitiveType() == CSSPrimitiveValue::CSS_TURN)
       
  6674                                     angleY = turn2deg(angleY);
       
  6675                             }
       
  6676                         }
       
  6677                     }
       
  6678                     operations.operations().append(SkewTransformOperation::create(angleX, angleY, getTransformOperationType(val->operationType())));
       
  6679                     break;
       
  6680                 }
       
  6681                 case WebKitCSSTransformValue::MatrixTransformOperation: {
       
  6682                     double a = firstValue->getDoubleValue();
       
  6683                     double b = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1))->getDoubleValue();
       
  6684                     double c = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(2))->getDoubleValue();
       
  6685                     double d = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(3))->getDoubleValue();
       
  6686                     double e = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(4))->getDoubleValue();
       
  6687                     double f = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(5))->getDoubleValue();
       
  6688                     operations.operations().append(MatrixTransformOperation::create(a, b, c, d, e, f));
       
  6689                     break;
       
  6690                 }
       
  6691                 case WebKitCSSTransformValue::Matrix3DTransformOperation: {
       
  6692                     TransformationMatrix matrix(static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(0))->getDoubleValue(),
       
  6693                                        static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1))->getDoubleValue(),
       
  6694                                        static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(2))->getDoubleValue(),
       
  6695                                        static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(3))->getDoubleValue(),
       
  6696                                        static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(4))->getDoubleValue(),
       
  6697                                        static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(5))->getDoubleValue(),
       
  6698                                        static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(6))->getDoubleValue(),
       
  6699                                        static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(7))->getDoubleValue(),
       
  6700                                        static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(8))->getDoubleValue(),
       
  6701                                        static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(9))->getDoubleValue(),
       
  6702                                        static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(10))->getDoubleValue(),
       
  6703                                        static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(11))->getDoubleValue(),
       
  6704                                        static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(12))->getDoubleValue(),
       
  6705                                        static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(13))->getDoubleValue(),
       
  6706                                        static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(14))->getDoubleValue(),
       
  6707                                        static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(15))->getDoubleValue());
       
  6708                     operations.operations().append(Matrix3DTransformOperation::create(matrix));
       
  6709                     break;
       
  6710                 }   
       
  6711                 case WebKitCSSTransformValue::PerspectiveTransformOperation: {
       
  6712                     double p = firstValue->getDoubleValue();
       
  6713                     if (p < 0.0)
       
  6714                         return false;
       
  6715                     operations.operations().append(PerspectiveTransformOperation::create(p));
       
  6716                     break;
       
  6717                 }
       
  6718                 case WebKitCSSTransformValue::UnknownTransformOperation:
       
  6719                     ASSERT_NOT_REACHED();
       
  6720                     break;
       
  6721             }
       
  6722         }
       
  6723     }
       
  6724     outOperations = operations;
       
  6725     return true;
       
  6726 }
       
  6727 
       
  6728 } // namespace WebCore