OSDN Git Service

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