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     documentStyle->setUserModify(document->inDesignMode() ? READ_WRITE : READ_ONLY);
   1198 
   1199     Element* docElement = document->documentElement();
   1200     RenderObject* docElementRenderer = docElement ? docElement->renderer() : 0;
   1201     if (docElementRenderer) {
   1202         // Use the direction and writing-mode of the body to set the
   1203         // viewport's direction and writing-mode unless the property is set on the document element.
   1204         // If there is no body, then use the document element.
   1205         RenderObject* bodyRenderer = document->body() ? document->body()->renderer() : 0;
   1206         if (bodyRenderer && !document->writingModeSetOnDocumentElement())
   1207             documentStyle->setWritingMode(bodyRenderer->style()->writingMode());
   1208         else
   1209             documentStyle->setWritingMode(docElementRenderer->style()->writingMode());
   1210         if (bodyRenderer && !document->directionSetOnDocumentElement())
   1211             documentStyle->setDirection(bodyRenderer->style()->direction());
   1212         else
   1213             documentStyle->setDirection(docElementRenderer->style()->direction());
   1214     }
   1215 
   1216     FontDescription fontDescription;
   1217     fontDescription.setUsePrinterFont(document->printing());
   1218     if (Settings* settings = document->settings()) {
   1219         fontDescription.setRenderingMode(settings->fontRenderingMode());
   1220         if (document->printing() && !settings->shouldPrintBackgrounds())
   1221             documentStyle->setForceBackgroundsToWhite(true);
   1222         const AtomicString& stdfont = settings->standardFontFamily();
   1223         if (!stdfont.isEmpty()) {
   1224             fontDescription.firstFamily().setFamily(stdfont);
   1225             fontDescription.firstFamily().appendFamily(0);
   1226         }
   1227         fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
   1228         int size = CSSStyleSelector::fontSizeForKeyword(document, CSSValueMedium, false);
   1229         fontDescription.setSpecifiedSize(size);
   1230         bool useSVGZoomRules = document->isSVGDocument();
   1231         fontDescription.setComputedSize(CSSStyleSelector::getComputedSizeFromSpecifiedSize(document, documentStyle.get(), fontDescription.isAbsoluteSize(), size, useSVGZoomRules));
   1232     }
   1233 
   1234     documentStyle->setFontDescription(fontDescription);
   1235     documentStyle->font().update(0);
   1236 
   1237     return documentStyle.release();
   1238 }
   1239 
   1240 // If resolveForRootDefault is true, style based on user agent style sheet only. This is used in media queries, where
   1241 // relative units are interpreted according to document root element style, styled only with UA stylesheet
   1242 
   1243 PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* e, RenderStyle* defaultParent, bool allowSharing, bool resolveForRootDefault, bool matchVisitedPseudoClass)
   1244 {
   1245     // Once an element has a renderer, we don't try to destroy it, since otherwise the renderer
   1246     // will vanish if a style recalc happens during loading.
   1247     if (allowSharing && !e->document()->haveStylesheetsLoaded() && !e->renderer()) {
   1248         if (!s_styleNotYetAvailable) {
   1249             s_styleNotYetAvailable = RenderStyle::create().releaseRef();
   1250             s_styleNotYetAvailable->ref();
   1251             s_styleNotYetAvailable->setDisplay(NONE);
   1252             s_styleNotYetAvailable->font().update(m_fontSelector);
   1253         }
   1254         s_styleNotYetAvailable->ref();
   1255         e->document()->setHasNodesWithPlaceholderStyle();
   1256         return s_styleNotYetAvailable;
   1257     }
   1258 
   1259     initElement(e);
   1260     initForStyleResolve(e, defaultParent);
   1261     if (allowSharing) {
   1262         RenderStyle* sharedStyle = locateSharedStyle();
   1263         if (sharedStyle)
   1264             return sharedStyle;
   1265     }
   1266 
   1267     // Compute our style allowing :visited to match first.
   1268     RefPtr<RenderStyle> visitedStyle;
   1269     if (!matchVisitedPseudoClass && m_parentStyle && (m_parentStyle->insideLink() || e->isLink()) && e->document()->usesLinkRules()) {
   1270         // Fetch our parent style.
   1271         RenderStyle* parentStyle = m_parentStyle;
   1272         if (!e->isLink()) {
   1273             // Use the parent's visited style if one exists.
   1274             RenderStyle* parentVisitedStyle = m_parentStyle->getCachedPseudoStyle(VISITED_LINK);
   1275             if (parentVisitedStyle)
   1276                 parentStyle = parentVisitedStyle;
   1277         }
   1278         visitedStyle = styleForElement(e, parentStyle, false, false, true);
   1279         initForStyleResolve(e, defaultParent);
   1280     }
   1281 
   1282     m_checker.m_matchVisitedPseudoClass = matchVisitedPseudoClass;
   1283 
   1284     m_style = RenderStyle::create();
   1285 
   1286     if (m_parentStyle)
   1287         m_style->inheritFrom(m_parentStyle);
   1288     else {
   1289         m_parentStyle = style();
   1290         // Make sure our fonts are initialized if we don't inherit them from our parent style.
   1291         m_style->font().update(0);
   1292     }
   1293 
   1294     if (e->isLink()) {
   1295         m_style->setIsLink(true);
   1296         m_style->setInsideLink(m_elementLinkState);
   1297     }
   1298 
   1299     if (visitedStyle) {
   1300         // Copy any pseudo bits that the visited style has to the primary style so that
   1301         // pseudo element styles will continue to work for pseudo elements inside :visited
   1302         // links.
   1303         for (unsigned pseudo = FIRST_PUBLIC_PSEUDOID; pseudo < FIRST_INTERNAL_PSEUDOID; ++pseudo) {
   1304             if (visitedStyle->hasPseudoStyle(static_cast<PseudoId>(pseudo)))
   1305                 m_style->setHasPseudoStyle(static_cast<PseudoId>(pseudo));
   1306         }
   1307         if (m_elementLinkState == InsideUnvisitedLink)
   1308             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.
   1309         else
   1310             visitedStyle->setStyleType(VISITED_LINK);
   1311     }
   1312 
   1313     if (simpleDefaultStyleSheet && !elementCanUseSimpleDefaultStyle(e)) {
   1314         loadFullDefaultStyle();
   1315         assertNoSiblingRulesInDefaultStyle();
   1316     }
   1317 
   1318 #if ENABLE(SVG)
   1319     static bool loadedSVGUserAgentSheet;
   1320     if (e->isSVGElement() && !loadedSVGUserAgentSheet) {
   1321         // SVG rules.
   1322         loadedSVGUserAgentSheet = true;
   1323         CSSStyleSheet* svgSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet));
   1324         defaultStyle->addRulesFromSheet(svgSheet, screenEval());
   1325         defaultPrintStyle->addRulesFromSheet(svgSheet, printEval());
   1326         assertNoSiblingRulesInDefaultStyle();
   1327     }
   1328 #endif
   1329 
   1330 #if ENABLE(MATHML)
   1331     static bool loadedMathMLUserAgentSheet;
   1332     if (e->isMathMLElement() && !loadedMathMLUserAgentSheet) {
   1333         // MathML rules.
   1334         loadedMathMLUserAgentSheet = true;
   1335         CSSStyleSheet* mathMLSheet = parseUASheet(mathmlUserAgentStyleSheet, sizeof(mathmlUserAgentStyleSheet));
   1336         defaultStyle->addRulesFromSheet(mathMLSheet, screenEval());
   1337         defaultPrintStyle->addRulesFromSheet(mathMLSheet, printEval());
   1338         // There are some sibling rules here.
   1339         collectSiblingRulesInDefaultStyle();
   1340     }
   1341 #endif
   1342 
   1343 #if ENABLE(WML)
   1344     static bool loadedWMLUserAgentSheet;
   1345     if (e->isWMLElement() && !loadedWMLUserAgentSheet) {
   1346         // WML rules.
   1347         loadedWMLUserAgentSheet = true;
   1348         CSSStyleSheet* wmlSheet = parseUASheet(wmlUserAgentStyleSheet, sizeof(wmlUserAgentStyleSheet));
   1349         defaultStyle->addRulesFromSheet(wmlSheet, screenEval());
   1350         defaultPrintStyle->addRulesFromSheet(wmlSheet, printEval());
   1351         assertNoSiblingRulesInDefaultStyle();
   1352     }
   1353 #endif
   1354 
   1355 #if ENABLE(VIDEO)
   1356     static bool loadedMediaStyleSheet;
   1357     if (!loadedMediaStyleSheet && (e->hasTagName(videoTag) || e->hasTagName(audioTag))) {
   1358         loadedMediaStyleSheet = true;
   1359         String mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + RenderTheme::themeForPage(e->document()->page())->extraMediaControlsStyleSheet();
   1360         CSSStyleSheet* mediaControlsSheet = parseUASheet(mediaRules);
   1361         defaultStyle->addRulesFromSheet(mediaControlsSheet, screenEval());
   1362         defaultPrintStyle->addRulesFromSheet(mediaControlsSheet, printEval());
   1363         assertNoSiblingRulesInDefaultStyle();
   1364     }
   1365 #endif
   1366 
   1367 #if ENABLE(FULLSCREEN_API)
   1368     static bool loadedFullScreenStyleSheet;
   1369     if (!loadedFullScreenStyleSheet && e->document()->webkitIsFullScreen()) {
   1370         loadedFullScreenStyleSheet = true;
   1371         String fullscreenRules = String(fullscreenUserAgentStyleSheet, sizeof(fullscreenUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraFullScreenStyleSheet();
   1372         CSSStyleSheet* fullscreenSheet = parseUASheet(fullscreenRules);
   1373         defaultStyle->addRulesFromSheet(fullscreenSheet, screenEval());
   1374         defaultQuirksStyle->addRulesFromSheet(fullscreenSheet, screenEval());
   1375     }
   1376 #endif
   1377 
   1378     int firstUARule = -1, lastUARule = -1;
   1379     int firstUserRule = -1, lastUserRule = -1;
   1380     int firstAuthorRule = -1, lastAuthorRule = -1;
   1381     matchUARules(firstUARule, lastUARule);
   1382 
   1383     if (!resolveForRootDefault) {
   1384         // 4. Now we check user sheet rules.
   1385         if (m_matchAuthorAndUserStyles)
   1386             matchRules(m_userStyle.get(), firstUserRule, lastUserRule, false);
   1387 
   1388         // 5. Now check author rules, beginning first with presentational attributes
   1389         // mapped from HTML.
   1390         if (m_styledElement) {
   1391             // Ask if the HTML element has mapped attributes.
   1392             if (m_styledElement->hasMappedAttributes()) {
   1393                 // Walk our attribute list and add in each decl.
   1394                 const NamedNodeMap* map = m_styledElement->attributeMap();
   1395                 for (unsigned i = 0; i < map->length(); i++) {
   1396                     Attribute* attr = map->attributeItem(i);
   1397                     if (attr->isMappedAttribute() && attr->decl()) {
   1398                         lastAuthorRule = m_matchedDecls.size();
   1399                         if (firstAuthorRule == -1)
   1400                             firstAuthorRule = lastAuthorRule;
   1401                         addMatchedDeclaration(attr->decl());
   1402                     }
   1403                 }
   1404             }
   1405 
   1406             // Now we check additional mapped declarations.
   1407             // Tables and table cells share an additional mapped rule that must be applied
   1408             // after all attributes, since their mapped style depends on the values of multiple attributes.
   1409             if (m_styledElement->canHaveAdditionalAttributeStyleDecls()) {
   1410                 m_additionalAttributeStyleDecls.clear();
   1411                 m_styledElement->additionalAttributeStyleDecls(m_additionalAttributeStyleDecls);
   1412                 if (!m_additionalAttributeStyleDecls.isEmpty()) {
   1413                     unsigned additionalDeclsSize = m_additionalAttributeStyleDecls.size();
   1414                     if (firstAuthorRule == -1)
   1415                         firstAuthorRule = m_matchedDecls.size();
   1416                     lastAuthorRule = m_matchedDecls.size() + additionalDeclsSize - 1;
   1417                     for (unsigned i = 0; i < additionalDeclsSize; i++)
   1418                         addMatchedDeclaration(m_additionalAttributeStyleDecls[i]);
   1419                 }
   1420             }
   1421             if (m_styledElement->isHTMLElement()) {
   1422                 bool isAuto;
   1423                 TextDirection textDirection = toHTMLElement(m_styledElement)->directionalityIfhasDirAutoAttribute(isAuto);
   1424                 if (isAuto)
   1425                     addMatchedDeclaration(textDirection == LTR ? leftToRightDeclaration() : rightToLeftDeclaration());
   1426             }
   1427         }
   1428 
   1429         // 6. Check the rules in author sheets next.
   1430         if (m_matchAuthorAndUserStyles)
   1431             matchRules(m_authorStyle.get(), firstAuthorRule, lastAuthorRule, false);
   1432 
   1433         // 7. Now check our inline style attribute.
   1434         if (m_matchAuthorAndUserStyles && m_styledElement) {
   1435             CSSMutableStyleDeclaration* inlineDecl = m_styledElement->inlineStyleDecl();
   1436             if (inlineDecl) {
   1437                 lastAuthorRule = m_matchedDecls.size();
   1438                 if (firstAuthorRule == -1)
   1439                     firstAuthorRule = lastAuthorRule;
   1440                 addMatchedDeclaration(inlineDecl);
   1441             }
   1442         }
   1443     }
   1444 
   1445     // Reset the value back before applying properties, so that -webkit-link knows what color to use.
   1446     m_checker.m_matchVisitedPseudoClass = matchVisitedPseudoClass;
   1447 
   1448     // Now we have all of the matched rules in the appropriate order.  Walk the rules and apply
   1449     // high-priority properties first, i.e., those properties that other properties depend on.
   1450     // The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
   1451     // and (4) normal important.
   1452     m_lineHeightValue = 0;
   1453     applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
   1454     if (!resolveForRootDefault) {
   1455         applyDeclarations<true>(true, firstAuthorRule, lastAuthorRule);
   1456         applyDeclarations<true>(true, firstUserRule, lastUserRule);
   1457     }
   1458     applyDeclarations<true>(true, firstUARule, lastUARule);
   1459 
   1460     // If our font got dirtied, go ahead and update it now.
   1461     if (m_fontDirty)
   1462         updateFont();
   1463 
   1464     // Line-height is set when we are sure we decided on the font-size
   1465     if (m_lineHeightValue)
   1466         applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
   1467 
   1468     // Now do the normal priority UA properties.
   1469     applyDeclarations<false>(false, firstUARule, lastUARule);
   1470 
   1471     // Cache our border and background so that we can examine them later.
   1472     cacheBorderAndBackground();
   1473 
   1474     // Now do the author and user normal priority properties and all the !important properties.
   1475     if (!resolveForRootDefault) {
   1476         applyDeclarations<false>(false, lastUARule + 1, m_matchedDecls.size() - 1);
   1477         applyDeclarations<false>(true, firstAuthorRule, lastAuthorRule);
   1478         applyDeclarations<false>(true, firstUserRule, lastUserRule);
   1479     }
   1480     applyDeclarations<false>(true, firstUARule, lastUARule);
   1481 
   1482     ASSERT(!m_fontDirty);
   1483     // If our font got dirtied by one of the non-essential font props,
   1484     // go ahead and update it a second time.
   1485     if (m_fontDirty)
   1486         updateFont();
   1487 
   1488     // Clean up our style object's display and text decorations (among other fixups).
   1489     adjustRenderStyle(style(), m_parentStyle, e);
   1490 
   1491     // Start loading images referenced by this style.
   1492     loadPendingImages();
   1493 
   1494     // If we have first-letter pseudo style, do not share this style
   1495     if (m_style->hasPseudoStyle(FIRST_LETTER))
   1496         m_style->setUnique();
   1497 
   1498     if (visitedStyle) {
   1499         // Add the visited style off the main style.
   1500         m_style->addCachedPseudoStyle(visitedStyle.release());
   1501     }
   1502 
   1503     if (!matchVisitedPseudoClass)
   1504         initElement(0); // Clear out for the next resolve.
   1505 
   1506     // Now return the style.
   1507     return m_style.release();
   1508 }
   1509 
   1510 PassRefPtr<RenderStyle> CSSStyleSelector::styleForKeyframe(const RenderStyle* elementStyle, const WebKitCSSKeyframeRule* keyframeRule, KeyframeValue& keyframe)
   1511 {
   1512     if (keyframeRule->style())
   1513         addMatchedDeclaration(keyframeRule->style());
   1514 
   1515     ASSERT(!m_style);
   1516 
   1517     // Create the style
   1518     m_style = RenderStyle::clone(elementStyle);
   1519 
   1520     m_lineHeightValue = 0;
   1521 
   1522     // We don't need to bother with !important. Since there is only ever one
   1523     // decl, there's nothing to override. So just add the first properties.
   1524     if (keyframeRule->style())
   1525         applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
   1526 
   1527     // If our font got dirtied, go ahead and update it now.
   1528     if (m_fontDirty)
   1529         updateFont();
   1530 
   1531     // Line-height is set when we are sure we decided on the font-size
   1532     if (m_lineHeightValue)
   1533         applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
   1534 
   1535     // Now do rest of the properties.
   1536     if (keyframeRule->style())
   1537         applyDeclarations<false>(false, 0, m_matchedDecls.size() - 1);
   1538 
   1539     // If our font got dirtied by one of the non-essential font props,
   1540     // go ahead and update it a second time.
   1541     if (m_fontDirty)
   1542         updateFont();
   1543 
   1544     // Start loading images referenced by this style.
   1545     loadPendingImages();
   1546 
   1547     // Add all the animating properties to the keyframe.
   1548     if (keyframeRule->style()) {
   1549         CSSMutableStyleDeclaration::const_iterator end = keyframeRule->style()->end();
   1550         for (CSSMutableStyleDeclaration::const_iterator it = keyframeRule->style()->begin(); it != end; ++it) {
   1551             int property = (*it).id();
   1552             // Timing-function within keyframes is special, because it is not animated; it just
   1553             // describes the timing function between this keyframe and the next.
   1554             if (property != CSSPropertyWebkitAnimationTimingFunction)
   1555                 keyframe.addProperty(property);
   1556         }
   1557     }
   1558 
   1559     return m_style.release();
   1560 }
   1561 
   1562 void CSSStyleSelector::keyframeStylesForAnimation(Element* e, const RenderStyle* elementStyle, KeyframeList& list)
   1563 {
   1564     list.clear();
   1565 
   1566     // Get the keyframesRule for this name
   1567     if (!e || list.animationName().isEmpty())
   1568         return;
   1569 
   1570     m_keyframesRuleMap.checkConsistency();
   1571 
   1572     if (!m_keyframesRuleMap.contains(list.animationName().impl()))
   1573         return;
   1574 
   1575     const WebKitCSSKeyframesRule* rule = m_keyframesRuleMap.find(list.animationName().impl()).get()->second.get();
   1576 
   1577     // Construct and populate the style for each keyframe
   1578     for (unsigned i = 0; i < rule->length(); ++i) {
   1579         // Apply the declaration to the style. This is a simplified version of the logic in styleForElement
   1580         initElement(e);
   1581         initForStyleResolve(e);
   1582 
   1583         const WebKitCSSKeyframeRule* keyframeRule = rule->item(i);
   1584 
   1585         KeyframeValue keyframe(0, 0);
   1586         keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule, keyframe));
   1587 
   1588         // Add this keyframe style to all the indicated key times
   1589         Vector<float> keys;
   1590         keyframeRule->getKeys(keys);
   1591         for (size_t keyIndex = 0; keyIndex < keys.size(); ++keyIndex) {
   1592             keyframe.setKey(keys[keyIndex]);
   1593             list.insert(keyframe);
   1594         }
   1595     }
   1596 
   1597     // If the 0% keyframe is missing, create it (but only if there is at least one other keyframe)
   1598     int initialListSize = list.size();
   1599     if (initialListSize > 0 && list[0].key() != 0) {
   1600         RefPtr<WebKitCSSKeyframeRule> keyframeRule = WebKitCSSKeyframeRule::create();
   1601         keyframeRule->setKeyText("0%");
   1602         KeyframeValue keyframe(0, 0);
   1603         keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule.get(), keyframe));
   1604         list.insert(keyframe);
   1605     }
   1606 
   1607     // If the 100% keyframe is missing, create it (but only if there is at least one other keyframe)
   1608     if (initialListSize > 0 && (list[list.size() - 1].key() != 1)) {
   1609         RefPtr<WebKitCSSKeyframeRule> keyframeRule = WebKitCSSKeyframeRule::create();
   1610         keyframeRule->setKeyText("100%");
   1611         KeyframeValue keyframe(1, 0);
   1612         keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule.get(), keyframe));
   1613         list.insert(keyframe);
   1614     }
   1615 }
   1616 
   1617 PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(PseudoId pseudo, Element* e, RenderStyle* parentStyle, bool matchVisitedPseudoClass)
   1618 {
   1619     if (!e)
   1620         return 0;
   1621 
   1622     initElement(e);
   1623 
   1624     // Compute our :visited style first, so that we know whether or not we'll need to create a normal style just to hang it
   1625     // off of.
   1626     RefPtr<RenderStyle> visitedStyle;
   1627     if (!matchVisitedPseudoClass && parentStyle && parentStyle->insideLink()) {
   1628         // Fetch our parent style with :visited in effect.
   1629         RenderStyle* parentVisitedStyle = parentStyle->getCachedPseudoStyle(VISITED_LINK);
   1630         visitedStyle = pseudoStyleForElement(pseudo, e, parentVisitedStyle ? parentVisitedStyle : parentStyle, true);
   1631         if (visitedStyle)
   1632             visitedStyle->setStyleType(VISITED_LINK);
   1633     }
   1634 
   1635     initForStyleResolve(e, parentStyle, pseudo);
   1636     m_style = RenderStyle::create();
   1637     if (parentStyle)
   1638         m_style->inheritFrom(parentStyle);
   1639 
   1640     m_checker.m_matchVisitedPseudoClass = matchVisitedPseudoClass;
   1641 
   1642     // Since we don't use pseudo-elements in any of our quirk/print user agent rules, don't waste time walking
   1643     // those rules.
   1644 
   1645     // Check UA, user and author rules.
   1646     int firstUARule = -1, lastUARule = -1, firstUserRule = -1, lastUserRule = -1, firstAuthorRule = -1, lastAuthorRule = -1;
   1647     matchUARules(firstUARule, lastUARule);
   1648 
   1649     if (m_matchAuthorAndUserStyles) {
   1650         matchRules(m_userStyle.get(), firstUserRule, lastUserRule, false);
   1651         matchRules(m_authorStyle.get(), firstAuthorRule, lastAuthorRule, false);
   1652     }
   1653 
   1654     if (m_matchedDecls.isEmpty() && !visitedStyle)
   1655         return 0;
   1656 
   1657     m_style->setStyleType(pseudo);
   1658 
   1659     m_lineHeightValue = 0;
   1660 
   1661     // Reset the value back before applying properties, so that -webkit-link knows what color to use.
   1662     m_checker.m_matchVisitedPseudoClass = matchVisitedPseudoClass;
   1663 
   1664     // High-priority properties.
   1665     applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
   1666     applyDeclarations<true>(true, firstAuthorRule, lastAuthorRule);
   1667     applyDeclarations<true>(true, firstUserRule, lastUserRule);
   1668     applyDeclarations<true>(true, firstUARule, lastUARule);
   1669 
   1670     // If our font got dirtied, go ahead and update it now.
   1671     if (m_fontDirty)
   1672         updateFont();
   1673 
   1674     // Line-height is set when we are sure we decided on the font-size
   1675     if (m_lineHeightValue)
   1676         applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
   1677 
   1678     // Now do the normal priority properties.
   1679     applyDeclarations<false>(false, firstUARule, lastUARule);
   1680 
   1681     // Cache our border and background so that we can examine them later.
   1682     cacheBorderAndBackground();
   1683 
   1684     applyDeclarations<false>(false, lastUARule + 1, m_matchedDecls.size() - 1);
   1685     applyDeclarations<false>(true, firstAuthorRule, lastAuthorRule);
   1686     applyDeclarations<false>(true, firstUserRule, lastUserRule);
   1687     applyDeclarations<false>(true, firstUARule, lastUARule);
   1688 
   1689     // If our font got dirtied by one of the non-essential font props,
   1690     // go ahead and update it a second time.
   1691     if (m_fontDirty)
   1692         updateFont();
   1693 
   1694     // Clean up our style object's display and text decorations (among other fixups).
   1695     adjustRenderStyle(style(), parentStyle, 0);
   1696 
   1697     // Start loading images referenced by this style.
   1698     loadPendingImages();
   1699 
   1700     // Hang our visited style off m_style.
   1701     if (visitedStyle)
   1702         m_style->addCachedPseudoStyle(visitedStyle.release());
   1703 
   1704     // Now return the style.
   1705     return m_style.release();
   1706 }
   1707 
   1708 PassRefPtr<RenderStyle> CSSStyleSelector::styleForPage(int pageIndex)
   1709 {
   1710     initForStyleResolve(m_checker.m_document->documentElement()); // m_rootElementStyle will be set to the document style.
   1711 
   1712     m_style = RenderStyle::create();
   1713     m_style->inheritFrom(m_rootElementStyle);
   1714 
   1715     const bool isLeft = isLeftPage(pageIndex);
   1716     const bool isFirst = isFirstPage(pageIndex);
   1717     const String page = pageName(pageIndex);
   1718     matchPageRules(defaultPrintStyle, isLeft, isFirst, page);
   1719     matchPageRules(m_userStyle.get(), isLeft, isFirst, page);
   1720     matchPageRules(m_authorStyle.get(), isLeft, isFirst, page);
   1721     m_lineHeightValue = 0;
   1722     applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
   1723 
   1724     // If our font got dirtied, go ahead and update it now.
   1725     if (m_fontDirty)
   1726         updateFont();
   1727 
   1728     // Line-height is set when we are sure we decided on the font-size
   1729     if (m_lineHeightValue)
   1730         applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
   1731 
   1732     applyDeclarations<false>(false, 0, m_matchedDecls.size() - 1);
   1733 
   1734     // Start loading images referenced by this style.
   1735     loadPendingImages();
   1736 
   1737     // Now return the style.
   1738     return m_style.release();
   1739 }
   1740 
   1741 #if ENABLE(DATAGRID)
   1742 
   1743 PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForDataGridColumn(DataGridColumn*, RenderStyle*)
   1744 {
   1745     // FIXME: Implement
   1746     return 0;
   1747 }
   1748 
   1749 PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForDataGridColumnHeader(DataGridColumn*, RenderStyle*)
   1750 {
   1751     // FIXME: Implement
   1752     return 0;
   1753 }
   1754 
   1755 #endif
   1756 
   1757 static void addIntrinsicMargins(RenderStyle* style)
   1758 {
   1759     // Intrinsic margin value.
   1760     const int intrinsicMargin = 2 * style->effectiveZoom();
   1761 
   1762     // FIXME: Using width/height alone and not also dealing with min-width/max-width is flawed.
   1763     // FIXME: Using "quirk" to decide the margin wasn't set is kind of lame.
   1764     if (style->width().isIntrinsicOrAuto()) {
   1765         if (style->marginLeft().quirk())
   1766             style->setMarginLeft(Length(intrinsicMargin, Fixed));
   1767         if (style->marginRight().quirk())
   1768             style->setMarginRight(Length(intrinsicMargin, Fixed));
   1769     }
   1770 
   1771     if (style->height().isAuto()) {
   1772         if (style->marginTop().quirk())
   1773             style->setMarginTop(Length(intrinsicMargin, Fixed));
   1774         if (style->marginBottom().quirk())
   1775             style->setMarginBottom(Length(intrinsicMargin, Fixed));
   1776     }
   1777 }
   1778 
   1779 static inline bool isAtShadowBoundary(Element* element)
   1780 {
   1781     if (!element)
   1782         return false;
   1783 
   1784     ContainerNode* parentNode = element->parentNode();
   1785     return parentNode && parentNode->isShadowBoundary();
   1786 }
   1787 
   1788 void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, RenderStyle* parentStyle, Element *e)
   1789 {
   1790     // Cache our original display.
   1791     style->setOriginalDisplay(style->display());
   1792 
   1793     if (style->display() != NONE) {
   1794         // If we have a <td> that specifies a float property, in quirks mode we just drop the float
   1795         // property.
   1796         // Sites also commonly use display:inline/block on <td>s and <table>s.  In quirks mode we force
   1797         // these tags to retain their display types.
   1798         if (!m_checker.m_strictParsing && e) {
   1799             if (e->hasTagName(tdTag)) {
   1800                 style->setDisplay(TABLE_CELL);
   1801                 style->setFloating(FNONE);
   1802             }
   1803             else if (e->hasTagName(tableTag))
   1804                 style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE);
   1805         }
   1806 
   1807         if (e && (e->hasTagName(tdTag) || e->hasTagName(thTag))) {
   1808             if (style->whiteSpace() == KHTML_NOWRAP) {
   1809                 // Figure out if we are really nowrapping or if we should just
   1810                 // use normal instead.  If the width of the cell is fixed, then
   1811                 // we don't actually use NOWRAP.
   1812                 if (style->width().isFixed())
   1813                     style->setWhiteSpace(NORMAL);
   1814                 else
   1815                     style->setWhiteSpace(NOWRAP);
   1816             }
   1817         }
   1818 
   1819         // Tables never support the -webkit-* values for text-align and will reset back to the default.
   1820         if (e && e->hasTagName(tableTag) && (style->textAlign() == WEBKIT_LEFT || style->textAlign() == WEBKIT_CENTER || style->textAlign() == WEBKIT_RIGHT))
   1821             style->setTextAlign(TAAUTO);
   1822 
   1823         // Frames and framesets never honor position:relative or position:absolute.  This is necessary to
   1824         // fix a crash where a site tries to position these objects.  They also never honor display.
   1825         if (e && (e->hasTagName(frameTag) || e->hasTagName(framesetTag))) {
   1826             style->setPosition(StaticPosition);
   1827             style->setDisplay(BLOCK);
   1828         }
   1829 
   1830         // Table headers with a text-align of auto will change the text-align to center.
   1831         if (e && e->hasTagName(thTag) && style->textAlign() == TAAUTO)
   1832             style->setTextAlign(CENTER);
   1833 
   1834         if (e && e->hasTagName(legendTag))
   1835             style->setDisplay(BLOCK);
   1836 
   1837         // Mutate the display to BLOCK or TABLE for certain cases, e.g., if someone attempts to
   1838         // position or float an inline, compact, or run-in.  Cache the original display, since it
   1839         // may be needed for positioned elements that have to compute their static normal flow
   1840         // positions.  We also force inline-level roots to be block-level.
   1841         if (style->display() != BLOCK && style->display() != TABLE && style->display() != BOX &&
   1842             (style->position() == AbsolutePosition || style->position() == FixedPosition || style->floating() != FNONE ||
   1843              (e && e->document()->documentElement() == e))) {
   1844             if (style->display() == INLINE_TABLE)
   1845                 style->setDisplay(TABLE);
   1846             else if (style->display() == INLINE_BOX)
   1847                 style->setDisplay(BOX);
   1848             else if (style->display() == LIST_ITEM) {
   1849                 // It is a WinIE bug that floated list items lose their bullets, so we'll emulate the quirk,
   1850                 // but only in quirks mode.
   1851                 if (!m_checker.m_strictParsing && style->floating() != FNONE)
   1852                     style->setDisplay(BLOCK);
   1853             }
   1854             else
   1855                 style->setDisplay(BLOCK);
   1856         }
   1857 
   1858         // FIXME: Don't support this mutation for pseudo styles like first-letter or first-line, since it's not completely
   1859         // clear how that should work.
   1860         if (style->display() == INLINE && style->styleType() == NOPSEUDO && parentStyle && style->writingMode() != parentStyle->writingMode())
   1861             style->setDisplay(INLINE_BLOCK);
   1862 
   1863         // After performing the display mutation, check table rows.  We do not honor position:relative on
   1864         // table rows or cells.  This has been established in CSS2.1 (and caused a crash in containingBlock()
   1865         // on some sites).
   1866         if ((style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW_GROUP
   1867              || style->display() == TABLE_FOOTER_GROUP || style->display() == TABLE_ROW) &&
   1868              style->position() == RelativePosition)
   1869             style->setPosition(StaticPosition);
   1870 
   1871         // writing-mode does not apply to table row groups, table column groups, table rows, and table columns.
   1872         // FIXME: Table cells should be allowed to be perpendicular or flipped with respect to the table, though.
   1873         if (style->display() == TABLE_COLUMN || style->display() == TABLE_COLUMN_GROUP || style->display() == TABLE_FOOTER_GROUP
   1874             || style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW || style->display() == TABLE_ROW_GROUP
   1875             || style->display() == TABLE_CELL)
   1876             style->setWritingMode(parentStyle->writingMode());
   1877 
   1878         // FIXME: Since we don't support block-flow on flexible boxes yet, disallow setting
   1879         // of block-flow to anything other than TopToBottomWritingMode.
   1880         // https://bugs.webkit.org/show_bug.cgi?id=46418 - Flexible box support.
   1881         if (style->writingMode() != TopToBottomWritingMode && (style->display() == BOX || style->display() == INLINE_BOX))
   1882             style->setWritingMode(TopToBottomWritingMode);
   1883     }
   1884 
   1885     // Make sure our z-index value is only applied if the object is positioned.
   1886     if (style->position() == StaticPosition)
   1887         style->setHasAutoZIndex();
   1888 
   1889     // Auto z-index becomes 0 for the root element and transparent objects.  This prevents
   1890     // cases where objects that should be blended as a single unit end up with a non-transparent
   1891     // object wedged in between them.  Auto z-index also becomes 0 for objects that specify transforms/masks/reflections.
   1892     if (style->hasAutoZIndex() && ((e && e->document()->documentElement() == e) || style->opacity() < 1.0f ||
   1893         style->hasTransformRelatedProperty() || style->hasMask() || style->boxReflect()))
   1894         style->setZIndex(0);
   1895 
   1896 #if ENABLE(WML)
   1897     if (e && (e->hasTagName(WMLNames::insertedLegendTag)
   1898               || e->hasTagName(WMLNames::inputTag))
   1899             && style->width().isAuto())
   1900         style->setWidth(Length(Intrinsic));
   1901 #endif
   1902 
   1903     // Textarea considers overflow visible as auto.
   1904     if (e && e->hasTagName(textareaTag)) {
   1905         style->setOverflowX(style->overflowX() == OVISIBLE ? OAUTO : style->overflowX());
   1906         style->setOverflowY(style->overflowY() == OVISIBLE ? OAUTO : style->overflowY());
   1907     }
   1908 
   1909     // Finally update our text decorations in effect, but don't allow text-decoration to percolate through
   1910     // tables, inline blocks, inline tables, run-ins, or shadow DOM.
   1911     if (style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN
   1912         || style->display() == INLINE_BLOCK || style->display() == INLINE_BOX || isAtShadowBoundary(e))
   1913         style->setTextDecorationsInEffect(style->textDecoration());
   1914     else
   1915         style->addToTextDecorationsInEffect(style->textDecoration());
   1916 
   1917     // If either overflow value is not visible, change to auto.
   1918     if (style->overflowX() == OMARQUEE && style->overflowY() != OMARQUEE)
   1919         style->setOverflowY(OMARQUEE);
   1920     else if (style->overflowY() == OMARQUEE && style->overflowX() != OMARQUEE)
   1921         style->setOverflowX(OMARQUEE);
   1922     else if (style->overflowX() == OVISIBLE && style->overflowY() != OVISIBLE)
   1923         style->setOverflowX(OAUTO);
   1924     else if (style->overflowY() == OVISIBLE && style->overflowX() != OVISIBLE)
   1925         style->setOverflowY(OAUTO);
   1926 
   1927     // Table rows, sections and the table itself will support overflow:hidden and will ignore scroll/auto.
   1928     // FIXME: Eventually table sections will support auto and scroll.
   1929     if (style->display() == TABLE || style->display() == INLINE_TABLE ||
   1930         style->display() == TABLE_ROW_GROUP || style->display() == TABLE_ROW) {
   1931         if (style->overflowX() != OVISIBLE && style->overflowX() != OHIDDEN)
   1932             style->setOverflowX(OVISIBLE);
   1933         if (style->overflowY() != OVISIBLE && style->overflowY() != OHIDDEN)
   1934             style->setOverflowY(OVISIBLE);
   1935     }
   1936 
   1937     // Menulists should have visible overflow
   1938     if (style->appearance() == MenulistPart) {
   1939         style->setOverflowX(OVISIBLE);
   1940         style->setOverflowY(OVISIBLE);
   1941     }
   1942 
   1943     // Cull out any useless layers and also repeat patterns into additional layers.
   1944     style->adjustBackgroundLayers();
   1945     style->adjustMaskLayers();
   1946 
   1947     // Do the same for animations and transitions.
   1948     style->adjustAnimations();
   1949     style->adjustTransitions();
   1950 
   1951     // Important: Intrinsic margins get added to controls before the theme has adjusted the style, since the theme will
   1952     // alter fonts and heights/widths.
   1953     if (e && e->isFormControlElement() && style->fontSize() >= 11) {
   1954         // Don't apply intrinsic margins to image buttons.  The designer knows how big the images are,
   1955         // so we have to treat all image buttons as though they were explicitly sized.
   1956         if (!e->hasTagName(inputTag) || !static_cast<HTMLInputElement*>(e)->isImageButton())
   1957             addIntrinsicMargins(style);
   1958     }
   1959 
   1960     // Let the theme also have a crack at adjusting the style.
   1961     if (style->hasAppearance())
   1962         RenderTheme::defaultTheme()->adjustStyle(this, style, e, m_hasUAAppearance, m_borderData, m_backgroundData, m_backgroundColor);
   1963 
   1964 #if ENABLE(SVG)
   1965     if (e && e->isSVGElement()) {
   1966         // Spec: http://www.w3.org/TR/SVG/masking.html#OverflowProperty
   1967         if (style->overflowY() == OSCROLL)
   1968             style->setOverflowY(OHIDDEN);
   1969         else if (style->overflowY() == OAUTO)
   1970             style->setOverflowY(OVISIBLE);
   1971 
   1972         if (style->overflowX() == OSCROLL)
   1973             style->setOverflowX(OHIDDEN);
   1974         else if (style->overflowX() == OAUTO)
   1975             style->setOverflowX(OVISIBLE);
   1976 
   1977         // Only the root <svg> element in an SVG document fragment tree honors css position
   1978         if (!(e->hasTagName(SVGNames::svgTag) && e->parentNode() && !e->parentNode()->isSVGElement()))
   1979             style->setPosition(RenderStyle::initialPosition());
   1980     }
   1981 #endif
   1982 }
   1983 
   1984 void CSSStyleSelector::updateFont()
   1985 {
   1986     checkForTextSizeAdjust();
   1987     checkForGenericFamilyChange(style(), m_parentStyle);
   1988     checkForZoomChange(style(), m_parentStyle);
   1989     m_style->font().update(m_fontSelector);
   1990     m_fontDirty = false;
   1991 }
   1992 
   1993 void CSSStyleSelector::cacheBorderAndBackground()
   1994 {
   1995     m_hasUAAppearance = m_style->hasAppearance();
   1996     if (m_hasUAAppearance) {
   1997         m_borderData = m_style->border();
   1998         m_backgroundData = *m_style->backgroundLayers();
   1999         m_backgroundColor = m_style->backgroundColor();
   2000     }
   2001 }
   2002 
   2003 PassRefPtr<CSSRuleList> CSSStyleSelector::styleRulesForElement(Element* e, bool authorOnly, bool includeEmptyRules, CSSRuleFilter filter)
   2004 {
   2005     return pseudoStyleRulesForElement(e, NOPSEUDO, authorOnly, includeEmptyRules, filter);
   2006 }
   2007 
   2008 PassRefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element* e, PseudoId pseudoId, bool authorOnly, bool includeEmptyRules, CSSRuleFilter filter)
   2009 {
   2010     if (!e || !e->document()->haveStylesheetsLoaded())
   2011         return 0;
   2012 
   2013     m_checker.m_collectRulesOnly = true;
   2014 
   2015     initElement(e);
   2016     initForStyleResolve(e, 0, pseudoId);
   2017 
   2018     if (!authorOnly) {
   2019         int firstUARule = -1, lastUARule = -1;
   2020         // First we match rules from the user agent sheet.
   2021         matchUARules(firstUARule, lastUARule);
   2022 
   2023         // Now we check user sheet rules.
   2024         if (m_matchAuthorAndUserStyles) {
   2025             int firstUserRule = -1, lastUserRule = -1;
   2026             matchRules(m_userStyle.get(), firstUserRule, lastUserRule, includeEmptyRules);
   2027         }
   2028     }
   2029 
   2030     if (m_matchAuthorAndUserStyles) {
   2031         m_checker.m_sameOriginOnly = (filter == SameOriginCSSRulesOnly);
   2032 
   2033         // Check the rules in author sheets.
   2034         int firstAuthorRule = -1, lastAuthorRule = -1;
   2035         matchRules(m_authorStyle.get(), firstAuthorRule, lastAuthorRule, includeEmptyRules);
   2036 
   2037         m_checker.m_sameOriginOnly = false;
   2038     }
   2039 
   2040     m_checker.m_collectRulesOnly = false;
   2041 
   2042     return m_ruleList.release();
   2043 }
   2044 
   2045 inline bool CSSStyleSelector::checkSelector(const RuleData& ruleData)
   2046 {
   2047     m_dynamicPseudo = NOPSEUDO;
   2048 
   2049     // Let the slow path handle SVG as it has some additional rules regarding shadow trees.
   2050     if (ruleData.hasFastCheckableSelector() && !m_element->isSVGElement()) {
   2051         // We know this selector does not include any pseudo selectors.
   2052         if (m_checker.m_pseudoStyle != NOPSEUDO)
   2053             return false;
   2054         // We know a sufficiently simple single part selector matches simply because we found it from the rule hash.
   2055         // This is limited to HTML only so we don't need to check the namespace.
   2056         if (ruleData.hasTopSelectorMatchingHTMLBasedOnRuleHash() && !ruleData.hasMultipartSelector() && m_element->isHTMLElement())
   2057             return true;
   2058         return SelectorChecker::fastCheckSelector(ruleData.selector(), m_element);
   2059     }
   2060 
   2061     // Slow path.
   2062     SelectorMatch match = m_checker.checkSelector(ruleData.selector(), m_element, &m_selectorAttrs, m_dynamicPseudo, false, false, style(), m_parentNode ? m_parentNode->renderStyle() : 0);
   2063     if (match != SelectorMatches)
   2064         return false;
   2065     if (m_checker.m_pseudoStyle != NOPSEUDO && m_checker.m_pseudoStyle != m_dynamicPseudo)
   2066         return false;
   2067     return true;
   2068 }
   2069 
   2070 static inline bool selectorTagMatches(const Element* element, const CSSSelector* selector)
   2071 {
   2072     if (!selector->hasTag())
   2073         return true;
   2074     const AtomicString& localName = selector->tag().localName();
   2075     if (localName != starAtom && localName != element->localName())
   2076         return false;
   2077     const AtomicString& namespaceURI = selector->tag().namespaceURI();
   2078     return namespaceURI == starAtom || namespaceURI == element->namespaceURI();
   2079 }
   2080 
   2081 static inline bool isFastCheckableSelector(const CSSSelector* selector)
   2082 {
   2083     for (; selector; selector = selector->tagHistory()) {
   2084         if (selector->relation() != CSSSelector::Descendant && selector->relation() != CSSSelector::Child && selector->relation() != CSSSelector::SubSelector)
   2085             return false;
   2086         if (selector->m_match != CSSSelector::None && selector->m_match != CSSSelector::Id && selector->m_match != CSSSelector::Class)
   2087             return false;
   2088     }
   2089     return true;
   2090 }
   2091 
   2092 template <class ValueChecker>
   2093 inline bool fastCheckSingleSelector(const CSSSelector*& selector, const Element*& element, const CSSSelector*& topChildOrSubselector, const Element*& topChildOrSubselectorMatchElement)
   2094 {
   2095     AtomicStringImpl* value = selector->value().impl();
   2096     for (; element; element = element->parentElement()) {
   2097         if (ValueChecker::checkValue(element, value) && selectorTagMatches(element, selector)) {
   2098             if (selector->relation() == CSSSelector::Descendant)
   2099                 topChildOrSubselector = 0;
   2100             else if (!topChildOrSubselector) {
   2101                 ASSERT(selector->relation() == CSSSelector::Child || selector->relation() == CSSSelector::SubSelector);
   2102                 topChildOrSubselector = selector;
   2103                 topChildOrSubselectorMatchElement = element;
   2104             }
   2105             if (selector->relation() != CSSSelector::SubSelector)
   2106                 element = element->parentElement();
   2107             selector = selector->tagHistory();
   2108             return true;
   2109         }
   2110         if (topChildOrSubselector) {
   2111             // Child or subselector check failed.
   2112             // If the match element is null, topChildOrSubselector was also the very topmost selector and had to match
   2113             // the original element we were checking.
   2114             if (!topChildOrSubselectorMatchElement)
   2115                 return false;
   2116             // There may be other matches down the ancestor chain.
   2117             // Rewind to the topmost child or subselector and the element it matched, continue checking ancestors.
   2118             selector = topChildOrSubselector;
   2119             element = topChildOrSubselectorMatchElement->parentElement();
   2120             topChildOrSubselector = 0;
   2121             return true;
   2122         }
   2123     }
   2124     return false;
   2125 }
   2126 
   2127 struct ClassCheck {
   2128     static bool checkValue(const Element* element, AtomicStringImpl* value)
   2129     {
   2130         return element->hasClass() && static_cast<const StyledElement*>(element)->classNames().contains(value);
   2131     }
   2132 };
   2133 struct IdCheck {
   2134     static bool checkValue(const Element* element, AtomicStringImpl* value)
   2135     {
   2136         return element->hasID() && element->idForStyleResolution().impl() == value;
   2137     }
   2138 };
   2139 struct TagCheck {
   2140     static bool checkValue(const Element*, AtomicStringImpl*)
   2141     {
   2142         return true;
   2143     }
   2144 };
   2145 
   2146 bool CSSStyleSelector::SelectorChecker::fastCheckSelector(const CSSSelector* selector, const Element* element)
   2147 {
   2148     ASSERT(isFastCheckableSelector(selector));
   2149 
   2150     // The top selector requires tag check only as rule hashes have already handled id and class matches.
   2151     if (!selectorTagMatches(element, selector))
   2152         return false;
   2153 
   2154     const CSSSelector* topChildOrSubselector = 0;
   2155     const Element* topChildOrSubselectorMatchElement = 0;
   2156     if (selector->relation() == CSSSelector::Child || selector->relation() == CSSSelector::SubSelector)
   2157         topChildOrSubselector = selector;
   2158 
   2159     if (selector->relation() != CSSSelector::SubSelector)
   2160         element = element->parentElement();
   2161 
   2162     selector = selector->tagHistory();
   2163 
   2164     // We know this compound selector has descendant, child and subselector combinators only and all components are simple.
   2165     while (selector) {
   2166         switch (selector->m_match) {
   2167         case CSSSelector::Class:
   2168             if (!fastCheckSingleSelector<ClassCheck>(selector, element, topChildOrSubselector, topChildOrSubselectorMatchElement))
   2169                 return false;
   2170             break;
   2171         case CSSSelector::Id:
   2172             if (!fastCheckSingleSelector<IdCheck>(selector, element, topChildOrSubselector, topChildOrSubselectorMatchElement))
   2173                 return false;
   2174             break;
   2175         case CSSSelector::None:
   2176             if (!fastCheckSingleSelector<TagCheck>(selector, element, topChildOrSubselector, topChildOrSubselectorMatchElement))
   2177                 return false;
   2178             break;
   2179         default:
   2180             ASSERT_NOT_REACHED();
   2181         }
   2182     }
   2183     return true;
   2184 }
   2185 
   2186 // Recursive check of selectors and combinators
   2187 // It can return 3 different values:
   2188 // * SelectorMatches         - the selector matches the element e
   2189 // * SelectorFailsLocally    - the selector fails for the element e
   2190 // * SelectorFailsCompletely - the selector fails for e and any sibling or ancestor of e
   2191 CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
   2192 {
   2193 #if ENABLE(SVG)
   2194     // Spec: CSS2 selectors cannot be applied to the (conceptually) cloned DOM tree
   2195     // because its contents are not part of the formal document structure.
   2196     if (e->isSVGElement() && e->isShadowRoot())
   2197         return SelectorFailsCompletely;
   2198 #endif
   2199 
   2200     // first selector has to match
   2201     if (!checkOneSelector(sel, e, selectorAttrs, dynamicPseudo, isSubSelector, encounteredLink, elementStyle, elementParentStyle))
   2202         return SelectorFailsLocally;
   2203 
   2204     // The rest of the selectors has to match
   2205     CSSSelector::Relation relation = sel->relation();
   2206 
   2207     // Prepare next sel
   2208     sel = sel->tagHistory();
   2209     if (!sel)
   2210         return SelectorMatches;
   2211 
   2212     if (relation != CSSSelector::SubSelector)
   2213         // Bail-out if this selector is irrelevant for the pseudoStyle
   2214         if (m_pseudoStyle != NOPSEUDO && m_pseudoStyle != dynamicPseudo)
   2215             return SelectorFailsCompletely;
   2216 
   2217     // Check for nested links.
   2218     if (m_matchVisitedPseudoClass && !isSubSelector) {
   2219         RenderStyle* currentStyle = elementStyle ? elementStyle : e->renderStyle();
   2220         if (currentStyle && currentStyle->insideLink() && e->isLink()) {
   2221             if (encounteredLink)
   2222                 m_matchVisitedPseudoClass = false; // This link is not relevant to the style being resolved, so disable matching.
   2223             else
   2224                 encounteredLink = true;
   2225         }
   2226     }
   2227 
   2228     switch (relation) {
   2229         case CSSSelector::Descendant:
   2230             while (true) {
   2231                 ContainerNode* n = e->parentNode();
   2232                 if (!n || !n->isElementNode())
   2233                     return SelectorFailsCompletely;
   2234                 e = static_cast<Element*>(n);
   2235                 SelectorMatch match = checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
   2236                 if (match != SelectorFailsLocally)
   2237                     return match;
   2238             }
   2239             break;
   2240         case CSSSelector::Child:
   2241         {
   2242             ContainerNode* n = e->parentNode();
   2243             if (!n || !n->isElementNode())
   2244                 return SelectorFailsCompletely;
   2245             e = static_cast<Element*>(n);
   2246             return checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
   2247         }
   2248         case CSSSelector::DirectAdjacent:
   2249         {
   2250             if (!m_collectRulesOnly && e->parentNode() && e->parentNode()->isElementNode()) {
   2251                 RenderStyle* parentStyle = elementStyle ? elementParentStyle : e->parentNode()->renderStyle();
   2252                 if (parentStyle)
   2253                     parentStyle->setChildrenAffectedByDirectAdjacentRules();
   2254             }
   2255             Node* n = e->previousSibling();
   2256             while (n && !n->isElementNode())
   2257                 n = n->previousSibling();
   2258             if (!n)
   2259                 return SelectorFailsLocally;
   2260             e = static_cast<Element*>(n);
   2261             m_matchVisitedPseudoClass = false;
   2262             return checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
   2263         }
   2264         case CSSSelector::IndirectAdjacent:
   2265             if (!m_collectRulesOnly && e->parentNode() && e->parentNode()->isElementNode()) {
   2266                 RenderStyle* parentStyle = elementStyle ? elementParentStyle : e->parentNode()->renderStyle();
   2267                 if (parentStyle)
   2268                     parentStyle->setChildrenAffectedByForwardPositionalRules();
   2269             }
   2270             while (true) {
   2271                 Node* n = e->previousSibling();
   2272                 while (n && !n->isElementNode())
   2273                     n = n->previousSibling();
   2274                 if (!n)
   2275                     return SelectorFailsLocally;
   2276                 e = static_cast<Element*>(n);
   2277                 m_matchVisitedPseudoClass = false;
   2278                 SelectorMatch match = checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
   2279                 if (match != SelectorFailsLocally)
   2280                     return match;
   2281             };
   2282             break;
   2283         case CSSSelector::SubSelector:
   2284             // a selector is invalid if something follows a pseudo-element
   2285             // We make an exception for scrollbar pseudo elements and allow a set of pseudo classes (but nothing else)
   2286             // to follow the pseudo elements.
   2287             if ((elementStyle || m_collectRulesOnly) && dynamicPseudo != NOPSEUDO && dynamicPseudo != SELECTION &&
   2288                 !((RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER) && sel->m_match == CSSSelector::PseudoClass))
   2289                 return SelectorFailsCompletely;
   2290             return checkSelector(sel, e, selectorAttrs, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle);
   2291         case CSSSelector::ShadowDescendant:
   2292         {
   2293             Node* shadowHostNode = e->shadowAncestorNode();
   2294             if (shadowHostNode == e || !shadowHostNode->isElementNode())
   2295                 return SelectorFailsCompletely;
   2296             e = static_cast<Element*>(shadowHostNode);
   2297             return checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
   2298         }
   2299     }
   2300 
   2301     return SelectorFailsCompletely;
   2302 }
   2303 
   2304 static void addLocalNameToSet(HashSet<AtomicStringImpl*>* set, const QualifiedName& qName)
   2305 {
   2306     set->add(qName.localName().impl());
   2307 }
   2308 
   2309 static HashSet<AtomicStringImpl*>* createHtmlCaseInsensitiveAttributesSet()
   2310 {
   2311     // This is the list of attributes in HTML 4.01 with values marked as "[CI]" or case-insensitive
   2312     // Mozilla treats all other values as case-sensitive, thus so do we.
   2313     HashSet<AtomicStringImpl*>* attrSet = new HashSet<AtomicStringImpl*>;
   2314 
   2315     addLocalNameToSet(attrSet, accept_charsetAttr);
   2316     addLocalNameToSet(attrSet, acceptAttr);
   2317     addLocalNameToSet(attrSet, alignAttr);
   2318     addLocalNameToSet(attrSet, alinkAttr);
   2319     addLocalNameToSet(attrSet, axisAttr);
   2320     addLocalNameToSet(attrSet, bgcolorAttr);
   2321     addLocalNameToSet(attrSet, charsetAttr);
   2322     addLocalNameToSet(attrSet, checkedAttr);
   2323     addLocalNameToSet(attrSet, clearAttr);
   2324     addLocalNameToSet(attrSet, codetypeAttr);
   2325     addLocalNameToSet(attrSet, colorAttr);
   2326     addLocalNameToSet(attrSet, compactAttr);
   2327     addLocalNameToSet(attrSet, declareAttr);
   2328     addLocalNameToSet(attrSet, deferAttr);
   2329     addLocalNameToSet(attrSet, dirAttr);
   2330     addLocalNameToSet(attrSet, disabledAttr);
   2331     addLocalNameToSet(attrSet, enctypeAttr);
   2332     addLocalNameToSet(attrSet, faceAttr);
   2333     addLocalNameToSet(attrSet, frameAttr);
   2334     addLocalNameToSet(attrSet, hreflangAttr);
   2335     addLocalNameToSet(attrSet, http_equivAttr);
   2336     addLocalNameToSet(attrSet, langAttr);
   2337     addLocalNameToSet(attrSet, languageAttr);
   2338     addLocalNameToSet(attrSet, linkAttr);
   2339     addLocalNameToSet(attrSet, mediaAttr);
   2340     addLocalNameToSet(attrSet, methodAttr);
   2341     addLocalNameToSet(attrSet, multipleAttr);
   2342     addLocalNameToSet(attrSet, nohrefAttr);
   2343     addLocalNameToSet(attrSet, noresizeAttr);
   2344     addLocalNameToSet(attrSet, noshadeAttr);
   2345     addLocalNameToSet(attrSet, nowrapAttr);
   2346     addLocalNameToSet(attrSet, readonlyAttr);
   2347     addLocalNameToSet(attrSet, relAttr);
   2348     addLocalNameToSet(attrSet, revAttr);
   2349     addLocalNameToSet(attrSet, rulesAttr);
   2350     addLocalNameToSet(attrSet, scopeAttr);
   2351     addLocalNameToSet(attrSet, scrollingAttr);
   2352     addLocalNameToSet(attrSet, selectedAttr);
   2353     addLocalNameToSet(attrSet, shapeAttr);
   2354     addLocalNameToSet(attrSet, targetAttr);
   2355     addLocalNameToSet(attrSet, textAttr);
   2356     addLocalNameToSet(attrSet, typeAttr);
   2357     addLocalNameToSet(attrSet, valignAttr);
   2358     addLocalNameToSet(attrSet, valuetypeAttr);
   2359     addLocalNameToSet(attrSet, vlinkAttr);
   2360 
   2361     return attrSet;
   2362 }
   2363 
   2364 static bool htmlAttributeHasCaseInsensitiveValue(const QualifiedName& attr)
   2365 {
   2366     static HashSet<AtomicStringImpl*>* htmlCaseInsensitiveAttributesSet = createHtmlCaseInsensitiveAttributesSet();
   2367     bool isPossibleHTMLAttr = !attr.hasPrefix() && (attr.namespaceURI() == nullAtom);
   2368     return isPossibleHTMLAttr && htmlCaseInsensitiveAttributesSet->contains(attr.localName().impl());
   2369 }
   2370 
   2371 bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
   2372 {
   2373     ASSERT(e);
   2374     if (!e)
   2375         return false;
   2376 
   2377     if (!selectorTagMatches(e, sel))
   2378         return false;
   2379 
   2380     if (sel->hasAttribute()) {
   2381         if (sel->m_match == CSSSelector::Class)
   2382             return e->hasClass() && static_cast<StyledElement*>(e)->classNames().contains(sel->value());
   2383 
   2384         if (sel->m_match == CSSSelector::Id)
   2385             return e->hasID() && e->idForStyleResolution() == sel->value();
   2386 
   2387         const QualifiedName& attr = sel->attribute();
   2388 
   2389         // FIXME: Handle the case were elementStyle is 0.
   2390         if (elementStyle && (!e->isStyledElement() || (!static_cast<StyledElement*>(e)->isMappedAttribute(attr) && attr != typeAttr && attr != readonlyAttr))) {
   2391             elementStyle->setAffectedByAttributeSelectors(); // Special-case the "type" and "readonly" attributes so input form controls can share style.
   2392             if (selectorAttrs)
   2393                 selectorAttrs->add(attr.localName().impl());
   2394         }
   2395 
   2396         const AtomicString& value = e->getAttribute(attr);
   2397         if (value.isNull())
   2398             return false; // attribute is not set
   2399 
   2400         bool caseSensitive = !m_documentIsHTML || !htmlAttributeHasCaseInsensitiveValue(attr);
   2401 
   2402         switch (sel->m_match) {
   2403         case CSSSelector::Exact:
   2404             if (caseSensitive ? sel->value() != value : !equalIgnoringCase(sel->value(), value))
   2405                 return false;
   2406             break;
   2407         case CSSSelector::List:
   2408         {
   2409             // Ignore empty selectors or selectors containing spaces
   2410             if (sel->value().contains(' ') || sel->value().isEmpty())
   2411                 return false;
   2412 
   2413             unsigned startSearchAt = 0;
   2414             while (true) {
   2415                 size_t foundPos = value.find(sel->value(), startSearchAt, caseSensitive);
   2416                 if (foundPos == notFound)
   2417                     return false;
   2418                 if (foundPos == 0 || value[foundPos - 1] == ' ') {
   2419                     unsigned endStr = foundPos + sel->value().length();
   2420                     if (endStr == value.length() || value[endStr] == ' ')
   2421                         break; // We found a match.
   2422                 }
   2423 
   2424                 // No match. Keep looking.
   2425                 startSearchAt = foundPos + 1;
   2426             }
   2427             break;
   2428         }
   2429         case CSSSelector::Contain:
   2430             if (!value.contains(sel->value(), caseSensitive) || sel->value().isEmpty())
   2431                 return false;
   2432             break;
   2433         case CSSSelector::Begin:
   2434             if (!value.startsWith(sel->value(), caseSensitive) || sel->value().isEmpty())
   2435                 return false;
   2436             break;
   2437         case CSSSelector::End:
   2438             if (!value.endsWith(sel->value(), caseSensitive) || sel->value().isEmpty())
   2439                 return false;
   2440             break;
   2441         case CSSSelector::Hyphen:
   2442             if (value.length() < sel->value().length())
   2443                 return false;
   2444             if (!value.startsWith(sel->value(), caseSensitive))
   2445                 return false;
   2446             // It they start the same, check for exact match or following '-':
   2447             if (value.length() != sel->value().length() && value[sel->value().length()] != '-')
   2448                 return false;
   2449             break;
   2450         case CSSSelector::PseudoClass:
   2451         case CSSSelector::PseudoElement:
   2452         default:
   2453             break;
   2454         }
   2455     }
   2456 
   2457     if (sel->m_match == CSSSelector::PseudoClass) {
   2458         // Handle :not up front.
   2459         if (sel->pseudoType() == CSSSelector::PseudoNot) {
   2460             ASSERT(sel->selectorList());
   2461             for (CSSSelector* subSel = sel->selectorList()->first(); subSel; subSel = subSel->tagHistory()) {
   2462                 // :not cannot nest. I don't really know why this is a
   2463                 // restriction in CSS3, but it is, so let's honor it.
   2464                 // the parser enforces that this never occurs
   2465                 ASSERT(subSel->pseudoType() != CSSSelector::PseudoNot);
   2466 
   2467                 if (!checkOneSelector(subSel, e, selectorAttrs, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle))
   2468                     return true;
   2469             }
   2470         } else if (dynamicPseudo != NOPSEUDO && (RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER)) {
   2471             // CSS scrollbars match a specific subset of pseudo classes, and they have specialized rules for each
   2472             // (since there are no elements involved).
   2473             return checkScrollbarPseudoClass(sel, dynamicPseudo);
   2474         } else if (dynamicPseudo == SELECTION) {
   2475             if (sel->pseudoType() == CSSSelector::PseudoWindowInactive)
   2476                 return !m_document->page()->focusController()->isActive();
   2477         }
   2478 
   2479         // Normal element pseudo class checking.
   2480         switch (sel->pseudoType()) {
   2481             // Pseudo classes:
   2482             case CSSSelector::PseudoNot:
   2483                 break; // Already handled up above.
   2484             case CSSSelector::PseudoEmpty: {
   2485                 bool result = true;
   2486                 for (Node* n = e->firstChild(); n; n = n->nextSibling()) {
   2487                     if (n->isElementNode()) {
   2488                         result = false;
   2489                         break;
   2490                     } else if (n->isTextNode()) {
   2491                         Text* textNode = static_cast<Text*>(n);
   2492                         if (!textNode->data().isEmpty()) {
   2493                             result = false;
   2494                             break;
   2495                         }
   2496                     }
   2497                 }
   2498                 if (!m_collectRulesOnly) {
   2499                     if (elementStyle)
   2500                         elementStyle->setEmptyState(result);
   2501                     else if (e->renderStyle() && (e->document()->usesSiblingRules() || e->renderStyle()->unique()))
   2502                         e->renderStyle()->setEmptyState(result);
   2503                 }
   2504                 return result;
   2505             }
   2506             case CSSSelector::PseudoFirstChild: {
   2507                 // first-child matches the first child that is an element
   2508                 if (e->parentNode() && e->parentNode()->isElementNode()) {
   2509                     bool result = false;
   2510                     Node* n = e->previousSibling();
   2511                     while (n && !n->isElementNode())
   2512                         n = n->previousSibling();
   2513                     if (!n)
   2514                         result = true;
   2515                     if (!m_collectRulesOnly) {
   2516                         RenderStyle* childStyle = elementStyle ? elementStyle : e->renderStyle();
   2517                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : e->parentNode()->renderStyle();
   2518                         if (parentStyle)
   2519                             parentStyle->setChildrenAffectedByFirstChildRules();
   2520                         if (result && childStyle)
   2521                             childStyle->setFirstChildState();
   2522                     }
   2523                     return result;
   2524                 }
   2525                 break;
   2526             }
   2527             case CSSSelector::PseudoFirstOfType: {
   2528                 // first-of-type matches the first element of its type
   2529                 if (e->parentNode() && e->parentNode()->isElementNode()) {
   2530                     bool result = false;
   2531                     const QualifiedName& type = e->tagQName();
   2532                     Node* n = e->previousSibling();
   2533                     while (n) {
   2534                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
   2535                             break;
   2536                         n = n->previousSibling();
   2537                     }
   2538                     if (!n)
   2539                         result = true;
   2540                     if (!m_collectRulesOnly) {
   2541                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : e->parentNode()->renderStyle();
   2542                         if (parentStyle)
   2543                             parentStyle->setChildrenAffectedByForwardPositionalRules();
   2544                     }
   2545                     return result;
   2546                 }
   2547                 break;
   2548             }
   2549             case CSSSelector::PseudoLastChild: {
   2550                 // last-child matches the last child that is an element
   2551                 if (Element* parentElement = e->parentElement()) {
   2552                     bool result = false;
   2553                     if (parentElement->isFinishedParsingChildren()) {
   2554                         Node* n = e->nextSibling();
   2555                         while (n && !n->isElementNode())
   2556                             n = n->nextSibling();
   2557                         if (!n)
   2558                             result = true;
   2559                     }
   2560                     if (!m_collectRulesOnly) {
   2561                         RenderStyle* childStyle = elementStyle ? elementStyle : e->renderStyle();
   2562                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
   2563                         if (parentStyle)
   2564                             parentStyle->setChildrenAffectedByLastChildRules();
   2565                         if (result && childStyle)
   2566                             childStyle->setLastChildState();
   2567                     }
   2568                     return result;
   2569                 }
   2570                 break;
   2571             }
   2572             case CSSSelector::PseudoLastOfType: {
   2573                 // last-of-type matches the last element of its type
   2574                 if (Element* parentElement = e->parentElement()) {
   2575                     if (!m_collectRulesOnly) {
   2576                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
   2577                         if (parentStyle)
   2578                             parentStyle->setChildrenAffectedByBackwardPositionalRules();
   2579                     }
   2580                     if (!parentElement->isFinishedParsingChildren())
   2581                         return false;
   2582                     bool result = false;
   2583                     const QualifiedName& type = e->tagQName();
   2584                     Node* n = e->nextSibling();
   2585                     while (n) {
   2586                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
   2587                             break;
   2588                         n = n->nextSibling();
   2589                     }
   2590                     if (!n)
   2591                         result = true;
   2592                     return result;
   2593                 }
   2594                 break;
   2595             }
   2596             case CSSSelector::PseudoOnlyChild: {
   2597                 if (Element* parentElement = e->parentElement()) {
   2598                     bool firstChild = false;
   2599                     bool lastChild = false;
   2600 
   2601                     Node* n = e->previousSibling();
   2602                     while (n && !n->isElementNode())
   2603                         n = n->previousSibling();
   2604                     if (!n)
   2605                         firstChild = true;
   2606                     if (firstChild && parentElement->isFinishedParsingChildren()) {
   2607                         n = e->nextSibling();
   2608                         while (n && !n->isElementNode())
   2609                             n = n->nextSibling();
   2610                         if (!n)
   2611                             lastChild = true;
   2612                     }
   2613                     if (!m_collectRulesOnly) {
   2614                         RenderStyle* childStyle = elementStyle ? elementStyle : e->renderStyle();
   2615                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
   2616                         if (parentStyle) {
   2617                             parentStyle->setChildrenAffectedByFirstChildRules();
   2618                             parentStyle->setChildrenAffectedByLastChildRules();
   2619                         }
   2620                         if (firstChild && childStyle)
   2621                             childStyle->setFirstChildState();
   2622                         if (lastChild && childStyle)
   2623                             childStyle->setLastChildState();
   2624                     }
   2625                     return firstChild && lastChild;
   2626                 }
   2627                 break;
   2628             }
   2629             case CSSSelector::PseudoOnlyOfType: {
   2630                 // FIXME: This selector is very slow.
   2631                 if (Element* parentElement = e->parentElement()) {
   2632                     if (!m_collectRulesOnly) {
   2633                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
   2634                         if (parentStyle) {
   2635                             parentStyle->setChildrenAffectedByForwardPositionalRules();
   2636                             parentStyle->setChildrenAffectedByBackwardPositionalRules();
   2637                         }
   2638                     }
   2639                     if (!parentElement->isFinishedParsingChildren())
   2640                         return false;
   2641                     bool firstChild = false;
   2642                     bool lastChild = false;
   2643                     const QualifiedName& type = e->tagQName();
   2644                     Node* n = e->previousSibling();
   2645                     while (n) {
   2646                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
   2647                             break;
   2648                         n = n->previousSibling();
   2649                     }
   2650                     if (!n)
   2651                         firstChild = true;
   2652                     if (firstChild) {
   2653                         n = e->nextSibling();
   2654                         while (n) {
   2655                             if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
   2656                                 break;
   2657                             n = n->nextSibling();
   2658                         }
   2659                         if (!n)
   2660                             lastChild = true;
   2661                     }
   2662                     return firstChild && lastChild;
   2663                 }
   2664                 break;
   2665             }
   2666             case CSSSelector::PseudoNthChild: {
   2667                 if (!sel->parseNth())
   2668                     break;
   2669                 if (Element* parentElement = e->parentElement()) {
   2670                     int count = 1;
   2671                     Node* n = e->previousSibling();
   2672                     while (n) {
   2673                         if (n->isElementNode()) {
   2674                             RenderStyle* s = n->renderStyle();
   2675                             unsigned index = s ? s->childIndex() : 0;
   2676                             if (index) {
   2677                                 count += index;
   2678                                 break;
   2679                             }
   2680                             count++;
   2681                         }
   2682                         n = n->previousSibling();
   2683                     }
   2684 
   2685                     if (!m_collectRulesOnly) {
   2686                         RenderStyle* childStyle = elementStyle ? elementStyle : e->renderStyle();
   2687                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
   2688                         if (childStyle)
   2689                             childStyle->setChildIndex(count);
   2690                         if (parentStyle)
   2691                             parentStyle->setChildrenAffectedByForwardPositionalRules();
   2692                     }
   2693 
   2694                     if (sel->matchNth(count))
   2695                         return true;
   2696                 }
   2697                 break;
   2698             }
   2699             case CSSSelector::PseudoNthOfType: {
   2700                 if (!sel->parseNth())
   2701                     break;
   2702                 if (Element* parentElement = e->parentElement()) {
   2703                     int count = 1;
   2704                     const QualifiedName& type = e->tagQName();
   2705                     Node* n = e->previousSibling();
   2706                     while (n) {
   2707                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
   2708                             count++;
   2709                         n = n->previousSibling();
   2710                     }
   2711 
   2712                     if (!m_collectRulesOnly) {
   2713                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
   2714                         if (parentStyle)
   2715                             parentStyle->setChildrenAffectedByForwardPositionalRules();
   2716                     }
   2717 
   2718                     if (sel->matchNth(count))
   2719                         return true;
   2720                 }
   2721                 break;
   2722             }
   2723             case CSSSelector::PseudoNthLastChild: {
   2724                 if (!sel->parseNth())
   2725                     break;
   2726                 if (Element* parentElement = e->parentElement()) {
   2727                     if (!m_collectRulesOnly) {
   2728                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
   2729                         if (parentStyle)
   2730                             parentStyle->setChildrenAffectedByBackwardPositionalRules();
   2731                     }
   2732                     if (!parentElement->isFinishedParsingChildren())
   2733                         return false;
   2734                     int count = 1;
   2735                     Node* n = e->nextSibling();
   2736                     while (n) {
   2737                         if (n->isElementNode())
   2738                             count++;
   2739                         n = n->nextSibling();
   2740                     }
   2741                     if (sel->matchNth(count))
   2742                         return true;
   2743                 }
   2744                 break;
   2745             }
   2746             case CSSSelector::PseudoNthLastOfType: {
   2747                 if (!sel->parseNth())
   2748                     break;
   2749                 if (Element* parentElement = e->parentElement()) {
   2750                     if (!m_collectRulesOnly) {
   2751                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
   2752                         if (parentStyle)
   2753                             parentStyle->setChildrenAffectedByBackwardPositionalRules();
   2754                     }
   2755                     if (!parentElement->isFinishedParsingChildren())
   2756                         return false;
   2757                     int count = 1;
   2758                     const QualifiedName& type = e->tagQName();
   2759                     Node* n = e->nextSibling();
   2760                     while (n) {
   2761                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
   2762                             count++;
   2763                         n = n->nextSibling();
   2764                     }
   2765                     if (sel->matchNth(count))
   2766                         return true;
   2767                 }
   2768                 break;
   2769             }
   2770             case CSSSelector::PseudoTarget:
   2771                 if (e == e->document()->cssTarget())
   2772                     return true;
   2773                 break;
   2774             case CSSSelector::PseudoAny:
   2775                 for (CSSSelector* selector = sel->selectorList()->first(); selector; selector = CSSSelectorList::next(selector)) {
   2776                     if (checkSelector(selector, e, selectorAttrs, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle) == SelectorMatches)
   2777                         return true;
   2778                 }
   2779                 break;
   2780             case CSSSelector::PseudoAnyLink:
   2781                 if (e && e->isLink())
   2782                     return true;
   2783                 break;
   2784             case CSSSelector::PseudoAutofill: {
   2785                 if (!e || !e->isFormControlElement())
   2786                     break;
   2787                 if (InputElement* inputElement = e->toInputElement())
   2788                     return inputElement->isAutofilled();
   2789                 break;
   2790             }
   2791             case CSSSelector::PseudoLink:
   2792                 if (e && e->isLink())
   2793                     return !m_matchVisitedPseudoClass;
   2794                 break;
   2795             case CSSSelector::PseudoVisited:
   2796                 if (e && e->isLink())
   2797                     return m_matchVisitedPseudoClass;
   2798                 break;
   2799             case CSSSelector::PseudoDrag: {
   2800                 if (elementStyle)
   2801                     elementStyle->setAffectedByDragRules(true);
   2802                 else if (e->renderStyle())
   2803                     e->renderStyle()->setAffectedByDragRules(true);
   2804                 if (e->renderer() && e->renderer()->isDragging())
   2805                     return true;
   2806                 break;
   2807             }
   2808             case CSSSelector::PseudoFocus:
   2809                 if (e && e->focused() && e->document()->frame() && e->document()->frame()->selection()->isFocusedAndActive())
   2810                     return true;
   2811                 break;
   2812             case CSSSelector::PseudoHover: {
   2813                 // If we're in quirks mode, then hover should never match anchors with no
   2814                 // href and *:hover should not match anything.  This is important for sites like wsj.com.
   2815                 if (m_strictParsing || isSubSelector || (sel->hasTag() && !e->hasTagName(aTag)) || e->isLink()) {
   2816                     if (elementStyle)
   2817                         elementStyle->setAffectedByHoverRules(true);
   2818                     else if (e->renderStyle())
   2819                         e->renderStyle()->setAffectedByHoverRules(true);
   2820                     if (e->hovered())
   2821                         return true;
   2822                 }
   2823                 break;
   2824             }
   2825             case CSSSelector::PseudoActive:
   2826                 // If we're in quirks mode, then :active should never match anchors with no
   2827                 // href and *:active should not match anything.
   2828                 if (m_strictParsing || isSubSelector || (sel->hasTag() && !e->hasTagName(aTag)) || e->isLink()) {
   2829                     if (elementStyle)
   2830                         elementStyle->setAffectedByActiveRules(true);
   2831                     else if (e->renderStyle())
   2832                         e->renderStyle()->setAffectedByActiveRules(true);
   2833                     if (e->active())
   2834                         return true;
   2835                 }
   2836                 break;
   2837             case CSSSelector::PseudoEnabled:
   2838                 if (e && e->isFormControlElement())
   2839                     return e->isEnabledFormControl();
   2840                 break;
   2841             case CSSSelector::PseudoFullPageMedia:
   2842                 return e && e->document() && e->document()->isMediaDocument();
   2843                 break;
   2844             case CSSSelector::PseudoDefault:
   2845                 return e && e->isDefaultButtonForForm();
   2846             case CSSSelector::PseudoDisabled:
   2847                 if (e && e->isFormControlElement())
   2848                     return !e->isEnabledFormControl();
   2849                 break;
   2850             case CSSSelector::PseudoReadOnly: {
   2851                 if (!e || !e->isFormControlElement())
   2852                     return false;
   2853                 return e->isTextFormControl() && e->isReadOnlyFormControl();
   2854             }
   2855             case CSSSelector::PseudoReadWrite: {
   2856                 if (!e || !e->isFormControlElement())
   2857                     return false;
   2858                 return e->isTextFormControl() && !e->isReadOnlyFormControl();
   2859             }
   2860             case CSSSelector::PseudoOptional:
   2861                 return e && e->isOptionalFormControl();
   2862             case CSSSelector::PseudoRequired:
   2863                 return e && e->isRequiredFormControl();
   2864             case CSSSelector::PseudoValid: {
   2865                 if (!e)
   2866                     return false;
   2867                 e->document()->setContainsValidityStyleRules();
   2868                 return e->willValidate() && e->isValidFormControlElement();
   2869             } case CSSSelector::PseudoInvalid: {
   2870                 if (!e)
   2871                     return false;
   2872                 e->document()->setContainsValidityStyleRules();
   2873                 return (e->willValidate() && !e->isValidFormControlElement()) || e->hasUnacceptableValue();
   2874             } case CSSSelector::PseudoChecked: {
   2875                 if (!e || !e->isFormControlElement())
   2876                     break;
   2877                 // Even though WinIE allows checked and indeterminate to co-exist, the CSS selector spec says that
   2878                 // you can't be both checked and indeterminate.  We will behave like WinIE behind the scenes and just
   2879                 // obey the CSS spec here in the test for matching the pseudo.
   2880                 InputElement* inputElement = e->toInputElement();
   2881                 if (inputElement && inputElement->isChecked() && !inputElement->isIndeterminate())
   2882                     return true;
   2883                 break;
   2884             }
   2885             case CSSSelector::PseudoIndeterminate: {
   2886                 if (!e || !e->isFormControlElement())
   2887                     break;
   2888                 InputElement* inputElement = e->toInputElement();
   2889                 if (inputElement && inputElement->isIndeterminate())
   2890                     return true;
   2891                 break;
   2892             }
   2893             case CSSSelector::PseudoRoot:
   2894                 if (e == e->document()->documentElement())
   2895                     return true;
   2896                 break;
   2897             case CSSSelector::PseudoLang: {
   2898                 AtomicString value = e->computeInheritedLanguage();
   2899                 const AtomicString& argument = sel->argument();
   2900                 if (value.isEmpty() || !value.startsWith(argument, false))
   2901                     break;
   2902                 if (value.length() != argument.length() && value[argument.length()] != '-')
   2903                     break;
   2904                 return true;
   2905             }
   2906 #if ENABLE(FULLSCREEN_API)
   2907             case CSSSelector::PseudoFullScreen:
   2908                 // While a Document is in the fullscreen state, and the document's current fullscreen
   2909                 // element is an element in the document, the 'full-screen' pseudoclass applies to
   2910                 // that element. Also, an <iframe>, <object> or <embed> element whose child browsing
   2911                 // context's Document is in the fullscreen state has the 'full-screen' pseudoclass applied.
   2912                 if (!e->document()->webkitIsFullScreen())
   2913                     return false;
   2914                 if (e != e->document()->webkitCurrentFullScreenElement())
   2915                     return false;
   2916                 return true;
   2917             case CSSSelector::PseudoFullScreenDocument:
   2918                 // While a Document is in the fullscreen state, the 'full-screen-document' pseudoclass applies
   2919                 // t