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