c8cd991803432f13abb3b40b92bf0a2239b371db
[WebKit.git] / Source / WebCore / css / CSSStyleSelector.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
4  * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
5  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
6  * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
7  * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
8  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  */
25
26 #include "config.h"
27 #include "CSSStyleSelector.h"
28
29 #include "Attribute.h"
30 #include "ContentData.h"
31 #include "CounterContent.h"
32 #include "CursorList.h"
33 #include "CSSBorderImageValue.h"
34 #include "CSSCursorImageValue.h"
35 #include "CSSFontFaceRule.h"
36 #include "CSSImportRule.h"
37 #include "CSSMediaRule.h"
38 #include "CSSPageRule.h"
39 #include "CSSParser.h"
40 #include "CSSPrimitiveValueMappings.h"
41 #include "CSSPropertyNames.h"
42 #include "CSSReflectValue.h"
43 #include "CSSRuleList.h"
44 #include "CSSSelector.h"
45 #include "CSSSelectorList.h"
46 #include "CSSStyleRule.h"
47 #include "CSSStyleSheet.h"
48 #include "CSSTimingFunctionValue.h"
49 #include "CSSValueList.h"
50 #include "CachedImage.h"
51 #include "Counter.h"
52 #include "FocusController.h"
53 #include "FontFamilyValue.h"
54 #include "FontValue.h"
55 #include "Frame.h"
56 #include "FrameView.h"
57 #include "HTMLDocument.h"
58 #include "HTMLElement.h"
59 #include "HTMLInputElement.h"
60 #include "HTMLNames.h"
61 #include "HTMLTextAreaElement.h"
62 #include "KeyframeList.h"
63 #include "LinkHash.h"
64 #include "Matrix3DTransformOperation.h"
65 #include "MatrixTransformOperation.h"
66 #include "MediaList.h"
67 #include "MediaQueryEvaluator.h"
68 #include "NodeRenderStyle.h"
69 #include "Page.h"
70 #include "PageGroup.h"
71 #include "Pair.h"
72 #include "PerspectiveTransformOperation.h"
73 #include "Rect.h"
74 #include "RenderScrollbar.h"
75 #include "RenderScrollbarTheme.h"
76 #include "RenderStyleConstants.h"
77 #include "RenderTheme.h"
78 #include "RotateTransformOperation.h"
79 #include "ScaleTransformOperation.h"
80 #include "SelectionController.h"
81 #include "Settings.h"
82 #include "ShadowData.h"
83 #include "ShadowValue.h"
84 #include "SkewTransformOperation.h"
85 #include "StyleCachedImage.h"
86 #include "StylePendingImage.h"
87 #include "StyleGeneratedImage.h"
88 #include "StyleSheetList.h"
89 #include "Text.h"
90 #include "TransformationMatrix.h"
91 #include "TranslateTransformOperation.h"
92 #include "UserAgentStyleSheets.h"
93 #include "WebKitCSSKeyframeRule.h"
94 #include "WebKitCSSKeyframesRule.h"
95 #include "WebKitCSSTransformValue.h"
96 #include "XMLNames.h"
97 #include <wtf/StdLibExtras.h>
98 #include <wtf/Vector.h>
99
100 #if USE(PLATFORM_STRATEGIES)
101 #include "PlatformStrategies.h"
102 #include "VisitedLinkStrategy.h"
103 #endif
104
105 #if ENABLE(DASHBOARD_SUPPORT)
106 #include "DashboardRegion.h"
107 #endif
108
109 #if ENABLE(SVG)
110 #include "XLinkNames.h"
111 #include "SVGNames.h"
112 #endif
113
114 #if ENABLE(WML)
115 #include "WMLNames.h"
116 #endif
117
118 #if PLATFORM(QT)
119 #include <qwebhistoryinterface.h>
120 #endif
121
122 using namespace std;
123
124 namespace WebCore {
125
126 using namespace HTMLNames;
127
128 #define HANDLE_INHERIT(prop, Prop) \
129 if (isInherit) { \
130     m_style->set##Prop(m_parentStyle->prop()); \
131     return; \
132 }
133
134 #define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
135 HANDLE_INHERIT(prop, Prop) \
136 if (isInitial) { \
137     m_style->set##Prop(RenderStyle::initial##Prop()); \
138     return; \
139 }
140
141 #define HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(prop, Prop, Value) \
142 HANDLE_INHERIT(prop, Prop) \
143 if (isInitial) { \
144     m_style->set##Prop(RenderStyle::initial##Value());\
145     return;\
146 }
147
148 #define HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(prop, Prop) \
149 HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
150 if (primitiveValue) \
151     m_style->set##Prop(*primitiveValue);
152
153 #define HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(prop, Prop, Value) \
154 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(prop, Prop, Value) \
155 if (primitiveValue) \
156     m_style->set##Prop(*primitiveValue);
157
158 #define HANDLE_FILL_LAYER_INHERIT_AND_INITIAL(layerType, LayerType, prop, Prop) \
159 if (isInherit) { \
160     FillLayer* currChild = m_style->access##LayerType##Layers(); \
161     FillLayer* prevChild = 0; \
162     const FillLayer* currParent = m_parentStyle->layerType##Layers(); \
163     while (currParent && currParent->is##Prop##Set()) { \
164         if (!currChild) { \
165             /* Need to make a new layer.*/ \
166             currChild = new FillLayer(LayerType##FillLayer); \
167             prevChild->setNext(currChild); \
168         } \
169         currChild->set##Prop(currParent->prop()); \
170         prevChild = currChild; \
171         currChild = prevChild->next(); \
172         currParent = currParent->next(); \
173     } \
174     \
175     while (currChild) { \
176         /* Reset any remaining layers to not have the property set. */ \
177         currChild->clear##Prop(); \
178         currChild = currChild->next(); \
179     } \
180 } else if (isInitial) { \
181     FillLayer* currChild = m_style->access##LayerType##Layers(); \
182     currChild->set##Prop(FillLayer::initialFill##Prop(LayerType##FillLayer)); \
183     for (currChild = currChild->next(); currChild; currChild = currChild->next()) \
184         currChild->clear##Prop(); \
185 }
186
187 #define HANDLE_FILL_LAYER_VALUE(layerType, LayerType, prop, Prop, value) { \
188 HANDLE_FILL_LAYER_INHERIT_AND_INITIAL(layerType, LayerType, prop, Prop) \
189 if (isInherit || isInitial) \
190     return; \
191 FillLayer* currChild = m_style->access##LayerType##Layers(); \
192 FillLayer* prevChild = 0; \
193 if (value->isValueList()) { \
194     /* Walk each value and put it into a layer, creating new layers as needed. */ \
195     CSSValueList* valueList = static_cast<CSSValueList*>(value); \
196     for (unsigned int i = 0; i < valueList->length(); i++) { \
197         if (!currChild) { \
198             /* Need to make a new layer to hold this value */ \
199             currChild = new FillLayer(LayerType##FillLayer); \
200             prevChild->setNext(currChild); \
201         } \
202         mapFill##Prop(property, currChild, valueList->itemWithoutBoundsCheck(i)); \
203         prevChild = currChild; \
204         currChild = currChild->next(); \
205     } \
206 } else { \
207     mapFill##Prop(property, currChild, value); \
208     currChild = currChild->next(); \
209 } \
210 while (currChild) { \
211     /* Reset all remaining layers to not have the property set. */ \
212     currChild->clear##Prop(); \
213     currChild = currChild->next(); \
214 } }
215
216 #define HANDLE_BACKGROUND_INHERIT_AND_INITIAL(prop, Prop) \
217 HANDLE_FILL_LAYER_INHERIT_AND_INITIAL(background, Background, prop, Prop)
218
219 #define HANDLE_BACKGROUND_VALUE(prop, Prop, value) \
220 HANDLE_FILL_LAYER_VALUE(background, Background, prop, Prop, value)
221
222 #define HANDLE_MASK_INHERIT_AND_INITIAL(prop, Prop) \
223 HANDLE_FILL_LAYER_INHERIT_AND_INITIAL(mask, Mask, prop, Prop)
224
225 #define HANDLE_MASK_VALUE(prop, Prop, value) \
226 HANDLE_FILL_LAYER_VALUE(mask, Mask, prop, Prop, value)
227
228 #define HANDLE_ANIMATION_INHERIT_AND_INITIAL(prop, Prop) \
229 if (isInherit) { \
230     AnimationList* list = m_style->accessAnimations(); \
231     const AnimationList* parentList = m_parentStyle->animations(); \
232     size_t i = 0, parentSize = parentList ? parentList->size() : 0; \
233     for ( ; i < parentSize && parentList->animation(i)->is##Prop##Set(); ++i) { \
234         if (list->size() <= i) \
235             list->append(Animation::create()); \
236         list->animation(i)->set##Prop(parentList->animation(i)->prop()); \
237     } \
238     \
239     /* Reset any remaining animations to not have the property set. */ \
240     for ( ; i < list->size(); ++i) \
241         list->animation(i)->clear##Prop(); \
242 } else if (isInitial) { \
243     AnimationList* list = m_style->accessAnimations(); \
244     if (list->isEmpty()) \
245         list->append(Animation::create()); \
246     list->animation(0)->set##Prop(Animation::initialAnimation##Prop()); \
247     for (size_t i = 1; i < list->size(); ++i) \
248         list->animation(0)->clear##Prop(); \
249 }
250
251 #define HANDLE_ANIMATION_VALUE(prop, Prop, value) { \
252 HANDLE_ANIMATION_INHERIT_AND_INITIAL(prop, Prop) \
253 if (isInherit || isInitial) \
254     return; \
255 AnimationList* list = m_style->accessAnimations(); \
256 size_t childIndex = 0; \
257 if (value->isValueList()) { \
258     /* Walk each value and put it into an animation, creating new animations as needed. */ \
259     CSSValueList* valueList = static_cast<CSSValueList*>(value); \
260     for (unsigned int i = 0; i < valueList->length(); i++) { \
261         if (childIndex <= list->size()) \
262             list->append(Animation::create()); \
263         mapAnimation##Prop(list->animation(childIndex), valueList->itemWithoutBoundsCheck(i)); \
264         ++childIndex; \
265     } \
266 } else { \
267     if (list->isEmpty()) \
268         list->append(Animation::create()); \
269     mapAnimation##Prop(list->animation(childIndex), value); \
270     childIndex = 1; \
271 } \
272 for ( ; childIndex < list->size(); ++childIndex) { \
273     /* Reset all remaining animations to not have the property set. */ \
274     list->animation(childIndex)->clear##Prop(); \
275 } \
276 }
277
278 #define HANDLE_TRANSITION_INHERIT_AND_INITIAL(prop, Prop) \
279 if (isInherit) { \
280     AnimationList* list = m_style->accessTransitions(); \
281     const AnimationList* parentList = m_parentStyle->transitions(); \
282     size_t i = 0, parentSize = parentList ? parentList->size() : 0; \
283     for ( ; i < parentSize && parentList->animation(i)->is##Prop##Set(); ++i) { \
284         if (list->size() <= i) \
285             list->append(Animation::create()); \
286         list->animation(i)->set##Prop(parentList->animation(i)->prop()); \
287     } \
288     \
289     /* Reset any remaining transitions to not have the property set. */ \
290     for ( ; i < list->size(); ++i) \
291         list->animation(i)->clear##Prop(); \
292 } else if (isInitial) { \
293     AnimationList* list = m_style->accessTransitions(); \
294     if (list->isEmpty()) \
295         list->append(Animation::create()); \
296     list->animation(0)->set##Prop(Animation::initialAnimation##Prop()); \
297     for (size_t i = 1; i < list->size(); ++i) \
298         list->animation(0)->clear##Prop(); \
299 }
300
301 #define HANDLE_TRANSITION_VALUE(prop, Prop, value) { \
302 HANDLE_TRANSITION_INHERIT_AND_INITIAL(prop, Prop) \
303 if (isInherit || isInitial) \
304     return; \
305 AnimationList* list = m_style->accessTransitions(); \
306 size_t childIndex = 0; \
307 if (value->isValueList()) { \
308     /* Walk each value and put it into a transition, creating new animations as needed. */ \
309     CSSValueList* valueList = static_cast<CSSValueList*>(value); \
310     for (unsigned int i = 0; i < valueList->length(); i++) { \
311         if (childIndex <= list->size()) \
312             list->append(Animation::create()); \
313         mapAnimation##Prop(list->animation(childIndex), valueList->itemWithoutBoundsCheck(i)); \
314         ++childIndex; \
315     } \
316 } else { \
317     if (list->isEmpty()) \
318         list->append(Animation::create()); \
319     mapAnimation##Prop(list->animation(childIndex), value); \
320     childIndex = 1; \
321 } \
322 for ( ; childIndex < list->size(); ++childIndex) { \
323     /* Reset all remaining transitions to not have the property set. */ \
324     list->animation(childIndex)->clear##Prop(); \
325 } \
326 }
327
328 #define HANDLE_INHERIT_COND(propID, prop, Prop) \
329 if (id == propID) { \
330     m_style->set##Prop(m_parentStyle->prop()); \
331     return; \
332 }
333     
334 #define HANDLE_INHERIT_COND_WITH_BACKUP(propID, prop, propAlt, Prop) \
335 if (id == propID) { \
336     if (m_parentStyle->prop().isValid()) \
337         m_style->set##Prop(m_parentStyle->prop()); \
338     else \
339         m_style->set##Prop(m_parentStyle->propAlt()); \
340     return; \
341 }
342
343 #define HANDLE_INITIAL_COND(propID, Prop) \
344 if (id == propID) { \
345     m_style->set##Prop(RenderStyle::initial##Prop()); \
346     return; \
347 }
348
349 #define HANDLE_INITIAL_COND_WITH_VALUE(propID, Prop, Value) \
350 if (id == propID) { \
351     m_style->set##Prop(RenderStyle::initial##Value()); \
352     return; \
353 }
354
355 class RuleData {
356 public:
357     RuleData(CSSStyleRule* rule, CSSSelector* selector, unsigned position)
358         : m_rule(rule)
359         , m_selector(selector)
360         , m_position(position)
361     {
362         collectDescendantSelectorIdentifierHashes();
363     }
364     void collectDescendantSelectorIdentifierHashes();
365     unsigned position() const { return m_position; }
366     CSSStyleRule* rule() const { return m_rule; }
367     CSSSelector* selector() const { return m_selector; }
368     
369     // Try to balance between memory usage (there can be lots of RuleData objects) and good filtering performance.
370     static const unsigned maximumIdentifierCount = 4;
371     const unsigned* descendantSelectorIdentifierHashes() const { return m_descendantSelectorIdentifierHashes; }
372
373 private:
374     CSSStyleRule* m_rule;
375     CSSSelector* m_selector;
376     unsigned m_position;
377     // Use plain array instead of a Vector to minimize memory overhead.
378     unsigned m_descendantSelectorIdentifierHashes[maximumIdentifierCount];
379 };
380
381 class RuleSet {
382     WTF_MAKE_NONCOPYABLE(RuleSet);
383 public:
384     RuleSet();
385     ~RuleSet();
386     
387     typedef HashMap<AtomicStringImpl*, Vector<RuleData>*> AtomRuleMap;
388     
389     void addRulesFromSheet(CSSStyleSheet*, const MediaQueryEvaluator&, CSSStyleSelector* = 0);
390
391     void addStyleRule(CSSStyleRule* item);
392     void addRule(CSSStyleRule* rule, CSSSelector* sel);
393     void addPageRule(CSSStyleRule* rule, CSSSelector* sel);
394     void addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map,
395                       CSSStyleRule* rule, CSSSelector* sel);
396     void shrinkToFit();
397     void disableAutoShrinkToFit() { m_autoShrinkToFitEnabled = false; }
398     
399     void collectIdsAndSiblingRules(HashSet<AtomicStringImpl*>& ids, OwnPtr<RuleSet>& siblingRules) const;
400     
401     const Vector<RuleData>* getIDRules(AtomicStringImpl* key) const { return m_idRules.get(key); }
402     const Vector<RuleData>* getClassRules(AtomicStringImpl* key) const { return m_classRules.get(key); }
403     const Vector<RuleData>* getTagRules(AtomicStringImpl* key) const { return m_tagRules.get(key); }
404     const Vector<RuleData>* getPseudoRules(AtomicStringImpl* key) const { return m_pseudoRules.get(key); }
405     const Vector<RuleData>* getUniversalRules() const { return &m_universalRules; }
406     const Vector<RuleData>* getPageRules() const { return &m_pageRules; }
407     
408 public:
409     AtomRuleMap m_idRules;
410     AtomRuleMap m_classRules;
411     AtomRuleMap m_tagRules;
412     AtomRuleMap m_pseudoRules;
413     Vector<RuleData> m_universalRules;
414     Vector<RuleData> m_pageRules;
415     unsigned m_ruleCount;
416     bool m_autoShrinkToFitEnabled;
417 };
418
419 static RuleSet* defaultStyle;
420 static RuleSet* defaultQuirksStyle;
421 static RuleSet* defaultPrintStyle;
422 static RuleSet* defaultViewSourceStyle;
423 static CSSStyleSheet* simpleDefaultStyleSheet;
424     
425 static RuleSet* siblingRulesInDefaultStyle;
426
427 RenderStyle* CSSStyleSelector::s_styleNotYetAvailable;
428
429 static void loadFullDefaultStyle();
430 #if ENABLE(FULLSCREEN_API)
431 static void loadFullScreenRulesIfNeeded(Document*);
432 #endif
433 static void loadSimpleDefaultStyle();
434 // FIXME: It would be nice to use some mechanism that guarantees this is in sync with the real UA stylesheet.
435 static const char* simpleUserAgentStyleSheet = "html,body,div{display:block}body{margin:8px}div:focus,span:focus{outline:auto 5px -webkit-focus-ring-color}a:-webkit-any-link{color:-webkit-link;text-decoration:underline}a:-webkit-any-link:active{color:-webkit-activelink}";
436
437 static inline bool elementCanUseSimpleDefaultStyle(Element* e)
438 {
439     return e->hasTagName(htmlTag) || e->hasTagName(bodyTag) || e->hasTagName(divTag) || e->hasTagName(spanTag) || e->hasTagName(brTag) || e->hasTagName(aTag);
440 }
441
442 static inline void collectSiblingRulesInDefaultStyle()
443 {
444     OwnPtr<RuleSet> siblingRules;
445     HashSet<AtomicStringImpl*> ids;
446     defaultStyle->collectIdsAndSiblingRules(ids, siblingRules);
447     ASSERT(ids.isEmpty());
448     delete siblingRulesInDefaultStyle;
449     siblingRulesInDefaultStyle = siblingRules.leakPtr();
450 }
451
452 static inline void assertNoSiblingRulesInDefaultStyle()
453 {
454 #ifndef NDEBUG
455     if (siblingRulesInDefaultStyle)
456         return;
457     collectSiblingRulesInDefaultStyle();
458     ASSERT(!siblingRulesInDefaultStyle);
459 #endif
460 }
461     
462 static const MediaQueryEvaluator& screenEval()
463 {
464     DEFINE_STATIC_LOCAL(const MediaQueryEvaluator, staticScreenEval, ("screen"));
465     return staticScreenEval;
466 }
467
468 static const MediaQueryEvaluator& printEval()
469 {
470     DEFINE_STATIC_LOCAL(const MediaQueryEvaluator, staticPrintEval, ("print"));
471     return staticPrintEval;
472 }
473
474 CSSStyleSelector::CSSStyleSelector(Document* document, StyleSheetList* styleSheets, CSSStyleSheet* mappedElementSheet,
475                                    CSSStyleSheet* pageUserSheet, const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets,
476                                    bool strictParsing, bool matchAuthorAndUserStyles)
477     : m_backgroundData(BackgroundFillLayer)
478     , m_checker(document, strictParsing)
479     , m_element(0)
480     , m_styledElement(0)
481     , m_elementLinkState(NotInsideLink)
482     , m_fontSelector(CSSFontSelector::create(document))
483 {
484     m_matchAuthorAndUserStyles = matchAuthorAndUserStyles;
485     
486     Element* root = document->documentElement();
487
488     if (!defaultStyle) {
489         if (!root || elementCanUseSimpleDefaultStyle(root))
490             loadSimpleDefaultStyle();
491         else {
492             loadFullDefaultStyle();
493 #if ENABLE(FULLSCREEN_API)
494             loadFullScreenRulesIfNeeded(document);
495 #endif
496         }
497     }
498
499     // construct document root element default style. this is needed
500     // to evaluate media queries that contain relative constraints, like "screen and (max-width: 10em)"
501     // This is here instead of constructor, because when constructor is run,
502     // document doesn't have documentElement
503     // NOTE: this assumes that element that gets passed to styleForElement -call
504     // is always from the document that owns the style selector
505     FrameView* view = document->view();
506     if (view)
507         m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType()));
508     else
509         m_medium = adoptPtr(new MediaQueryEvaluator("all"));
510
511     if (root)
512         m_rootDefaultStyle = styleForElement(root, 0, false, true); // don't ref, because the RenderStyle is allocated from global heap
513
514     if (m_rootDefaultStyle && view)
515         m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType(), view->frame(), m_rootDefaultStyle.get()));
516
517     m_authorStyle = adoptPtr(new RuleSet);
518     // Adding rules from multiple sheets, shrink at the end.
519     m_authorStyle->disableAutoShrinkToFit();
520
521     // FIXME: This sucks! The user sheet is reparsed every time!
522     OwnPtr<RuleSet> tempUserStyle = adoptPtr(new RuleSet);
523     if (pageUserSheet)
524         tempUserStyle->addRulesFromSheet(pageUserSheet, *m_medium, this);
525     if (pageGroupUserSheets) {
526         unsigned length = pageGroupUserSheets->size();
527         for (unsigned i = 0; i < length; i++) {
528             if (pageGroupUserSheets->at(i)->isUserStyleSheet())
529                 tempUserStyle->addRulesFromSheet(pageGroupUserSheets->at(i).get(), *m_medium, this);
530             else
531                 m_authorStyle->addRulesFromSheet(pageGroupUserSheets->at(i).get(), *m_medium, this);
532         }
533     }
534
535     if (tempUserStyle->m_ruleCount > 0 || tempUserStyle->m_pageRules.size() > 0)
536         m_userStyle = tempUserStyle.release();
537
538     // Add rules from elements like SVG's <font-face>
539     if (mappedElementSheet)
540         m_authorStyle->addRulesFromSheet(mappedElementSheet, *m_medium, this);
541
542     // add stylesheets from document
543     unsigned length = styleSheets->length();
544     for (unsigned i = 0; i < length; i++) {
545         StyleSheet* sheet = styleSheets->item(i);
546         if (sheet->isCSSStyleSheet() && !sheet->disabled())
547             m_authorStyle->addRulesFromSheet(static_cast<CSSStyleSheet*>(sheet), *m_medium, this);
548     }    
549     // Collect all ids and rules using sibling selectors (:first-child and similar)
550     // in the current set of stylesheets. Style sharing code uses this information to reject
551     // sharing candidates.
552     // Usually there are no sibling rules in the default style but the MathML sheet has some.
553     if (siblingRulesInDefaultStyle)
554         siblingRulesInDefaultStyle->collectIdsAndSiblingRules(m_idsInRules, m_siblingRules);
555     m_authorStyle->collectIdsAndSiblingRules(m_idsInRules, m_siblingRules);
556     if (m_userStyle)
557         m_userStyle->collectIdsAndSiblingRules(m_idsInRules, m_siblingRules);
558
559     m_authorStyle->shrinkToFit();
560     if (m_siblingRules)
561         m_siblingRules->shrinkToFit();
562
563     if (document->renderer() && document->renderer()->style())
564         document->renderer()->style()->font().update(fontSelector());
565 }
566
567 // This is a simplified style setting function for keyframe styles
568 void CSSStyleSelector::addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule> rule)
569 {
570     AtomicString s(rule->name());
571     m_keyframesRuleMap.add(s.impl(), rule);
572 }
573
574 CSSStyleSelector::~CSSStyleSelector()
575 {
576     m_fontSelector->clearDocument();
577     deleteAllValues(m_viewportDependentMediaQueryResults);
578 }
579
580 static CSSStyleSheet* parseUASheet(const String& str)
581 {
582     CSSStyleSheet* sheet = CSSStyleSheet::create().releaseRef(); // leak the sheet on purpose
583     sheet->parseString(str);
584     return sheet;
585 }
586
587 static CSSStyleSheet* parseUASheet(const char* characters, unsigned size)
588 {
589     return parseUASheet(String(characters, size));
590 }
591
592 static void loadFullDefaultStyle()
593 {
594     if (simpleDefaultStyleSheet) {
595         ASSERT(defaultStyle);
596         delete defaultStyle;
597         simpleDefaultStyleSheet->deref();
598         defaultStyle = new RuleSet;
599         simpleDefaultStyleSheet = 0;
600     } else {
601         ASSERT(!defaultStyle);
602         defaultStyle = new RuleSet;
603         defaultPrintStyle = new RuleSet;
604         defaultQuirksStyle = new RuleSet;
605     }
606
607     // Strict-mode rules.
608     String defaultRules = String(htmlUserAgentStyleSheet, sizeof(htmlUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraDefaultStyleSheet();
609     CSSStyleSheet* defaultSheet = parseUASheet(defaultRules);
610     defaultStyle->addRulesFromSheet(defaultSheet, screenEval());
611     defaultPrintStyle->addRulesFromSheet(defaultSheet, printEval());
612
613     // Quirks-mode rules.
614     String quirksRules = String(quirksUserAgentStyleSheet, sizeof(quirksUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraQuirksStyleSheet();
615     CSSStyleSheet* quirksSheet = parseUASheet(quirksRules);
616     defaultQuirksStyle->addRulesFromSheet(quirksSheet, screenEval());
617 }
618
619 #if ENABLE(FULLSCREEN_API)
620 static void loadFullScreenRulesIfNeeded(Document* document)
621 {
622     if (!document->webkitIsFullScreen())
623         return;
624     // Full-screen rules.
625     String fullscreenRules = String(fullscreenUserAgentStyleSheet, sizeof(fullscreenUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraDefaultStyleSheet();
626     CSSStyleSheet* fullscreenSheet = parseUASheet(fullscreenRules);
627     defaultStyle->addRulesFromSheet(fullscreenSheet, screenEval());
628     defaultQuirksStyle->addRulesFromSheet(fullscreenSheet, screenEval());
629 }
630 #endif
631
632 static void loadSimpleDefaultStyle()
633 {
634     ASSERT(!defaultStyle);
635     ASSERT(!simpleDefaultStyleSheet);
636     
637     defaultStyle = new RuleSet;
638     defaultPrintStyle = new RuleSet;
639     defaultQuirksStyle = new RuleSet;
640
641     simpleDefaultStyleSheet = parseUASheet(simpleUserAgentStyleSheet, strlen(simpleUserAgentStyleSheet));
642     defaultStyle->addRulesFromSheet(simpleDefaultStyleSheet, screenEval());
643     
644     // No need to initialize quirks sheet yet as there are no quirk rules for elements allowed in simple default style.
645 }
646     
647 static void loadViewSourceStyle()
648 {
649     ASSERT(!defaultViewSourceStyle);
650     defaultViewSourceStyle = new RuleSet;
651     defaultViewSourceStyle->addRulesFromSheet(parseUASheet(sourceUserAgentStyleSheet, sizeof(sourceUserAgentStyleSheet)), screenEval());
652 }
653     
654 static inline void collectElementIdentifierHashes(Element* element, Vector<unsigned, 4>& identifierHashes)
655 {
656     identifierHashes.append(element->localName().impl()->existingHash());
657     if (element->hasID())
658         identifierHashes.append(element->idForStyleResolution().impl()->existingHash());
659     StyledElement* styledElement = element->isStyledElement() ? static_cast<StyledElement*>(element) : 0;
660     if (styledElement && styledElement->hasClass()) {
661         const SpaceSplitString& classNames = static_cast<StyledElement*>(element)->classNames();
662         size_t count = classNames.size();
663         for (size_t i = 0; i < count; ++i)
664             identifierHashes.append(classNames[i].impl()->existingHash());
665     }
666 }
667     
668 void CSSStyleSelector::pushParent(Element* parent)
669 {
670     // If we are not invoked consistently for each parent, just pause maintaining the stack.
671     // There are all kinds of wacky special cases where the style recalc may temporarily branch to some random elements.
672     // FIXME: Perhaps we should fix up the stack instead? There is some danger of getting into O(n^2) situations doing that.
673     if (m_parentStack.isEmpty()) {
674         ASSERT(m_ancestorIdentifierFilter.isEmpty());
675         // We must start from the root.
676         if (parent->parentElement())
677             return;
678     } else if (m_parentStack.last().element != parent->parentElement())
679         return;
680
681     m_parentStack.append(ParentStackFrame(parent));
682     ParentStackFrame& parentFrame = m_parentStack.last();
683     // Mix tags, class names and ids into some sort of weird bouillabaisse.
684     // The filter is used for fast rejection of child and descendant selectors.
685     collectElementIdentifierHashes(parent, parentFrame.identifierHashes);
686     size_t count = parentFrame.identifierHashes.size();
687     for (size_t i = 0; i < count; ++i)
688         m_ancestorIdentifierFilter.add(parentFrame.identifierHashes[i]);
689 }
690
691 void CSSStyleSelector::popParent(Element* parent)
692 {
693     if (m_parentStack.isEmpty() || m_parentStack.last().element != parent)
694         return;
695
696     const ParentStackFrame& parentFrame = m_parentStack.last();
697     size_t count = parentFrame.identifierHashes.size();
698     for (size_t i = 0; i < count; ++i)
699         m_ancestorIdentifierFilter.remove(parentFrame.identifierHashes[i]);
700     m_parentStack.removeLast();
701     ASSERT(!m_parentStack.isEmpty() || m_ancestorIdentifierFilter.isEmpty());
702 }
703
704 void CSSStyleSelector::addMatchedDeclaration(CSSMutableStyleDeclaration* decl)
705 {
706     m_matchedDecls.append(decl);
707 }
708
709 void CSSStyleSelector::matchRules(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules)
710 {
711     m_matchedRules.clear();
712
713     if (!rules || !m_element)
714         return;
715     
716     // We need to collect the rules for id, class, tag, and everything else into a buffer and
717     // then sort the buffer.
718     if (m_element->hasID())
719         matchRulesForList(rules->getIDRules(m_element->idForStyleResolution().impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
720     if (m_element->hasClass()) {
721         ASSERT(m_styledElement);
722         const SpaceSplitString& classNames = m_styledElement->classNames();
723         size_t size = classNames.size();
724         for (size_t i = 0; i < size; ++i)
725             matchRulesForList(rules->getClassRules(classNames[i].impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
726     }
727     if (!m_element->shadowPseudoId().isEmpty()) {
728         ASSERT(m_styledElement);
729         matchRulesForList(rules->getPseudoRules(m_element->shadowPseudoId().impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
730     }
731     matchRulesForList(rules->getTagRules(m_element->localName().impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
732     matchRulesForList(rules->getUniversalRules(), firstRuleIndex, lastRuleIndex, includeEmptyRules);
733     
734     // If we didn't match any rules, we're done.
735     if (m_matchedRules.isEmpty())
736         return;
737     
738     // Sort the set of matched rules.
739     sortMatchedRules(0, m_matchedRules.size());
740     
741     // Now transfer the set of matched rules over to our list of decls.
742     if (!m_checker.m_collectRulesOnly) {
743         for (unsigned i = 0; i < m_matchedRules.size(); i++)
744             addMatchedDeclaration(m_matchedRules[i]->rule()->declaration());
745     } else {
746         for (unsigned i = 0; i < m_matchedRules.size(); i++) {
747             if (!m_ruleList)
748                 m_ruleList = CSSRuleList::create();
749             m_ruleList->append(m_matchedRules[i]->rule());
750         }
751     }
752 }
753
754 inline bool CSSStyleSelector::fastRejectSelector(const RuleData& ruleData) const
755 {
756     const unsigned* descendantSelectorIdentifierHashes = ruleData.descendantSelectorIdentifierHashes();
757     for (unsigned n = 0; n < RuleData::maximumIdentifierCount && descendantSelectorIdentifierHashes[n]; ++n) {
758         if (!m_ancestorIdentifierFilter.contains(descendantSelectorIdentifierHashes[n]))
759             return true;
760     }
761     return false;
762 }
763
764 void CSSStyleSelector::matchRulesForList(const Vector<RuleData>* rules, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules)
765 {
766     if (!rules)
767         return;
768     // In some cases we may end up looking up style for random elements in the middle of a recursive tree resolve.
769     // Ancestor identifier filter won't be up-to-date in that case and we can't use the fast path.
770     bool canUseFastReject = !m_parentStack.isEmpty() && m_parentStack.last().element == m_parentNode;
771
772     unsigned size = rules->size();
773     for (unsigned i = 0; i < size; ++i) {
774         const RuleData& ruleData = rules->at(i);
775         CSSStyleRule* rule = ruleData.rule();
776         if (canUseFastReject && fastRejectSelector(ruleData))
777             continue;
778         if (checkSelector(ruleData.selector())) {
779             // If the rule has no properties to apply, then ignore it in the non-debug mode.
780             CSSMutableStyleDeclaration* decl = rule->declaration();
781             if (!decl || (!decl->length() && !includeEmptyRules))
782                 continue;
783             if (m_checker.m_sameOriginOnly && !m_checker.m_document->securityOrigin()->canRequest(rule->baseURL()))
784                 continue; 
785             // If we're matching normal rules, set a pseudo bit if 
786             // we really just matched a pseudo-element.
787             if (m_dynamicPseudo != NOPSEUDO && m_checker.m_pseudoStyle == NOPSEUDO) {
788                 if (m_checker.m_collectRulesOnly)
789                     continue;
790                 if (m_dynamicPseudo < FIRST_INTERNAL_PSEUDOID)
791                     m_style->setHasPseudoStyle(m_dynamicPseudo);
792             } else {
793                 // Update our first/last rule indices in the matched rules array.
794                 lastRuleIndex = m_matchedDecls.size() + m_matchedRules.size();
795                 if (firstRuleIndex == -1)
796                     firstRuleIndex = lastRuleIndex;
797
798                 // Add this rule to our list of matched rules.
799                 addMatchedRule(&ruleData);
800             }
801         }
802     }
803 }
804
805 static bool operator >(const RuleData& r1, const RuleData& r2)
806 {
807     int spec1 = r1.selector()->specificity();
808     int spec2 = r2.selector()->specificity();
809     return (spec1 == spec2) ? r1.position() > r2.position() : spec1 > spec2; 
810 }
811     
812 static bool operator <=(const RuleData& r1, const RuleData& r2)
813 {
814     return !(r1 > r2);
815 }
816
817 void CSSStyleSelector::sortMatchedRules(unsigned start, unsigned end)
818 {
819     if (start >= end || (end - start == 1))
820         return; // Sanity check.
821
822     if (end - start <= 6) {
823         // Apply a bubble sort for smaller lists.
824         for (unsigned i = end - 1; i > start; i--) {
825             bool sorted = true;
826             for (unsigned j = start; j < i; j++) {
827                 const RuleData* elt = m_matchedRules[j];
828                 const RuleData* elt2 = m_matchedRules[j + 1];
829                 if (*elt > *elt2) {
830                     sorted = false;
831                     m_matchedRules[j] = elt2;
832                     m_matchedRules[j + 1] = elt;
833                 }
834             }
835             if (sorted)
836                 return;
837         }
838         return;
839     }
840
841     // Perform a merge sort for larger lists.
842     unsigned mid = (start + end) / 2;
843     sortMatchedRules(start, mid);
844     sortMatchedRules(mid, end);
845     
846     const RuleData* elt = m_matchedRules[mid - 1];
847     const RuleData* elt2 = m_matchedRules[mid];
848     
849     // Handle the fast common case (of equal specificity).  The list may already
850     // be completely sorted.
851     if (*elt <= *elt2)
852         return;
853     
854     // We have to merge sort.  Ensure our merge buffer is big enough to hold
855     // all the items.
856     Vector<const RuleData*> rulesMergeBuffer;
857     rulesMergeBuffer.reserveInitialCapacity(end - start); 
858
859     unsigned i1 = start;
860     unsigned i2 = mid;
861     
862     elt = m_matchedRules[i1];
863     elt2 = m_matchedRules[i2];
864     
865     while (i1 < mid || i2 < end) {
866         if (i1 < mid && (i2 == end || *elt <= *elt2)) {
867             rulesMergeBuffer.append(elt);
868             if (++i1 < mid)
869                 elt = m_matchedRules[i1];
870         } else {
871             rulesMergeBuffer.append(elt2);
872             if (++i2 < end)
873                 elt2 = m_matchedRules[i2];
874         }
875     }
876     
877     for (unsigned i = start; i < end; i++)
878         m_matchedRules[i] = rulesMergeBuffer[i - start];
879 }
880
881 inline EInsideLink CSSStyleSelector::SelectorChecker::determineLinkState(Element* element) const
882 {
883     if (!element || !element->isLink())
884         return NotInsideLink;
885     return determineLinkStateSlowCase(element);
886 }
887     
888 inline void CSSStyleSelector::initElement(Element* e)
889 {
890     if (m_element != e) {
891         m_element = e;
892         m_styledElement = m_element && m_element->isStyledElement() ? static_cast<StyledElement*>(m_element) : 0;
893         m_elementLinkState = m_checker.determineLinkState(m_element);
894         if (e && e == e->document()->documentElement()) {
895             e->document()->setDirectionSetOnDocumentElement(false);
896             e->document()->setWritingModeSetOnDocumentElement(false);
897         }
898     }
899 }
900
901 inline void CSSStyleSelector::initForStyleResolve(Element* e, RenderStyle* parentStyle, PseudoId pseudoID)
902 {
903     m_checker.m_pseudoStyle = pseudoID;
904
905     m_parentNode = e ? e->parentOrHostNode() : 0;
906
907     if (parentStyle)
908         m_parentStyle = parentStyle;
909     else
910         m_parentStyle = m_parentNode ? m_parentNode->renderStyle() : 0;
911
912     Node* docElement = e ? e->document()->documentElement() : 0;
913     RenderStyle* docStyle = m_checker.m_document->renderStyle();
914     m_rootElementStyle = docElement && e != docElement ? docElement->renderStyle() : docStyle;
915
916     m_style = 0;
917
918     m_matchedDecls.clear();
919
920     m_pendingImageProperties.clear();
921
922     m_ruleList = 0;
923
924     m_fontDirty = false;
925 }
926
927 static inline const AtomicString* linkAttribute(Node* node)
928 {
929     if (!node->isLink())
930         return 0;
931
932     ASSERT(node->isElementNode());
933     Element* element = static_cast<Element*>(node);
934     if (element->isHTMLElement())
935         return &element->fastGetAttribute(hrefAttr);
936
937 #if ENABLE(WML)
938     if (element->isWMLElement()) {
939         // <anchor> elements don't have href attributes, but we still want to
940         // appear as link, so linkAttribute() has to return a non-null value!
941         if (element->hasTagName(WMLNames::anchorTag))
942             return &emptyAtom;
943
944         return &element->fastGetAttribute(hrefAttr);
945     }
946 #endif
947
948 #if ENABLE(SVG)
949     if (element->isSVGElement())
950         return &element->fastGetAttribute(XLinkNames::hrefAttr);
951 #endif
952
953     return 0;
954 }
955
956 CSSStyleSelector::SelectorChecker::SelectorChecker(Document* document, bool strictParsing)
957     : m_document(document)
958     , m_strictParsing(strictParsing)
959     , m_collectRulesOnly(false)
960     , m_sameOriginOnly(false)
961     , m_pseudoStyle(NOPSEUDO)
962     , m_documentIsHTML(document->isHTMLDocument())
963     , m_matchVisitedPseudoClass(false)
964 {
965 }
966
967 EInsideLink CSSStyleSelector::SelectorChecker::determineLinkStateSlowCase(Element* element) const
968 {
969     ASSERT(element->isLink());
970     
971     const AtomicString* attr = linkAttribute(element);
972     if (!attr || attr->isNull())
973         return NotInsideLink;
974
975 #if PLATFORM(QT)
976     Vector<UChar, 512> url;
977     visitedURL(m_document->baseURL(), *attr, url);
978     if (url.isEmpty())
979         return InsideUnvisitedLink;
980
981     // If the Qt4.4 interface for the history is used, we will have to fallback
982     // to the old global history.
983     QWebHistoryInterface* iface = QWebHistoryInterface::defaultInterface();
984     if (iface)
985         return iface->historyContains(QString(reinterpret_cast<QChar*>(url.data()), url.size())) ? InsideVisitedLink : InsideUnvisitedLink;
986
987     LinkHash hash = visitedLinkHash(url.data(), url.size());
988     if (!hash)
989         return InsideUnvisitedLink;
990 #else
991     LinkHash hash = visitedLinkHash(m_document->baseURL(), *attr);
992     if (!hash)
993         return InsideUnvisitedLink;
994 #endif
995
996     Frame* frame = m_document->frame();
997     if (!frame)
998         return InsideUnvisitedLink;
999
1000     Page* page = frame->page();
1001     if (!page)
1002         return InsideUnvisitedLink;
1003
1004     m_linksCheckedForVisitedState.add(hash);
1005
1006 #if USE(PLATFORM_STRATEGIES)
1007     return platformStrategies()->visitedLinkStrategy()->isLinkVisited(page, hash) ? InsideVisitedLink : InsideUnvisitedLink;
1008 #else
1009     return page->group().isLinkVisited(hash) ? InsideVisitedLink : InsideUnvisitedLink;
1010 #endif
1011 }
1012
1013 bool CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* element) const
1014 {
1015     PseudoId dynamicPseudo = NOPSEUDO;
1016     return checkSelector(sel, element, 0, dynamicPseudo, false, false) == SelectorMatches;
1017 }
1018
1019 static const unsigned cStyleSearchThreshold = 10;
1020
1021 Node* CSSStyleSelector::locateCousinList(Element* parent, unsigned depth) const
1022 {
1023     if (!parent || !parent->isStyledElement())
1024         return 0;
1025     StyledElement* p = static_cast<StyledElement*>(parent);
1026     if (p->inlineStyleDecl())
1027         return 0;
1028     if (p->hasID() && m_idsInRules.contains(p->idForStyleResolution().impl()))
1029         return 0;
1030     Node* r = p->previousSibling();
1031     unsigned subcount = 0;
1032     RenderStyle* st = p->renderStyle();
1033     while (r) {
1034         if (r->renderStyle() == st)
1035             return r->lastChild();
1036         if (subcount++ == cStyleSearchThreshold)
1037             return 0;
1038         r = r->previousSibling();
1039     }
1040     if (!r && depth < cStyleSearchThreshold)
1041         r = locateCousinList(parent->parentElement(), depth + 1);
1042     while (r) {
1043         if (r->renderStyle() == st)
1044             return r->lastChild();
1045         if (subcount++ == cStyleSearchThreshold)
1046             return 0;
1047         r = r->previousSibling();
1048     }
1049     return 0;
1050 }
1051
1052 bool CSSStyleSelector::matchesSiblingRules()
1053 {
1054     int firstSiblingRule = -1, lastSiblingRule = -1;
1055     matchRules(m_siblingRules.get(), firstSiblingRule, lastSiblingRule, false);
1056     if (m_matchedDecls.isEmpty())
1057         return false;
1058     m_matchedDecls.clear();
1059     return true;
1060 }
1061
1062 bool CSSStyleSelector::canShareStyleWithElement(Node* n) const
1063 {
1064     if (n->isStyledElement()) {
1065         StyledElement* s = static_cast<StyledElement*>(n);
1066         RenderStyle* style = s->renderStyle();
1067         if (style && !style->unique() &&
1068             (s->tagQName() == m_element->tagQName()) &&
1069             (s->hasClass() == m_element->hasClass()) && !s->inlineStyleDecl() &&
1070             (s->hasMappedAttributes() == m_styledElement->hasMappedAttributes()) &&
1071             (s->isLink() == m_element->isLink()) && 
1072             !style->affectedByAttributeSelectors() &&
1073             (s->hovered() == m_element->hovered()) &&
1074             (s->active() == m_element->active()) &&
1075             (s->focused() == m_element->focused()) &&
1076             (s->shadowPseudoId() == m_element->shadowPseudoId()) &&
1077             (s != s->document()->cssTarget() && m_element != m_element->document()->cssTarget()) &&
1078             (s->fastGetAttribute(typeAttr) == m_element->fastGetAttribute(typeAttr)) &&
1079             (s->fastGetAttribute(XMLNames::langAttr) == m_element->fastGetAttribute(XMLNames::langAttr)) &&
1080             (s->fastGetAttribute(langAttr) == m_element->fastGetAttribute(langAttr)) &&
1081             (s->fastGetAttribute(readonlyAttr) == m_element->fastGetAttribute(readonlyAttr)) &&
1082             (s->fastGetAttribute(cellpaddingAttr) == m_element->fastGetAttribute(cellpaddingAttr))) {
1083             
1084             if (s->hasID() && m_idsInRules.contains(s->idForStyleResolution().impl()))
1085                 return 0;
1086             
1087             bool isControl = s->isFormControlElement();
1088             if (isControl != m_element->isFormControlElement())
1089                 return false;
1090             if (isControl) {
1091                 InputElement* thisInputElement = toInputElement(s);
1092                 InputElement* otherInputElement = toInputElement(m_element);
1093                 if (thisInputElement && otherInputElement) {
1094                     if ((thisInputElement->isAutofilled() != otherInputElement->isAutofilled()) ||
1095                         (thisInputElement->isChecked() != otherInputElement->isChecked()) ||
1096                         (thisInputElement->isIndeterminate() != otherInputElement->isIndeterminate()))
1097                     return false;
1098                 } else
1099                     return false;
1100
1101                 if (s->isEnabledFormControl() != m_element->isEnabledFormControl())
1102                     return false;
1103
1104                 if (s->isDefaultButtonForForm() != m_element->isDefaultButtonForForm())
1105                     return false;
1106                 
1107                 if (!m_element->document()->containsValidityStyleRules())
1108                     return false;
1109                 
1110                 bool willValidate = s->willValidate();
1111                 if (willValidate != m_element->willValidate())
1112                     return false;
1113                 
1114                 if (willValidate && (s->isValidFormControlElement() != m_element->isValidFormControlElement()))
1115                     return false;
1116
1117                 if (s->isInRange() != m_element->isInRange())
1118                     return false;
1119
1120                 if (s->isOutOfRange() != m_element->isOutOfRange())
1121                     return false;
1122             }
1123
1124             if (style->transitions() || style->animations())
1125                 return false;
1126
1127 #if USE(ACCELERATED_COMPOSITING)
1128             // Turn off style sharing for elements that can gain layers for reasons outside of the style system.
1129             // See comments in RenderObject::setStyle().
1130             if (s->hasTagName(iframeTag) || s->hasTagName(embedTag) || s->hasTagName(objectTag) || s->hasTagName(appletTag))
1131                 return false;
1132 #endif
1133
1134             bool classesMatch = true;
1135             if (s->hasClass()) {
1136                 const AtomicString& class1 = m_element->fastGetAttribute(classAttr);
1137                 const AtomicString& class2 = s->fastGetAttribute(classAttr);
1138                 classesMatch = (class1 == class2);
1139             }
1140             
1141             if (classesMatch) {
1142                 bool mappedAttrsMatch = true;
1143                 if (s->hasMappedAttributes())
1144                     mappedAttrsMatch = s->attributeMap()->mappedMapsEquivalent(m_styledElement->attributeMap());
1145                 if (mappedAttrsMatch) {
1146                     if (s->isLink()) {
1147                         if (m_elementLinkState != style->insideLink())
1148                             return false;
1149                     }
1150                     return true;
1151                 }
1152             }
1153         }
1154     }
1155     return false;
1156 }
1157     
1158 inline Node* CSSStyleSelector::findSiblingForStyleSharing(Node* node, unsigned& count) const
1159 {
1160     for (; node; node = node->previousSibling()) {
1161         if (!node->isElementNode())
1162             continue;
1163         if (canShareStyleWithElement(node))
1164             break;
1165         if (count++ == cStyleSearchThreshold)
1166             return 0;
1167     }
1168     return node;
1169 }
1170
1171 static inline bool parentStylePreventsSharing(const RenderStyle* parentStyle)
1172 {
1173     return parentStyle->childrenAffectedByPositionalRules() 
1174         || parentStyle->childrenAffectedByFirstChildRules()
1175         || parentStyle->childrenAffectedByLastChildRules() 
1176         || parentStyle->childrenAffectedByDirectAdjacentRules();
1177 }
1178
1179 ALWAYS_INLINE RenderStyle* CSSStyleSelector::locateSharedStyle()
1180 {
1181     if (!m_styledElement || !m_parentStyle)
1182         return 0;
1183     // If the element has inline style it is probably unique.
1184     if (m_styledElement->inlineStyleDecl())
1185         return 0;
1186     // Ids stop style sharing if they show up in the stylesheets.
1187     if (m_styledElement->hasID() && m_idsInRules.contains(m_styledElement->idForStyleResolution().impl()))
1188         return 0;
1189     if (parentStylePreventsSharing(m_parentStyle))
1190         return 0;
1191     // Check previous siblings.
1192     unsigned count = 0;
1193     Node* shareNode = findSiblingForStyleSharing(m_styledElement->previousSibling(), count);
1194     if (!shareNode) {
1195         Node* cousinList = locateCousinList(m_styledElement->parentElement());
1196         shareNode = findSiblingForStyleSharing(cousinList, count); 
1197         if (!shareNode)
1198             return 0;
1199     }
1200     // Can't share if sibling rules apply. This is checked at the end as it should rarely fail.
1201     if (matchesSiblingRules())
1202         return 0;
1203     // Tracking child index requires unique style for each node. This may get set by the sibling rule match above.
1204     if (parentStylePreventsSharing(m_parentStyle))
1205         return 0;
1206     return shareNode->renderStyle();
1207 }
1208
1209 void CSSStyleSelector::matchUARules(int& firstUARule, int& lastUARule)
1210 {
1211     // First we match rules from the user agent sheet.
1212     RuleSet* userAgentStyleSheet = m_medium->mediaTypeMatchSpecific("print")
1213         ? defaultPrintStyle : defaultStyle;
1214     matchRules(userAgentStyleSheet, firstUARule, lastUARule, false);
1215
1216     // In quirks mode, we match rules from the quirks user agent sheet.
1217     if (!m_checker.m_strictParsing)
1218         matchRules(defaultQuirksStyle, firstUARule, lastUARule, false);
1219         
1220     // If we're in view source mode, then we match rules from the view source style sheet.
1221     if (m_checker.m_document->frame() && m_checker.m_document->frame()->inViewSourceMode()) {
1222         if (!defaultViewSourceStyle)
1223             loadViewSourceStyle();
1224         matchRules(defaultViewSourceStyle, firstUARule, lastUARule, false);
1225     }
1226 }
1227
1228 PassRefPtr<RenderStyle> CSSStyleSelector::styleForDocument(Document* document)
1229 {
1230     Frame* frame = document->frame();
1231
1232     RefPtr<RenderStyle> documentStyle = RenderStyle::create();
1233     documentStyle->setDisplay(BLOCK);
1234     documentStyle->setVisuallyOrdered(document->visuallyOrdered());
1235     documentStyle->setZoom(frame ? frame->pageZoomFactor() : 1);
1236     documentStyle->setPageScaleTransform(frame ? frame->pageScaleFactor() : 1);
1237     
1238     Element* docElement = document->documentElement();
1239     RenderObject* docElementRenderer = docElement ? docElement->renderer() : 0;
1240     if (docElementRenderer) {
1241         // Use the direction and writing-mode of the body to set the
1242         // viewport's direction and writing-mode unless the property is set on the document element.
1243         // If there is no body, then use the document element.
1244         RenderObject* bodyRenderer = document->body() ? document->body()->renderer() : 0;
1245         if (bodyRenderer && !document->writingModeSetOnDocumentElement())
1246             documentStyle->setWritingMode(bodyRenderer->style()->writingMode());
1247         else
1248             documentStyle->setWritingMode(docElementRenderer->style()->writingMode());
1249         if (bodyRenderer && !document->directionSetOnDocumentElement())
1250             documentStyle->setDirection(bodyRenderer->style()->direction());
1251         else
1252             documentStyle->setDirection(docElementRenderer->style()->direction());
1253     }
1254
1255     FontDescription fontDescription;
1256     fontDescription.setUsePrinterFont(document->printing());
1257     if (Settings* settings = document->settings()) {
1258         fontDescription.setRenderingMode(settings->fontRenderingMode());
1259         if (document->printing() && !settings->shouldPrintBackgrounds())
1260             documentStyle->setForceBackgroundsToWhite(true);
1261         const AtomicString& stdfont = settings->standardFontFamily();
1262         if (!stdfont.isEmpty()) {
1263             fontDescription.firstFamily().setFamily(stdfont);
1264             fontDescription.firstFamily().appendFamily(0);
1265         }
1266         fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
1267         int size = CSSStyleSelector::fontSizeForKeyword(document, CSSValueMedium, false);
1268         fontDescription.setSpecifiedSize(size);
1269         bool useSVGZoomRules = document->isSVGDocument();
1270         fontDescription.setComputedSize(CSSStyleSelector::getComputedSizeFromSpecifiedSize(document, documentStyle.get(), fontDescription.isAbsoluteSize(), size, useSVGZoomRules));
1271     }
1272
1273     documentStyle->setFontDescription(fontDescription);
1274     documentStyle->font().update(0);
1275         
1276     return documentStyle.release();
1277 }
1278
1279 // If resolveForRootDefault is true, style based on user agent style sheet only. This is used in media queries, where
1280 // relative units are interpreted according to document root element style, styled only with UA stylesheet
1281
1282 PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* e, RenderStyle* defaultParent, bool allowSharing, bool resolveForRootDefault, bool matchVisitedPseudoClass)
1283 {
1284     // Once an element has a renderer, we don't try to destroy it, since otherwise the renderer
1285     // will vanish if a style recalc happens during loading.
1286     if (allowSharing && !e->document()->haveStylesheetsLoaded() && !e->renderer()) {
1287         if (!s_styleNotYetAvailable) {
1288             s_styleNotYetAvailable = RenderStyle::create().releaseRef();
1289             s_styleNotYetAvailable->ref();
1290             s_styleNotYetAvailable->setDisplay(NONE);
1291             s_styleNotYetAvailable->font().update(m_fontSelector);
1292         }
1293         s_styleNotYetAvailable->ref();
1294         e->document()->setHasNodesWithPlaceholderStyle();
1295         return s_styleNotYetAvailable;
1296     }
1297
1298     initElement(e);
1299     initForStyleResolve(e, defaultParent);
1300     if (allowSharing) {
1301         RenderStyle* sharedStyle = locateSharedStyle();
1302         if (sharedStyle)
1303             return sharedStyle;
1304     }
1305
1306     // Compute our style allowing :visited to match first.
1307     RefPtr<RenderStyle> visitedStyle;
1308     if (!matchVisitedPseudoClass && m_parentStyle && (m_parentStyle->insideLink() || e->isLink()) && e->document()->usesLinkRules()) {
1309         // Fetch our parent style.
1310         RenderStyle* parentStyle = m_parentStyle;
1311         if (!e->isLink()) {
1312             // Use the parent's visited style if one exists.
1313             RenderStyle* parentVisitedStyle = m_parentStyle->getCachedPseudoStyle(VISITED_LINK);
1314             if (parentVisitedStyle)
1315                 parentStyle = parentVisitedStyle;
1316         }
1317         visitedStyle = styleForElement(e, parentStyle, false, false, true);
1318         if (visitedStyle) {
1319             if (m_elementLinkState == InsideUnvisitedLink)
1320                 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.
1321             else
1322                 visitedStyle->setStyleType(VISITED_LINK);
1323         }
1324         initForStyleResolve(e, defaultParent);
1325     }
1326
1327     m_checker.m_matchVisitedPseudoClass = matchVisitedPseudoClass;
1328
1329     m_style = RenderStyle::create();
1330
1331     if (m_parentStyle)
1332         m_style->inheritFrom(m_parentStyle);
1333     else
1334         m_parentStyle = style();
1335
1336     if (e->isLink()) {
1337         m_style->setIsLink(true);
1338         m_style->setInsideLink(m_elementLinkState);
1339     }
1340     
1341     if (simpleDefaultStyleSheet && !elementCanUseSimpleDefaultStyle(e)) {
1342         loadFullDefaultStyle();
1343 #if ENABLE(FULLSCREEN_API)
1344         loadFullScreenRulesIfNeeded(e->document());
1345 #endif
1346         assertNoSiblingRulesInDefaultStyle();
1347     }
1348
1349 #if ENABLE(SVG)
1350     static bool loadedSVGUserAgentSheet;
1351     if (e->isSVGElement() && !loadedSVGUserAgentSheet) {
1352         // SVG rules.
1353         loadedSVGUserAgentSheet = true;
1354         CSSStyleSheet* svgSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet));
1355         defaultStyle->addRulesFromSheet(svgSheet, screenEval());
1356         defaultPrintStyle->addRulesFromSheet(svgSheet, printEval());
1357         assertNoSiblingRulesInDefaultStyle();
1358     }
1359 #endif
1360
1361 #if ENABLE(MATHML)
1362     static bool loadedMathMLUserAgentSheet;
1363     if (e->isMathMLElement() && !loadedMathMLUserAgentSheet) {
1364         // MathML rules.
1365         loadedMathMLUserAgentSheet = true;
1366         CSSStyleSheet* mathMLSheet = parseUASheet(mathmlUserAgentStyleSheet, sizeof(mathmlUserAgentStyleSheet));
1367         defaultStyle->addRulesFromSheet(mathMLSheet, screenEval());
1368         defaultPrintStyle->addRulesFromSheet(mathMLSheet, printEval());
1369         // There are some sibling rules here.
1370         collectSiblingRulesInDefaultStyle();
1371     }
1372 #endif
1373
1374 #if ENABLE(WML)
1375     static bool loadedWMLUserAgentSheet;
1376     if (e->isWMLElement() && !loadedWMLUserAgentSheet) {
1377         // WML rules.
1378         loadedWMLUserAgentSheet = true;
1379         CSSStyleSheet* wmlSheet = parseUASheet(wmlUserAgentStyleSheet, sizeof(wmlUserAgentStyleSheet));
1380         defaultStyle->addRulesFromSheet(wmlSheet, screenEval());
1381         defaultPrintStyle->addRulesFromSheet(wmlSheet, printEval());
1382         assertNoSiblingRulesInDefaultStyle();
1383     }
1384 #endif
1385
1386 #if ENABLE(VIDEO)
1387     static bool loadedMediaStyleSheet;
1388     if (!loadedMediaStyleSheet && (e->hasTagName(videoTag) || e->hasTagName(audioTag))) {
1389         loadedMediaStyleSheet = true;
1390         String mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + RenderTheme::themeForPage(e->document()->page())->extraMediaControlsStyleSheet();
1391         CSSStyleSheet* mediaControlsSheet = parseUASheet(mediaRules);
1392         defaultStyle->addRulesFromSheet(mediaControlsSheet, screenEval());
1393         defaultPrintStyle->addRulesFromSheet(mediaControlsSheet, printEval());
1394         assertNoSiblingRulesInDefaultStyle();
1395     }
1396 #endif
1397
1398     int firstUARule = -1, lastUARule = -1;
1399     int firstUserRule = -1, lastUserRule = -1;
1400     int firstAuthorRule = -1, lastAuthorRule = -1;
1401     matchUARules(firstUARule, lastUARule);
1402
1403     if (!resolveForRootDefault) {
1404         // 4. Now we check user sheet rules.
1405         if (m_matchAuthorAndUserStyles)
1406             matchRules(m_userStyle.get(), firstUserRule, lastUserRule, false);
1407
1408         // 5. Now check author rules, beginning first with presentational attributes
1409         // mapped from HTML.
1410         if (m_styledElement) {
1411             // Ask if the HTML element has mapped attributes.
1412             if (m_styledElement->hasMappedAttributes()) {
1413                 // Walk our attribute list and add in each decl.
1414                 const NamedNodeMap* map = m_styledElement->attributeMap();
1415                 for (unsigned i = 0; i < map->length(); i++) {
1416                     Attribute* attr = map->attributeItem(i);
1417                     if (attr->isMappedAttribute() && attr->decl()) {
1418                         lastAuthorRule = m_matchedDecls.size();
1419                         if (firstAuthorRule == -1)
1420                             firstAuthorRule = lastAuthorRule;
1421                         addMatchedDeclaration(attr->decl());
1422                     }
1423                 }
1424             }
1425
1426             // Now we check additional mapped declarations.
1427             // Tables and table cells share an additional mapped rule that must be applied
1428             // after all attributes, since their mapped style depends on the values of multiple attributes.
1429             if (m_styledElement->canHaveAdditionalAttributeStyleDecls()) {
1430                 m_additionalAttributeStyleDecls.clear();
1431                 m_styledElement->additionalAttributeStyleDecls(m_additionalAttributeStyleDecls);
1432                 if (!m_additionalAttributeStyleDecls.isEmpty()) {
1433                     unsigned additionalDeclsSize = m_additionalAttributeStyleDecls.size();
1434                     if (firstAuthorRule == -1)
1435                         firstAuthorRule = m_matchedDecls.size();
1436                     lastAuthorRule = m_matchedDecls.size() + additionalDeclsSize - 1;
1437                     for (unsigned i = 0; i < additionalDeclsSize; i++)
1438                         addMatchedDeclaration(m_additionalAttributeStyleDecls[i]);
1439                 }
1440             }
1441         }
1442     
1443         // 6. Check the rules in author sheets next.
1444         if (m_matchAuthorAndUserStyles)
1445             matchRules(m_authorStyle.get(), firstAuthorRule, lastAuthorRule, false);
1446
1447         // 7. Now check our inline style attribute.
1448         if (m_matchAuthorAndUserStyles && m_styledElement) {
1449             CSSMutableStyleDeclaration* inlineDecl = m_styledElement->inlineStyleDecl();
1450             if (inlineDecl) {
1451                 lastAuthorRule = m_matchedDecls.size();
1452                 if (firstAuthorRule == -1)
1453                     firstAuthorRule = lastAuthorRule;
1454                 addMatchedDeclaration(inlineDecl);
1455             }
1456         }
1457     }
1458
1459     // Reset the value back before applying properties, so that -webkit-link knows what color to use.
1460     m_checker.m_matchVisitedPseudoClass = matchVisitedPseudoClass;
1461     
1462     // Now we have all of the matched rules in the appropriate order.  Walk the rules and apply
1463     // high-priority properties first, i.e., those properties that other properties depend on.
1464     // The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
1465     // and (4) normal important.
1466     m_lineHeightValue = 0;
1467     applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
1468     if (!resolveForRootDefault) {
1469         applyDeclarations<true>(true, firstAuthorRule, lastAuthorRule);
1470         applyDeclarations<true>(true, firstUserRule, lastUserRule);
1471     }
1472     applyDeclarations<true>(true, firstUARule, lastUARule);
1473     
1474     // If our font got dirtied, go ahead and update it now.
1475     if (m_fontDirty)
1476         updateFont();
1477
1478     // Line-height is set when we are sure we decided on the font-size
1479     if (m_lineHeightValue)
1480         applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
1481
1482     // Now do the normal priority UA properties.
1483     applyDeclarations<false>(false, firstUARule, lastUARule);
1484     
1485     // Cache our border and background so that we can examine them later.
1486     cacheBorderAndBackground();
1487     
1488     // Now do the author and user normal priority properties and all the !important properties.
1489     if (!resolveForRootDefault) {
1490         applyDeclarations<false>(false, lastUARule + 1, m_matchedDecls.size() - 1);
1491         applyDeclarations<false>(true, firstAuthorRule, lastAuthorRule);
1492         applyDeclarations<false>(true, firstUserRule, lastUserRule);
1493     }
1494     applyDeclarations<false>(true, firstUARule, lastUARule);
1495
1496     ASSERT(!m_fontDirty);
1497     // If our font got dirtied by one of the non-essential font props, 
1498     // go ahead and update it a second time.
1499     if (m_fontDirty)
1500         updateFont();
1501     
1502     // Clean up our style object's display and text decorations (among other fixups).
1503     adjustRenderStyle(style(), m_parentStyle, e);
1504
1505     // Start loading images referenced by this style.
1506     loadPendingImages();
1507
1508     // If we have first-letter pseudo style, do not share this style
1509     if (m_style->hasPseudoStyle(FIRST_LETTER))
1510         m_style->setUnique();
1511
1512     if (visitedStyle) {
1513         // Copy any pseudo bits that the visited style has to the primary style so that
1514         // pseudo element styles will continue to work for pseudo elements inside :visited
1515         // links.
1516         for (unsigned pseudo = FIRST_PUBLIC_PSEUDOID; pseudo < FIRST_INTERNAL_PSEUDOID; ++pseudo) {
1517             if (visitedStyle->hasPseudoStyle(static_cast<PseudoId>(pseudo)))
1518                 m_style->setHasPseudoStyle(static_cast<PseudoId>(pseudo));
1519         }
1520         
1521         // Add the visited style off the main style.
1522         m_style->addCachedPseudoStyle(visitedStyle.release());
1523     }
1524
1525     if (!matchVisitedPseudoClass)
1526         initElement(0); // Clear out for the next resolve.
1527
1528     // Now return the style.
1529     return m_style.release();
1530 }
1531
1532 PassRefPtr<RenderStyle> CSSStyleSelector::styleForKeyframe(const RenderStyle* elementStyle, const WebKitCSSKeyframeRule* keyframeRule, KeyframeValue& keyframe)
1533 {
1534     if (keyframeRule->style())
1535         addMatchedDeclaration(keyframeRule->style());
1536
1537     ASSERT(!m_style);
1538
1539     // Create the style
1540     m_style = RenderStyle::clone(elementStyle);
1541
1542     m_lineHeightValue = 0;
1543
1544     // We don't need to bother with !important. Since there is only ever one
1545     // decl, there's nothing to override. So just add the first properties.
1546     if (keyframeRule->style())
1547         applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
1548
1549     // If our font got dirtied, go ahead and update it now.
1550     if (m_fontDirty)
1551         updateFont();
1552
1553     // Line-height is set when we are sure we decided on the font-size
1554     if (m_lineHeightValue)
1555         applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
1556
1557     // Now do rest of the properties.
1558     if (keyframeRule->style())
1559         applyDeclarations<false>(false, 0, m_matchedDecls.size() - 1);
1560
1561     // If our font got dirtied by one of the non-essential font props,
1562     // go ahead and update it a second time.
1563     if (m_fontDirty)
1564         updateFont();
1565
1566     // Start loading images referenced by this style.
1567     loadPendingImages();
1568
1569     // Add all the animating properties to the keyframe.
1570     if (keyframeRule->style()) {
1571         CSSMutableStyleDeclaration::const_iterator end = keyframeRule->style()->end();
1572         for (CSSMutableStyleDeclaration::const_iterator it = keyframeRule->style()->begin(); it != end; ++it) {
1573             int property = (*it).id();
1574             // Timing-function within keyframes is special, because it is not animated; it just
1575             // describes the timing function between this keyframe and the next.
1576             if (property != CSSPropertyWebkitAnimationTimingFunction)
1577                 keyframe.addProperty(property);
1578         }
1579     }
1580
1581     return m_style.release();
1582 }
1583
1584 void CSSStyleSelector::keyframeStylesForAnimation(Element* e, const RenderStyle* elementStyle, KeyframeList& list)
1585 {
1586     list.clear();
1587     
1588     // Get the keyframesRule for this name
1589     if (!e || list.animationName().isEmpty())
1590         return;
1591
1592     m_keyframesRuleMap.checkConsistency();
1593    
1594     if (!m_keyframesRuleMap.contains(list.animationName().impl()))
1595         return;
1596         
1597     const WebKitCSSKeyframesRule* rule = m_keyframesRuleMap.find(list.animationName().impl()).get()->second.get();
1598     
1599     // Construct and populate the style for each keyframe
1600     for (unsigned i = 0; i < rule->length(); ++i) {
1601         // Apply the declaration to the style. This is a simplified version of the logic in styleForElement
1602         initElement(e);
1603         initForStyleResolve(e);
1604         
1605         const WebKitCSSKeyframeRule* keyframeRule = rule->item(i);
1606
1607         KeyframeValue keyframe(0, 0);
1608         keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule, keyframe));
1609
1610         // Add this keyframe style to all the indicated key times
1611         Vector<float> keys;
1612         keyframeRule->getKeys(keys);
1613         for (size_t keyIndex = 0; keyIndex < keys.size(); ++keyIndex) {
1614             keyframe.setKey(keys[keyIndex]);
1615             list.insert(keyframe);
1616         }
1617     }
1618     
1619     // If the 0% keyframe is missing, create it (but only if there is at least one other keyframe)
1620     int initialListSize = list.size();
1621     if (initialListSize > 0 && list[0].key() != 0) {
1622         RefPtr<WebKitCSSKeyframeRule> keyframeRule = WebKitCSSKeyframeRule::create();
1623         keyframeRule->setKeyText("0%");
1624         KeyframeValue keyframe(0, 0);
1625         keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule.get(), keyframe));
1626         list.insert(keyframe);
1627     }
1628
1629     // If the 100% keyframe is missing, create it (but only if there is at least one other keyframe)
1630     if (initialListSize > 0 && (list[list.size() - 1].key() != 1)) {
1631         RefPtr<WebKitCSSKeyframeRule> keyframeRule = WebKitCSSKeyframeRule::create();
1632         keyframeRule->setKeyText("100%");
1633         KeyframeValue keyframe(1, 0);
1634         keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule.get(), keyframe));
1635         list.insert(keyframe);
1636     }
1637 }
1638
1639 PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(PseudoId pseudo, Element* e, RenderStyle* parentStyle, bool matchVisitedPseudoClass)
1640 {
1641     if (!e)
1642         return 0;
1643
1644     initElement(e);
1645
1646     // Compute our :visited style first, so that we know whether or not we'll need to create a normal style just to hang it
1647     // off of.
1648     RefPtr<RenderStyle> visitedStyle;
1649     if (!matchVisitedPseudoClass && parentStyle && parentStyle->insideLink()) {
1650         // Fetch our parent style with :visited in effect.
1651         RenderStyle* parentVisitedStyle = parentStyle->getCachedPseudoStyle(VISITED_LINK);
1652         visitedStyle = pseudoStyleForElement(pseudo, e, parentVisitedStyle ? parentVisitedStyle : parentStyle, true);
1653         if (visitedStyle) {
1654             if (m_elementLinkState == InsideUnvisitedLink)
1655                 visitedStyle = 0;  // We made the style to avoid timing attacks. Just throw it away now that we did that.
1656             else
1657                 visitedStyle->setStyleType(VISITED_LINK);
1658         }
1659     }
1660
1661     initForStyleResolve(e, parentStyle, pseudo);
1662     m_style = RenderStyle::create();
1663     if (parentStyle)
1664         m_style->inheritFrom(parentStyle);
1665
1666     m_checker.m_matchVisitedPseudoClass = matchVisitedPseudoClass;
1667
1668     // Since we don't use pseudo-elements in any of our quirk/print user agent rules, don't waste time walking
1669     // those rules.
1670     
1671     // Check UA, user and author rules.
1672     int firstUARule = -1, lastUARule = -1, firstUserRule = -1, lastUserRule = -1, firstAuthorRule = -1, lastAuthorRule = -1;
1673     matchUARules(firstUARule, lastUARule);
1674
1675     if (m_matchAuthorAndUserStyles) {
1676         matchRules(m_userStyle.get(), firstUserRule, lastUserRule, false);
1677         matchRules(m_authorStyle.get(), firstAuthorRule, lastAuthorRule, false);
1678     }
1679
1680     if (m_matchedDecls.isEmpty() && !visitedStyle)
1681         return 0;
1682
1683     m_style->setStyleType(pseudo);
1684     
1685     m_lineHeightValue = 0;
1686     
1687     // Reset the value back before applying properties, so that -webkit-link knows what color to use.
1688     m_checker.m_matchVisitedPseudoClass = matchVisitedPseudoClass;
1689
1690     // High-priority properties.
1691     applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
1692     applyDeclarations<true>(true, firstAuthorRule, lastAuthorRule);
1693     applyDeclarations<true>(true, firstUserRule, lastUserRule);
1694     applyDeclarations<true>(true, firstUARule, lastUARule);
1695     
1696     // If our font got dirtied, go ahead and update it now.
1697     if (m_fontDirty)
1698         updateFont();
1699
1700     // Line-height is set when we are sure we decided on the font-size
1701     if (m_lineHeightValue)
1702         applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
1703     
1704     // Now do the normal priority properties.
1705     applyDeclarations<false>(false, firstUARule, lastUARule);
1706     
1707     // Cache our border and background so that we can examine them later.
1708     cacheBorderAndBackground();
1709     
1710     applyDeclarations<false>(false, lastUARule + 1, m_matchedDecls.size() - 1);
1711     applyDeclarations<false>(true, firstAuthorRule, lastAuthorRule);
1712     applyDeclarations<false>(true, firstUserRule, lastUserRule);
1713     applyDeclarations<false>(true, firstUARule, lastUARule);
1714     
1715     // If our font got dirtied by one of the non-essential font props, 
1716     // go ahead and update it a second time.
1717     if (m_fontDirty)
1718         updateFont();
1719
1720     // Clean up our style object's display and text decorations (among other fixups).
1721     adjustRenderStyle(style(), parentStyle, 0);
1722
1723     // Start loading images referenced by this style.
1724     loadPendingImages();
1725
1726     // Hang our visited style off m_style.
1727     if (visitedStyle)
1728         m_style->addCachedPseudoStyle(visitedStyle.release());
1729         
1730     // Now return the style.
1731     return m_style.release();
1732 }
1733
1734 PassRefPtr<RenderStyle> CSSStyleSelector::styleForPage(int pageIndex)
1735 {
1736     initForStyleResolve(m_checker.m_document->documentElement()); // m_rootElementStyle will be set to the document style.
1737
1738     m_style = RenderStyle::create();
1739     m_style->inheritFrom(m_rootElementStyle);
1740
1741     const bool isLeft = isLeftPage(pageIndex);
1742     const bool isFirst = isFirstPage(pageIndex);
1743     const String page = pageName(pageIndex);
1744     matchPageRules(defaultPrintStyle, isLeft, isFirst, page);
1745     matchPageRules(m_userStyle.get(), isLeft, isFirst, page);
1746     matchPageRules(m_authorStyle.get(), isLeft, isFirst, page);
1747     m_lineHeightValue = 0;
1748     applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
1749
1750     // If our font got dirtied, go ahead and update it now.
1751     if (m_fontDirty)
1752         updateFont();
1753
1754     // Line-height is set when we are sure we decided on the font-size
1755     if (m_lineHeightValue)
1756         applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
1757
1758     applyDeclarations<false>(false, 0, m_matchedDecls.size() - 1);
1759
1760     // Start loading images referenced by this style.
1761     loadPendingImages();
1762
1763     // Now return the style.
1764     return m_style.release();
1765 }
1766
1767 #if ENABLE(DATAGRID)
1768
1769 PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForDataGridColumn(DataGridColumn*, RenderStyle*)
1770 {
1771     // FIXME: Implement
1772     return 0;
1773 }
1774
1775 PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForDataGridColumnHeader(DataGridColumn*, RenderStyle*)
1776 {
1777     // FIXME: Implement
1778     return 0;
1779 }
1780
1781 #endif
1782
1783 static void addIntrinsicMargins(RenderStyle* style)
1784 {
1785     // Intrinsic margin value.
1786     const int intrinsicMargin = 2 * style->effectiveZoom();
1787     
1788     // FIXME: Using width/height alone and not also dealing with min-width/max-width is flawed.
1789     // FIXME: Using "quirk" to decide the margin wasn't set is kind of lame.
1790     if (style->width().isIntrinsicOrAuto()) {
1791         if (style->marginLeft().quirk())
1792             style->setMarginLeft(Length(intrinsicMargin, Fixed));
1793         if (style->marginRight().quirk())
1794             style->setMarginRight(Length(intrinsicMargin, Fixed));
1795     }
1796
1797     if (style->height().isAuto()) {
1798         if (style->marginTop().quirk())
1799             style->setMarginTop(Length(intrinsicMargin, Fixed));
1800         if (style->marginBottom().quirk())
1801             style->setMarginBottom(Length(intrinsicMargin, Fixed));
1802     }
1803 }
1804
1805 void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, RenderStyle* parentStyle, Element *e)
1806 {
1807     // Cache our original display.
1808     style->setOriginalDisplay(style->display());
1809
1810     if (style->display() != NONE) {
1811         // If we have a <td> that specifies a float property, in quirks mode we just drop the float
1812         // property.
1813         // Sites also commonly use display:inline/block on <td>s and <table>s.  In quirks mode we force
1814         // these tags to retain their display types.
1815         if (!m_checker.m_strictParsing && e) {
1816             if (e->hasTagName(tdTag)) {
1817                 style->setDisplay(TABLE_CELL);
1818                 style->setFloating(FNONE);
1819             }
1820             else if (e->hasTagName(tableTag))
1821                 style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE);
1822         }
1823
1824         if (e && (e->hasTagName(tdTag) || e->hasTagName(thTag))) {
1825             if (style->whiteSpace() == KHTML_NOWRAP) {
1826                 // Figure out if we are really nowrapping or if we should just
1827                 // use normal instead.  If the width of the cell is fixed, then
1828                 // we don't actually use NOWRAP.
1829                 if (style->width().isFixed())
1830                     style->setWhiteSpace(NORMAL);
1831                 else
1832                     style->setWhiteSpace(NOWRAP);
1833             }
1834         }
1835
1836         // Tables never support the -webkit-* values for text-align and will reset back to the default.
1837         if (e && e->hasTagName(tableTag) && (style->textAlign() == WEBKIT_LEFT || style->textAlign() == WEBKIT_CENTER || style->textAlign() == WEBKIT_RIGHT))
1838             style->setTextAlign(TAAUTO);
1839
1840         // Frames and framesets never honor position:relative or position:absolute.  This is necessary to
1841         // fix a crash where a site tries to position these objects.  They also never honor display.
1842         if (e && (e->hasTagName(frameTag) || e->hasTagName(framesetTag))) {
1843             style->setPosition(StaticPosition);
1844             style->setDisplay(BLOCK);
1845         }
1846
1847         // Table headers with a text-align of auto will change the text-align to center.
1848         if (e && e->hasTagName(thTag) && style->textAlign() == TAAUTO)
1849             style->setTextAlign(CENTER);
1850
1851         if (e && e->hasTagName(legendTag))
1852             style->setDisplay(BLOCK);
1853
1854         // Mutate the display to BLOCK or TABLE for certain cases, e.g., if someone attempts to
1855         // position or float an inline, compact, or run-in.  Cache the original display, since it
1856         // may be needed for positioned elements that have to compute their static normal flow
1857         // positions.  We also force inline-level roots to be block-level.
1858         if (style->display() != BLOCK && style->display() != TABLE && style->display() != BOX &&
1859             (style->position() == AbsolutePosition || style->position() == FixedPosition || style->floating() != FNONE ||
1860              (e && e->document()->documentElement() == e))) {
1861             if (style->display() == INLINE_TABLE)
1862                 style->setDisplay(TABLE);
1863             else if (style->display() == INLINE_BOX)
1864                 style->setDisplay(BOX);
1865             else if (style->display() == LIST_ITEM) {
1866                 // It is a WinIE bug that floated list items lose their bullets, so we'll emulate the quirk,
1867                 // but only in quirks mode.
1868                 if (!m_checker.m_strictParsing && style->floating() != FNONE)
1869                     style->setDisplay(BLOCK);
1870             }
1871             else
1872                 style->setDisplay(BLOCK);
1873         }
1874         
1875         // FIXME: Don't support this mutation for pseudo styles like first-letter or first-line, since it's not completely
1876         // clear how that should work.
1877         if (style->display() == INLINE && style->styleType() == NOPSEUDO && parentStyle && style->writingMode() != parentStyle->writingMode())
1878             style->setDisplay(INLINE_BLOCK);
1879         
1880         // After performing the display mutation, check table rows.  We do not honor position:relative on
1881         // table rows or cells.  This has been established in CSS2.1 (and caused a crash in containingBlock()
1882         // on some sites).
1883         if ((style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW_GROUP ||
1884              style->display() == TABLE_FOOTER_GROUP || style->display() == TABLE_ROW || style->display() == TABLE_CELL) &&
1885              style->position() == RelativePosition)
1886             style->setPosition(StaticPosition);
1887
1888         // writing-mode does not apply to table row groups, table column groups, table rows, and table columns.
1889         // FIXME: Table cells should be allowed to be perpendicular or flipped with respect to the table, though.
1890         if (style->display() == TABLE_COLUMN || style->display() == TABLE_COLUMN_GROUP || style->display() == TABLE_FOOTER_GROUP
1891             || style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW || style->display() == TABLE_ROW_GROUP
1892             || style->display() == TABLE_CELL)
1893             style->setWritingMode(parentStyle->writingMode());
1894
1895         // FIXME: Since we don't support block-flow on flexible boxes yet, disallow setting
1896         // of block-flow to anything other than TopToBottomWritingMode.
1897         // https://bugs.webkit.org/show_bug.cgi?id=46418 - Flexible box support.
1898         if (style->writingMode() != TopToBottomWritingMode && (style->display() == BOX || style->display() == INLINE_BOX))
1899             style->setWritingMode(TopToBottomWritingMode);
1900     }
1901
1902     // Make sure our z-index value is only applied if the object is positioned.
1903     if (style->position() == StaticPosition)
1904         style->setHasAutoZIndex();
1905
1906     // Auto z-index becomes 0 for the root element and transparent objects.  This prevents
1907     // cases where objects that should be blended as a single unit end up with a non-transparent
1908     // object wedged in between them.  Auto z-index also becomes 0 for objects that specify transforms/masks/reflections.
1909     if (style->hasAutoZIndex() && ((e && e->document()->documentElement() == e) || style->opacity() < 1.0f || 
1910         style->hasTransformRelatedProperty() || style->hasMask() || style->boxReflect()))
1911         style->setZIndex(0);
1912     
1913 #if ENABLE(WML)
1914     if (e && (e->hasTagName(WMLNames::insertedLegendTag)
1915               || e->hasTagName(WMLNames::inputTag))
1916             && style->width().isAuto())
1917         style->setWidth(Length(Intrinsic));
1918 #endif
1919
1920     // Textarea considers overflow visible as auto.
1921     if (e && e->hasTagName(textareaTag)) {
1922         style->setOverflowX(style->overflowX() == OVISIBLE ? OAUTO : style->overflowX());
1923         style->setOverflowY(style->overflowY() == OVISIBLE ? OAUTO : style->overflowY());
1924     }
1925
1926     // Finally update our text decorations in effect, but don't allow text-decoration to percolate through
1927     // tables, inline blocks, inline tables, or run-ins.
1928     if (style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN
1929         || style->display() == INLINE_BLOCK || style->display() == INLINE_BOX)
1930         style->setTextDecorationsInEffect(style->textDecoration());
1931     else
1932         style->addToTextDecorationsInEffect(style->textDecoration());
1933     
1934     // If either overflow value is not visible, change to auto.
1935     if (style->overflowX() == OMARQUEE && style->overflowY() != OMARQUEE)
1936         style->setOverflowY(OMARQUEE);
1937     else if (style->overflowY() == OMARQUEE && style->overflowX() != OMARQUEE)
1938         style->setOverflowX(OMARQUEE);
1939     else if (style->overflowX() == OVISIBLE && style->overflowY() != OVISIBLE)
1940         style->setOverflowX(OAUTO);
1941     else if (style->overflowY() == OVISIBLE && style->overflowX() != OVISIBLE)
1942         style->setOverflowY(OAUTO);
1943
1944     // Table rows, sections and the table itself will support overflow:hidden and will ignore scroll/auto.
1945     // FIXME: Eventually table sections will support auto and scroll.
1946     if (style->display() == TABLE || style->display() == INLINE_TABLE ||
1947         style->display() == TABLE_ROW_GROUP || style->display() == TABLE_ROW) {
1948         if (style->overflowX() != OVISIBLE && style->overflowX() != OHIDDEN) 
1949             style->setOverflowX(OVISIBLE);
1950         if (style->overflowY() != OVISIBLE && style->overflowY() != OHIDDEN) 
1951             style->setOverflowY(OVISIBLE);
1952     }
1953
1954     // Menulists should have visible overflow
1955     if (style->appearance() == MenulistPart) {
1956         style->setOverflowX(OVISIBLE);
1957         style->setOverflowY(OVISIBLE);
1958     }
1959
1960     // Cull out any useless layers and also repeat patterns into additional layers.
1961     style->adjustBackgroundLayers();
1962     style->adjustMaskLayers();
1963
1964     // Do the same for animations and transitions.
1965     style->adjustAnimations();
1966     style->adjustTransitions();
1967
1968     // Important: Intrinsic margins get added to controls before the theme has adjusted the style, since the theme will
1969     // alter fonts and heights/widths.
1970     if (e && e->isFormControlElement() && style->fontSize() >= 11) {
1971         // Don't apply intrinsic margins to image buttons.  The designer knows how big the images are,
1972         // so we have to treat all image buttons as though they were explicitly sized.
1973         if (!e->hasTagName(inputTag) || !static_cast<HTMLInputElement*>(e)->isImageButton())
1974             addIntrinsicMargins(style);
1975     }
1976
1977     // Let the theme also have a crack at adjusting the style.
1978     if (style->hasAppearance())
1979         RenderTheme::defaultTheme()->adjustStyle(this, style, e, m_hasUAAppearance, m_borderData, m_backgroundData, m_backgroundColor);
1980
1981 #if ENABLE(SVG)
1982     if (e && e->isSVGElement()) {
1983         // Spec: http://www.w3.org/TR/SVG/masking.html#OverflowProperty
1984         if (style->overflowY() == OSCROLL)
1985             style->setOverflowY(OHIDDEN);
1986         else if (style->overflowY() == OAUTO)
1987             style->setOverflowY(OVISIBLE);
1988
1989         if (style->overflowX() == OSCROLL)
1990             style->setOverflowX(OHIDDEN);
1991         else if (style->overflowX() == OAUTO)
1992             style->setOverflowX(OVISIBLE);
1993
1994         // Only the root <svg> element in an SVG document fragment tree honors css position
1995         if (!(e->hasTagName(SVGNames::svgTag) && e->parentNode() && !e->parentNode()->isSVGElement()))
1996             style->setPosition(RenderStyle::initialPosition());
1997     }
1998 #endif
1999 }
2000
2001 void CSSStyleSelector::updateFont()
2002 {
2003     checkForTextSizeAdjust();
2004     checkForGenericFamilyChange(style(), m_parentStyle);
2005     checkForZoomChange(style(), m_parentStyle);
2006     m_style->font().update(m_fontSelector);
2007     m_fontDirty = false;
2008 }
2009
2010 void CSSStyleSelector::cacheBorderAndBackground()
2011 {
2012     m_hasUAAppearance = m_style->hasAppearance();
2013     if (m_hasUAAppearance) {
2014         m_borderData = m_style->border();
2015         m_backgroundData = *m_style->backgroundLayers();
2016         m_backgroundColor = m_style->backgroundColor();
2017     }
2018 }
2019
2020 PassRefPtr<CSSRuleList> CSSStyleSelector::styleRulesForElement(Element* e, bool authorOnly, bool includeEmptyRules, CSSRuleFilter filter)
2021 {
2022     return pseudoStyleRulesForElement(e, NOPSEUDO, authorOnly, includeEmptyRules, filter);
2023 }
2024
2025 PassRefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element* e, PseudoId pseudoId, bool authorOnly, bool includeEmptyRules, CSSRuleFilter filter)
2026 {
2027     if (!e || !e->document()->haveStylesheetsLoaded())
2028         return 0;
2029
2030     m_checker.m_collectRulesOnly = true;
2031
2032     initElement(e);
2033     initForStyleResolve(e, 0, pseudoId);
2034
2035     if (!authorOnly) {
2036         int firstUARule = -1, lastUARule = -1;
2037         // First we match rules from the user agent sheet.
2038         matchUARules(firstUARule, lastUARule);
2039
2040         // Now we check user sheet rules.
2041         if (m_matchAuthorAndUserStyles) {
2042             int firstUserRule = -1, lastUserRule = -1;
2043             matchRules(m_userStyle.get(), firstUserRule, lastUserRule, includeEmptyRules);
2044         }
2045     }
2046
2047     if (m_matchAuthorAndUserStyles) {
2048         m_checker.m_sameOriginOnly = (filter == SameOriginCSSRulesOnly);
2049
2050         // Check the rules in author sheets.
2051         int firstAuthorRule = -1, lastAuthorRule = -1;
2052         matchRules(m_authorStyle.get(), firstAuthorRule, lastAuthorRule, includeEmptyRules);
2053
2054         m_checker.m_sameOriginOnly = false;
2055     }
2056
2057     m_checker.m_collectRulesOnly = false;
2058    
2059     return m_ruleList.release();
2060 }
2061
2062 bool CSSStyleSelector::checkSelector(CSSSelector* sel)
2063 {
2064     m_dynamicPseudo = NOPSEUDO;
2065
2066     // Check the selector
2067     SelectorMatch match = m_checker.checkSelector(sel, m_element, &m_selectorAttrs, m_dynamicPseudo, false, false, style(), m_parentNode ? m_parentNode->renderStyle() : 0);
2068     if (match != SelectorMatches)
2069         return false;
2070
2071     if (m_checker.m_pseudoStyle != NOPSEUDO && m_checker.m_pseudoStyle != m_dynamicPseudo)
2072         return false;
2073
2074     return true;
2075 }
2076
2077 // Recursive check of selectors and combinators
2078 // It can return 3 different values:
2079 // * SelectorMatches         - the selector matches the element e
2080 // * SelectorFailsLocally    - the selector fails for the element e
2081 // * SelectorFailsCompletely - the selector fails for e and any sibling or ancestor of e
2082 CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
2083 {
2084 #if ENABLE(SVG)
2085     // Spec: CSS2 selectors cannot be applied to the (conceptually) cloned DOM tree
2086     // because its contents are not part of the formal document structure.
2087     if (e->isSVGElement() && e->isShadowRoot())
2088         return SelectorFailsCompletely;
2089 #endif
2090
2091     // first selector has to match
2092     if (!checkOneSelector(sel, e, selectorAttrs, dynamicPseudo, isSubSelector, elementStyle, elementParentStyle))
2093         return SelectorFailsLocally;
2094
2095     // The rest of the selectors has to match
2096     CSSSelector::Relation relation = sel->relation();
2097
2098     // Prepare next sel
2099     sel = sel->tagHistory();
2100     if (!sel)
2101         return SelectorMatches;
2102
2103     if (relation != CSSSelector::SubSelector)
2104         // Bail-out if this selector is irrelevant for the pseudoStyle
2105         if (m_pseudoStyle != NOPSEUDO && m_pseudoStyle != dynamicPseudo)
2106             return SelectorFailsCompletely;
2107
2108     // Check for nested links.
2109     if (m_matchVisitedPseudoClass && !isSubSelector) {
2110         RenderStyle* currentStyle = elementStyle ? elementStyle : e->renderStyle();
2111         if (currentStyle && currentStyle->insideLink() && e->isLink()) {
2112             if (encounteredLink)
2113                 m_matchVisitedPseudoClass = false; // This link is not relevant to the style being resolved, so disable matching.
2114             else
2115                 encounteredLink = true;
2116         }
2117     }
2118
2119     switch (relation) {
2120         case CSSSelector::Descendant:
2121             while (true) {
2122                 ContainerNode* n = e->parentNode();
2123                 if (!n || !n->isElementNode())
2124                     return SelectorFailsCompletely;
2125                 e = static_cast<Element*>(n);
2126                 SelectorMatch match = checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
2127                 if (match != SelectorFailsLocally)
2128                     return match;
2129             }
2130             break;
2131         case CSSSelector::Child:
2132         {
2133             ContainerNode* n = e->parentNode();
2134             if (!n || !n->isElementNode())
2135                 return SelectorFailsCompletely;
2136             e = static_cast<Element*>(n);
2137             return checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
2138         }
2139         case CSSSelector::DirectAdjacent:
2140         {
2141             if (!m_collectRulesOnly && e->parentNode() && e->parentNode()->isElementNode()) {
2142                 RenderStyle* parentStyle = elementStyle ? elementParentStyle : e->parentNode()->renderStyle();
2143                 if (parentStyle)
2144                     parentStyle->setChildrenAffectedByDirectAdjacentRules();
2145             }
2146             Node* n = e->previousSibling();
2147             while (n && !n->isElementNode())
2148                 n = n->previousSibling();
2149             if (!n)
2150                 return SelectorFailsLocally;
2151             e = static_cast<Element*>(n);
2152             m_matchVisitedPseudoClass = false;
2153             return checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink); 
2154         }
2155         case CSSSelector::IndirectAdjacent:
2156             if (!m_collectRulesOnly && e->parentNode() && e->parentNode()->isElementNode()) {
2157                 RenderStyle* parentStyle = elementStyle ? elementParentStyle : e->parentNode()->renderStyle();
2158                 if (parentStyle)
2159                     parentStyle->setChildrenAffectedByForwardPositionalRules();
2160             }
2161             while (true) {
2162                 Node* n = e->previousSibling();
2163                 while (n && !n->isElementNode())
2164                     n = n->previousSibling();
2165                 if (!n)
2166                     return SelectorFailsLocally;
2167                 e = static_cast<Element*>(n);
2168                 m_matchVisitedPseudoClass = false;
2169                 SelectorMatch match = checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
2170                 if (match != SelectorFailsLocally)
2171                     return match;
2172             };
2173             break;
2174         case CSSSelector::SubSelector:
2175             // a selector is invalid if something follows a pseudo-element
2176             // We make an exception for scrollbar pseudo elements and allow a set of pseudo classes (but nothing else)
2177             // to follow the pseudo elements.
2178             if ((elementStyle || m_collectRulesOnly) && dynamicPseudo != NOPSEUDO && dynamicPseudo != SELECTION &&
2179                 !((RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER) && sel->m_match == CSSSelector::PseudoClass))
2180                 return SelectorFailsCompletely;
2181             return checkSelector(sel, e, selectorAttrs, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle);
2182         case CSSSelector::ShadowDescendant:
2183         {
2184             Node* shadowHostNode = e->shadowAncestorNode();
2185             if (shadowHostNode == e || !shadowHostNode->isElementNode())
2186                 return SelectorFailsCompletely;
2187             e = static_cast<Element*>(shadowHostNode);
2188             return checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);
2189         }
2190     }
2191
2192     return SelectorFailsCompletely;
2193 }
2194
2195 static void addLocalNameToSet(HashSet<AtomicStringImpl*>* set, const QualifiedName& qName)
2196 {
2197     set->add(qName.localName().impl());
2198 }
2199
2200 static HashSet<AtomicStringImpl*>* createHtmlCaseInsensitiveAttributesSet()
2201 {
2202     // This is the list of attributes in HTML 4.01 with values marked as "[CI]" or case-insensitive
2203     // Mozilla treats all other values as case-sensitive, thus so do we.
2204     HashSet<AtomicStringImpl*>* attrSet = new HashSet<AtomicStringImpl*>;
2205
2206     addLocalNameToSet(attrSet, accept_charsetAttr);
2207     addLocalNameToSet(attrSet, acceptAttr);
2208     addLocalNameToSet(attrSet, alignAttr);
2209     addLocalNameToSet(attrSet, alinkAttr);
2210     addLocalNameToSet(attrSet, axisAttr);
2211     addLocalNameToSet(attrSet, bgcolorAttr);
2212     addLocalNameToSet(attrSet, charsetAttr);
2213     addLocalNameToSet(attrSet, checkedAttr);
2214     addLocalNameToSet(attrSet, clearAttr);
2215     addLocalNameToSet(attrSet, codetypeAttr);
2216     addLocalNameToSet(attrSet, colorAttr);
2217     addLocalNameToSet(attrSet, compactAttr);
2218     addLocalNameToSet(attrSet, declareAttr);
2219     addLocalNameToSet(attrSet, deferAttr);
2220     addLocalNameToSet(attrSet, dirAttr);
2221     addLocalNameToSet(attrSet, disabledAttr);
2222     addLocalNameToSet(attrSet, enctypeAttr);
2223     addLocalNameToSet(attrSet, faceAttr);
2224     addLocalNameToSet(attrSet, frameAttr);
2225     addLocalNameToSet(attrSet, hreflangAttr);
2226     addLocalNameToSet(attrSet, http_equivAttr);
2227     addLocalNameToSet(attrSet, langAttr);
2228     addLocalNameToSet(attrSet, languageAttr);
2229     addLocalNameToSet(attrSet, linkAttr);
2230     addLocalNameToSet(attrSet, mediaAttr);
2231     addLocalNameToSet(attrSet, methodAttr);
2232     addLocalNameToSet(attrSet, multipleAttr);
2233     addLocalNameToSet(attrSet, nohrefAttr);
2234     addLocalNameToSet(attrSet, noresizeAttr);
2235     addLocalNameToSet(attrSet, noshadeAttr);
2236     addLocalNameToSet(attrSet, nowrapAttr);
2237     addLocalNameToSet(attrSet, readonlyAttr);
2238     addLocalNameToSet(attrSet, relAttr);
2239     addLocalNameToSet(attrSet, revAttr);
2240     addLocalNameToSet(attrSet, rulesAttr);
2241     addLocalNameToSet(attrSet, scopeAttr);
2242     addLocalNameToSet(attrSet, scrollingAttr);
2243     addLocalNameToSet(attrSet, selectedAttr);
2244     addLocalNameToSet(attrSet, shapeAttr);
2245     addLocalNameToSet(attrSet, targetAttr);
2246     addLocalNameToSet(attrSet, textAttr);
2247     addLocalNameToSet(attrSet, typeAttr);
2248     addLocalNameToSet(attrSet, valignAttr);
2249     addLocalNameToSet(attrSet, valuetypeAttr);
2250     addLocalNameToSet(attrSet, vlinkAttr);
2251
2252     return attrSet;
2253 }
2254
2255 static bool htmlAttributeHasCaseInsensitiveValue(const QualifiedName& attr)
2256 {
2257     static HashSet<AtomicStringImpl*>* htmlCaseInsensitiveAttributesSet = createHtmlCaseInsensitiveAttributesSet();
2258     bool isPossibleHTMLAttr = !attr.hasPrefix() && (attr.namespaceURI() == nullAtom);
2259     return isPossibleHTMLAttr && htmlCaseInsensitiveAttributesSet->contains(attr.localName().impl());
2260 }
2261
2262 bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
2263 {
2264     ASSERT(e);
2265     if (!e)
2266         return false;
2267
2268     if (sel->hasTag()) {
2269         const AtomicString& selLocalName = sel->tag().localName();
2270         if (selLocalName != starAtom && selLocalName != e->localName())
2271             return false;
2272         const AtomicString& selNS = sel->tag().namespaceURI();
2273         if (selNS != starAtom && selNS != e->namespaceURI())
2274             return false;
2275     }
2276
2277     if (sel->hasAttribute()) {
2278         if (sel->m_match == CSSSelector::Class)
2279             return e->hasClass() && static_cast<StyledElement*>(e)->classNames().contains(sel->value());
2280
2281         if (sel->m_match == CSSSelector::Id)
2282             return e->hasID() && e->idForStyleResolution() == sel->value();
2283         
2284         const QualifiedName& attr = sel->attribute();
2285
2286         // FIXME: Handle the case were elementStyle is 0.
2287         if (elementStyle && (!e->isStyledElement() || (!static_cast<StyledElement*>(e)->isMappedAttribute(attr) && attr != typeAttr && attr != readonlyAttr))) {
2288             elementStyle->setAffectedByAttributeSelectors(); // Special-case the "type" and "readonly" attributes so input form controls can share style.
2289             if (selectorAttrs)
2290                 selectorAttrs->add(attr.localName().impl());
2291         }
2292
2293         const AtomicString& value = e->getAttribute(attr);
2294         if (value.isNull())
2295             return false; // attribute is not set
2296
2297         bool caseSensitive = !m_documentIsHTML || !htmlAttributeHasCaseInsensitiveValue(attr);
2298
2299         switch (sel->m_match) {
2300         case CSSSelector::Exact:
2301             if (caseSensitive ? sel->value() != value : !equalIgnoringCase(sel->value(), value))
2302                 return false;
2303             break;
2304         case CSSSelector::List:
2305         {
2306             // Ignore empty selectors or selectors containing spaces
2307             if (sel->value().contains(' ') || sel->value().isEmpty())
2308                 return false;
2309
2310             unsigned startSearchAt = 0;
2311             while (true) {
2312                 size_t foundPos = value.find(sel->value(), startSearchAt, caseSensitive);
2313                 if (foundPos == notFound)
2314                     return false;
2315                 if (foundPos == 0 || value[foundPos - 1] == ' ') {
2316                     unsigned endStr = foundPos + sel->value().length();
2317                     if (endStr == value.length() || value[endStr] == ' ')
2318                         break; // We found a match.
2319                 }
2320                 
2321                 // No match. Keep looking.
2322                 startSearchAt = foundPos + 1;
2323             }
2324             break;
2325         }
2326         case CSSSelector::Contain:
2327             if (!value.contains(sel->value(), caseSensitive) || sel->value().isEmpty())
2328                 return false;
2329             break;
2330         case CSSSelector::Begin:
2331             if (!value.startsWith(sel->value(), caseSensitive) || sel->value().isEmpty())
2332                 return false;
2333             break;
2334         case CSSSelector::End:
2335             if (!value.endsWith(sel->value(), caseSensitive) || sel->value().isEmpty())
2336                 return false;
2337             break;
2338         case CSSSelector::Hyphen:
2339             if (value.length() < sel->value().length())
2340                 return false;
2341             if (!value.startsWith(sel->value(), caseSensitive))
2342                 return false;
2343             // It they start the same, check for exact match or following '-':
2344             if (value.length() != sel->value().length() && value[sel->value().length()] != '-')
2345                 return false;
2346             break;
2347         case CSSSelector::PseudoClass:
2348         case CSSSelector::PseudoElement:
2349         default:
2350             break;
2351         }
2352     }
2353     
2354     if (sel->m_match == CSSSelector::PseudoClass) {
2355         // Handle :not up front.
2356         if (sel->pseudoType() == CSSSelector::PseudoNot) {
2357             // check the simple selector
2358             for (CSSSelector* subSel = sel->simpleSelector(); subSel; subSel = subSel->tagHistory()) {
2359                 // :not cannot nest. I don't really know why this is a
2360                 // restriction in CSS3, but it is, so let's honor it.
2361                 // the parser enforces that this never occurs
2362                 ASSERT(!subSel->simpleSelector());
2363
2364                 if (!checkOneSelector(subSel, e, selectorAttrs, dynamicPseudo, true, elementStyle, elementParentStyle))
2365                     return true;
2366             }
2367         } else if (dynamicPseudo != NOPSEUDO && (RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER)) {
2368             // CSS scrollbars match a specific subset of pseudo classes, and they have specialized rules for each
2369             // (since there are no elements involved).
2370             return checkScrollbarPseudoClass(sel, dynamicPseudo);
2371         } else if (dynamicPseudo == SELECTION) {
2372             if (sel->pseudoType() == CSSSelector::PseudoWindowInactive)
2373                 return !m_document->page()->focusController()->isActive();
2374         }
2375         
2376         // Normal element pseudo class checking.
2377         switch (sel->pseudoType()) {
2378             // Pseudo classes:
2379             case CSSSelector::PseudoNot:
2380                 break; // Already handled up above.
2381             case CSSSelector::PseudoEmpty: {
2382                 bool result = true;
2383                 for (Node* n = e->firstChild(); n; n = n->nextSibling()) {
2384                     if (n->isElementNode()) {
2385                         result = false;
2386                         break;
2387                     } else if (n->isTextNode()) {
2388                         Text* textNode = static_cast<Text*>(n);
2389                         if (!textNode->data().isEmpty()) {
2390                             result = false;
2391                             break;
2392                         }
2393                     }
2394                 }
2395                 if (!m_collectRulesOnly) {
2396                     if (elementStyle)
2397                         elementStyle->setEmptyState(result);
2398                     else if (e->renderStyle() && (e->document()->usesSiblingRules() || e->renderStyle()->unique()))
2399                         e->renderStyle()->setEmptyState(result);
2400                 }
2401                 return result;
2402             }
2403             case CSSSelector::PseudoFirstChild: {
2404                 // first-child matches the first child that is an element
2405                 if (e->parentNode() && e->parentNode()->isElementNode()) {
2406                     bool result = false;
2407                     Node* n = e->previousSibling();
2408                     while (n && !n->isElementNode())
2409                         n = n->previousSibling();
2410                     if (!n)
2411                         result = true;
2412                     if (!m_collectRulesOnly) {
2413                         RenderStyle* childStyle = elementStyle ? elementStyle : e->renderStyle();
2414                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : e->parentNode()->renderStyle();
2415                         if (parentStyle)
2416                             parentStyle->setChildrenAffectedByFirstChildRules();
2417                         if (result && childStyle)
2418                             childStyle->setFirstChildState();
2419                     }
2420                     return result;
2421                 }
2422                 break;
2423             }
2424             case CSSSelector::PseudoFirstOfType: {
2425                 // first-of-type matches the first element of its type
2426                 if (e->parentNode() && e->parentNode()->isElementNode()) {
2427                     bool result = false;
2428                     const QualifiedName& type = e->tagQName();
2429                     Node* n = e->previousSibling();
2430                     while (n) {
2431                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
2432                             break;
2433                         n = n->previousSibling();
2434                     }
2435                     if (!n)
2436                         result = true;
2437                     if (!m_collectRulesOnly) {
2438                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : e->parentNode()->renderStyle();
2439                         if (parentStyle)
2440                             parentStyle->setChildrenAffectedByForwardPositionalRules();
2441                     }
2442                     return result;
2443                 }
2444                 break;
2445             }
2446             case CSSSelector::PseudoLastChild: {
2447                 // last-child matches the last child that is an element
2448                 if (Element* parentElement = e->parentElement()) {
2449                     bool result = false;
2450                     if (parentElement->isFinishedParsingChildren()) {
2451                         Node* n = e->nextSibling();
2452                         while (n && !n->isElementNode())
2453                             n = n->nextSibling();
2454                         if (!n)
2455                             result = true;
2456                     }
2457                     if (!m_collectRulesOnly) {
2458                         RenderStyle* childStyle = elementStyle ? elementStyle : e->renderStyle();
2459                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
2460                         if (parentStyle)
2461                             parentStyle->setChildrenAffectedByLastChildRules();
2462                         if (result && childStyle)
2463                             childStyle->setLastChildState();
2464                     }
2465                     return result;
2466                 }
2467                 break;
2468             }
2469             case CSSSelector::PseudoLastOfType: {
2470                 // last-of-type matches the last element of its type
2471                 if (Element* parentElement = e->parentElement()) {
2472                     if (!m_collectRulesOnly) {
2473                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
2474                         if (parentStyle)
2475                             parentStyle->setChildrenAffectedByBackwardPositionalRules();
2476                     }
2477                     if (!parentElement->isFinishedParsingChildren())
2478                         return false;
2479                     bool result = false;
2480                     const QualifiedName& type = e->tagQName();
2481                     Node* n = e->nextSibling();
2482                     while (n) {
2483                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
2484                             break;
2485                         n = n->nextSibling();
2486                     }
2487                     if (!n)
2488                         result = true;
2489                     return result;
2490                 }
2491                 break;
2492             }
2493             case CSSSelector::PseudoOnlyChild: {
2494                 if (Element* parentElement = e->parentElement()) {
2495                     bool firstChild = false;
2496                     bool lastChild = false;
2497                     
2498                     Node* n = e->previousSibling();
2499                     while (n && !n->isElementNode())
2500                         n = n->previousSibling();
2501                     if (!n)
2502                         firstChild = true;
2503                     if (firstChild && parentElement->isFinishedParsingChildren()) {
2504                         n = e->nextSibling();
2505                         while (n && !n->isElementNode())
2506                             n = n->nextSibling();
2507                         if (!n)
2508                             lastChild = true;
2509                     }
2510                     if (!m_collectRulesOnly) {
2511                         RenderStyle* childStyle = elementStyle ? elementStyle : e->renderStyle();
2512                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
2513                         if (parentStyle) {
2514                             parentStyle->setChildrenAffectedByFirstChildRules();
2515                             parentStyle->setChildrenAffectedByLastChildRules();
2516                         }
2517                         if (firstChild && childStyle)
2518                             childStyle->setFirstChildState();
2519                         if (lastChild && childStyle)
2520                             childStyle->setLastChildState();
2521                     }
2522                     return firstChild && lastChild;
2523                 }
2524                 break;
2525             }
2526             case CSSSelector::PseudoOnlyOfType: {
2527                 // FIXME: This selector is very slow.
2528                 if (Element* parentElement = e->parentElement()) {
2529                     if (!m_collectRulesOnly) {
2530                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
2531                         if (parentStyle) {
2532                             parentStyle->setChildrenAffectedByForwardPositionalRules();
2533                             parentStyle->setChildrenAffectedByBackwardPositionalRules();
2534                         }
2535                     }
2536                     if (!parentElement->isFinishedParsingChildren())
2537                         return false;
2538                     bool firstChild = false;
2539                     bool lastChild = false;
2540                     const QualifiedName& type = e->tagQName();
2541                     Node* n = e->previousSibling();
2542                     while (n) {
2543                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
2544                             break;
2545                         n = n->previousSibling();
2546                     }
2547                     if (!n)
2548                         firstChild = true;
2549                     if (firstChild) {
2550                         n = e->nextSibling();
2551                         while (n) {
2552                             if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
2553                                 break;
2554                             n = n->nextSibling();
2555                         }
2556                         if (!n)
2557                             lastChild = true;
2558                     }
2559                     return firstChild && lastChild;
2560                 }
2561                 break;
2562             }
2563             case CSSSelector::PseudoNthChild: {
2564                 if (!sel->parseNth())
2565                     break;
2566                 if (Element* parentElement = e->parentElement()) {
2567                     int count = 1;
2568                     Node* n = e->previousSibling();
2569                     while (n) {
2570                         if (n->isElementNode()) {
2571                             RenderStyle* s = n->renderStyle();
2572                             unsigned index = s ? s->childIndex() : 0;
2573                             if (index) {
2574                                 count += index;
2575                                 break;
2576                             }
2577                             count++;
2578                         }
2579                         n = n->previousSibling();
2580                     }
2581                     
2582                     if (!m_collectRulesOnly) {
2583                         RenderStyle* childStyle = elementStyle ? elementStyle : e->renderStyle();
2584                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
2585                         if (childStyle)
2586                             childStyle->setChildIndex(count);
2587                         if (parentStyle)
2588                             parentStyle->setChildrenAffectedByForwardPositionalRules();
2589                     }
2590                     
2591                     if (sel->matchNth(count))
2592                         return true;
2593                 }
2594                 break;
2595             }
2596             case CSSSelector::PseudoNthOfType: {
2597                 if (!sel->parseNth())
2598                     break;
2599                 if (Element* parentElement = e->parentElement()) {
2600                     int count = 1;
2601                     const QualifiedName& type = e->tagQName();
2602                     Node* n = e->previousSibling();
2603                     while (n) {
2604                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
2605                             count++;
2606                         n = n->previousSibling();
2607                     }
2608                     
2609                     if (!m_collectRulesOnly) {
2610                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
2611                         if (parentStyle)
2612                             parentStyle->setChildrenAffectedByForwardPositionalRules();
2613                     }
2614
2615                     if (sel->matchNth(count))
2616                         return true;
2617                 }
2618                 break;
2619             }
2620             case CSSSelector::PseudoNthLastChild: {
2621                 if (!sel->parseNth())
2622                     break;
2623                 if (Element* parentElement = e->parentElement()) {
2624                     if (!m_collectRulesOnly) {
2625                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
2626                         if (parentStyle)
2627                             parentStyle->setChildrenAffectedByBackwardPositionalRules();
2628                     }
2629                     if (!parentElement->isFinishedParsingChildren())
2630                         return false;
2631                     int count = 1;
2632                     Node* n = e->nextSibling();
2633                     while (n) {
2634                         if (n->isElementNode())
2635                             count++;
2636                         n = n->nextSibling();
2637                     }
2638                     if (sel->matchNth(count))
2639                         return true;
2640                 }
2641                 break;
2642             }
2643             case CSSSelector::PseudoNthLastOfType: {
2644                 if (!sel->parseNth())
2645                     break;
2646                 if (Element* parentElement = e->parentElement()) {
2647                     if (!m_collectRulesOnly) {
2648                         RenderStyle* parentStyle = elementStyle ? elementParentStyle : parentElement->renderStyle();
2649                         if (parentStyle)
2650                             parentStyle->setChildrenAffectedByBackwardPositionalRules();
2651                     }
2652                     if (!parentElement->isFinishedParsingChildren())
2653                         return false;
2654                     int count = 1;
2655                     const QualifiedName& type = e->tagQName();
2656                     Node* n = e->nextSibling();
2657                     while (n) {
2658                         if (n->isElementNode() && static_cast<Element*>(n)->hasTagName(type))
2659                             count++;
2660                         n = n->nextSibling();
2661                     }
2662                     if (sel->matchNth(count))
2663                         return true;
2664                 }
2665                 break;
2666             }
2667             case CSSSelector::PseudoTarget:
2668                 if (e == e->document()->cssTarget())
2669                     return true;
2670                 break;
2671             case CSSSelector::PseudoAnyLink:
2672                 if (e && e->isLink())
2673                     return true;
2674                 break;
2675             case CSSSelector::PseudoAutofill: {
2676                 if (!e || !e->isFormControlElement())
2677                     break;
2678                 if (InputElement* inputElement = toInputElement(e))
2679                     return inputElement->isAutofilled();
2680                 break;
2681             }
2682             case CSSSelector::PseudoLink:
2683                 if (e && e->isLink())
2684                     return !m_matchVisitedPseudoClass;
2685                 break;
2686             case CSSSelector::PseudoVisited:
2687                 if (e && e->isLink())
2688                     return m_matchVisitedPseudoClass;
2689                 break;
2690             case CSSSelector::PseudoDrag: {
2691                 if (elementStyle)
2692                     elementStyle->setAffectedByDragRules(true);
2693                 else if (e->renderStyle())
2694                     e->renderStyle()->setAffectedByDragRules(true);
2695                 if (e->renderer() && e->renderer()->isDragging())
2696                     return true;
2697                 break;
2698             }
2699             case CSSSelector::PseudoFocus:
2700                 if (e && e->focused() && e->document()->frame() && e->document()->frame()->selection()->isFocusedAndActive())
2701                     return true;
2702                 break;
2703             case CSSSelector::PseudoHover: {
2704                 // If we're in quirks mode, then hover should never match anchors with no
2705                 // href and *:hover should not match anything.  This is important for sites like wsj.com.
2706                 if (m_strictParsing || isSubSelector || (sel->hasTag() && !e->hasTagName(aTag)) || e->isLink()) {
2707                     if (elementStyle)
2708                         elementStyle->setAffectedByHoverRules(true);
2709                     else if (e->renderStyle())
2710                         e->renderStyle()->setAffectedByHoverRules(true);
2711                     if (e->hovered())
2712                         return true;
2713                 }
2714                 break;
2715             }
2716             case CSSSelector::PseudoActive:
2717                 // If we're in quirks mode, then :active should never match anchors with no
2718                 // href and *:active should not match anything. 
2719                 if (m_strictParsing || isSubSelector || (sel->hasTag() && !e->hasTagName(aTag)) || e->isLink()) {
2720                     if (elementStyle)
2721                         elementStyle->setAffectedByActiveRules(true);
2722                     else if (e->renderStyle())
2723                         e->renderStyle()->setAffectedByActiveRules(true);
2724                     if (e->active())
2725                         return true;
2726                 }
2727                 break;
2728             case CSSSelector::PseudoEnabled:
2729                 if (e && e->isFormControlElement())
2730                     return e->isEnabledFormControl();
2731                 break;
2732             case CSSSelector::PseudoFullPageMedia:
2733                 return e && e->document() && e->document()->isMediaDocument();
2734                 break;
2735             case CSSSelector::PseudoDefault:
2736                 return e && e->isDefaultButtonForForm();
2737             case CSSSelector::PseudoDisabled:
2738                 if (e && e->isFormControlElement())
2739                     return !e->isEnabledFormControl();
2740                 break;
2741             case CSSSelector::PseudoReadOnly: {
2742                 if (!e || !e->isFormControlElement())
2743                     return false;
2744                 return e->isTextFormControl() && e->isReadOnlyFormControl();
2745             }
2746             case CSSSelector::PseudoReadWrite: {
2747                 if (!e || !e->isFormControlElement())
2748                     return false;
2749                 return e->isTextFormControl() && !e->isReadOnlyFormControl();
2750             }
2751             case CSSSelector::PseudoOptional:
2752                 return e && e->isOptionalFormControl();
2753             case CSSSelector::PseudoRequired:
2754                 return e && e->isRequiredFormControl();
2755             case CSSSelector::PseudoValid: {
2756                 if (!e)
2757                     return false;
2758                 e->document()->setContainsValidityStyleRules();
2759                 return e->willValidate() && e->isValidFormControlElement();
2760             } case CSSSelector::PseudoInvalid: {
2761                 if (!e)
2762                     return false;
2763                 e->document()->setContainsValidityStyleRules();
2764                 return (e->willValidate() && !e->isValidFormControlElement()) || e->hasUnacceptableValue();
2765             } case CSSSelector::PseudoChecked: {
2766                 if (!e || !e->isFormControlElement())
2767                     break;
2768                 // Even though WinIE allows checked and indeterminate to co-exist, the CSS selector spec says that
2769                 // you can't be both checked and indeterminate.  We will behave like WinIE behind the scenes and just
2770                 // obey the CSS spec here in the test for matching the pseudo.
2771                 InputElement* inputElement = toInputElement(e);
2772                 if (inputElement && inputElement->isChecked() && !inputElement->isIndeterminate())
2773                     return true;
2774                 break;
2775             }
2776             case CSSSelector::PseudoIndeterminate: {
2777                 if (!e || !e->isFormControlElement())
2778                     break;
2779                 InputElement* inputElement = toInputElement(e);
2780                 if (inputElement && inputElement->isIndeterminate())
2781                     return true;
2782                 break;
2783             }
2784             case CSSSelector::PseudoRoot:
2785                 if (e == e->document()->documentElement())
2786                     return true;
2787                 break;
2788             case CSSSelector::PseudoLang: {
2789                 AtomicString value = e->computeInheritedLanguage();
2790                 const AtomicString& argument = sel->argument();
2791                 if (value.isEmpty() || !value.startsWith(argument, false))
2792                     break;
2793                 if (value.length() != argument.length() && value[argument.length()] != '-')
2794                     break;
2795                 return true;
2796             }
2797 #if ENABLE(FULLSCREEN_API)
2798             case CSSSelector::PseudoFullScreen:
2799                 // While a Document is in the fullscreen state, and the document's current fullscreen 
2800                 // element is an element in the document, the 'full-screen' pseudoclass applies to 
2801                 // that element. Also, an <iframe>, <object> or <embed> element whose child browsing 
2802                 // context's Document is in the fullscreen state has the 'full-screen' pseudoclass applied.
2803                 if (!e->document()->webkitIsFullScreen())
2804                     return false;
2805                 if (e != e->document()->webkitCurrentFullScreenElement())
2806                     return false;
2807                 return true;
2808             case CSSSelector::PseudoFullScreenDocument:
2809                 // While a Document is in the fullscreen state, the 'full-screen-document' pseudoclass applies 
2810                 // to all elements of that Document.
2811                 if (!e->document()->webkitIsFullScreen())
2812                     return false;
2813                 return true;
2814 #endif
2815             case CSSSelector::PseudoInRange:
2816                 if (!e)
2817                     return false;
2818                 e->document()->setContainsValidityStyleRules();
2819                 return e->isInRange();
2820             case CSSSelector::PseudoOutOfRange:
2821                 if (!e)
2822                     return false;
2823                 e->document()->setContainsValidityStyleRules();
2824                 return e->isOutOfRange();
2825             case CSSSelector::PseudoUnknown:
2826             case CSSSelector::PseudoNotParsed:
2827             default:
2828                 ASSERT_NOT_REACHED();
2829                 break;
2830         }
2831         return false;
2832     }
2833     if (sel->m_match == CSSSelector::PseudoElement) {
2834         if (!elementStyle && !m_collectRulesOnly)
2835             return false;
2836
2837         PseudoId pseudoId = CSSSelector::pseudoId(sel->pseudoType());
2838         if (pseudoId == FIRST_LETTER) {
2839             if (Document* document = e->document())
2840                 document->setUsesFirstLetterRules(true);
2841         }
2842         if (pseudoId != NOPSEUDO)
2843             dynamicPseudo = pseudoId;
2844     }
2845     // ### add the rest of the checks...
2846     return true;
2847 }
2848
2849 bool CSSStyleSelector::SelectorChecker::checkScrollbarPseudoClass(CSSSelector* sel, PseudoId&) const
2850 {
2851     RenderScrollbar* scrollbar = RenderScrollbar::scrollbarForStyleResolve();
2852     ScrollbarPart part = RenderScrollbar::partForStyleResolve();
2853
2854     // FIXME: This is a temporary hack for resizers and scrollbar corners.  Eventually :window-inactive should become a real
2855     // pseudo class and just apply to everything.
2856     if (sel->pseudoType() == CSSSelector::PseudoWindowInactive)
2857         return !m_document->page()->focusController()->isActive();
2858     
2859     if (!scrollbar)
2860         return false;
2861         
2862     ASSERT(sel->m_match == CSSSelector::PseudoClass);
2863     switch (sel->pseudoType()) {
2864         case CSSSelector::PseudoEnabled:
2865             return scrollbar->enabled();
2866         case CSSSelector::PseudoDisabled:
2867             return !scrollbar->enabled();
2868         case CSSSelector::PseudoHover: {
2869             ScrollbarPart hoveredPart = scrollbar->hoveredPart();
2870             if (part == ScrollbarBGPart)
2871                 return hoveredPart != NoPart;
2872             if (part == TrackBGPart)
2873                 return hoveredPart == BackTrackPart || hoveredPart == ForwardTrackPart || hoveredPart == ThumbPart;
2874             return part == hoveredPart;
2875         }
2876         case CSSSelector::PseudoActive: {
2877             ScrollbarPart pressedPart = scrollbar->pressedPart();
2878             if (part == ScrollbarBGPart)
2879                 return pressedPart != NoPart;
2880             if (part == TrackBGPart)
2881                 return pressedPart == BackTrackPart || pressedPart == ForwardTrackPart || pressedPart == ThumbPart;
2882             return part == pressedPart;
2883         }
2884         case CSSSelector::PseudoHorizontal:
2885             return scrollbar->orientation() == HorizontalScrollbar;
2886         case CSSSelector::PseudoVertical:
2887             return scrollbar->orientation() == VerticalScrollbar;
2888         case CSSSelector::PseudoDecrement:
2889             return part == BackButtonStartPart || part == BackButtonEndPart || part == BackTrackPart;
2890         case CSSSelector::PseudoIncrement:
2891             return part == ForwardButtonStartPart || part == ForwardButtonEndPart || part == ForwardTrackPart;
2892         case CSSSelector::PseudoStart:
2893             return part == BackButtonStartPart || part == ForwardButtonStartPart || part == BackTrackPart;
2894         case CSSSelector::PseudoEnd:
2895             return part == BackButtonEndPart || part == ForwardButtonEndPart || part == ForwardTrackPart;
2896         case CSSSelector::PseudoDoubleButton: {
2897             ScrollbarButtonsPlacement buttonsPlacement = scrollbar->theme()->buttonsPlacement();
2898             if (part == BackButtonStartPart || part == ForwardButtonStartPart || part == BackTrackPart)
2899                 return buttonsPlacement == ScrollbarButtonsDoubleStart || buttonsPlacement == ScrollbarButtonsDoubleBoth;
2900             if (part == BackButtonEndPart || part == ForwardButtonEndPart || part == ForwardTrackPart)
2901                 return buttonsPlacement == ScrollbarButtonsDoubleEnd || buttonsPlacement == ScrollbarButtonsDoubleBoth;
2902             return false;
2903         } 
2904         case CSSSelector::PseudoSingleButton: {
2905             ScrollbarButtonsPlacement buttonsPlacement = scrollbar->theme()->buttonsPlacement();
2906             if (part == BackButtonStartPart || part == ForwardButtonEndPart || part == BackTrackPart || part == ForwardTrackPart)
2907                 return buttonsPlacement == ScrollbarButtonsSingle;
2908             return false;
2909         }
2910         case CSSSelector::PseudoNoButton: {
2911             ScrollbarButtonsPlacement buttonsPlacement = scrollbar->theme()->buttonsPlacement();
2912             if (part == BackTrackPart)
2913                 return buttonsPlacement == ScrollbarButtonsNone || buttonsPlacement == ScrollbarButtonsDoubleEnd;
2914             if (part == ForwardTrackPart)
2915                 return buttonsPlacement == ScrollbarButtonsNone || buttonsPlacement == ScrollbarButtonsDoubleStart;
2916             return false;
2917         }
2918         case CSSSelector::PseudoCornerPresent:
2919             return scrollbar->scrollableArea()->scrollbarCornerPresent();
2920         default:
2921             return false;
2922     }
2923 }
2924
2925 // -----------------------------------------------------------------
2926
2927 inline void RuleData::collectDescendantSelectorIdentifierHashes()
2928 {
2929     unsigned identifierCount = 0;
2930     CSSSelector::Relation relation = m_selector->relation();
2931     CSSSelector* selector = m_selector->tagHistory();
2932     // Skip the topmost selector. It is handled quickly by the rule hashes.
2933     for (; selector; selector = selector->tagHistory()) {
2934         if (relation != CSSSelector::SubSelector)
2935             break;
2936         relation = selector->relation();
2937     }
2938     for (; selector; selector = selector->tagHistory()) {
2939         // Only collect identifiers that match direct ancestors.
2940         // FIXME: Intead of just stopping, this should skip over sibling selectors.
2941         if (relation != CSSSelector::Descendant && relation != CSSSelector::Child && relation != CSSSelector::SubSelector)
2942             break;
2943         if ((selector->m_match == CSSSelector::Id || selector->m_match == CSSSelector::Class) && !selector->value().isEmpty())
2944             m_descendantSelectorIdentifierHashes[identifierCount++] = selector->value().impl()->existingHash();
2945         if (identifierCount == maximumIdentifierCount)
2946             return;
2947         const AtomicString& localName = selector->tag().localName();
2948         if (localName != starAtom)
2949             m_descendantSelectorIdentifierHashes[identifierCount++] = localName.impl()->existingHash();
2950         if (identifierCount == maximumIdentifierCount)
2951             return;
2952         relation = selector->relation();
2953     }
2954     m_descendantSelectorIdentifierHashes[identifierCount] = 0;
2955 }
2956
2957 RuleSet::RuleSet()
2958     : m_ruleCount(0)
2959     , m_autoShrinkToFitEnabled(true)
2960 {
2961 }
2962
2963 RuleSet::~RuleSet()
2964
2965     deleteAllValues(m_idRules);
2966     deleteAllValues(m_classRules);
2967     deleteAllValues(m_pseudoRules);
2968     deleteAllValues(m_tagRules);
2969 }
2970
2971
2972 void RuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map,
2973                               CSSStyleRule* rule, CSSSelector* sel)
2974 {
2975     if (!key) return;
2976     Vector<RuleData>* rules = map.get(key);
2977     if (!rules) {
2978         rules = new Vector<RuleData>;
2979         map.set(key, rules);
2980     }
2981     rules->append(RuleData(rule, sel, m_ruleCount++));
2982 }
2983
2984 void RuleSet::addRule(CSSStyleRule* rule, CSSSelector* sel)
2985 {
2986     if (sel->m_match == CSSSelector::Id) {
2987         addToRuleSet(sel->value().impl(), m_idRules, rule, sel);
2988         return;
2989     }
2990     if (sel->m_match == CSSSelector::Class) {
2991         addToRuleSet(sel->value().impl(), m_classRules, rule, sel);
2992         return;
2993     }
2994      
2995     if (sel->isUnknownPseudoElement()) {
2996         addToRuleSet(sel->value().impl(), m_pseudoRules, rule, sel);
2997         return;
2998     }
2999
3000     const AtomicString& localName = sel->tag().localName();
3001     if (localName != starAtom) {
3002         addToRuleSet(localName.impl(), m_tagRules, rule, sel);
3003         return;
3004     }
3005
3006     m_universalRules.append(RuleData(rule, sel, m_ruleCount++));
3007 }
3008
3009 void RuleSet::addPageRule(CSSStyleRule* rule, CSSSelector* sel)
3010 {
3011     m_pageRules.append(RuleData(rule, sel, m_pageRules.size()));
3012 }
3013
3014 void RuleSet::addRulesFromSheet(CSSStyleSheet* sheet, const MediaQueryEvaluator& medium, CSSStyleSelector* styleSelector)
3015 {
3016     if (!sheet)
3017         return;
3018
3019     // No media implies "all", but if a media list exists it must
3020     // contain our current medium
3021     if (sheet->media() && !medium.eval(sheet->media(), styleSelector))
3022         return; // the style sheet doesn't apply
3023
3024     int len = sheet->length();
3025
3026     for (int i = 0; i < len; i++) {
3027         StyleBase* item = sheet->item(i);
3028         if (item->isStyleRule())
3029             addStyleRule(static_cast<CSSStyleRule*>(item));
3030         else if (item->isImportRule()) {
3031             CSSImportRule* import = static_cast<CSSImportRule*>(item);
3032             if (!import->media() || medium.eval(import->media(), styleSelector))
3033                 addRulesFromSheet(import->styleSheet(), medium, styleSelector);
3034         }
3035         else if (item->isMediaRule()) {
3036             CSSMediaRule* r = static_cast<CSSMediaRule*>(item);
3037             CSSRuleList* rules = r->cssRules();
3038
3039             if ((!r->media() || medium.eval(r->media(), styleSelector)) && rules) {
3040                 // Traverse child elements of the @media rule.
3041                 for (unsigned j = 0; j < rules->length(); j++) {
3042                     CSSRule *childItem = rules->item(j);
3043                     if (childItem->isStyleRule()) {
3044                         // It is a StyleRule, so append it to our list
3045                         addStyleRule(static_cast<CSSStyleRule*>(childItem));
3046                     } else if (childItem->isFontFaceRule() && styleSelector) {
3047                         // Add this font face to our set.
3048                         const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(childItem);
3049                         styleSelector->fontSelector()->addFontFaceRule(fontFaceRule);
3050                     } else if (childItem->isKeyframesRule() && styleSelector) {
3051                         // Add this keyframe rule to our set.
3052                         styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(childItem));
3053                     }
3054                 }   // for rules
3055             }   // if rules
3056         } else if (item->isFontFaceRule() && styleSelector) {
3057             // Add this font face to our set.
3058             const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(item);
3059             styleSelector->fontSelector()->addFontFaceRule(fontFaceRule);
3060         } else if (item->isKeyframesRule())
3061             styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(item));
3062     }
3063     if (m_autoShrinkToFitEnabled)
3064         shrinkToFit();
3065 }
3066
3067 void RuleSet::addStyleRule(CSSStyleRule* rule)
3068 {
3069     if (rule->isPageRule()) {
3070         CSSPageRule* pageRule = static_cast<CSSPageRule*>(rule);
3071         addPageRule(pageRule, pageRule->selectorList().first());
3072     } else {
3073         for (CSSSelector* s = rule->selectorList().first(); s; s = CSSSelectorList::next(s))
3074             addRule(rule, s);
3075     }
3076 }
3077
3078 static void collectIdsAndSiblingRulesFromList(HashSet<AtomicStringImpl*>& ids, OwnPtr<RuleSet>& siblingRules, const Vector<RuleData>& rules)
3079 {
3080     unsigned size = rules.size();
3081     for (unsigned i = 0; i < size; ++i) {
3082         const RuleData& ruleData = rules[i];
3083         bool foundSiblingSelector = false;
3084         for (CSSSelector* selector = ruleData.selector(); selector; selector = selector->tagHistory()) {
3085             if (selector->m_match == CSSSelector::Id && !selector->value().isEmpty())
3086                 ids.add(selector->value().impl());
3087             if (CSSSelector* simpleSelector = selector->simpleSelector()) {
3088                 ASSERT(!simpleSelector->simpleSelector());
3089                 if (simpleSelector->m_match == CSSSelector::Id && !simpleSelector->value().isEmpty())
3090                     ids.add(simpleSelector->value().impl());
3091             }
3092             if (selector->isSiblingSelector())
3093                 foundSiblingSelector = true;
3094         }
3095         if (foundSiblingSelector) {
3096             if (!siblingRules)
3097                 siblingRules = adoptPtr(new RuleSet);
3098             siblingRules->addRule(ruleData.rule(), ruleData.selector());   
3099         }
3100     }
3101 }
3102
3103 void RuleSet::collectIdsAndSiblingRules(HashSet<AtomicStringImpl*>& ids, OwnPtr<RuleSet>& siblingRules) const
3104 {
3105     AtomRuleMap::const_iterator end = m_idRules.end();
3106     for (AtomRuleMap::const_iterator it = m_idRules.begin(); it != end; ++it)
3107         collectIdsAndSiblingRulesFromList(ids, siblingRules, *it->second);
3108     end = m_classRules.end();
3109     for (AtomRuleMap::const_iterator it = m_classRules.begin(); it != end; ++it)
3110         collectIdsAndSiblingRulesFromList(ids, siblingRules, *it->second);
3111     end = m_tagRules.end();
3112     for (AtomRuleMap::const_iterator it = m_tagRules.begin(); it != end; ++it)
3113         collectIdsAndSiblingRulesFromList(ids, siblingRules, *it->second);
3114     end = m_pseudoRules.end();
3115     for (AtomRuleMap::const_iterator it = m_pseudoRules.begin(); it != end; ++it)
3116         collectIdsAndSiblingRulesFromList(ids, siblingRules, *it->second);
3117     collectIdsAndSiblingRulesFromList(ids, siblingRules, m_universalRules);
3118 }
3119     
3120 static inline void shrinkMapVectorsToFit(RuleSet::AtomRuleMap& map)
3121 {
3122     RuleSet::AtomRuleMap::iterator end = map.end();
3123     for (RuleSet::AtomRuleMap::iterator it = map.begin(); it != end; ++it)
3124         it->second->shrinkToFit();
3125 }
3126     
3127 void RuleSet::shrinkToFit()
3128 {
3129     shrinkMapVectorsToFit(m_idRules);
3130     shrinkMapVectorsToFit(m_classRules);
3131     shrinkMapVectorsToFit(m_tagRules);
3132     shrinkMapVectorsToFit(m_pseudoRules);
3133     m_universalRules.shrinkToFit();
3134     m_pageRules.shrinkToFit();
3135 }
3136
3137 // -------------------------------------------------------------------------------------
3138 // this is mostly boring stuff on how to apply a certain rule to the renderstyle...
3139
3140 static Length convertToLength(CSSPrimitiveValue* primitiveValue, RenderStyle* style, RenderStyle* rootStyle, double multiplier = 1, bool *ok = 0)
3141 {
3142     // This function is tolerant of a null style value. The only place style is used is in
3143     // length measurements, like 'ems' and 'px'. And in those cases style is only used
3144     // when the units are EMS or EXS. So we will just fail in those cases.
3145     Length l;
3146     if (!primitiveValue) {
3147         if (ok)
3148             *ok = false;
3149     } else {
3150         int type = primitiveValue->primitiveType();
3151         
3152         if (!style && (type == CSSPrimitiveValue::CSS_EMS || type == CSSPrimitiveValue::CSS_EXS || type == CSSPrimitiveValue::CSS_REMS)) {
3153             if (ok)
3154                 *ok = false;
3155         } else if (CSSPrimitiveValue::isUnitTypeLength(type))
3156             l = Length(primitiveValue->computeLengthIntForLength(style, rootStyle, multiplier), Fixed);
3157         else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
3158             l = Length(primitiveValue->getDoubleValue(), Percent);
3159         else if (type == CSSPrimitiveValue::CSS_NUMBER)
3160             l = Length(primitiveValue->getDoubleValue() * 100.0, Percent);
3161         else if (ok)
3162             *ok = false;
3163     }
3164     return l;
3165 }
3166
3167 template <bool applyFirst>
3168 void CSSStyleSelector::applyDeclarations(bool isImportant, int startIndex, int endIndex)
3169 {
3170     if (startIndex == -1)
3171         return;
3172
3173     for (int i = startIndex; i <= endIndex; i++) {
3174         CSSMutableStyleDeclaration* decl = m_matchedDecls[i];
3175         CSSMutableStyleDeclaration::const_iterator end = decl->end();
3176         for (CSSMutableStyleDeclaration::const_iterator it = decl->begin(); it != end; ++it) {
3177             const CSSProperty& current = *it;
3178             if (isImportant == current.isImportant()) {
3179                 int property = current.id();
3180
3181                 if (applyFirst) {
3182                     COMPILE_ASSERT(firstCSSProperty == CSSPropertyColor, CSS_color_is_first_property);
3183                     COMPILE_ASSERT(CSSPropertyZoom == CSSPropertyColor + 13, CSS_zoom_is_end_of_first_prop_range);
3184                     COMPILE_ASSERT(CSSPropertyLineHeight == CSSPropertyZoom + 1, CSS_line_height_is_after_zoom);
3185
3186                     // give special priority to font-xxx, color properties, etc
3187                     if (property <= CSSPropertyLineHeight) {
3188                         // we apply line-height later
3189                         if (property == CSSPropertyLineHeight)
3190                             m_lineHeightValue = current.value(); 
3191                         else 
3192                             applyProperty(current.id(), current.value());
3193                     }
3194                 } else {
3195                     if (property > CSSPropertyLineHeight)
3196                         applyProperty(current.id(), current.value());
3197                 }
3198             }
3199         }
3200     }
3201 }
3202
3203 void CSSStyleSelector::matchPageRules(RuleSet* rules, bool isLeftPage, bool isFirstPage, const String& pageName)
3204 {
3205     m_matchedRules.clear();
3206
3207     if (!rules)
3208         return;
3209
3210     matchPageRulesForList(rules->getPageRules(), isLeftPage, isFirstPage, pageName);
3211
3212     // If we didn't match any rules, we're done.
3213     if (m_matchedRules.isEmpty())
3214         return;
3215
3216     // Sort the set of matched rules.
3217     sortMatchedRules(0, m_matchedRules.size());
3218
3219     // Now transfer the set of matched rules over to our list of decls.
3220     for (unsigned i = 0; i < m_matchedRules.size(); i++)
3221         addMatchedDeclaration(m_matchedRules[i]->rule()->declaration());
3222 }
3223
3224 void CSSStyleSelector::matchPageRulesForList(const Vector<RuleData>* rules, bool isLeftPage, bool isFirstPage, const String& pageName)
3225 {
3226     if (!rules)
3227         return;
3228
3229     unsigned size = rules->size();
3230     for (unsigned i = 0; i < size; ++i) {
3231         const RuleData& ruleData = rules->at(i);
3232         CSSStyleRule* rule = ruleData.rule();
3233         const AtomicString& selectorLocalName = ruleData.selector()->tag().localName();
3234         if (selectorLocalName != starAtom && selectorLocalName != pageName)
3235             continue;
3236         CSSSelector::PseudoType pseudoType = ruleData.selector()->pseudoType();
3237         if ((pseudoType == CSSSelector::PseudoLeftPage && !isLeftPage)
3238             || (pseudoType == CSSSelector::PseudoRightPage && isLeftPage)
3239             || (pseudoType == CSSSelector::PseudoFirstPage && !isFirstPage))
3240             continue;
3241
3242         // If the rule has no properties to apply, then ignore it.
3243         CSSMutableStyleDeclaration* decl = rule->declaration();
3244         if (!decl || !decl->length())
3245             continue;
3246
3247         // Add this rule to our list of matched rules.
3248         addMatchedRule(&ruleData);
3249     }
3250 }
3251
3252 bool CSSStyleSelector::isLeftPage(int pageIndex) const
3253 {
3254     bool isFirstPageLeft = false;
3255     if (!m_rootElementStyle->isLeftToRightDirection())
3256         isFirstPageLeft = true;
3257
3258     return (pageIndex + (isFirstPageLeft ? 1 : 0)) % 2;
3259 }
3260
3261 bool CSSStyleSelector::isFirstPage(int pageIndex) const
3262 {
3263     // FIXME: In case of forced left/right page, page at index 1 (not 0) can be the first page.
3264     return (!pageIndex);
3265 }
3266
3267 String CSSStyleSelector::pageName(int /* pageIndex */) const
3268 {
3269     // FIXME: Implement page index to page name mapping.
3270     return "";
3271 }
3272
3273 static void applyCounterList(RenderStyle* style, CSSValueList* list, bool isReset)
3274 {