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