9a9dad095619594bd3e912d0c2151741331e81c4
[WebKit-https.git] / Source / WebCore / css / CSSStyleSelector.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
4  * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
5  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 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  * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
10  * Copyright (C) Research In Motion Limited 2011. All rights reserved.
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Library General Public
14  * License as published by the Free Software Foundation; either
15  * version 2 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public License
23  * along with this library; see the file COPYING.LIB.  If not, write to
24  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25  * Boston, MA 02110-1301, USA.
26  */
27
28 #include "config.h"
29 #include "CSSStyleSelector.h"
30
31 #include "Attribute.h"
32 #include "CachedImage.h"
33 #include "ContentData.h"
34 #include "Counter.h"
35 #include "CounterContent.h"
36 #include "CSSBorderImageValue.h"
37 #include "CSSCursorImageValue.h"
38 #include "CSSFontFaceRule.h"
39 #include "CSSFontSelector.h"
40 #include "CSSImportRule.h"
41 #include "CSSLineBoxContainValue.h"
42 #include "CSSMediaRule.h"
43 #include "CSSPageRule.h"
44 #include "CSSParser.h"
45 #include "CSSPrimitiveValueMappings.h"
46 #include "CSSPropertyNames.h"
47 #include "CSSReflectValue.h"
48 #include "CSSRuleList.h"
49 #include "CSSSelector.h"
50 #include "CSSSelectorList.h"
51 #include "CSSStyleApplyProperty.h"
52 #include "CSSStyleRule.h"
53 #include "CSSStyleSheet.h"
54 #include "CSSTimingFunctionValue.h"
55 #include "CSSValueList.h"
56 #include "CursorList.h"
57 #include "FontFamilyValue.h"
58 #include "FontFeatureValue.h"
59 #include "FontValue.h"
60 #include "Frame.h"
61 #include "FrameSelection.h"
62 #include "FrameView.h"
63 #include "HTMLDocument.h"
64 #include "HTMLElement.h"
65 #include "HTMLInputElement.h"
66 #include "HTMLNames.h"
67 #include "HTMLProgressElement.h"
68 #include "HTMLTextAreaElement.h"
69 #include "InspectorInstrumentation.h"
70 #include "KeyframeList.h"
71 #include "LinkHash.h"
72 #include "LocaleToScriptMapping.h"
73 #include "Matrix3DTransformOperation.h"
74 #include "MatrixTransformOperation.h"
75 #include "MediaList.h"
76 #include "MediaQueryEvaluator.h"
77 #include "NodeRenderStyle.h"
78 #include "Page.h"
79 #include "PageGroup.h"
80 #include "Pair.h"
81 #include "PerspectiveTransformOperation.h"
82 #include "QuotesData.h"
83 #include "Rect.h"
84 #include "RenderScrollbar.h"
85 #include "RenderScrollbarTheme.h"
86 #include "RenderStyleConstants.h"
87 #include "RenderTheme.h"
88 #include "RotateTransformOperation.h"
89 #include "ScaleTransformOperation.h"
90 #include "SecurityOrigin.h"
91 #include "Settings.h"
92 #include "ShadowData.h"
93 #include "ShadowValue.h"
94 #include "SkewTransformOperation.h"
95 #include "StyleCachedImage.h"
96 #include "StylePendingImage.h"
97 #include "StyleGeneratedImage.h"
98 #include "StyleSheetList.h"
99 #include "Text.h"
100 #include "TransformationMatrix.h"
101 #include "TranslateTransformOperation.h"
102 #include "UserAgentStyleSheets.h"
103 #include "WebKitCSSKeyframeRule.h"
104 #include "WebKitCSSKeyframesRule.h"
105 #include "WebKitCSSRegionRule.h"
106 #include "WebKitCSSTransformValue.h"
107 #include "WebKitFontFamilyNames.h"
108 #include "XMLNames.h"
109 #include <wtf/StdLibExtras.h>
110 #include <wtf/Vector.h>
111
112 #if ENABLE(CSS_FILTERS)
113 #include "FilterOperation.h"
114 #include "WebKitCSSFilterValue.h"
115 #endif
116
117 #if ENABLE(DASHBOARD_SUPPORT)
118 #include "DashboardRegion.h"
119 #endif
120
121 #if ENABLE(SVG)
122 #include "SVGNames.h"
123 #endif
124
125 #if ENABLE(CSS_SHADERS)
126 #include "CustomFilterOperation.h"
127 #include "StyleCachedShader.h"
128 #include "StyleCustomFilterProgram.h"
129 #include "StylePendingShader.h"
130 #include "StyleShader.h"
131 #include "WebKitCSSShaderValue.h"
132 #endif
133
134 using namespace std;
135
136 namespace WebCore {
137
138 using namespace HTMLNames;
139
140 #define HANDLE_INHERIT(prop, Prop) \
141 if (isInherit) { \
142     m_style->set##Prop(m_parentStyle->prop()); \
143     return; \
144 }
145
146 #define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
147 HANDLE_INHERIT(prop, Prop) \
148 if (isInitial) { \
149     m_style->set##Prop(RenderStyle::initial##Prop()); \
150     return; \
151 }
152
153 #define HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(prop, Prop, Value) \
154 HANDLE_INHERIT(prop, Prop) \
155 if (isInitial) { \
156     m_style->set##Prop(RenderStyle::initial##Value());\
157     return;\
158 }
159
160 #define HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(prop, Prop) \
161 HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
162 if (primitiveValue) \
163     m_style->set##Prop(*primitiveValue);
164
165 #define HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(prop, Prop, Value) \
166 HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(prop, Prop, Value) \
167 if (primitiveValue) \
168     m_style->set##Prop(*primitiveValue);
169
170 class RuleData {
171 public:
172     RuleData(CSSStyleRule*, CSSSelector*, unsigned position);
173
174     unsigned position() const { return m_position; }
175     CSSStyleRule* rule() const { return m_rule; }
176     CSSSelector* selector() const { return m_selector; }
177
178     bool hasFastCheckableSelector() const { return m_hasFastCheckableSelector; }
179     bool hasMultipartSelector() const { return m_hasMultipartSelector; }
180     bool hasRightmostSelectorMatchingHTMLBasedOnRuleHash() const { return m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash; }
181     bool containsUncommonAttributeSelector() const { return m_containsUncommonAttributeSelector; }
182     unsigned specificity() const { return m_specificity; }
183     unsigned linkMatchType() const { return m_linkMatchType; }
184
185     // Try to balance between memory usage (there can be lots of RuleData objects) and good filtering performance.
186     static const unsigned maximumIdentifierCount = 4;
187     const unsigned* descendantSelectorIdentifierHashes() const { return m_descendantSelectorIdentifierHashes; }
188
189 private:
190     CSSStyleRule* m_rule;
191     CSSSelector* m_selector;
192     unsigned m_specificity;
193     // This number was picked fairly arbitrarily. We can probably lower it if we need to.
194     // Some simple testing showed <100,000 RuleData's on large sites.
195     unsigned m_position : 26;
196     unsigned m_hasFastCheckableSelector : 1;
197     unsigned m_hasMultipartSelector : 1;
198     unsigned m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash : 1;
199     unsigned m_containsUncommonAttributeSelector : 1;
200     unsigned m_linkMatchType : 2; //  SelectorChecker::LinkMatchMask
201     // Use plain array instead of a Vector to minimize memory overhead.
202     unsigned m_descendantSelectorIdentifierHashes[maximumIdentifierCount];
203 };
204     
205 struct SameSizeAsRuleData {
206     void* a;
207     void* b;
208     unsigned c;
209     unsigned d;
210     unsigned e[4];
211 };
212
213 COMPILE_ASSERT(sizeof(RuleData) == sizeof(SameSizeAsRuleData), RuleData_should_stay_small);
214
215 class RuleSet {
216     WTF_MAKE_NONCOPYABLE(RuleSet);
217 public:
218     RuleSet();
219
220     typedef HashMap<AtomicStringImpl*, OwnPtr<Vector<RuleData> > > AtomRuleMap;
221
222     void addRulesFromSheet(CSSStyleSheet*, const MediaQueryEvaluator&, CSSStyleSelector* = 0);
223
224     void addStyleRule(CSSStyleRule* item);
225     void addRule(CSSStyleRule* rule, CSSSelector* sel);
226     void addPageRule(CSSPageRule*);
227     void addToRuleSet(AtomicStringImpl* key, AtomRuleMap&, CSSStyleRule*, CSSSelector*);
228     void shrinkToFit();
229     void disableAutoShrinkToFit() { m_autoShrinkToFitEnabled = false; }
230
231     void collectFeatures(CSSStyleSelector::Features&) const;
232
233     const Vector<RuleData>* idRules(AtomicStringImpl* key) const { return m_idRules.get(key); }
234     const Vector<RuleData>* classRules(AtomicStringImpl* key) const { return m_classRules.get(key); }
235     const Vector<RuleData>* tagRules(AtomicStringImpl* key) const { return m_tagRules.get(key); }
236     const Vector<RuleData>* shadowPseudoElementRules(AtomicStringImpl* key) const { return m_shadowPseudoElementRules.get(key); }
237     const Vector<RuleData>* linkPseudoClassRules() const { return &m_linkPseudoClassRules; }
238     const Vector<RuleData>* focusPseudoClassRules() const { return &m_focusPseudoClassRules; }
239     const Vector<RuleData>* universalRules() const { return &m_universalRules; }
240     const Vector<RuleData>* pageRules() const { return &m_pageRules; }
241
242 public:
243     AtomRuleMap m_idRules;
244     AtomRuleMap m_classRules;
245     AtomRuleMap m_tagRules;
246     AtomRuleMap m_shadowPseudoElementRules;
247     Vector<RuleData> m_linkPseudoClassRules;
248     Vector<RuleData> m_focusPseudoClassRules;
249     Vector<RuleData> m_universalRules;
250     Vector<RuleData> m_pageRules;
251     unsigned m_ruleCount;
252     bool m_autoShrinkToFitEnabled;
253 };
254
255 static RuleSet* defaultStyle;
256 static RuleSet* defaultQuirksStyle;
257 static RuleSet* defaultPrintStyle;
258 static RuleSet* defaultViewSourceStyle;
259 static CSSStyleSheet* simpleDefaultStyleSheet;
260
261 static RuleSet* siblingRulesInDefaultStyle;
262 static RuleSet* uncommonAttributeRulesInDefaultStyle;
263
264 RenderStyle* CSSStyleSelector::s_styleNotYetAvailable;
265
266 static void loadFullDefaultStyle();
267 static void loadSimpleDefaultStyle();
268 // FIXME: It would be nice to use some mechanism that guarantees this is in sync with the real UA stylesheet.
269 static const char* simpleUserAgentStyleSheet = "html,body,div{display:block}head{display:none}body{margin:8px}div:focus,span:focus{outline:auto 5px -webkit-focus-ring-color}a:-webkit-any-link{color:-webkit-link;text-decoration:underline}a:-webkit-any-link:active{color:-webkit-activelink}";
270
271 static inline bool elementCanUseSimpleDefaultStyle(Element* e)
272 {
273     return e->hasTagName(htmlTag) || e->hasTagName(headTag) || e->hasTagName(bodyTag) || e->hasTagName(divTag) || e->hasTagName(spanTag) || e->hasTagName(brTag) || e->hasTagName(aTag);
274 }
275
276 static inline void collectSpecialRulesInDefaultStyle()
277 {
278     CSSStyleSelector::Features features;
279     defaultStyle->collectFeatures(features);
280     ASSERT(features.idsInRules.isEmpty());
281     delete siblingRulesInDefaultStyle;
282     delete uncommonAttributeRulesInDefaultStyle;
283     siblingRulesInDefaultStyle = features.siblingRules.leakPtr();
284     uncommonAttributeRulesInDefaultStyle = features.uncommonAttributeRules.leakPtr();
285 }
286
287 static inline void assertNoSiblingRulesInDefaultStyle()
288 {
289 #ifndef NDEBUG
290     if (siblingRulesInDefaultStyle)
291         return;
292     collectSpecialRulesInDefaultStyle();
293     ASSERT(!siblingRulesInDefaultStyle);
294 #endif
295 }
296
297 static const MediaQueryEvaluator& screenEval()
298 {
299     DEFINE_STATIC_LOCAL(const MediaQueryEvaluator, staticScreenEval, ("screen"));
300     return staticScreenEval;
301 }
302
303 static const MediaQueryEvaluator& printEval()
304 {
305     DEFINE_STATIC_LOCAL(const MediaQueryEvaluator, staticPrintEval, ("print"));
306     return staticPrintEval;
307 }
308
309 static CSSMutableStyleDeclaration* leftToRightDeclaration()
310 {
311     DEFINE_STATIC_LOCAL(RefPtr<CSSMutableStyleDeclaration>, leftToRightDecl, (CSSMutableStyleDeclaration::create()));
312     if (!leftToRightDecl->length()) {
313         leftToRightDecl->setProperty(CSSPropertyDirection, "ltr", false);
314         leftToRightDecl->setStrictParsing(false);
315     }
316     return leftToRightDecl.get();
317 }
318
319 static CSSMutableStyleDeclaration* rightToLeftDeclaration()
320 {
321     DEFINE_STATIC_LOCAL(RefPtr<CSSMutableStyleDeclaration>, rightToLeftDecl, (CSSMutableStyleDeclaration::create()));
322     if (!rightToLeftDecl->length()) {
323         rightToLeftDecl->setProperty(CSSPropertyDirection, "rtl", false);
324         rightToLeftDecl->setStrictParsing(false);
325     }
326     return rightToLeftDecl.get();
327 }
328
329 CSSStyleSelector::CSSStyleSelector(Document* document, StyleSheetList* styleSheets, CSSStyleSheet* mappedElementSheet,
330                                    CSSStyleSheet* pageUserSheet, const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets, const Vector<RefPtr<CSSStyleSheet> >* documentUserSheets,
331                                    bool strictParsing, bool matchAuthorAndUserStyles)
332     : m_hasUAAppearance(false)
333     , m_backgroundData(BackgroundFillLayer)
334     , m_matchedDeclarationCacheAdditionsSinceLastSweep(0)
335     , m_checker(document, strictParsing)
336     , m_parentStyle(0)
337     , m_rootElementStyle(0)
338     , m_element(0)
339     , m_styledElement(0)
340     , m_elementLinkState(NotInsideLink)
341     , m_parentNode(0)
342     , m_lineHeightValue(0)
343     , m_fontDirty(false)
344     , m_matchAuthorAndUserStyles(matchAuthorAndUserStyles)
345     , m_sameOriginOnly(false)
346     , m_fontSelector(CSSFontSelector::create(document))
347     , m_applyPropertyToRegularStyle(true)
348     , m_applyPropertyToVisitedLinkStyle(false)
349     , m_applyProperty(CSSStyleApplyProperty::sharedCSSStyleApplyProperty())
350 #if ENABLE(CSS_SHADERS)
351     , m_hasPendingShaders(false)
352 #endif
353 {
354     Element* root = document->documentElement();
355
356     if (!defaultStyle) {
357         if (!root || elementCanUseSimpleDefaultStyle(root))
358             loadSimpleDefaultStyle();
359         else {
360             loadFullDefaultStyle();
361         }
362     }
363
364     // construct document root element default style. this is needed
365     // to evaluate media queries that contain relative constraints, like "screen and (max-width: 10em)"
366     // This is here instead of constructor, because when constructor is run,
367     // document doesn't have documentElement
368     // NOTE: this assumes that element that gets passed to styleForElement -call
369     // is always from the document that owns the style selector
370     FrameView* view = document->view();
371     if (view)
372         m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType()));
373     else
374         m_medium = adoptPtr(new MediaQueryEvaluator("all"));
375
376     if (root)
377         m_rootDefaultStyle = styleForElement(root, 0, false, true); // don't ref, because the RenderStyle is allocated from global heap
378
379     if (m_rootDefaultStyle && view)
380         m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType(), view->frame(), m_rootDefaultStyle.get()));
381
382     m_authorStyle = adoptPtr(new RuleSet);
383     // Adding rules from multiple sheets, shrink at the end.
384     m_authorStyle->disableAutoShrinkToFit();
385
386     // FIXME: This sucks! The user sheet is reparsed every time!
387     OwnPtr<RuleSet> tempUserStyle = adoptPtr(new RuleSet);
388     if (pageUserSheet)
389         tempUserStyle->addRulesFromSheet(pageUserSheet, *m_medium, this);
390     if (pageGroupUserSheets) {
391         unsigned length = pageGroupUserSheets->size();
392         for (unsigned i = 0; i < length; i++) {
393             if (pageGroupUserSheets->at(i)->isUserStyleSheet())
394                 tempUserStyle->addRulesFromSheet(pageGroupUserSheets->at(i).get(), *m_medium, this);
395             else
396                 m_authorStyle->addRulesFromSheet(pageGroupUserSheets->at(i).get(), *m_medium, this);
397         }
398     }
399     if (documentUserSheets) {
400         unsigned length = documentUserSheets->size();
401         for (unsigned i = 0; i < length; i++) {
402             if (documentUserSheets->at(i)->isUserStyleSheet())
403                 tempUserStyle->addRulesFromSheet(documentUserSheets->at(i).get(), *m_medium, this);
404             else
405                 m_authorStyle->addRulesFromSheet(documentUserSheets->at(i).get(), *m_medium, this);
406         }
407     }
408
409     if (tempUserStyle->m_ruleCount > 0 || tempUserStyle->m_pageRules.size() > 0)
410         m_userStyle = tempUserStyle.release();
411
412     // Add rules from elements like SVG's <font-face>
413     if (mappedElementSheet)
414         m_authorStyle->addRulesFromSheet(mappedElementSheet, *m_medium, this);
415
416     // add stylesheets from document
417     unsigned length = styleSheets->length();
418     for (unsigned i = 0; i < length; i++) {
419         StyleSheet* sheet = styleSheets->item(i);
420         if (sheet->isCSSStyleSheet() && !sheet->disabled())
421             m_authorStyle->addRulesFromSheet(static_cast<CSSStyleSheet*>(sheet), *m_medium, this);
422     }
423     m_authorStyle->shrinkToFit();
424
425     collectFeatures();
426     
427     if (document->renderer() && document->renderer()->style())
428         document->renderer()->style()->font().update(fontSelector());
429 }
430
431 void CSSStyleSelector::collectFeatures()
432 {
433     // Collect all ids and rules using sibling selectors (:first-child and similar)
434     // in the current set of stylesheets. Style sharing code uses this information to reject
435     // sharing candidates.
436     // Usually there are no sibling rules in the default style but the MathML sheet has some.
437     if (siblingRulesInDefaultStyle)
438         siblingRulesInDefaultStyle->collectFeatures(m_features);
439     if (uncommonAttributeRulesInDefaultStyle)
440         uncommonAttributeRulesInDefaultStyle->collectFeatures(m_features);
441     m_authorStyle->collectFeatures(m_features);
442     if (m_userStyle)
443         m_userStyle->collectFeatures(m_features);
444     if (m_features.siblingRules)
445         m_features.siblingRules->shrinkToFit();
446     if (m_features.uncommonAttributeRules)
447         m_features.uncommonAttributeRules->shrinkToFit();
448 }
449
450 void CSSStyleSelector::appendAuthorStylesheets(unsigned firstNew, const Vector<RefPtr<StyleSheet> >& stylesheets)
451 {
452     // This handles sheets added to the end of the stylesheet list only. In other cases the style resolver
453     // needs to be reconstructed. To handle insertions too the rule order numbers would need to be updated.
454     unsigned size = stylesheets.size();
455     for (unsigned i = firstNew; i < size; ++i) {
456         if (!stylesheets[i]->isCSSStyleSheet() || stylesheets[i]->disabled())
457             continue;
458         m_authorStyle->addRulesFromSheet(static_cast<CSSStyleSheet*>(stylesheets[i].get()), *m_medium, this);
459     }
460     m_authorStyle->shrinkToFit();
461     // FIXME: This really only needs to collect the features from the newly added sheets.
462     m_features.clear();
463     collectFeatures();
464     
465     if (document()->renderer() && document()->renderer()->style())
466         document()->renderer()->style()->font().update(fontSelector());
467 }
468
469 void CSSStyleSelector::addRegionRule(PassRefPtr<WebKitCSSRegionRule> regionStyleRule)
470 {
471     m_regionStyleRules.append(regionStyleRule);
472 }
473
474 // This is a simplified style setting function for keyframe styles
475 void CSSStyleSelector::addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule> rule)
476 {
477     AtomicString s(rule->name());
478     m_keyframesRuleMap.set(s.impl(), rule);
479 }
480
481 CSSStyleSelector::~CSSStyleSelector()
482 {
483     m_fontSelector->clearDocument();
484 }
485
486 void CSSStyleSelector::sweepMatchedDeclarationCache()
487 {
488     // Look for cache entries containing a style declaration with a single ref and remove them.
489     // This may happen when an element attribute mutation causes it to swap out its Attribute::decl()
490     // for another CSSMappedAttributeDeclaration, potentially leaving this cache with the last ref.
491     Vector<unsigned, 16> toRemove;
492     MatchedStyleDeclarationCache::iterator it = m_matchedStyleDeclarationCache.begin();
493     MatchedStyleDeclarationCache::iterator end = m_matchedStyleDeclarationCache.end();
494     for (; it != end; ++it) {
495         Vector<MatchedStyleDeclaration>& matchedStyleDeclarations = it->second.matchedStyleDeclarations;
496         for (size_t i = 0; i < matchedStyleDeclarations.size(); ++i) {
497             if (matchedStyleDeclarations[i].styleDeclaration->hasOneRef()) {
498                 toRemove.append(it->first);
499                 break;
500             }
501         }
502     }
503     for (size_t i = 0; i < toRemove.size(); ++i)
504         m_matchedStyleDeclarationCache.remove(toRemove[i]);
505 }
506
507 CSSStyleSelector::Features::Features()
508     : usesFirstLineRules(false)
509     , usesBeforeAfterRules(false)
510     , usesLinkRules(false)
511 {
512 }
513
514 CSSStyleSelector::Features::~Features()
515 {
516 }
517
518 void CSSStyleSelector::Features::clear()
519 {
520     idsInRules.clear();
521     attrsInRules.clear();
522     siblingRules.clear();
523     uncommonAttributeRules.clear();
524     usesFirstLineRules = false;
525     usesBeforeAfterRules = false;
526     usesLinkRules = false;
527 }
528
529 static CSSStyleSheet* parseUASheet(const String& str)
530 {
531     CSSStyleSheet* sheet = CSSStyleSheet::create().leakRef(); // leak the sheet on purpose
532     sheet->parseString(str);
533     return sheet;
534 }
535
536 static CSSStyleSheet* parseUASheet(const char* characters, unsigned size)
537 {
538     return parseUASheet(String(characters, size));
539 }
540
541 static void loadFullDefaultStyle()
542 {
543     if (simpleDefaultStyleSheet) {
544         ASSERT(defaultStyle);
545         ASSERT(defaultPrintStyle == defaultStyle);
546         delete defaultStyle;
547         simpleDefaultStyleSheet->deref();
548         defaultStyle = new RuleSet;
549         defaultPrintStyle = new RuleSet;
550         simpleDefaultStyleSheet = 0;
551     } else {
552         ASSERT(!defaultStyle);
553         defaultStyle = new RuleSet;
554         defaultPrintStyle = new RuleSet;
555         defaultQuirksStyle = new RuleSet;
556     }
557
558     // Strict-mode rules.
559     String defaultRules = String(htmlUserAgentStyleSheet, sizeof(htmlUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraDefaultStyleSheet();
560     CSSStyleSheet* defaultSheet = parseUASheet(defaultRules);
561     defaultStyle->addRulesFromSheet(defaultSheet, screenEval());
562     defaultPrintStyle->addRulesFromSheet(defaultSheet, printEval());
563
564     // Quirks-mode rules.
565     String quirksRules = String(quirksUserAgentStyleSheet, sizeof(quirksUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraQuirksStyleSheet();
566     CSSStyleSheet* quirksSheet = parseUASheet(quirksRules);
567     defaultQuirksStyle->addRulesFromSheet(quirksSheet, screenEval());
568 }
569
570 static void loadSimpleDefaultStyle()
571 {
572     ASSERT(!defaultStyle);
573     ASSERT(!simpleDefaultStyleSheet);
574
575     defaultStyle = new RuleSet;
576     // There are no media-specific rules in the simple default style.
577     defaultPrintStyle = defaultStyle;
578     defaultQuirksStyle = new RuleSet;
579
580     simpleDefaultStyleSheet = parseUASheet(simpleUserAgentStyleSheet, strlen(simpleUserAgentStyleSheet));
581     defaultStyle->addRulesFromSheet(simpleDefaultStyleSheet, screenEval());
582
583     // No need to initialize quirks sheet yet as there are no quirk rules for elements allowed in simple default style.
584 }
585
586 static void loadViewSourceStyle()
587 {
588     ASSERT(!defaultViewSourceStyle);
589     defaultViewSourceStyle = new RuleSet;
590     defaultViewSourceStyle->addRulesFromSheet(parseUASheet(sourceUserAgentStyleSheet, sizeof(sourceUserAgentStyleSheet)), screenEval());
591 }
592
593 static void ensureDefaultStyleSheetsForElement(Element* element)
594 {
595     if (simpleDefaultStyleSheet && !elementCanUseSimpleDefaultStyle(element)) {
596         loadFullDefaultStyle();
597         assertNoSiblingRulesInDefaultStyle();
598         collectSpecialRulesInDefaultStyle();
599     }
600
601 #if ENABLE(SVG)
602     static bool loadedSVGUserAgentSheet;
603     if (element->isSVGElement() && !loadedSVGUserAgentSheet) {
604         // SVG rules.
605         loadedSVGUserAgentSheet = true;
606         CSSStyleSheet* svgSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet));
607         defaultStyle->addRulesFromSheet(svgSheet, screenEval());
608         defaultPrintStyle->addRulesFromSheet(svgSheet, printEval());
609         assertNoSiblingRulesInDefaultStyle();
610         collectSpecialRulesInDefaultStyle();
611     }
612 #endif
613
614 #if ENABLE(MATHML)
615     static bool loadedMathMLUserAgentSheet;
616     if (element->isMathMLElement() && !loadedMathMLUserAgentSheet) {
617         // MathML rules.
618         loadedMathMLUserAgentSheet = true;
619         CSSStyleSheet* mathMLSheet = parseUASheet(mathmlUserAgentStyleSheet, sizeof(mathmlUserAgentStyleSheet));
620         defaultStyle->addRulesFromSheet(mathMLSheet, screenEval());
621         defaultPrintStyle->addRulesFromSheet(mathMLSheet, printEval());
622         // There are some sibling and uncommon attribute rules here.
623         collectSpecialRulesInDefaultStyle();
624     }
625 #endif
626
627 #if ENABLE(VIDEO)
628     static bool loadedMediaStyleSheet;
629     if (!loadedMediaStyleSheet && (element->hasTagName(videoTag) || element->hasTagName(audioTag))) {
630         loadedMediaStyleSheet = true;
631         String mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + RenderTheme::themeForPage(element->document()->page())->extraMediaControlsStyleSheet();
632         CSSStyleSheet* mediaControlsSheet = parseUASheet(mediaRules);
633         defaultStyle->addRulesFromSheet(mediaControlsSheet, screenEval());
634         defaultPrintStyle->addRulesFromSheet(mediaControlsSheet, printEval());
635         collectSpecialRulesInDefaultStyle();
636     }
637 #endif
638
639 #if ENABLE(FULLSCREEN_API)
640     static bool loadedFullScreenStyleSheet;
641     if (!loadedFullScreenStyleSheet && element->document()->webkitIsFullScreen()) {
642         loadedFullScreenStyleSheet = true;
643         String fullscreenRules = String(fullscreenUserAgentStyleSheet, sizeof(fullscreenUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraFullScreenStyleSheet();
644         CSSStyleSheet* fullscreenSheet = parseUASheet(fullscreenRules);
645         defaultStyle->addRulesFromSheet(fullscreenSheet, screenEval());
646         defaultQuirksStyle->addRulesFromSheet(fullscreenSheet, screenEval());
647         collectSpecialRulesInDefaultStyle();
648     }
649 #endif
650 }
651
652 void CSSStyleSelector::addMatchedDeclaration(CSSMutableStyleDeclaration* styleDeclaration, unsigned linkMatchType)
653 {
654     m_matchedDecls.grow(m_matchedDecls.size() + 1);
655     MatchedStyleDeclaration& newDeclaration = m_matchedDecls.last();
656     newDeclaration.styleDeclaration = styleDeclaration;
657     newDeclaration.linkMatchType = linkMatchType;
658 }
659
660 void CSSStyleSelector::matchRules(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules)
661 {
662     m_matchedRules.clear();
663
664     if (!rules || !m_element)
665         return;
666
667     // We need to collect the rules for id, class, tag, and everything else into a buffer and
668     // then sort the buffer.
669     if (m_element->hasID())
670         matchRulesForList(rules->idRules(m_element->idForStyleResolution().impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
671     if (m_element->hasClass()) {
672         ASSERT(m_styledElement);
673         const SpaceSplitString& classNames = m_styledElement->classNames();
674         size_t size = classNames.size();
675         for (size_t i = 0; i < size; ++i)
676             matchRulesForList(rules->classRules(classNames[i].impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
677     }
678     const AtomicString& pseudoId = m_element->shadowPseudoId();
679     if (!pseudoId.isEmpty()) {
680         ASSERT(m_styledElement);
681         matchRulesForList(rules->shadowPseudoElementRules(pseudoId.impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
682     }
683     if (m_element->isLink())
684         matchRulesForList(rules->linkPseudoClassRules(), firstRuleIndex, lastRuleIndex, includeEmptyRules);
685     if (m_checker.matchesFocusPseudoClass(m_element))
686         matchRulesForList(rules->focusPseudoClassRules(), firstRuleIndex, lastRuleIndex, includeEmptyRules);
687     matchRulesForList(rules->tagRules(m_element->localName().impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);
688     matchRulesForList(rules->universalRules(), firstRuleIndex, lastRuleIndex, includeEmptyRules);
689
690     if (m_matchedRules.isEmpty())
691         return;
692
693     sortMatchedRules();
694
695     if (m_checker.isCollectingRulesOnly()) {
696         if (!m_ruleList)
697             m_ruleList = CSSRuleList::create();
698         for (unsigned i = 0; i < m_matchedRules.size(); ++i)
699             m_ruleList->append(m_matchedRules[i]->rule());
700         return;
701     }
702
703     // Now transfer the set of matched rules over to our list of declarations.
704     // FIXME: This sucks, the inspector should get the style from the visited style itself.
705     bool swapVisitedUnvisited = InspectorInstrumentation::forcePseudoState(m_element, CSSSelector::PseudoVisited);
706     for (unsigned i = 0; i < m_matchedRules.size(); i++) {
707         if (m_style && m_matchedRules[i]->containsUncommonAttributeSelector())
708             m_style->setAffectedByUncommonAttributeSelectors();
709         unsigned linkMatchType = m_matchedRules[i]->linkMatchType();
710         if (swapVisitedUnvisited && linkMatchType && linkMatchType != SelectorChecker::MatchAll)
711             linkMatchType = (linkMatchType == SelectorChecker::MatchVisited) ? SelectorChecker::MatchLink : SelectorChecker::MatchVisited;
712         addMatchedDeclaration(m_matchedRules[i]->rule()->declaration(), linkMatchType);
713     }
714 }
715
716 class MatchingUARulesScope {
717 public:
718     MatchingUARulesScope();
719     ~MatchingUARulesScope();
720
721     static bool isMatchingUARules();
722
723 private:
724     static bool m_matchingUARules;
725 };
726
727 MatchingUARulesScope::MatchingUARulesScope()
728 {
729     ASSERT(!m_matchingUARules);
730     m_matchingUARules = true;
731 }
732
733 MatchingUARulesScope::~MatchingUARulesScope()
734 {
735     m_matchingUARules = false;
736 }
737
738 inline bool MatchingUARulesScope::isMatchingUARules()
739 {
740     return m_matchingUARules;
741 }
742
743 bool MatchingUARulesScope::m_matchingUARules = false;
744
745 inline static bool matchesInTreeScope(TreeScope* treeScope, bool ruleReachesIntoShadowDOM)
746 {
747     return MatchingUARulesScope::isMatchingUARules() || treeScope->applyAuthorSheets() || ruleReachesIntoShadowDOM;
748 }
749
750 void CSSStyleSelector::matchRulesForList(const Vector<RuleData>* rules, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules)
751 {
752     if (!rules)
753         return;
754     // In some cases we may end up looking up style for random elements in the middle of a recursive tree resolve.
755     // Ancestor identifier filter won't be up-to-date in that case and we can't use the fast path.
756     bool canUseFastReject = m_checker.parentStackIsConsistent(m_parentNode);
757
758     unsigned size = rules->size();
759     for (unsigned i = 0; i < size; ++i) {
760         const RuleData& ruleData = rules->at(i);
761         if (canUseFastReject && m_checker.fastRejectSelector<RuleData::maximumIdentifierCount>(ruleData.descendantSelectorIdentifierHashes()))
762             continue;
763
764         CSSStyleRule* rule = ruleData.rule();
765         InspectorInstrumentationCookie cookie = InspectorInstrumentation::willMatchRule(document(), rule);
766         if (checkSelector(ruleData)) {
767             if (!matchesInTreeScope(m_element->treeScope(), m_checker.hasUnknownPseudoElements())) {
768                 InspectorInstrumentation::didMatchRule(cookie, false);
769                 continue;
770             }
771             // If the rule has no properties to apply, then ignore it in the non-debug mode.
772             CSSMutableStyleDeclaration* decl = rule->declaration();
773             if (!decl || (!decl->length() && !includeEmptyRules)) {
774                 InspectorInstrumentation::didMatchRule(cookie, false);
775                 continue;
776             }
777             if (m_sameOriginOnly && !m_checker.document()->securityOrigin()->canRequest(rule->baseURL())) {
778                 InspectorInstrumentation::didMatchRule(cookie, false);
779                 continue;
780             }
781             // If we're matching normal rules, set a pseudo bit if
782             // we really just matched a pseudo-element.
783             if (m_dynamicPseudo != NOPSEUDO && m_checker.pseudoStyle() == NOPSEUDO) {
784                 if (m_checker.isCollectingRulesOnly()) {
785                     InspectorInstrumentation::didMatchRule(cookie, false);
786                     continue;
787                 }
788                 if (m_dynamicPseudo < FIRST_INTERNAL_PSEUDOID)
789                     m_style->setHasPseudoStyle(m_dynamicPseudo);
790             } else {
791                 // Update our first/last rule indices in the matched rules array.
792                 lastRuleIndex = m_matchedDecls.size() + m_matchedRules.size();
793                 if (firstRuleIndex == -1)
794                     firstRuleIndex = lastRuleIndex;
795
796                 // Add this rule to our list of matched rules.
797                 addMatchedRule(&ruleData);
798                 InspectorInstrumentation::didMatchRule(cookie, true);
799                 continue;
800             }
801         }
802         InspectorInstrumentation::didMatchRule(cookie, false);
803     }
804 }
805
806 static inline bool compareRules(const RuleData* r1, const RuleData* r2)
807 {
808     unsigned specificity1 = r1->specificity();
809     unsigned specificity2 = r2->specificity();
810     return (specificity1 == specificity2) ? r1->position() < r2->position() : specificity1 < specificity2;
811 }
812
813 void CSSStyleSelector::sortMatchedRules()
814 {
815     std::sort(m_matchedRules.begin(), m_matchedRules.end(), compareRules);
816 }
817
818 void CSSStyleSelector::matchAllRules(MatchResult& result)
819 {
820     matchUARules(result);
821
822     // Now we check user sheet rules.
823     if (m_matchAuthorAndUserStyles)
824         matchRules(m_userStyle.get(), result.firstUserRule, result.lastUserRule, false);
825         
826     // Now check author rules, beginning first with presentational attributes mapped from HTML.
827     if (m_styledElement) {
828         // Ask if the HTML element has mapped attributes.
829         if (m_styledElement->hasMappedAttributes()) {
830             // Walk our attribute list and add in each decl.
831             const NamedNodeMap* map = m_styledElement->attributeMap();
832             for (unsigned i = 0; i < map->length(); ++i) {
833                 Attribute* attr = map->attributeItem(i);
834                 if (attr->decl()) {
835                     ASSERT(attr->isMappedAttribute());
836                     result.lastAuthorRule = m_matchedDecls.size();
837                     if (result.firstAuthorRule == -1)
838                         result.firstAuthorRule = result.lastAuthorRule;
839                     addMatchedDeclaration(attr->decl());
840                 }
841             }
842         }
843         
844         // Now we check additional mapped declarations.
845         // Tables and table cells share an additional mapped rule that must be applied
846         // after all attributes, since their mapped style depends on the values of multiple attributes.
847         if (m_styledElement->canHaveAdditionalAttributeStyleDecls()) {
848             Vector<CSSMutableStyleDeclaration*> additionalAttributeStyleDecls;
849             m_styledElement->additionalAttributeStyleDecls(additionalAttributeStyleDecls);
850             if (!additionalAttributeStyleDecls.isEmpty()) {
851                 unsigned additionalDeclsSize = additionalAttributeStyleDecls.size();
852                 if (result.firstAuthorRule == -1)
853                     result.firstAuthorRule = m_matchedDecls.size();
854                 result.lastAuthorRule = m_matchedDecls.size() + additionalDeclsSize - 1;
855                 for (unsigned i = 0; i < additionalDeclsSize; ++i)
856                     addMatchedDeclaration(additionalAttributeStyleDecls[i]);
857                 result.isCacheable = false;
858             }
859         }
860         if (m_styledElement->isHTMLElement()) {
861             bool isAuto;
862             TextDirection textDirection = toHTMLElement(m_styledElement)->directionalityIfhasDirAutoAttribute(isAuto);
863             if (isAuto)
864                 addMatchedDeclaration(textDirection == LTR ? leftToRightDeclaration() : rightToLeftDeclaration());
865         }
866     }
867     
868     // Check the rules in author sheets next.
869     if (m_matchAuthorAndUserStyles)
870         matchRules(m_authorStyle.get(), result.firstAuthorRule, result.lastAuthorRule, false);
871
872     // Now check our inline style attribute.
873     if (m_matchAuthorAndUserStyles && m_styledElement) {
874         CSSMutableStyleDeclaration* inlineDecl = m_styledElement->inlineStyleDecl();
875         if (inlineDecl) {
876             result.lastAuthorRule = m_matchedDecls.size();
877             if (result.firstAuthorRule == -1)
878                 result.firstAuthorRule = result.lastAuthorRule;
879             addMatchedDeclaration(inlineDecl);
880             result.isCacheable = false;
881         }
882     }
883 }
884     
885 inline void CSSStyleSelector::initElement(Element* e)
886 {
887     if (m_element != e) {
888         m_element = e;
889         m_styledElement = m_element && m_element->isStyledElement() ? static_cast<StyledElement*>(m_element) : 0;
890         m_elementLinkState = m_checker.determineLinkState(m_element);
891         if (e && e == e->document()->documentElement()) {
892             e->document()->setDirectionSetOnDocumentElement(false);
893             e->document()->setWritingModeSetOnDocumentElement(false);
894         }
895     }
896 }
897
898 inline void CSSStyleSelector::initForStyleResolve(Element* e, RenderStyle* parentStyle, PseudoId pseudoID)
899 {
900     m_checker.setPseudoStyle(pseudoID);
901
902     m_parentNode = e ? e->parentNodeForRenderingAndStyle() : 0;
903
904     if (parentStyle)
905         m_parentStyle = parentStyle;
906     else
907         m_parentStyle = m_parentNode ? m_parentNode->renderStyle() : 0;
908
909     Node* docElement = e ? e->document()->documentElement() : 0;
910     RenderStyle* docStyle = m_checker.document()->renderStyle();
911     m_rootElementStyle = docElement && e != docElement ? docElement->renderStyle() : docStyle;
912
913     m_style = 0;
914
915     m_matchedDecls.clear();
916
917     m_pendingImageProperties.clear();
918
919     m_ruleList = 0;
920
921     m_fontDirty = false;
922 }
923
924 static const unsigned cStyleSearchThreshold = 10;
925 static const unsigned cStyleSearchLevelThreshold = 10;
926
927 Node* CSSStyleSelector::locateCousinList(Element* parent, unsigned& visitedNodeCount) const
928 {
929     if (visitedNodeCount >= cStyleSearchThreshold * cStyleSearchLevelThreshold)
930         return 0;
931     if (!parent || !parent->isStyledElement())
932         return 0;
933     StyledElement* p = static_cast<StyledElement*>(parent);
934     if (p->inlineStyleDecl())
935         return 0;
936     if (p->hasID() && m_features.idsInRules.contains(p->idForStyleResolution().impl()))
937         return 0;
938
939     RenderStyle* parentStyle = p->renderStyle();
940     unsigned subcount = 0;
941     Node* thisCousin = p;
942     Node* currentNode = p->previousSibling();
943
944     // Reserve the tries for this level. This effectively makes sure that the algorithm
945     // will never go deeper than cStyleSearchLevelThreshold levels into recursion.
946     visitedNodeCount += cStyleSearchThreshold;
947     while (thisCousin) {
948         while (currentNode) {
949             ++subcount;
950             if (currentNode->renderStyle() == parentStyle && currentNode->lastChild()) {
951                 // Adjust for unused reserved tries.
952                 visitedNodeCount -= cStyleSearchThreshold - subcount;
953                 return currentNode->lastChild();
954             }
955             if (subcount >= cStyleSearchThreshold)
956                 return 0;
957             currentNode = currentNode->previousSibling();
958         }
959         currentNode = locateCousinList(thisCousin->parentElement(), visitedNodeCount);
960         thisCousin = currentNode;
961     }
962
963     return 0;
964 }
965
966 bool CSSStyleSelector::matchesRuleSet(RuleSet* ruleSet)
967 {
968     int firstSiblingRule = -1, lastSiblingRule = -1;
969     matchRules(ruleSet, firstSiblingRule, lastSiblingRule, false);
970     if (m_matchedDecls.isEmpty())
971         return false;
972     m_matchedDecls.clear();
973     return true;
974 }
975
976 bool CSSStyleSelector::canShareStyleWithControl(StyledElement* element) const
977 {
978 #if ENABLE(PROGRESS_TAG)
979     if (element->hasTagName(progressTag)) {
980         if (!m_element->hasTagName(progressTag))
981             return false;
982
983         HTMLProgressElement* thisProgressElement = static_cast<HTMLProgressElement*>(element);
984         HTMLProgressElement* otherProgressElement = static_cast<HTMLProgressElement*>(m_element);
985         if (thisProgressElement->isDeterminate() != otherProgressElement->isDeterminate())
986             return false;
987
988         return true;
989     }
990 #endif
991
992     HTMLInputElement* thisInputElement = element->toInputElement();
993     HTMLInputElement* otherInputElement = m_element->toInputElement();
994
995     if (!thisInputElement || !otherInputElement)
996         return false;
997
998     if (thisInputElement->isAutofilled() != otherInputElement->isAutofilled())
999         return false;
1000     if (thisInputElement->shouldAppearChecked() != otherInputElement->shouldAppearChecked())
1001         return false;
1002     if (thisInputElement->isIndeterminate() != otherInputElement->isIndeterminate())
1003         return false;
1004     if (thisInputElement->required() != otherInputElement->required())
1005         return false;
1006
1007     if (element->isEnabledFormControl() != m_element->isEnabledFormControl())
1008         return false;
1009
1010     if (element->isDefaultButtonForForm() != m_element->isDefaultButtonForForm())
1011         return false;
1012
1013     if (!m_element->document()->containsValidityStyleRules())
1014         return false;
1015
1016     bool willValidate = element->willValidate();
1017
1018     if (willValidate != m_element->willValidate())
1019         return false;
1020
1021     if (willValidate && (element->isValidFormControlElement() != m_element->isValidFormControlElement()))
1022         return false;
1023
1024     if (element->isInRange() != m_element->isInRange())
1025         return false;
1026
1027     if (element->isOutOfRange() != m_element->isOutOfRange())
1028         return false;
1029
1030     return true;
1031 }
1032
1033 bool CSSStyleSelector::canShareStyleWithElement(StyledElement* element) const
1034 {
1035     RenderStyle* style = element->renderStyle();
1036
1037     if (!style)
1038         return false;
1039     if (style->unique())
1040         return false;
1041     if (element->tagQName() != m_element->tagQName())
1042         return false;
1043     if (element->hasClass() != m_element->hasClass())
1044         return false;
1045     if (element->inlineStyleDecl())
1046         return false;
1047     if (element->hasMappedAttributes() != m_styledElement->hasMappedAttributes())
1048         return false;
1049     if (element->isLink() != m_element->isLink())
1050         return false;
1051     if (style->affectedByUncommonAttributeSelectors())
1052         return false;
1053     if (element->hovered() != m_element->hovered())
1054         return false;
1055     if (element->active() != m_element->active())
1056         return false;
1057     if (element->focused() != m_element->focused())
1058         return false;
1059     if (element->shadowPseudoId() != m_element->shadowPseudoId())
1060         return false;
1061     if (element == element->document()->cssTarget())
1062         return false;
1063     if (m_element == m_element->document()->cssTarget())
1064         return false;
1065     if (element->getAttribute(typeAttr) != m_element->getAttribute(typeAttr))
1066         return false;
1067     if (element->fastGetAttribute(XMLNames::langAttr) != m_element->fastGetAttribute(XMLNames::langAttr))
1068         return false;
1069     if (element->fastGetAttribute(langAttr) != m_element->fastGetAttribute(langAttr))
1070         return false;
1071     if (element->fastGetAttribute(readonlyAttr) != m_element->fastGetAttribute(readonlyAttr))
1072         return false;
1073     if (element->fastGetAttribute(cellpaddingAttr) != m_element->fastGetAttribute(cellpaddingAttr))
1074         return false;
1075
1076     if (element->hasID() && m_features.idsInRules.contains(element->idForStyleResolution().impl()))
1077         return false;
1078
1079     bool isControl = element->isFormControlElement();
1080
1081     if (isControl != m_element->isFormControlElement())
1082         return false;
1083
1084     if (isControl && !canShareStyleWithControl(element))
1085         return false;
1086
1087     if (style->transitions() || style->animations())
1088         return false;
1089
1090 #if USE(ACCELERATED_COMPOSITING)
1091     // Turn off style sharing for elements that can gain layers for reasons outside of the style system.
1092     // See comments in RenderObject::setStyle().
1093     if (element->hasTagName(iframeTag) || element->hasTagName(frameTag) || element->hasTagName(embedTag) || element->hasTagName(objectTag) || element->hasTagName(appletTag)
1094 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1095         // With proxying, the media elements are backed by a RenderEmbeddedObject.
1096         || element->hasTagName(videoTag) || element->hasTagName(audioTag)
1097 #endif
1098         )
1099         return false;
1100 #endif
1101
1102     if (equalIgnoringCase(element->fastGetAttribute(dirAttr), "auto") || equalIgnoringCase(m_element->fastGetAttribute(dirAttr), "auto"))
1103         return false;
1104
1105     if (element->hasClass() && m_element->getAttribute(classAttr) != element->getAttribute(classAttr))
1106         return false;
1107
1108     if (element->hasMappedAttributes() && !element->attributeMap()->mappedMapsEquivalent(m_styledElement->attributeMap()))
1109         return false;
1110
1111     if (element->isLink() && m_elementLinkState != style->insideLink())
1112         return false;
1113
1114     return true;
1115 }
1116
1117 inline StyledElement* CSSStyleSelector::findSiblingForStyleSharing(Node* node, unsigned& count) const
1118 {
1119     for (; node; node = node->previousSibling()) {
1120         if (!node->isStyledElement())
1121             continue;
1122         if (canShareStyleWithElement(static_cast<StyledElement*>(node)))
1123             break;
1124         if (count++ == cStyleSearchThreshold)
1125             return 0;
1126     }
1127     return static_cast<StyledElement*>(node);
1128 }
1129
1130 static inline bool parentStylePreventsSharing(const RenderStyle* parentStyle)
1131 {
1132     return parentStyle->childrenAffectedByPositionalRules()
1133         || parentStyle->childrenAffectedByFirstChildRules()
1134         || parentStyle->childrenAffectedByLastChildRules() 
1135         || parentStyle->childrenAffectedByDirectAdjacentRules();
1136 }
1137
1138 RenderStyle* CSSStyleSelector::locateSharedStyle()
1139 {
1140     if (!m_styledElement || !m_parentStyle)
1141         return 0;
1142     // If the element has inline style it is probably unique.
1143     if (m_styledElement->inlineStyleDecl())
1144         return 0;
1145     // Ids stop style sharing if they show up in the stylesheets.
1146     if (m_styledElement->hasID() && m_features.idsInRules.contains(m_styledElement->idForStyleResolution().impl()))
1147         return 0;
1148     if (parentStylePreventsSharing(m_parentStyle))
1149         return 0;
1150
1151     // Check previous siblings and their cousins.
1152     unsigned count = 0;
1153     unsigned visitedNodeCount = 0;
1154     StyledElement* shareElement = 0;
1155     Node* cousinList = m_styledElement->previousSibling();
1156     while (cousinList) {
1157         shareElement = findSiblingForStyleSharing(cousinList, count);
1158         if (shareElement)
1159             break;
1160         cousinList = locateCousinList(cousinList->parentElement(), visitedNodeCount);
1161     }
1162
1163     // If we have exhausted all our budget or our cousins.
1164     if (!shareElement)
1165         return 0;
1166
1167     // Can't share if sibling rules apply. This is checked at the end as it should rarely fail.
1168     if (matchesRuleSet(m_features.siblingRules.get()))
1169         return 0;
1170     // Can't share if attribute rules apply.
1171     if (matchesRuleSet(m_features.uncommonAttributeRules.get()))
1172         return 0;
1173     // Tracking child index requires unique style for each node. This may get set by the sibling rule match above.
1174     if (parentStylePreventsSharing(m_parentStyle))
1175         return 0;
1176     return shareElement->renderStyle();
1177 }
1178
1179 void CSSStyleSelector::matchUARules(MatchResult& result)
1180 {
1181     MatchingUARulesScope scope;
1182
1183     // First we match rules from the user agent sheet.
1184     if (simpleDefaultStyleSheet)
1185         result.isCacheable = false;
1186     RuleSet* userAgentStyleSheet = m_medium->mediaTypeMatchSpecific("print")
1187         ? defaultPrintStyle : defaultStyle;
1188     matchRules(userAgentStyleSheet, result.firstUARule, result.lastUARule, false);
1189
1190     // In quirks mode, we match rules from the quirks user agent sheet.
1191     if (!m_checker.strictParsing())
1192         matchRules(defaultQuirksStyle, result.firstUARule, result.lastUARule, false);
1193
1194     // If document uses view source styles (in view source mode or in xml viewer mode), then we match rules from the view source style sheet.
1195     if (m_checker.document()->isViewSource()) {
1196         if (!defaultViewSourceStyle)
1197             loadViewSourceStyle();
1198         matchRules(defaultViewSourceStyle, result.firstUARule, result.lastUARule, false);
1199     }
1200 }
1201
1202 PassRefPtr<RenderStyle> CSSStyleSelector::styleForDocument(Document* document, CSSFontSelector* fontSelector)
1203 {
1204     Frame* frame = document->frame();
1205
1206     RefPtr<RenderStyle> documentStyle = RenderStyle::create();
1207     documentStyle->setDisplay(BLOCK);
1208     documentStyle->setRTLOrdering(document->visuallyOrdered() ? VisualOrder : LogicalOrder);
1209     documentStyle->setZoom(frame ? frame->pageZoomFactor() : 1);
1210     documentStyle->setPageScaleTransform(frame ? frame->frameScaleFactor() : 1);
1211     documentStyle->setUserModify(document->inDesignMode() ? READ_WRITE : READ_ONLY);
1212
1213     Element* docElement = document->documentElement();
1214     RenderObject* docElementRenderer = docElement ? docElement->renderer() : 0;
1215     if (docElementRenderer) {
1216         // Use the direction and writing-mode of the body to set the
1217         // viewport's direction and writing-mode unless the property is set on the document element.
1218         // If there is no body, then use the document element.
1219         RenderObject* bodyRenderer = document->body() ? document->body()->renderer() : 0;
1220         if (bodyRenderer && !document->writingModeSetOnDocumentElement())
1221             documentStyle->setWritingMode(bodyRenderer->style()->writingMode());
1222         else
1223             documentStyle->setWritingMode(docElementRenderer->style()->writingMode());
1224         if (bodyRenderer && !document->directionSetOnDocumentElement())
1225             documentStyle->setDirection(bodyRenderer->style()->direction());
1226         else
1227             documentStyle->setDirection(docElementRenderer->style()->direction());
1228     }
1229
1230     if (frame) {
1231         if (Page* page = frame->page()) {
1232             const Page::Pagination& pagination = page->pagination();
1233             if (pagination.mode != Page::Pagination::Unpaginated) {
1234                 documentStyle->setColumnAxis(pagination.mode == Page::Pagination::HorizontallyPaginated ? HorizontalColumnAxis : VerticalColumnAxis);
1235                 documentStyle->setColumnGap(pagination.gap);
1236             }
1237         }
1238     }
1239
1240     FontDescription fontDescription;
1241     fontDescription.setUsePrinterFont(document->printing());
1242     if (Settings* settings = document->settings()) {
1243         fontDescription.setRenderingMode(settings->fontRenderingMode());
1244         const AtomicString& stdfont = settings->standardFontFamily();
1245         if (!stdfont.isEmpty()) {
1246             fontDescription.setGenericFamily(FontDescription::StandardFamily);
1247             fontDescription.firstFamily().setFamily(stdfont);
1248             fontDescription.firstFamily().appendFamily(0);
1249         }
1250         fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
1251         int size = CSSStyleSelector::fontSizeForKeyword(document, CSSValueMedium, false);
1252         fontDescription.setSpecifiedSize(size);
1253         bool useSVGZoomRules = document->isSVGDocument();
1254         fontDescription.setComputedSize(CSSStyleSelector::getComputedSizeFromSpecifiedSize(document, documentStyle.get(), fontDescription.isAbsoluteSize(), size, useSVGZoomRules));
1255     }
1256
1257     documentStyle->setFontDescription(fontDescription);
1258     documentStyle->font().update(fontSelector);
1259
1260     return documentStyle.release();
1261 }
1262
1263 static inline bool isAtShadowBoundary(Element* element)
1264 {
1265     if (!element)
1266         return false;
1267     ContainerNode* parentNode = element->parentNode();
1268     return parentNode && parentNode->isShadowRoot();
1269 }
1270
1271 // If resolveForRootDefault is true, style based on user agent style sheet only. This is used in media queries, where
1272 // relative units are interpreted according to document root element style, styled only with UA stylesheet
1273
1274 PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* element, RenderStyle* defaultParent, bool allowSharing, bool resolveForRootDefault)
1275 {
1276     // Once an element has a renderer, we don't try to destroy it, since otherwise the renderer
1277     // will vanish if a style recalc happens during loading.
1278     if (allowSharing && !element->document()->haveStylesheetsLoaded() && !element->renderer()) {
1279         if (!s_styleNotYetAvailable) {
1280             s_styleNotYetAvailable = RenderStyle::create().leakRef();
1281             s_styleNotYetAvailable->setDisplay(NONE);
1282             s_styleNotYetAvailable->font().update(m_fontSelector);
1283         }
1284         element->document()->setHasNodesWithPlaceholderStyle();
1285         return s_styleNotYetAvailable;
1286     }
1287
1288     initElement(element);
1289     initForStyleResolve(element, defaultParent);
1290     if (allowSharing) {
1291         RenderStyle* sharedStyle = locateSharedStyle();
1292         if (sharedStyle)
1293             return sharedStyle;
1294     }
1295
1296     m_style = RenderStyle::create();
1297
1298     if (m_parentStyle)
1299         m_style->inheritFrom(m_parentStyle);
1300     else {
1301         m_parentStyle = style();
1302         // Make sure our fonts are initialized if we don't inherit them from our parent style.
1303         m_style->font().update(0);
1304     }
1305
1306     // Even if surrounding content is user-editable, shadow DOM should act as a single unit, and not necessarily be editable
1307     if (isAtShadowBoundary(element))
1308         m_style->setUserModify(RenderStyle::initialUserModify());
1309
1310     if (element->isLink()) {
1311         m_style->setIsLink(true);
1312         m_style->setInsideLink(m_elementLinkState);
1313     }
1314
1315     ensureDefaultStyleSheetsForElement(element);
1316
1317     MatchResult matchResult;
1318     if (resolveForRootDefault)
1319         matchUARules(matchResult);
1320     else
1321         matchAllRules(matchResult);
1322
1323     applyMatchedDeclarations(matchResult);
1324
1325     // Clean up our style object's display and text decorations (among other fixups).
1326     adjustRenderStyle(style(), m_parentStyle, element);
1327
1328     initElement(0); // Clear out for the next resolve.
1329
1330     // Now return the style.
1331     return m_style.release();
1332 }
1333
1334 PassRefPtr<RenderStyle> CSSStyleSelector::styleForKeyframe(const RenderStyle* elementStyle, const WebKitCSSKeyframeRule* keyframeRule, KeyframeValue& keyframe)
1335 {
1336     if (keyframeRule->style())
1337         addMatchedDeclaration(keyframeRule->style());
1338
1339     ASSERT(!m_style);
1340
1341     // Create the style
1342     m_style = RenderStyle::clone(elementStyle);
1343
1344     m_lineHeightValue = 0;
1345
1346     // We don't need to bother with !important. Since there is only ever one
1347     // decl, there's nothing to override. So just add the first properties.
1348     bool inheritedOnly = false;
1349     if (keyframeRule->style())
1350         applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1, inheritedOnly);
1351
1352     // If our font got dirtied, go ahead and update it now.
1353     updateFont();
1354
1355     // Line-height is set when we are sure we decided on the font-size
1356     if (m_lineHeightValue)
1357         applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
1358
1359     // Now do rest of the properties.
1360     if (keyframeRule->style())
1361         applyDeclarations<false>(false, 0, m_matchedDecls.size() - 1, inheritedOnly);
1362
1363     // If our font got dirtied by one of the non-essential font props,
1364     // go ahead and update it a second time.
1365     updateFont();
1366
1367     // Start loading images referenced by this style.
1368     loadPendingImages();
1369     
1370 #if ENABLE(CSS_SHADERS)
1371     // Start loading the shaders referenced by this style.
1372     loadPendingShaders();
1373 #endif
1374
1375     // Add all the animating properties to the keyframe.
1376     if (keyframeRule->style()) {
1377         CSSMutableStyleDeclaration::const_iterator end = keyframeRule->style()->end();
1378         for (CSSMutableStyleDeclaration::const_iterator it = keyframeRule->style()->begin(); it != end; ++it) {
1379             int property = (*it).id();
1380             // Timing-function within keyframes is special, because it is not animated; it just
1381             // describes the timing function between this keyframe and the next.
1382             if (property != CSSPropertyWebkitAnimationTimingFunction)
1383                 keyframe.addProperty(property);
1384         }
1385     }
1386
1387     return m_style.release();
1388 }
1389
1390 void CSSStyleSelector::keyframeStylesForAnimation(Element* e, const RenderStyle* elementStyle, KeyframeList& list)
1391 {
1392     list.clear();
1393
1394     // Get the keyframesRule for this name
1395     if (!e || list.animationName().isEmpty())
1396         return;
1397
1398     m_keyframesRuleMap.checkConsistency();
1399
1400     KeyframesRuleMap::iterator it = m_keyframesRuleMap.find(list.animationName().impl());
1401     if (it == m_keyframesRuleMap.end())
1402         return;
1403
1404     const WebKitCSSKeyframesRule* rule = it->second.get();
1405
1406     // Construct and populate the style for each keyframe
1407     for (unsigned i = 0; i < rule->length(); ++i) {
1408         // Apply the declaration to the style. This is a simplified version of the logic in styleForElement
1409         initElement(e);
1410         initForStyleResolve(e);
1411
1412         const WebKitCSSKeyframeRule* keyframeRule = rule->item(i);
1413
1414         KeyframeValue keyframe(0, 0);
1415         keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule, keyframe));
1416
1417         // Add this keyframe style to all the indicated key times
1418         Vector<float> keys;
1419         keyframeRule->getKeys(keys);
1420         for (size_t keyIndex = 0; keyIndex < keys.size(); ++keyIndex) {
1421             keyframe.setKey(keys[keyIndex]);
1422             list.insert(keyframe);
1423         }
1424     }
1425
1426     // If the 0% keyframe is missing, create it (but only if there is at least one other keyframe)
1427     int initialListSize = list.size();
1428     if (initialListSize > 0 && list[0].key() != 0) {
1429         RefPtr<WebKitCSSKeyframeRule> keyframeRule = WebKitCSSKeyframeRule::create();
1430         keyframeRule->setKeyText("0%");
1431         KeyframeValue keyframe(0, 0);
1432         keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule.get(), keyframe));
1433         list.insert(keyframe);
1434     }
1435
1436     // If the 100% keyframe is missing, create it (but only if there is at least one other keyframe)
1437     if (initialListSize > 0 && (list[list.size() - 1].key() != 1)) {
1438         RefPtr<WebKitCSSKeyframeRule> keyframeRule = WebKitCSSKeyframeRule::create();
1439         keyframeRule->setKeyText("100%");
1440         KeyframeValue keyframe(1, 0);
1441         keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule.get(), keyframe));
1442         list.insert(keyframe);
1443     }
1444 }
1445
1446 PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(PseudoId pseudo, Element* e, RenderStyle* parentStyle)
1447 {
1448     if (!e)
1449         return 0;
1450
1451     initElement(e);
1452
1453     initForStyleResolve(e, parentStyle, pseudo);
1454     m_style = RenderStyle::create();
1455
1456     if (m_parentStyle)
1457         m_style->inheritFrom(m_parentStyle);
1458
1459     // Since we don't use pseudo-elements in any of our quirk/print user agent rules, don't waste time walking
1460     // those rules.
1461
1462     // Check UA, user and author rules.
1463     MatchResult matchResult;
1464     matchUARules(matchResult);
1465
1466     if (m_matchAuthorAndUserStyles) {
1467         matchRules(m_userStyle.get(), matchResult.firstUserRule, matchResult.lastUserRule, false);
1468         matchRules(m_authorStyle.get(), matchResult.firstAuthorRule, matchResult.lastAuthorRule, false);
1469     }
1470
1471     if (m_matchedDecls.isEmpty())
1472         return 0;
1473
1474     m_style->setStyleType(pseudo);
1475
1476     applyMatchedDeclarations(matchResult);
1477
1478     // Clean up our style object's display and text decorations (among other fixups).
1479     adjustRenderStyle(style(), parentStyle, 0);
1480
1481     // Start loading images referenced by this style.
1482     loadPendingImages();
1483
1484 #if ENABLE(CSS_SHADERS)
1485     // Start loading the shaders referenced by this style.
1486     loadPendingShaders();
1487 #endif
1488
1489     // Now return the style.
1490     return m_style.release();
1491 }
1492
1493 PassRefPtr<RenderStyle> CSSStyleSelector::styleForPage(int pageIndex)
1494 {
1495     initForStyleResolve(m_checker.document()->documentElement()); // m_rootElementStyle will be set to the document style.
1496
1497     m_style = RenderStyle::create();
1498     m_style->inheritFrom(m_rootElementStyle);
1499
1500     const bool isLeft = isLeftPage(pageIndex);
1501     const bool isFirst = isFirstPage(pageIndex);
1502     const String page = pageName(pageIndex);
1503     matchPageRules(defaultPrintStyle, isLeft, isFirst, page);
1504     matchPageRules(m_userStyle.get(), isLeft, isFirst, page);
1505     matchPageRules(m_authorStyle.get(), isLeft, isFirst, page);
1506     m_lineHeightValue = 0;
1507     bool inheritedOnly = false;
1508     applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1, inheritedOnly);
1509
1510     // If our font got dirtied, go ahead and update it now.
1511     updateFont();
1512
1513     // Line-height is set when we are sure we decided on the font-size.
1514     if (m_lineHeightValue)
1515         applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
1516
1517     applyDeclarations<false>(false, 0, m_matchedDecls.size() - 1, inheritedOnly);
1518
1519     // Start loading images referenced by this style.
1520     loadPendingImages();
1521
1522 #if ENABLE(CSS_SHADERS)
1523     // Start loading the shaders referenced by this style.
1524     loadPendingShaders();
1525 #endif
1526
1527     // Now return the style.
1528     return m_style.release();
1529 }
1530
1531 static void addIntrinsicMargins(RenderStyle* style)
1532 {
1533     // Intrinsic margin value.
1534     const int intrinsicMargin = 2 * style->effectiveZoom();
1535
1536     // FIXME: Using width/height alone and not also dealing with min-width/max-width is flawed.
1537     // FIXME: Using "quirk" to decide the margin wasn't set is kind of lame.
1538     if (style->width().isIntrinsicOrAuto()) {
1539         if (style->marginLeft().quirk())
1540             style->setMarginLeft(Length(intrinsicMargin, Fixed));
1541         if (style->marginRight().quirk())
1542             style->setMarginRight(Length(intrinsicMargin, Fixed));
1543     }
1544
1545     if (style->height().isAuto()) {
1546         if (style->marginTop().quirk())
1547             style->setMarginTop(Length(intrinsicMargin, Fixed));
1548         if (style->marginBottom().quirk())
1549             style->setMarginBottom(Length(intrinsicMargin, Fixed));
1550     }
1551 }
1552
1553 void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, RenderStyle* parentStyle, Element *e)
1554 {
1555     // Cache our original display.
1556     style->setOriginalDisplay(style->display());
1557
1558     if (style->display() != NONE) {
1559         // If we have a <td> that specifies a float property, in quirks mode we just drop the float
1560         // property.
1561         // Sites also commonly use display:inline/block on <td>s and <table>s.  In quirks mode we force
1562         // these tags to retain their display types.
1563         if (!m_checker.strictParsing() && e) {
1564             if (e->hasTagName(tdTag)) {
1565                 style->setDisplay(TABLE_CELL);
1566                 style->setFloating(NoFloat);
1567             }
1568             else if (e->hasTagName(tableTag))
1569                 style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE);
1570         }
1571
1572         if (e && (e->hasTagName(tdTag) || e->hasTagName(thTag))) {
1573             if (style->whiteSpace() == KHTML_NOWRAP) {
1574                 // Figure out if we are really nowrapping or if we should just
1575                 // use normal instead.  If the width of the cell is fixed, then
1576                 // we don't actually use NOWRAP.
1577                 if (style->width().isFixed())
1578                     style->setWhiteSpace(NORMAL);
1579                 else
1580                     style->setWhiteSpace(NOWRAP);
1581             }
1582         }
1583
1584         // Tables never support the -webkit-* values for text-align and will reset back to the default.
1585         if (e && e->hasTagName(tableTag) && (style->textAlign() == WEBKIT_LEFT || style->textAlign() == WEBKIT_CENTER || style->textAlign() == WEBKIT_RIGHT))
1586             style->setTextAlign(TAAUTO);
1587
1588         // Frames and framesets never honor position:relative or position:absolute.  This is necessary to
1589         // fix a crash where a site tries to position these objects.  They also never honor display.
1590         if (e && (e->hasTagName(frameTag) || e->hasTagName(framesetTag))) {
1591             style->setPosition(StaticPosition);
1592             style->setDisplay(BLOCK);
1593         }
1594
1595         // Table headers with a text-align of auto will change the text-align to center.
1596         if (e && e->hasTagName(thTag) && style->textAlign() == TAAUTO)
1597             style->setTextAlign(CENTER);
1598
1599         if (e && e->hasTagName(legendTag))
1600             style->setDisplay(BLOCK);
1601
1602         // Mutate the display to BLOCK or TABLE for certain cases, e.g., if someone attempts to
1603         // position or float an inline, compact, or run-in.  Cache the original display, since it
1604         // may be needed for positioned elements that have to compute their static normal flow
1605         // positions.  We also force inline-level roots to be block-level.
1606         if (style->display() != BLOCK && style->display() != TABLE && style->display() != BOX &&
1607             (style->position() == AbsolutePosition || style->position() == FixedPosition || style->isFloating() ||
1608              (e && e->document()->documentElement() == e))) {
1609             if (style->display() == INLINE_TABLE)
1610                 style->setDisplay(TABLE);
1611             else if (style->display() == INLINE_BOX)
1612                 style->setDisplay(BOX);
1613             else if (style->display() == LIST_ITEM) {
1614                 // It is a WinIE bug that floated list items lose their bullets, so we'll emulate the quirk,
1615                 // but only in quirks mode.
1616                 if (!m_checker.strictParsing() && style->isFloating())
1617                     style->setDisplay(BLOCK);
1618             }
1619             else
1620                 style->setDisplay(BLOCK);
1621         }
1622
1623         // FIXME: Don't support this mutation for pseudo styles like first-letter or first-line, since it's not completely
1624         // clear how that should work.
1625         if (style->display() == INLINE && style->styleType() == NOPSEUDO && parentStyle && style->writingMode() != parentStyle->writingMode())
1626             style->setDisplay(INLINE_BLOCK);
1627
1628         // After performing the display mutation, check table rows.  We do not honor position:relative on
1629         // table rows or cells.  This has been established in CSS2.1 (and caused a crash in containingBlock()
1630         // on some sites).
1631         if ((style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW_GROUP
1632              || style->display() == TABLE_FOOTER_GROUP || style->display() == TABLE_ROW) &&
1633              style->position() == RelativePosition)
1634             style->setPosition(StaticPosition);
1635
1636         // writing-mode does not apply to table row groups, table column groups, table rows, and table columns.
1637         // FIXME: Table cells should be allowed to be perpendicular or flipped with respect to the table, though.
1638         if (style->display() == TABLE_COLUMN || style->display() == TABLE_COLUMN_GROUP || style->display() == TABLE_FOOTER_GROUP
1639             || style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW || style->display() == TABLE_ROW_GROUP
1640             || style->display() == TABLE_CELL)
1641             style->setWritingMode(parentStyle->writingMode());
1642
1643         // FIXME: Since we don't support block-flow on flexible boxes yet, disallow setting
1644         // of block-flow to anything other than TopToBottomWritingMode.
1645         // https://bugs.webkit.org/show_bug.cgi?id=46418 - Flexible box support.
1646         if (style->writingMode() != TopToBottomWritingMode && (style->display() == BOX || style->display() == INLINE_BOX))
1647             style->setWritingMode(TopToBottomWritingMode);
1648     }
1649
1650     // Make sure our z-index value is only applied if the object is positioned.
1651     if (style->position() == StaticPosition)
1652         style->setHasAutoZIndex();
1653
1654     // Auto z-index becomes 0 for the root element and transparent objects.  This prevents
1655     // cases where objects that should be blended as a single unit end up with a non-transparent
1656     // object wedged in between them.  Auto z-index also becomes 0 for objects that specify transforms/masks/reflections.
1657     if (style->hasAutoZIndex() && ((e && e->document()->documentElement() == e) || style->opacity() < 1.0f
1658         || style->hasTransformRelatedProperty() || style->hasMask() || style->boxReflect() || style->hasFilter()))
1659         style->setZIndex(0);
1660
1661     // Textarea considers overflow visible as auto.
1662     if (e && e->hasTagName(textareaTag)) {
1663         style->setOverflowX(style->overflowX() == OVISIBLE ? OAUTO : style->overflowX());
1664         style->setOverflowY(style->overflowY() == OVISIBLE ? OAUTO : style->overflowY());
1665     }
1666
1667     // Finally update our text decorations in effect, but don't allow text-decoration to percolate through
1668     // tables, inline blocks, inline tables, run-ins, or shadow DOM.
1669     if (style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN
1670         || style->display() == INLINE_BLOCK || style->display() == INLINE_BOX || isAtShadowBoundary(e))
1671         style->setTextDecorationsInEffect(style->textDecoration());
1672     else
1673         style->addToTextDecorationsInEffect(style->textDecoration());
1674
1675     // If either overflow value is not visible, change to auto.
1676     if (style->overflowX() == OMARQUEE && style->overflowY() != OMARQUEE)
1677         style->setOverflowY(OMARQUEE);
1678     else if (style->overflowY() == OMARQUEE && style->overflowX() != OMARQUEE)
1679         style->setOverflowX(OMARQUEE);
1680     else if (style->overflowX() == OVISIBLE && style->overflowY() != OVISIBLE)
1681         style->setOverflowX(OAUTO);
1682     else if (style->overflowY() == OVISIBLE && style->overflowX() != OVISIBLE)
1683         style->setOverflowY(OAUTO);
1684
1685     // Table rows, sections and the table itself will support overflow:hidden and will ignore scroll/auto.
1686     // FIXME: Eventually table sections will support auto and scroll.
1687     if (style->display() == TABLE || style->display() == INLINE_TABLE ||
1688         style->display() == TABLE_ROW_GROUP || style->display() == TABLE_ROW) {
1689         if (style->overflowX() != OVISIBLE && style->overflowX() != OHIDDEN)
1690             style->setOverflowX(OVISIBLE);
1691         if (style->overflowY() != OVISIBLE && style->overflowY() != OHIDDEN)
1692             style->setOverflowY(OVISIBLE);
1693     }
1694
1695     // Menulists should have visible overflow
1696     if (style->appearance() == MenulistPart) {
1697         style->setOverflowX(OVISIBLE);
1698         style->setOverflowY(OVISIBLE);
1699     }
1700
1701     // Cull out any useless layers and also repeat patterns into additional layers.
1702     style->adjustBackgroundLayers();
1703     style->adjustMaskLayers();
1704
1705     // Do the same for animations and transitions.
1706     style->adjustAnimations();
1707     style->adjustTransitions();
1708
1709     // Important: Intrinsic margins get added to controls before the theme has adjusted the style, since the theme will
1710     // alter fonts and heights/widths.
1711     if (e && e->isFormControlElement() && style->fontSize() >= 11) {
1712         // Don't apply intrinsic margins to image buttons.  The designer knows how big the images are,
1713         // so we have to treat all image buttons as though they were explicitly sized.
1714         if (!e->hasTagName(inputTag) || !static_cast<HTMLInputElement*>(e)->isImageButton())
1715             addIntrinsicMargins(style);
1716     }
1717
1718     // Let the theme also have a crack at adjusting the style.
1719     if (style->hasAppearance())
1720         RenderTheme::defaultTheme()->adjustStyle(this, style, e, m_hasUAAppearance, m_borderData, m_backgroundData, m_backgroundColor);
1721
1722     // If we have first-letter pseudo style, do not share this style.
1723     if (style->hasPseudoStyle(FIRST_LETTER))
1724         style->setUnique();
1725
1726 #if ENABLE(SVG)
1727     if (e && e->isSVGElement()) {
1728         // Spec: http://www.w3.org/TR/SVG/masking.html#OverflowProperty
1729         if (style->overflowY() == OSCROLL)
1730             style->setOverflowY(OHIDDEN);
1731         else if (style->overflowY() == OAUTO)
1732             style->setOverflowY(OVISIBLE);
1733
1734         if (style->overflowX() == OSCROLL)
1735             style->setOverflowX(OHIDDEN);
1736         else if (style->overflowX() == OAUTO)
1737             style->setOverflowX(OVISIBLE);
1738
1739         // Only the root <svg> element in an SVG document fragment tree honors css position
1740         if (!(e->hasTagName(SVGNames::svgTag) && e->parentNode() && !e->parentNode()->isSVGElement()))
1741             style->setPosition(RenderStyle::initialPosition());
1742     }
1743 #endif
1744 }
1745
1746 bool CSSStyleSelector::checkRegionStyle(Element* e)
1747 {
1748     m_checker.clearHasUnknownPseudoElements();
1749     m_checker.setPseudoStyle(NOPSEUDO);
1750
1751     for (Vector<RefPtr<WebKitCSSRegionRule> >::iterator it = m_regionStyleRules.begin(); it != m_regionStyleRules.end(); ++it) {
1752         const CSSSelectorList& regionSelectorList = (*it)->selectorList();
1753         for (CSSSelector* s = regionSelectorList.first(); s; s = regionSelectorList.next(s)) {
1754             if (m_checker.checkSelector(s, e))
1755                 return true;
1756         }
1757     }
1758
1759     return false;
1760 }
1761
1762 void CSSStyleSelector::updateFont()
1763 {
1764     if (!m_fontDirty)
1765         return;
1766
1767     checkForTextSizeAdjust();
1768     checkForGenericFamilyChange(style(), m_parentStyle);
1769     checkForZoomChange(style(), m_parentStyle);
1770     m_style->font().update(m_fontSelector);
1771     m_fontDirty = false;
1772 }
1773
1774 void CSSStyleSelector::cacheBorderAndBackground()
1775 {
1776     m_hasUAAppearance = m_style->hasAppearance();
1777     if (m_hasUAAppearance) {
1778         m_borderData = m_style->border();
1779         m_backgroundData = *m_style->backgroundLayers();
1780         m_backgroundColor = m_style->backgroundColor();
1781     }
1782 }
1783
1784 PassRefPtr<CSSRuleList> CSSStyleSelector::styleRulesForElement(Element* e, unsigned rulesToInclude)
1785 {
1786     return pseudoStyleRulesForElement(e, NOPSEUDO, rulesToInclude);
1787 }
1788
1789 PassRefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element* e, PseudoId pseudoId, unsigned rulesToInclude)
1790 {
1791     if (!e || !e->document()->haveStylesheetsLoaded())
1792         return 0;
1793
1794     m_checker.setCollectingRulesOnly(true);
1795
1796     initElement(e);
1797     initForStyleResolve(e, 0, pseudoId);
1798
1799     MatchResult dummy;
1800     if (rulesToInclude & UAAndUserCSSRules) {
1801         // First we match rules from the user agent sheet.
1802         matchUARules(dummy);
1803
1804         // Now we check user sheet rules.
1805         if (m_matchAuthorAndUserStyles)
1806             matchRules(m_userStyle.get(), dummy.firstUserRule, dummy.lastUserRule, rulesToInclude & EmptyCSSRules);
1807     }
1808
1809     if (m_matchAuthorAndUserStyles && (rulesToInclude & AuthorCSSRules)) {
1810         m_sameOriginOnly = !(rulesToInclude & CrossOriginCSSRules);
1811
1812         // Check the rules in author sheets.
1813         matchRules(m_authorStyle.get(), dummy.firstAuthorRule, dummy.lastAuthorRule, rulesToInclude & EmptyCSSRules);
1814
1815         m_sameOriginOnly = false;
1816     }
1817
1818     m_checker.setCollectingRulesOnly(false);
1819
1820     return m_ruleList.release();
1821 }
1822
1823 inline bool CSSStyleSelector::checkSelector(const RuleData& ruleData)
1824 {
1825     m_dynamicPseudo = NOPSEUDO;
1826     m_checker.clearHasUnknownPseudoElements();
1827
1828     // Let the slow path handle SVG as it has some additional rules regarding shadow trees.
1829     if (ruleData.hasFastCheckableSelector() && !m_element->isSVGElement()) {
1830         // We know this selector does not include any pseudo elements.
1831         if (m_checker.pseudoStyle() != NOPSEUDO)
1832             return false;
1833         // We know a sufficiently simple single part selector matches simply because we found it from the rule hash.
1834         // This is limited to HTML only so we don't need to check the namespace.
1835         if (ruleData.hasRightmostSelectorMatchingHTMLBasedOnRuleHash() && m_element->isHTMLElement()) {
1836             if (!ruleData.hasMultipartSelector())
1837                 return true;
1838         } else if (!SelectorChecker::tagMatches(m_element, ruleData.selector()))
1839             return false;
1840         if (!SelectorChecker::fastCheckRightmostAttributeSelector(m_element, ruleData.selector()))
1841             return false;
1842         return m_checker.fastCheckSelector(ruleData.selector(), m_element);
1843     }
1844
1845     // Slow path.
1846     SelectorChecker::SelectorMatch match = m_checker.checkSelector(ruleData.selector(), m_element, m_dynamicPseudo, false, SelectorChecker::VisitedMatchEnabled, style(), m_parentNode ? m_parentNode->renderStyle() : 0);
1847     if (match != SelectorChecker::SelectorMatches)
1848         return false;
1849     if (m_checker.pseudoStyle() != NOPSEUDO && m_checker.pseudoStyle() != m_dynamicPseudo)
1850         return false;
1851     return true;
1852 }
1853     
1854 bool CSSStyleSelector::determineStylesheetSelectorScopes(CSSStyleSheet* stylesheet, HashSet<AtomicStringImpl*>& idScopes, HashSet<AtomicStringImpl*>& classScopes)
1855 {
1856     ASSERT(!stylesheet->isLoading());
1857     
1858     size_t size = stylesheet->length();
1859     for (size_t i = 0; i < size; i++) {
1860         CSSRule* rule = stylesheet->item(i);
1861         if (rule->isStyleRule()) {
1862             CSSStyleRule* styleRule = static_cast<CSSStyleRule*>(rule);
1863             if (!SelectorChecker::determineSelectorScopes(styleRule->selectorList(), idScopes, classScopes))
1864                 return false;
1865             continue;
1866         } 
1867         if (rule->isImportRule()) {
1868             CSSImportRule* importRule = static_cast<CSSImportRule*>(rule);
1869             if (importRule->styleSheet()) {
1870                 if (!determineStylesheetSelectorScopes(importRule->styleSheet(), idScopes, classScopes))
1871                     return false;
1872             }
1873             continue;
1874         }
1875         // FIXME: Media rules and maybe some others could be allowed.
1876         return false;
1877     }
1878     return true;
1879 }
1880
1881 // -----------------------------------------------------------------
1882
1883 static inline bool isSelectorMatchingHTMLBasedOnRuleHash(const CSSSelector* selector)
1884 {
1885     const AtomicString& selectorNamespace = selector->tag().namespaceURI();
1886     if (selectorNamespace != starAtom && selectorNamespace != xhtmlNamespaceURI)
1887         return false;
1888     if (selector->m_match == CSSSelector::None)
1889         return true;
1890     if (selector->tag() != starAtom)
1891         return false;
1892     if (SelectorChecker::isCommonPseudoClassSelector(selector))
1893         return true;
1894     return selector->m_match == CSSSelector::Id || selector->m_match == CSSSelector::Class;
1895 }
1896
1897 static inline bool selectorListContainsUncommonAttributeSelector(const CSSSelector* selector)
1898 {
1899     CSSSelectorList* selectorList = selector->selectorList();
1900     if (!selectorList)
1901         return false;
1902     for (CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
1903         if (subSelector->isAttributeSelector())
1904             return true;
1905     }
1906     return false;
1907 }
1908
1909 static inline bool isCommonAttributeSelectorAttribute(const QualifiedName& attribute)
1910 {
1911     // These are explicitly tested for equality in canShareStyleWithElement.
1912     return attribute == typeAttr || attribute == readonlyAttr;
1913 }
1914
1915 static inline bool containsUncommonAttributeSelector(const CSSSelector* selector)
1916 {
1917     while (selector) {
1918         // Allow certain common attributes (used in the default style) in the selectors that match the current element.
1919         if (selector->isAttributeSelector() && !isCommonAttributeSelectorAttribute(selector->attribute()))
1920             return true;
1921         if (selectorListContainsUncommonAttributeSelector(selector))
1922             return true;
1923         if (selector->relation() != CSSSelector::SubSelector)
1924             break;
1925         selector = selector->tagHistory();
1926     };
1927
1928     for (selector = selector->tagHistory(); selector; selector = selector->tagHistory()) {
1929         if (selector->isAttributeSelector())
1930             return true;
1931         if (selectorListContainsUncommonAttributeSelector(selector))
1932             return true;
1933     }
1934     return false;
1935 }
1936
1937 RuleData::RuleData(CSSStyleRule* rule, CSSSelector* selector, unsigned position)
1938     : m_rule(rule)
1939     , m_selector(selector)
1940     , m_specificity(selector->specificity())
1941     , m_position(position)
1942     , m_hasFastCheckableSelector(SelectorChecker::isFastCheckableSelector(selector))
1943     , m_hasMultipartSelector(!!selector->tagHistory())
1944     , m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash(isSelectorMatchingHTMLBasedOnRuleHash(selector))
1945     , m_containsUncommonAttributeSelector(WebCore::containsUncommonAttributeSelector(selector))
1946     , m_linkMatchType(SelectorChecker::determineLinkMatchType(selector))
1947 {
1948     SelectorChecker::collectIdentifierHashes(m_selector, m_descendantSelectorIdentifierHashes, maximumIdentifierCount);
1949 }
1950
1951 RuleSet::RuleSet()
1952     : m_ruleCount(0)
1953     , m_autoShrinkToFitEnabled(true)
1954 {
1955 }
1956
1957 void RuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map, CSSStyleRule* rule, CSSSelector* selector)
1958 {
1959     if (!key)
1960         return;
1961     OwnPtr<Vector<RuleData> >& rules = map.add(key, nullptr).first->second;
1962     if (!rules)
1963         rules = adoptPtr(new Vector<RuleData>);
1964     rules->append(RuleData(rule, selector, m_ruleCount++));
1965 }
1966
1967 void RuleSet::addRule(CSSStyleRule* rule, CSSSelector* sel)
1968 {
1969     if (sel->m_match == CSSSelector::Id) {
1970         addToRuleSet(sel->value().impl(), m_idRules, rule, sel);
1971         return;
1972     }
1973     if (sel->m_match == CSSSelector::Class) {
1974         addToRuleSet(sel->value().impl(), m_classRules, rule, sel);
1975         return;
1976     }
1977     if (sel->isUnknownPseudoElement()) {
1978         addToRuleSet(sel->value().impl(), m_shadowPseudoElementRules, rule, sel);
1979         return;
1980     }
1981     if (SelectorChecker::isCommonPseudoClassSelector(sel)) {
1982         RuleData ruleData(rule, sel, m_ruleCount++);
1983         switch (sel->pseudoType()) {
1984         case CSSSelector::PseudoLink:
1985         case CSSSelector::PseudoVisited:
1986         case CSSSelector::PseudoAnyLink:
1987             m_linkPseudoClassRules.append(ruleData);
1988             return;
1989         case CSSSelector::PseudoFocus:
1990             m_focusPseudoClassRules.append(ruleData);
1991             return;
1992         default:
1993             ASSERT_NOT_REACHED();
1994         }
1995         return;
1996     }
1997     const AtomicString& localName = sel->tag().localName();
1998     if (localName != starAtom) {
1999         addToRuleSet(localName.impl(), m_tagRules, rule, sel);
2000         return;
2001     }
2002
2003     m_universalRules.append(RuleData(rule, sel, m_ruleCount++));
2004 }
2005
2006 void RuleSet::addPageRule(CSSPageRule* rule)
2007 {
2008     m_pageRules.append(RuleData(rule, rule->selectorList().first(), m_pageRules.size()));
2009 }
2010
2011 void RuleSet::addRulesFromSheet(CSSStyleSheet* sheet, const MediaQueryEvaluator& medium, CSSStyleSelector* styleSelector)
2012 {
2013     ASSERT(sheet);
2014
2015     // No media implies "all", but if a media list exists it must
2016     // contain our current medium
2017     if (sheet->media() && !medium.eval(sheet->media(), styleSelector))
2018         return; // the style sheet doesn't apply
2019
2020     int len = sheet->length();
2021
2022     for (int i = 0; i < len; i++) {
2023         CSSRule* rule = sheet->item(i);
2024         if (rule->isStyleRule())
2025             addStyleRule(static_cast<CSSStyleRule*>(rule));
2026         else if (rule->isPageRule())
2027             addPageRule(static_cast<CSSPageRule*>(rule));
2028         else if (rule->isImportRule()) {
2029             CSSImportRule* import = static_cast<CSSImportRule*>(rule);
2030             if (import->styleSheet() && (!import->media() || medium.eval(import->media(), styleSelector)))
2031                 addRulesFromSheet(import->styleSheet(), medium, styleSelector);
2032         }
2033         else if (rule->isMediaRule()) {
2034             CSSMediaRule* r = static_cast<CSSMediaRule*>(rule);
2035             CSSRuleList* rules = r->cssRules();
2036
2037             if ((!r->media() || medium.eval(r->media(), styleSelector)) && rules) {
2038                 // Traverse child elements of the @media rule.
2039                 for (unsigned j = 0; j < rules->length(); j++) {
2040                     CSSRule *childItem = rules->item(j);
2041                     if (childItem->isStyleRule())
2042                         addStyleRule(static_cast<CSSStyleRule*>(childItem));
2043                     else if (childItem->isPageRule())
2044                         addPageRule(static_cast<CSSPageRule*>(childItem));
2045                     else if (childItem->isFontFaceRule() && styleSelector) {
2046                         // Add this font face to our set.
2047                         const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(childItem);
2048                         styleSelector->fontSelector()->addFontFaceRule(fontFaceRule);
2049                         styleSelector->invalidateMatchedDeclarationCache();
2050                     } else if (childItem->isKeyframesRule() && styleSelector) {
2051                         // Add this keyframe rule to our set.
2052                         styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(childItem));
2053                     }
2054                 }   // for rules
2055             }   // if rules
2056         } else if (rule->isFontFaceRule() && styleSelector) {
2057             // Add this font face to our set.
2058             const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(rule);
2059             styleSelector->fontSelector()->addFontFaceRule(fontFaceRule);
2060             styleSelector->invalidateMatchedDeclarationCache();
2061         } else if (rule->isKeyframesRule())
2062             styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(rule));
2063         else if (rule->isRegionRule() && styleSelector)
2064             styleSelector->addRegionRule(static_cast<WebKitCSSRegionRule*>(rule));
2065     }
2066     if (m_autoShrinkToFitEnabled)
2067         shrinkToFit();
2068 }
2069
2070 void RuleSet::addStyleRule(CSSStyleRule* rule)
2071 {
2072     for (CSSSelector* s = rule->selectorList().first(); s; s = CSSSelectorList::next(s))
2073         addRule(rule, s);
2074 }
2075
2076 static inline void collectFeaturesFromSelector(CSSStyleSelector::Features& features, const CSSSelector* selector)
2077 {
2078     if (selector->m_match == CSSSelector::Id && !selector->value().isEmpty())
2079         features.idsInRules.add(selector->value().impl());
2080     if (selector->isAttributeSelector())
2081         features.attrsInRules.add(selector->attribute().localName().impl());
2082     switch (selector->pseudoType()) {
2083     case CSSSelector::PseudoFirstLine:
2084         features.usesFirstLineRules = true;
2085         break;
2086     case CSSSelector::PseudoBefore:
2087     case CSSSelector::PseudoAfter:
2088         features.usesBeforeAfterRules = true;
2089         break;
2090     case CSSSelector::PseudoLink:
2091     case CSSSelector::PseudoVisited:
2092         features.usesLinkRules = true;
2093         break;
2094     default:
2095         break;
2096     }
2097 }
2098
2099 static void collectFeaturesFromList(CSSStyleSelector::Features& features, const Vector<RuleData>& rules)
2100 {
2101     unsigned size = rules.size();
2102     for (unsigned i = 0; i < size; ++i) {
2103         const RuleData& ruleData = rules[i];
2104         bool foundSiblingSelector = false;
2105         for (CSSSelector* selector = ruleData.selector(); selector; selector = selector->tagHistory()) {
2106             collectFeaturesFromSelector(features, selector);
2107
2108             if (CSSSelectorList* selectorList = selector->selectorList()) {
2109                 for (CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
2110                     if (selector->isSiblingSelector())
2111                         foundSiblingSelector = true;
2112                     collectFeaturesFromSelector(features, subSelector);
2113                 }
2114             } else if (selector->isSiblingSelector())
2115                 foundSiblingSelector = true;
2116         }
2117         if (foundSiblingSelector) {
2118             if (!features.siblingRules)
2119                 features.siblingRules = adoptPtr(new RuleSet);
2120             features.siblingRules->addRule(ruleData.rule(), ruleData.selector());
2121         }
2122         if (ruleData.containsUncommonAttributeSelector()) {
2123             if (!features.uncommonAttributeRules)
2124                 features.uncommonAttributeRules = adoptPtr(new RuleSet);
2125             features.uncommonAttributeRules->addRule(ruleData.rule(), ruleData.selector());
2126         }
2127     }
2128 }
2129
2130 void RuleSet::collectFeatures(CSSStyleSelector::Features& features) const
2131 {
2132     AtomRuleMap::const_iterator end = m_idRules.end();
2133     for (AtomRuleMap::const_iterator it = m_idRules.begin(); it != end; ++it)
2134         collectFeaturesFromList(features, *it->second);
2135     end = m_classRules.end();
2136     for (AtomRuleMap::const_iterator it = m_classRules.begin(); it != end; ++it)
2137         collectFeaturesFromList(features, *it->second);
2138     end = m_tagRules.end();
2139     for (AtomRuleMap::const_iterator it = m_tagRules.begin(); it != end; ++it)
2140         collectFeaturesFromList(features, *it->second);
2141     end = m_shadowPseudoElementRules.end();
2142     for (AtomRuleMap::const_iterator it = m_shadowPseudoElementRules.begin(); it != end; ++it)
2143         collectFeaturesFromList(features, *it->second);
2144     collectFeaturesFromList(features, m_linkPseudoClassRules);
2145     collectFeaturesFromList(features, m_focusPseudoClassRules);
2146     collectFeaturesFromList(features, m_universalRules);
2147 }
2148
2149 static inline void shrinkMapVectorsToFit(RuleSet::AtomRuleMap& map)
2150 {
2151     RuleSet::AtomRuleMap::iterator end = map.end();
2152     for (RuleSet::AtomRuleMap::iterator it = map.begin(); it != end; ++it)
2153         it->second->shrinkToFit();
2154 }
2155
2156 void RuleSet::shrinkToFit()
2157 {
2158     shrinkMapVectorsToFit(m_idRules);
2159     shrinkMapVectorsToFit(m_classRules);
2160     shrinkMapVectorsToFit(m_tagRules);
2161     shrinkMapVectorsToFit(m_shadowPseudoElementRules);
2162     m_linkPseudoClassRules.shrinkToFit();
2163     m_focusPseudoClassRules.shrinkToFit();
2164     m_universalRules.shrinkToFit();
2165     m_pageRules.shrinkToFit();
2166 }
2167
2168 // -------------------------------------------------------------------------------------
2169 // this is mostly boring stuff on how to apply a certain rule to the renderstyle...
2170
2171 static Length convertToLength(CSSPrimitiveValue* primitiveValue, RenderStyle* style, RenderStyle* rootStyle, bool toFloat, double multiplier = 1, bool *ok = 0)
2172 {
2173     // This function is tolerant of a null style value. The only place style is used is in
2174     // length measurements, like 'ems' and 'px'. And in those cases style is only used
2175     // when the units are EMS or EXS. So we will just fail in those cases.
2176     Length l;
2177     if (!primitiveValue) {
2178         if (ok)
2179             *ok = false;
2180     } else {
2181         int type = primitiveValue->primitiveType();
2182
2183         if (!style && (type == CSSPrimitiveValue::CSS_EMS || type == CSSPrimitiveValue::CSS_EXS || type == CSSPrimitiveValue::CSS_REMS)) {
2184             if (ok)
2185                 *ok = false;
2186         } else if (CSSPrimitiveValue::isUnitTypeLength(type)) {
2187             if (toFloat)
2188                 l = Length(primitiveValue->computeLength<double>(style, rootStyle, multiplier), Fixed);
2189             else
2190                 l = primitiveValue->computeLength<Length>(style, rootStyle, multiplier);
2191         }
2192         else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
2193             l = Length(primitiveValue->getDoubleValue(), Percent);
2194         else if (type == CSSPrimitiveValue::CSS_NUMBER)
2195             l = Length(primitiveValue->getDoubleValue() * 100.0, Percent);
2196         else if (ok)
2197             *ok = false;
2198     }
2199     return l;
2200 }
2201
2202 static Length convertToIntLength(CSSPrimitiveValue* primitiveValue, RenderStyle* style, RenderStyle* rootStyle, double multiplier = 1, bool *ok = 0)
2203 {
2204     return convertToLength(primitiveValue, style, rootStyle, false, multiplier, ok);
2205 }
2206
2207 static Length convertToFloatLength(CSSPrimitiveValue* primitiveValue, RenderStyle* style, RenderStyle* rootStyle, double multiplier = 1, bool *ok = 0)
2208 {
2209     return convertToLength(primitiveValue, style, rootStyle, true, multiplier, ok);
2210 }
2211
2212 template <bool applyFirst>
2213 void CSSStyleSelector::applyDeclaration(CSSMutableStyleDeclaration* styleDeclaration, bool isImportant, bool inheritedOnly)
2214 {
2215     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willProcessRule(document(), styleDeclaration->parentRule());
2216     CSSMutableStyleDeclaration::const_iterator end = styleDeclaration->end();
2217     for (CSSMutableStyleDeclaration::const_iterator it = styleDeclaration->begin(); it != end; ++it) {
2218         const CSSProperty& current = *it;
2219         if (isImportant != current.isImportant())
2220             continue;
2221         if (inheritedOnly && !current.isInherited()) {
2222             // If the property value is explicitly inherited, we need to apply further non-inherited properties
2223             // as they might override the value inherited here. For this reason we don't allow declarations with
2224             // explicitly inherited properties to be cached.
2225             ASSERT(!current.value()->isInheritedValue());
2226             continue;
2227         }
2228         int property = current.id();
2229         if (applyFirst) {
2230             COMPILE_ASSERT(firstCSSProperty == CSSPropertyColor, CSS_color_is_first_property);
2231             COMPILE_ASSERT(CSSPropertyZoom == CSSPropertyColor + 17, CSS_zoom_is_end_of_first_prop_range);
2232             COMPILE_ASSERT(CSSPropertyLineHeight == CSSPropertyZoom + 1, CSS_line_height_is_after_zoom);
2233             // give special priority to font-xxx, color properties, etc
2234             if (property > CSSPropertyLineHeight)
2235                 continue;
2236             // we apply line-height later
2237             if (property == CSSPropertyLineHeight) {
2238                 m_lineHeightValue = current.value();
2239                 continue;
2240             }
2241             applyProperty(current.id(), current.value());
2242             continue;
2243         }
2244         if (property > CSSPropertyLineHeight)
2245             applyProperty(current.id(), current.value());
2246     }
2247     InspectorInstrumentation::didProcessRule(cookie);
2248 }
2249
2250 template <bool applyFirst>
2251 void CSSStyleSelector::applyDeclarations(bool isImportant, int startIndex, int endIndex, bool inheritedOnly)
2252 {
2253     if (startIndex == -1)
2254         return;
2255
2256     if (m_style->insideLink() != NotInsideLink) {
2257         for (int i = startIndex; i <= endIndex; ++i) {
2258             CSSMutableStyleDeclaration* styleDeclaration = m_matchedDecls[i].styleDeclaration.get();
2259             unsigned linkMatchType = m_matchedDecls[i].linkMatchType;
2260             // FIXME: It would be nicer to pass these as arguments but that requires changes in many places.
2261             m_applyPropertyToRegularStyle = linkMatchType & SelectorChecker::MatchLink;
2262             m_applyPropertyToVisitedLinkStyle = linkMatchType & SelectorChecker::MatchVisited;
2263
2264             applyDeclaration<applyFirst>(styleDeclaration, isImportant, inheritedOnly);
2265         }
2266         m_applyPropertyToRegularStyle = true;
2267         m_applyPropertyToVisitedLinkStyle = false;
2268         return;
2269     }
2270     for (int i = startIndex; i <= endIndex; ++i)
2271         applyDeclaration<applyFirst>(m_matchedDecls[i].styleDeclaration.get(), isImportant, inheritedOnly);
2272 }
2273
2274 unsigned CSSStyleSelector::computeDeclarationHash(MatchedStyleDeclaration* declarations, unsigned size)
2275 {
2276     return StringHasher::hashMemory(declarations, sizeof(MatchedStyleDeclaration) * size);
2277 }
2278
2279 bool operator==(const CSSStyleSelector::MatchResult& a, const CSSStyleSelector::MatchResult& b)
2280 {
2281     return a.firstUARule == b.firstUARule
2282         && a.lastUARule == b.lastUARule
2283         && a.firstAuthorRule == b.firstAuthorRule
2284         && a.lastAuthorRule == b.lastAuthorRule
2285         && a.firstUserRule == b.firstUserRule
2286         && a.lastUserRule == b.lastUserRule
2287         && a.isCacheable == b.isCacheable;
2288 }
2289
2290 bool operator!=(const CSSStyleSelector::MatchResult& a, const CSSStyleSelector::MatchResult& b)
2291 {
2292     return !(a == b);
2293 }
2294
2295 bool operator==(const CSSStyleSelector::MatchedStyleDeclaration& a, const CSSStyleSelector::MatchedStyleDeclaration& b)
2296 {
2297     return a.styleDeclaration == b.styleDeclaration && a.linkMatchType == b.linkMatchType;
2298 }
2299
2300 bool operator!=(const CSSStyleSelector::MatchedStyleDeclaration& a, const CSSStyleSelector::MatchedStyleDeclaration& b)
2301 {
2302     return !(a == b);
2303 }
2304
2305 const CSSStyleSelector::MatchedStyleDeclarationCacheItem* CSSStyleSelector::findFromMatchedDeclarationCache(unsigned hash, const MatchResult& matchResult)
2306 {
2307     ASSERT(hash);
2308
2309     MatchedStyleDeclarationCache::iterator it = m_matchedStyleDeclarationCache.find(hash);
2310     if (it == m_matchedStyleDeclarationCache.end())
2311         return 0;
2312     MatchedStyleDeclarationCacheItem& cacheItem = it->second;
2313     ASSERT(cacheItem.matchResult.isCacheable);
2314     
2315     size_t size = m_matchedDecls.size();
2316     if (size != cacheItem.matchedStyleDeclarations.size())
2317         return 0;
2318     for (size_t i = 0; i < size; ++i) {
2319         if (m_matchedDecls[i] != cacheItem.matchedStyleDeclarations[i])
2320             return 0;
2321     }
2322     if (cacheItem.matchResult != matchResult)
2323         return 0;
2324     return &cacheItem;
2325 }
2326
2327 void CSSStyleSelector::addToMatchedDeclarationCache(const RenderStyle* style, const RenderStyle* parentStyle, unsigned hash, const MatchResult& matchResult)
2328 {
2329     static unsigned matchedDeclarationCacheAdditionsBetweenSweeps = 100;
2330     if (++m_matchedDeclarationCacheAdditionsSinceLastSweep >= matchedDeclarationCacheAdditionsBetweenSweeps) {
2331         sweepMatchedDeclarationCache();
2332         m_matchedDeclarationCacheAdditionsSinceLastSweep = 0;
2333     }
2334
2335     ASSERT(hash);
2336     MatchedStyleDeclarationCacheItem cacheItem;
2337     cacheItem.matchedStyleDeclarations.append(m_matchedDecls);
2338     cacheItem.matchResult = matchResult;
2339     // Note that we don't cache the original RenderStyle instance. It may be further modified.
2340     // The RenderStyle in the cache is really just a holder for the substructures and never used as-is.
2341     cacheItem.renderStyle = RenderStyle::clone(style);
2342     cacheItem.parentRenderStyle = RenderStyle::clone(parentStyle);
2343     m_matchedStyleDeclarationCache.add(hash, cacheItem);
2344 }
2345     
2346 void CSSStyleSelector::invalidateMatchedDeclarationCache()
2347 {
2348     m_matchedStyleDeclarationCache.clear();
2349 }
2350
2351 static bool isCacheableInMatchedDeclarationCache(const RenderStyle* style, const RenderStyle* parentStyle)
2352 {
2353     if (style->unique() || (style->styleType() != NOPSEUDO && parentStyle->unique()))
2354         return false;
2355     if (style->hasAppearance())
2356         return false;
2357     if (style->zoom() != RenderStyle::initialZoom())
2358         return false;
2359     // The cache assumes static knowledge about which properties are inherited.
2360     if (parentStyle->hasExplicitlyInheritedProperties())
2361         return false;
2362     return true;
2363 }
2364
2365 void CSSStyleSelector::applyMatchedDeclarations(const MatchResult& matchResult)
2366 {
2367     unsigned cacheHash = matchResult.isCacheable ? computeDeclarationHash(m_matchedDecls.data(), m_matchedDecls.size()) : 0;
2368     bool applyInheritedOnly = false;
2369     const MatchedStyleDeclarationCacheItem* cacheItem = 0;
2370     if (cacheHash && (cacheItem = findFromMatchedDeclarationCache(cacheHash, matchResult))) {
2371         // We can build up the style by copying non-inherited properties from an earlier style object built using the same exact
2372         // style declarations. We then only need to apply the inherited properties, if any, as their values can depend on the 
2373         // element context. This is fast and saves memory by reusing the style data structures.
2374         m_style->copyNonInheritedFrom(cacheItem->renderStyle.get());
2375         if (m_parentStyle->inheritedDataShared(cacheItem->parentRenderStyle.get())) {
2376             EInsideLink linkStatus = m_style->insideLink();
2377             // If the cache item parent style has identical inherited properties to the current parent style then the
2378             // resulting style will be identical too. We copy the inherited properties over from the cache and are done.
2379             m_style->inheritFrom(cacheItem->renderStyle.get());
2380             // Unfortunately the link status is treated like an inherited property. We need to explicitly restore it.
2381             m_style->setInsideLink(linkStatus);
2382             return;
2383         }
2384         applyInheritedOnly = true; 
2385     }
2386     // Now we have all of the matched rules in the appropriate order. Walk the rules and apply
2387     // high-priority properties first, i.e., those properties that other properties depend on.
2388     // The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
2389     // and (4) normal important.
2390     m_lineHeightValue = 0;
2391     applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1, applyInheritedOnly);
2392     applyDeclarations<true>(true, matchResult.firstAuthorRule, matchResult.lastAuthorRule, applyInheritedOnly);
2393     applyDeclarations<true>(true, matchResult.firstUserRule, matchResult.lastUserRule, applyInheritedOnly);
2394     applyDeclarations<true>(true, matchResult.firstUARule, matchResult.lastUARule, applyInheritedOnly);
2395
2396     if (cacheItem && cacheItem->renderStyle->effectiveZoom() != m_style->effectiveZoom()) {
2397         m_fontDirty = true;
2398         applyInheritedOnly = false;
2399     }
2400
2401     // If our font got dirtied, go ahead and update it now.
2402     updateFont();
2403
2404     // Line-height is set when we are sure we decided on the font-size.
2405     if (m_lineHeightValue)
2406         applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
2407
2408     // Many properties depend on the font. If it changes we just apply all properties.
2409     if (cacheItem && cacheItem->renderStyle->fontDescription() != m_style->fontDescription())
2410         applyInheritedOnly = false;
2411
2412     // Now do the normal priority UA properties.
2413     applyDeclarations<false>(false, matchResult.firstUARule, matchResult.lastUARule, applyInheritedOnly);
2414     
2415     // Cache our border and background so that we can examine them later.
2416     cacheBorderAndBackground();
2417     
2418     // Now do the author and user normal priority properties and all the !important properties.
2419     applyDeclarations<false>(false, matchResult.lastUARule + 1, m_matchedDecls.size() - 1, applyInheritedOnly);
2420     applyDeclarations<false>(true, matchResult.firstAuthorRule, matchResult.lastAuthorRule, applyInheritedOnly);
2421     applyDeclarations<false>(true, matchResult.firstUserRule, matchResult.lastUserRule, applyInheritedOnly);
2422     applyDeclarations<false>(true, matchResult.firstUARule, matchResult.lastUARule, applyInheritedOnly);
2423     
2424     loadPendingImages();
2425     
2426 #if ENABLE(CSS_SHADERS)
2427     loadPendingShaders();
2428 #endif
2429     
2430     ASSERT(!m_fontDirty);
2431     
2432     if (cacheItem || !cacheHash)
2433         return;
2434     if (!isCacheableInMatchedDeclarationCache(m_style.get(), m_parentStyle))
2435         return;
2436     addToMatchedDeclarationCache(m_style.get(), m_parentStyle, cacheHash, matchResult);
2437 }
2438
2439 void CSSStyleSelector::matchPageRules(RuleSet* rules, bool isLeftPage, bool isFirstPage, const String& pageName)
2440 {
2441     m_matchedRules.clear();
2442
2443     if (!rules)
2444         return;
2445
2446     matchPageRulesForList(rules->pageRules(), isLeftPage, isFirstPage, pageName);
2447
2448     // If we didn't match any rules, we're done.
2449     if (m_matchedRules.isEmpty())
2450         return;
2451
2452     // Sort the set of matched rules.
2453     sortMatchedRules();
2454
2455     // Now transfer the set of matched rules over to our list of decls.
2456     for (unsigned i = 0; i < m_matchedRules.size(); i++)
2457         addMatchedDeclaration(m_matchedRules[i]->rule()->declaration());
2458 }
2459
2460 void CSSStyleSelector::matchPageRulesForList(const Vector<RuleData>* rules, bool isLeftPage, bool isFirstPage, const String& pageName)
2461 {
2462     if (!rules)
2463         return;
2464
2465     unsigned size = rules->size();
2466     for (unsigned i = 0; i < size; ++i) {
2467         const RuleData& ruleData = rules->at(i);
2468         CSSStyleRule* rule = ruleData.rule();
2469         const AtomicString& selectorLocalName = ruleData.selector()->tag().localName();
2470         if (selectorLocalName != starAtom && selectorLocalName != pageName)
2471             continue;
2472         CSSSelector::PseudoType pseudoType = ruleData.selector()->pseudoType();
2473         if ((pseudoType == CSSSelector::PseudoLeftPage && !isLeftPage)
2474             || (pseudoType == CSSSelector::PseudoRightPage && isLeftPage)
2475             || (pseudoType == CSSSelector::PseudoFirstPage && !isFirstPage))
2476             continue;
2477
2478         // If the rule has no properties to apply, then ignore it.
2479         CSSMutableStyleDeclaration* decl = rule->declaration();
2480         if (!decl || !decl->length())
2481             continue;
2482
2483         // Add this rule to our list of matched rules.
2484         addMatchedRule(&ruleData);
2485     }
2486 }
2487
2488 bool CSSStyleSelector::isLeftPage(int pageIndex) const
2489 {
2490     bool isFirstPageLeft = false;
2491     if (!m_rootElementStyle->isLeftToRightDirection())
2492         isFirstPageLeft = true;
2493
2494     return (pageIndex + (isFirstPageLeft ? 1 : 0)) % 2;
2495 }
2496
2497 bool CSSStyleSelector::isFirstPage(int pageIndex) const
2498 {
2499     // FIXME: In case of forced left/right page, page at index 1 (not 0) can be the first page.
2500     return (!pageIndex);
2501 }
2502
2503 String CSSStyleSelector::pageName(int /* pageIndex */) const
2504 {
2505     // FIXME: Implement page index to page name mapping.
2506     return "";
2507 }
2508
2509 void CSSStyleSelector::applyPropertyToStyle(int id, CSSValue* value, RenderStyle* style)
2510 {
2511     initElement(0);
2512     initForStyleResolve(0, style);
2513     m_style = style;
2514     applyPropertyToCurrentStyle(id, value);
2515 }
2516
2517 void CSSStyleSelector::applyPropertyToCurrentStyle(int id, CSSValue* value)
2518 {
2519     if (value)
2520         applyProperty(id, value);
2521 }
2522
2523 inline bool isValidVisitedLinkProperty(int id)
2524 {
2525     switch(static_cast<CSSPropertyID>(id)) {
2526         case CSSPropertyBackgroundColor:
2527         case CSSPropertyBorderLeftColor:
2528         case CSSPropertyBorderRightColor:
2529         case CSSPropertyBorderTopColor:
2530         case CSSPropertyBorderBottomColor:
2531         case CSSPropertyColor:
2532         case CSSPropertyOutlineColor:
2533         case CSSPropertyWebkitColumnRuleColor:
2534         case CSSPropertyWebkitTextEmphasisColor:
2535         case CSSPropertyWebkitTextFillColor:
2536         case CSSPropertyWebkitTextStrokeColor:
2537         // Also allow shorthands so that inherit/initial still work.
2538         case CSSPropertyBackground:
2539         case CSSPropertyBorderLeft:
2540         case CSSPropertyBorderRight:
2541         case CSSPropertyBorderTop:
2542         case CSSPropertyBorderBottom:
2543         case CSSPropertyOutline:
2544         case CSSPropertyWebkitColumnRule:
2545 #if ENABLE(SVG)
2546         case CSSPropertyFill:
2547         case CSSPropertyStroke:
2548 #endif
2549             return true;
2550         default:
2551             break;
2552     }
2553
2554     return false;
2555 }
2556
2557 // SVG handles zooming in a different way compared to CSS. The whole document is scaled instead
2558 // of each individual length value in the render style / tree. CSSPrimitiveValue::computeLength*()
2559 // multiplies each resolved length with the zoom multiplier - so for SVG we need to disable that.
2560 // Though all CSS values that can be applied to outermost <svg> elements (width/height/border/padding...)
2561 // need to respect the scaling. RenderBox (the parent class of RenderSVGRoot) grabs values like
2562 // width/height/border/padding/... from the RenderStyle -> for SVG these values would never scale,
2563 // if we'd pass a 1.0 zoom factor everyhwere. So we only pass a zoom factor of 1.0 for specific
2564 // properties that are NOT allowed to scale within a zoomed SVG document (letter/word-spacing/font-size).
2565 bool CSSStyleSelector::useSVGZoomRules()
2566 {
2567     return m_element && m_element->isSVGElement();
2568 }
2569
2570 #if ENABLE(CSS_GRID_LAYOUT)
2571
2572 static bool createGridTrackBreadth(CSSPrimitiveValue* primitiveValue, CSSStyleSelector* selector, Length& length)
2573 {
2574     if (primitiveValue->getIdent() == CSSValueAuto) {
2575         length = Length();
2576         return true;
2577     }
2578
2579     int type = primitiveValue->primitiveType();
2580     if (CSSPrimitiveValue::isUnitTypeLength(type)) {
2581         length = primitiveValue->computeLength<Length>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom());
2582         length.setQuirk(primitiveValue->isQuirkValue());
2583         return true;
2584     }
2585
2586     if (type == CSSPrimitiveValue::CSS_PERCENTAGE) {
2587         length = Length(primitiveValue->getDoubleValue(), Percent);
2588         return true;
2589     }
2590
2591     return false;
2592 }
2593
2594 static bool createGridTrackList(CSSValue* value, Vector<Length>& lengths, CSSStyleSelector* selector)
2595 {
2596     // Handle 'none'.
2597     if (value->isPrimitiveValue()) {
2598         CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
2599         if (primitiveValue->getIdent() == CSSValueNone) {
2600             lengths.append(Length(Undefined));
2601             return true;
2602         }
2603         return false;
2604     }
2605
2606     if (value->isValueList()) {
2607         for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
2608             CSSValue* currValue = i.value();
2609             if (!currValue->isPrimitiveValue())
2610                 return false;
2611
2612             Length length;
2613             if (!createGridTrackBreadth(static_cast<CSSPrimitiveValue*>(currValue), selector, length))
2614                 return false;
2615
2616             lengths.append(length);
2617         }
2618         return true;
2619     }
2620
2621     return false;
2622 }
2623 #endif
2624
2625 void CSSStyleSelector::applyProperty(int id, CSSValue *value)
2626 {
2627     bool isInherit = m_parentNode && value->isInheritedValue();
2628     bool isInitial = value->isInitialValue() || (!m_parentNode && value->isInheritedValue());
2629
2630     ASSERT(!isInherit || !isInitial); // isInherit -> !isInitial && isInitial -> !isInherit
2631
2632     if (!applyPropertyToRegularStyle() && (!applyPropertyToVisitedLinkStyle() || !isValidVisitedLinkProperty(id))) {
2633         // Limit the properties that can be applied to only the ones honored by :visited.
2634         return;
2635     }
2636
2637     CSSPropertyID property = static_cast<CSSPropertyID>(id);
2638
2639     if (isInherit && m_parentStyle && !m_parentStyle->hasExplicitlyInheritedProperties() && !CSSProperty::isInheritedProperty(property))
2640         m_parentStyle->setHasExplicitlyInheritedProperties();
2641
2642     // check lookup table for implementations and use when available
2643     const PropertyHandler& handler = m_applyProperty.propertyHandler(property);
2644     if (handler.isValid()) {
2645         if (isInherit)
2646             handler.applyInheritValue(this);
2647         else if (isInitial)
2648             handler.applyInitialValue(this);
2649         else
2650             handler.applyValue(this, value);
2651         return;
2652     }
2653
2654     CSSPrimitiveValue* primitiveValue = value->isPrimitiveValue() ? static_cast<CSSPrimitiveValue*>(value) : 0;
2655
2656     float zoomFactor = m_style->effectiveZoom();
2657
2658     // What follows is a list that maps the CSS properties into their corresponding front-end
2659     // RenderStyle values.  Shorthands (e.g. border, background) occur in this list as well and
2660     // are only hit when mapping "inherit" or "initial" into front-end values.
2661     switch (property) {
2662 // ident only properties
2663     case CSSPropertyBorderCollapse:
2664         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(borderCollapse, BorderCollapse)
2665         return;
2666     case CSSPropertyCaptionSide:
2667         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(captionSide, CaptionSide)
2668         return;
2669     case CSSPropertyClear:
2670         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(clear, Clear)
2671         return;
2672     case CSSPropertyEmptyCells:
2673         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(emptyCells, EmptyCells)
2674         return;
2675     case CSSPropertyFloat:
2676         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(floating, Floating)
2677         return;
2678     case CSSPropertyPageBreakBefore:
2679         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(pageBreakBefore, PageBreakBefore, PageBreak)
2680         return;
2681     case CSSPropertyPageBreakAfter:
2682         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(pageBreakAfter, PageBreakAfter, PageBreak)
2683         return;
2684     case CSSPropertyPageBreakInside:
2685         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(pageBreakInside, PageBreakInside, PageBreak)
2686         return;
2687     case CSSPropertyPosition:
2688         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(position, Position)
2689         return;
2690     case CSSPropertyTableLayout:
2691         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(tableLayout, TableLayout)
2692         return;
2693     case CSSPropertyUnicodeBidi:
2694         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(unicodeBidi, UnicodeBidi)
2695         return;
2696     case CSSPropertyTextTransform:
2697         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(textTransform, TextTransform)
2698         return;
2699     case CSSPropertyVisibility:
2700         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(visibility, Visibility)
2701         return;
2702     case CSSPropertyWhiteSpace:
2703         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(whiteSpace, WhiteSpace)
2704         return;
2705 // uri || inherit
2706     case CSSPropertyWordBreak:
2707         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(wordBreak, WordBreak)
2708         return;
2709     case CSSPropertyWordWrap:
2710         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(wordWrap, WordWrap)
2711         return;
2712     case CSSPropertyWebkitNbspMode:
2713         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(nbspMode, NBSPMode)
2714         return;
2715     case CSSPropertyWebkitLineBreak:
2716         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(khtmlLineBreak, KHTMLLineBreak)
2717         return;
2718     case CSSPropertyWebkitMatchNearestMailBlockquoteColor:
2719         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(matchNearestMailBlockquoteColor, MatchNearestMailBlockquoteColor)
2720         return;
2721     case CSSPropertyWidows:
2722         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(widows, Widows)
2723         return;
2724     case CSSPropertyOrphans:
2725         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(orphans, Orphans)
2726         return;
2727 // rect
2728     case CSSPropertyClip:
2729     {
2730         Length top;
2731         Length right;
2732         Length bottom;
2733         Length left;
2734         bool hasClip = true;
2735         if (isInherit) {
2736             if (m_parentStyle->hasClip()) {
2737                 top = m_parentStyle->clipTop();
2738                 right = m_parentStyle->clipRight();
2739                 bottom = m_parentStyle->clipBottom();
2740                 left = m_parentStyle->clipLeft();
2741             } else {
2742                 hasClip = false;
2743                 top = right = bottom = left = Length();
2744             }
2745         } else if (isInitial) {
2746             hasClip = false;
2747             top = right = bottom = left = Length();
2748         } else if (!primitiveValue) {
2749             return;
2750         } else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_RECT) {
2751             Rect* rect = primitiveValue->getRectValue();
2752             if (!rect)
2753                 return;
2754             top = convertToIntLength(rect->top(), style(), m_rootElementStyle, zoomFactor);
2755             right = convertToIntLength(rect->right(), style(), m_rootElementStyle, zoomFactor);
2756             bottom = convertToIntLength(rect->bottom(), style(), m_rootElementStyle, zoomFactor);
2757             left = convertToIntLength(rect->left(), style(), m_rootElementStyle, zoomFactor);
2758         } else if (primitiveValue->getIdent() != CSSValueAuto) {
2759             return;
2760         }
2761         m_style->setClip(top, right, bottom, left);
2762         m_style->setHasClip(hasClip);
2763
2764         // rect, ident
2765         return;
2766     }
2767
2768 // lists
2769     case CSSPropertyContent:
2770         // list of string, uri, counter, attr, i
2771     {
2772         // FIXME: In CSS3, it will be possible to inherit content.  In CSS2 it is not.  This
2773         // note is a reminder that eventually "inherit" needs to be supported.
2774
2775         if (isInitial) {
2776             m_style->clearContent();
2777             return;
2778         }
2779
2780         if (!value->isValueList())
2781             return;
2782
2783         bool didSet = false;
2784         for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
2785             CSSValue* item = i.value();
2786             if (item->isImageGeneratorValue()) {
2787                 m_style->setContent(StyleGeneratedImage::create(static_cast<CSSImageGeneratorValue*>(item)), didSet);
2788                 didSet = true;
2789             }
2790
2791             if (!item->isPrimitiveValue())
2792                 continue;
2793
2794             CSSPrimitiveValue* contentValue = static_cast<CSSPrimitiveValue*>(item);
2795             switch (contentValue->primitiveType()) {
2796             case CSSPrimitiveValue::CSS_STRING:
2797                 m_style->setContent(contentValue->getStringValue().impl(), didSet);
2798                 didSet = true;
2799                 break;
2800             case CSSPrimitiveValue::CSS_ATTR: {
2801                 // FIXME: Can a namespace be specified for an attr(foo)?
2802                 if (m_style->styleType() == NOPSEUDO)
2803                     m_style->setUnique();
2804                 else
2805                     m_parentStyle->setUnique();
2806                 QualifiedName attr(nullAtom, contentValue->getStringValue().impl(), nullAtom);
2807                 const AtomicString& value = m_element->getAttribute(attr);
2808                 m_style->setContent(value.isNull() ? emptyAtom : value.impl(), didSet);
2809                 didSet = true;
2810                 // register the fact that the attribute value affects the style
2811                 m_features.attrsInRules.add(attr.localName().impl());
2812                 break;
2813             }
2814             case CSSPrimitiveValue::CSS_URI: {
2815                 if (!contentValue->isImageValue())
2816                     break;
2817                 m_style->setContent(cachedOrPendingFromValue(CSSPropertyContent, static_cast<CSSImageValue*>(contentValue)), didSet);
2818                 didSet = true;
2819                 break;
2820             }
2821             case CSSPrimitiveValue::CSS_COUNTER: {
2822                 Counter* counterValue = contentValue->getCounterValue();
2823                 EListStyleType listStyleType = NoneListStyle;
2824                 int listStyleIdent = counterValue->listStyleIdent();
2825                 if (listStyleIdent != CSSValueNone)
2826                     listStyleType = static_cast<EListStyleType>(listStyleIdent - CSSValueDisc);
2827                 OwnPtr<CounterContent> counter = adoptPtr(new CounterContent(counterValue->identifier(), listStyleType, counterValue->separator()));
2828                 m_style->setContent(counter.release(), didSet);
2829                 didSet = true;
2830                 break;
2831             }
2832             case CSSPrimitiveValue::CSS_IDENT:
2833                 switch (contentValue->getIdent()) {
2834                 case CSSValueOpenQuote:
2835                     m_style->setContent(OPEN_QUOTE, didSet);
2836                     didSet = true;
2837                     break;
2838                 case CSSValueCloseQuote:
2839                     m_style->setContent(CLOSE_QUOTE, didSet);
2840                     didSet = true;
2841                     break;
2842                 case CSSValueNoOpenQuote:
2843                     m_style->setContent(NO_OPEN_QUOTE, didSet);
2844                     didSet = true;
2845                     break;
2846                 case CSSValueNoCloseQuote:
2847                     m_style->setContent(NO_CLOSE_QUOTE, didSet);
2848                     didSet = true;
2849                     break;
2850                 default:
2851                     // normal and none do not have any effect.
2852                     {}
2853                 }
2854             }
2855         }
2856         if (!didSet)
2857             m_style->clearContent();
2858         return;
2859     }
2860     case CSSPropertyQuotes:
2861         if (isInherit) {
2862             if (m_parentStyle)
2863                 m_style->setQuotes(m_parentStyle->quotes());
2864             return;
2865         }
2866         if (isInitial) {
2867             m_style->setQuotes(0);
2868             return;
2869         }
2870         if (value->isValueList()) {
2871             CSSValueList* list = static_cast<CSSValueList*>(value);
2872             QuotesData* data = QuotesData::create(list->length());
2873             if (!data)
2874                 return; // Out of memory
2875             String* quotes = data->data();
2876             for (CSSValueListIterator i = list; i.hasMore(); i.advance()) {
2877                 CSSValue* item = i.value();
2878                 ASSERT(item->isPrimitiveValue());
2879                 primitiveValue = static_cast<CSSPrimitiveValue*>(item);
2880                 ASSERT(primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_STRING);
2881                 quotes[i.index()] = primitiveValue->getStringValue();
2882             }
2883             m_style->setQuotes(adoptRef(data));
2884         } else if (primitiveValue) {
2885             ASSERT(primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_IDENT);
2886             if (primitiveValue->getIdent() == CSSValueNone)
2887                 m_style->setQuotes(adoptRef(QuotesData::create(0)));
2888         }
2889         return;
2890     case CSSPropertyFontFamily: {
2891         // list of strings and ids
2892         if (isInherit) {
2893             FontDescription parentFontDescription = m_parentStyle->fontDescription();
2894             FontDescription fontDescription = m_style->fontDescription();
2895             fontDescription.setGenericFamily(parentFontDescription.genericFamily());
2896             fontDescription.setFamily(parentFontDescription.firstFamily());
2897             fontDescription.setIsSpecifiedFont(parentFontDescription.isSpecifiedFont());
2898             setFontDescription(fontDescription);
2899             return;
2900         } else if (isInitial) {
2901             FontDescription initialDesc = FontDescription();
2902             FontDescription fontDescription = m_style->fontDescription();
2903             // We need to adjust the size to account for the generic family change from monospace
2904             // to non-monospace.
2905             if (fontDescription.keywordSize() && fontDescription.useFixedDefaultSize())
2906                 setFontSize(fontDescription, fontSizeForKeyword(m_checker.document(), CSSValueXxSmall + fontDescription.keywordSize() - 1, false));
2907             fontDescription.setGenericFamily(initialDesc.genericFamily());
2908             if (!initialDesc.firstFamily().familyIsEmpty())
2909                 fontDescription.setFamily(initialDesc.firstFamily());
2910             setFontDescription(fontDescription);
2911             return;
2912         }
2913
2914         if (!value->isValueList())
2915             return;
2916         FontDescription fontDescription = m_style->fontDescription();
2917         FontFamily& firstFamily = fontDescription.firstFamily();
2918         FontFamily* currFamily = 0;
2919
2920         // Before mapping in a new font-family property, we should reset the generic family.
2921         bool oldFamilyUsedFixedDefaultSize = fontDescription.useFixedDefaultSize();
2922         fontDescription.setGenericFamily(FontDescription::NoFamily);
2923
2924         for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
2925             CSSValue* item = i.value();
2926             if (!item->isPrimitiveValue())
2927                 continue;
2928             CSSPrimitiveValue* contentValue = static_cast<CSSPrimitiveValue*>(item);
2929             AtomicString face;
2930             Settings* settings = m_checker.document()->settings();
2931             if (contentValue->primitiveType() == CSSPrimitiveValue::CSS_STRING) {
2932                 if (contentValue->isFontFamilyValue())
2933                     face = static_cast<FontFamilyValue*>(contentValue)->familyName();
2934             } else if (contentValue->primitiveType() == CSSPrimitiveValue::CSS_IDENT && settings) {
2935                 switch (contentValue->getIdent()) {
2936                     case CSSValueWebkitBody:
2937                         face = settings->standardFontFamily();
2938                         break;
2939                     case CSSValueSerif:
2940                         face = serifFamily;
2941                         fontDescription.setGenericFamily(FontDescription::SerifFamily);
2942                         break;
2943                     case CSSValueSansSerif:
2944                         face = sansSerifFamily;
2945                         fontDescription.setGenericFamily(FontDescription::SansSerifFamily);
2946                         break;
2947                     case CSSValueCursive:
2948                         face = cursiveFamily;
2949                         fontDescription.setGenericFamily(FontDescription::CursiveFamily);
2950                         break;
2951                     case CSSValueFantasy:
2952                         face = fantasyFamily;
2953                         fontDescription.setGenericFamily(FontDescription::FantasyFamily);
2954                         break;
2955                     case CSSValueMonospace:
2956                         face = monospaceFamily;
2957                         fontDescription.setGenericFamily(FontDescription::MonospaceFamily);
2958                         break;
2959                     case CSSValueWebkitPictograph:
2960                         face = pictographFamily;
2961                         fontDescription.setGenericFamily(FontDescription::PictographFamily);
2962                         break;
2963                 }
2964             }
2965
2966             if (!face.isEmpty()) {
2967                 if (!currFamily) {
2968                     // Filling in the first family.
2969                     firstFamily.setFamily(face);
2970                     firstFamily.appendFamily(0); // Remove any inherited family-fallback list.
2971                     currFamily = &firstFamily;
2972                     fontDescription.setIsSpecifiedFont(fontDescription.genericFamily() == FontDescription::NoFamily);
2973                 } else {
2974                     RefPtr<SharedFontFamily> newFamily = SharedFontFamily::create();
2975                     newFamily->setFamily(face);
2976                     currFamily->appendFamily(newFamily);
2977                     currFamily = newFamily.get();
2978                 }
2979             }
2980         }
2981
2982         // We can't call useFixedDefaultSize() until all new font families have been added
2983         // If currFamily is non-zero then we set at least one family on this description.
2984         if (currFamily) {
2985             if (fontDescription.keywordSize() && fontDescription.useFixedDefaultSize() != oldFamilyUsedFixedDefaultSize)
2986                 setFontSize(fontDescription, fontSizeForKeyword(m_checker.document(), CSSValueXxSmall + fontDescription.keywordSize() - 1, !oldFamilyUsedFixedDefaultSize));
2987
2988             setFontDescription(fontDescription);
2989         }
2990         return;
2991     }
2992 // shorthand properties
2993     case CSSPropertyBackground:
2994         if (isInitial) {
2995             m_style->clearBackgroundLayers();
2996             m_style->setBackgroundColor(Color());
2997         }
2998         else if (isInherit) {
2999             m_style->inheritBackgroundLayers(*m_parentStyle->backgroundLayers());
3000             m_style->setBackgroundColor(m_parentStyle->backgroundColor());
3001         }
3002         return;
3003     case CSSPropertyWebkitMask:
3004         if (isInitial)
3005             m_style->clearMaskLayers();
3006         else if (isInherit)
3007             m_style->inheritMaskLayers(*m_parentStyle->maskLayers());
3008         return;
3009     case CSSPropertyFont:
3010         if (isInherit) {
3011             FontDescription fontDescription = m_parentStyle->fontDescription();
3012             m_style->setLineHeight(m_parentStyle->lineHeight());
3013             m_lineHeightValue = 0;
3014             setFontDescription(fontDescription);
3015         } else if (isInitial) {
3016             Settings* settings = m_checker.document()->settings();
3017             ASSERT(settings); // If we're doing style resolution, this document should always be in a frame and thus have settings
3018             if (!settings)
3019                 return;
3020             FontDescription fontDescription;
3021             fontDescription.setGenericFamily(FontDescription::StandardFamily);
3022             fontDescription.setRenderingMode(settings->fontRenderingMode());
3023             fontDescription.setUsePrinterFont(m_checker.document()->printing());
3024             const AtomicString& standardFontFamily = m_checker.document()->settings()->standardFontFamily();
3025             if (!standardFontFamily.isEmpty()) {
3026                 fontDescription.firstFamily().setFamily(standardFontFamily);
3027                 fontDescription.firstFamily().appendFamily(0);
3028             }
3029             fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
3030             setFontSize(fontDescription, fontSizeForKeyword(m_checker.document(), CSSValueMedium, false));
3031             m_style->setLineHeight(RenderStyle::initialLineHeight());
3032             m_lineHeightValue = 0;
3033             setFontDescription(fontDescription);
3034         } else if (primitiveValue) {
3035             m_style->setLineHeight(RenderStyle::initialLineHeight());
3036             m_lineHeightValue = 0;
3037
3038             FontDescription fontDescription;
3039             RenderTheme::defaultTheme()->systemFont(primitiveValue->getIdent(), fontDescription);
3040
3041             // Double-check and see if the theme did anything.  If not, don't bother updating the font.
3042             if (fontDescription.isAbsoluteSize()) {
3043                 // Make sure the rendering mode and printer font settings are updated.
3044                 Settings* settings = m_checker.document()->settings();
3045                 ASSERT(settings); // If we're doing style resolution, this document should always be in a frame and thus have settings
3046                 if (!settings)
3047                     return;
3048                 fontDescription.setRenderingMode(settings->fontRenderingMode());
3049                 fontDescription.setUsePrinterFont(m_checker.document()->printing());
3050
3051                 // Handle the zoom factor.
3052                 fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(m_checker.document(), m_style.get(), fontDescription.isAbsoluteSize(), fontDescription.specifiedSize(), useSVGZoomRules()));
3053                 setFontDescription(fontDescription);
3054             }
3055         } else if (value->isFontValue()) {
3056             FontValue *font = static_cast<FontValue*>(value);
3057             if (!font->style || !font->variant || !font->weight ||
3058                  !font->size || !font->lineHeight || !font->family)
3059                 return;
3060             applyProperty(CSSPropertyFontStyle, font->style.get());
3061             applyProperty(CSSPropertyFontVariant, font->variant.get());
3062             applyProperty(CSSPropertyFontWeight, font->weight.get());
3063             // The previous properties can dirty our font but they don't try to read the font's
3064             // properties back, which is safe. However if font-size is using the 'ex' unit, it will
3065             // need query the dirtied font's x-height to get the computed size. To be safe in this
3066             // case, let's just update the font now.
3067             updateFont();
3068             applyProperty(CSSPropertyFontSize, font->size.get());
3069
3070             m_lineHeightValue = font->lineHeight.get();
3071
3072             applyProperty(CSSPropertyFontFamily, font->family.get());
3073         }
3074         return;
3075
3076     // CSS3 Properties
3077     case CSSPropertyWebkitAppearance:
3078         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(appearance, Appearance)
3079         return;
3080     case CSSPropertyImageRendering:
3081         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(imageRendering, ImageRendering);
3082         return;
3083     case CSSPropertyTextShadow:
3084     case CSSPropertyBoxShadow:
3085     case CSSPropertyWebkitBoxShadow: {
3086         if (isInherit) {
3087             if (id == CSSPropertyTextShadow)
3088                 return m_style->setTextShadow(m_parentStyle->textShadow() ? adoptPtr(new ShadowData(*m_parentStyle->textShadow())) : nullptr);
3089             return m_style->setBoxShadow(m_parentStyle->boxShadow() ? adoptPtr(new ShadowData(*m_parentStyle->boxShadow())) : nullptr);
3090         }
3091         if (isInitial || primitiveValue) // initial | none
3092             return id == CSSPropertyTextShadow ? m_style->setTextShadow(nullptr) : m_style->setBoxShadow(nullptr);
3093
3094         if (!value->isValueList())
3095             return;
3096
3097         for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
3098             CSSValue* currValue = i.value();
3099             if (!currValue->isShadowValue())
3100                 continue;
3101             ShadowValue* item = static_cast<ShadowValue*>(currValue);
3102             int x = item->x->computeLength<int>(style(), m_rootElementStyle, zoomFactor);
3103             int y = item->y->computeLength<int>(style(), m_rootElementStyle, zoomFactor);
3104             int blur = item->blur ? item->blur->computeLength<int>(style(), m_rootElementStyle, zoomFactor) : 0;
3105             int spread = item->spread ? item->spread->computeLength<int>(style(), m_rootElementStyle, zoomFactor) : 0;
3106             ShadowStyle shadowStyle = item->style && item->style->getIdent() == CSSValueInset ? Inset : Normal;
3107             Color color;
3108             if (item->color)
3109                 color = colorFromPrimitiveValue(item->color.get());
3110             OwnPtr<ShadowData> shadowData = adoptPtr(new ShadowData(x, y, blur, spread, shadowStyle, id == CSSPropertyWebkitBoxShadow, color.isValid() ? color : Color::transparent));
3111             if (id == CSSPropertyTextShadow)
3112                 m_style->setTextShadow(shadowData.release(), i.index()); // add to the list if this is not the first entry
3113             else
3114                 m_style->setBoxShadow(shadowData.release(), i.index()); // add to the list if this is not the first entry
3115         }
3116         return;
3117     }
3118     case CSSPropertyWebkitBoxReflect: {
3119         HANDLE_INHERIT_AND_INITIAL(boxReflect, BoxReflect)
3120         if (primitiveValue) {
3121             m_style->setBoxReflect(RenderStyle::initialBoxReflect());
3122             return;
3123         }
3124
3125         if (!value->isReflectValue())
3126             return;
3127
3128         CSSReflectValue* reflectValue = static_cast<CSSReflectValue*>(value);
3129         RefPtr<StyleReflection> reflection = StyleReflection::create();
3130         reflection->setDirection(reflectValue->direction());
3131         if (reflectValue->offset()) {
3132             int type = reflectValue->offset()->primitiveType();
3133             if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
3134                 reflection->setOffset(Length(reflectValue->offset()->getDoubleValue(), Percent));
3135             else
3136                 reflection->setOffset(reflectValue->offset()->computeLength<Length>(style(), m_rootElementStyle, zoomFactor));
3137         }
3138         NinePieceImage mask;
3139         mask.setMaskDefaults();
3140         mapNinePieceImage(property, reflectValue->mask(), mask);
3141         reflection->setMask(mask);
3142
3143         m_style->setBoxReflect(reflection.release());
3144         return;
3145     }
3146     case CSSPropertyOpacity:
3147         HANDLE_INHERIT_AND_INITIAL(opacity, Opacity)
3148         if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
3149             return; // Error case.
3150         // Clamp opacity to the range 0-1
3151         m_style->setOpacity(clampTo<float>(primitiveValue->getDoubleValue(), 0, 1));
3152         return;
3153     case CSSPropertyWebkitBoxAlign:
3154         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(boxAlign, BoxAlign)
3155         return;
3156     case CSSPropertySrc: // Only used in @font-face rules.
3157         return;
3158     case CSSPropertyUnicodeRange: // Only used in @font-face rules.
3159         return;
3160     case CSSPropertyWebkitBackfaceVisibility:
3161         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(backfaceVisibility, BackfaceVisibility)
3162         return;
3163     case CSSPropertyWebkitBoxDirection:
3164         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(boxDirection, BoxDirection)
3165         return;
3166     case CSSPropertyWebkitBoxLines:
3167         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(boxLines, BoxLines)
3168         return;
3169     case CSSPropertyWebkitBoxOrient:
3170         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(boxOrient, BoxOrient)
3171         return;
3172     case CSSPropertyWebkitBoxPack:
3173         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(boxPack, BoxPack)
3174         return;
3175     case CSSPropertyWebkitBoxFlex:
3176         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(boxFlex, BoxFlex)
3177         return;
3178     case CSSPropertyWebkitBoxFlexGroup:
3179         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(boxFlexGroup, BoxFlexGroup)
3180         return;
3181     case CSSPropertyWebkitBoxOrdinalGroup:
3182         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(boxOrdinalGroup, BoxOrdinalGroup)
3183         return;
3184     case CSSPropertyBoxSizing:
3185         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(boxSizing, BoxSizing);
3186         return;
3187     case CSSPropertyWebkitColumnSpan:
3188         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(columnSpan, ColumnSpan)
3189         return;
3190     case CSSPropertyWebkitColumnRuleStyle:
3191         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(columnRuleStyle, ColumnRuleStyle, BorderStyle)
3192         return;
3193     case CSSPropertyWebkitColumnBreakBefore:
3194         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(columnBreakBefore, ColumnBreakBefore, PageBreak)
3195         return;
3196     case CSSPropertyWebkitColumnBreakAfter:
3197         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(columnBreakAfter, ColumnBreakAfter, PageBreak)
3198         return;
3199     case CSSPropertyWebkitColumnBreakInside:
3200         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(columnBreakInside, ColumnBreakInside, PageBreak)
3201         return;
3202     case CSSPropertyWebkitColumnRule:
3203         if (isInherit) {
3204             m_style->setColumnRuleColor(m_parentStyle->columnRuleColor().isValid() ? m_parentStyle->columnRuleColor() : m_parentStyle->color());
3205             m_style->setColumnRuleStyle(m_parentStyle->columnRuleStyle());
3206             m_style->setColumnRuleWidth(m_parentStyle->columnRuleWidth());
3207         }
3208         else if (isInitial)
3209             m_style->resetColumnRule();
3210         return;
3211     case CSSPropertyWebkitRegionBreakBefore:
3212         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(regionBreakBefore, RegionBreakBefore, PageBreak)
3213         return;
3214     case CSSPropertyWebkitRegionBreakAfter:
3215         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(regionBreakAfter, RegionBreakAfter, PageBreak)
3216         return;
3217     case CSSPropertyWebkitRegionBreakInside:
3218         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE_WITH_VALUE(regionBreakInside, RegionBreakInside, PageBreak)
3219         return;
3220     case CSSPropertyWebkitMarquee:
3221         if (!m_parentNode || !value->isInheritedValue())
3222             return;
3223         m_style->setMarqueeDirection(m_parentStyle->marqueeDirection());
3224         m_style->setMarqueeIncrement(m_parentStyle->marqueeIncrement());
3225         m_style->setMarqueeSpeed(m_parentStyle->marqueeSpeed());
3226         m_style->setMarqueeLoopCount(m_parentStyle->marqueeLoopCount());
3227         m_style->setMarqueeBehavior(m_parentStyle->marqueeBehavior());
3228         return;
3229     case CSSPropertyWebkitMarqueeRepetition: {
3230         HANDLE_INHERIT_AND_INITIAL(marqueeLoopCount, MarqueeLoopCount)
3231         if (!primitiveValue)
3232             return;
3233         if (primitiveValue->getIdent() == CSSValueInfinite)
3234             m_style->setMarqueeLoopCount(-1); // -1 means repeat forever.
3235         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
3236             m_style->setMarqueeLoopCount(primitiveValue->getIntValue());
3237         return;
3238     }
3239     case CSSPropertyWebkitMarqueeSpeed: {
3240         HANDLE_INHERIT_AND_INITIAL(marqueeSpeed, MarqueeSpeed)
3241         if (!primitiveValue)
3242             return;
3243         if (primitiveValue->getIdent()) {
3244             switch (primitiveValue->getIdent()) {
3245                 case CSSValueSlow:
3246                     m_style->setMarqueeSpeed(500); // 500 msec.
3247                     break;
3248                 case CSSValueNormal:
3249                     m_style->setMarqueeSpeed(85); // 85msec. The WinIE default.
3250                     break;
3251                 case CSSValueFast:
3252                     m_style->setMarqueeSpeed(10); // 10msec. Super fast.
3253                     break;
3254             }
3255         }
3256         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_S)
3257             m_style->setMarqueeSpeed(1000 * primitiveValue->getIntValue());
3258         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_MS)
3259             m_style->setMarqueeSpeed(primitiveValue->getIntValue());
3260         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) // For scrollamount support.
3261             m_style->setMarqueeSpeed(primitiveValue->getIntValue());
3262         return;
3263     }
3264     case CSSPropertyWebkitMarqueeIncrement: {
3265         HANDLE_INHERIT_AND_INITIAL(marqueeIncrement, MarqueeIncrement)
3266         if (!primitiveValue)
3267             return;
3268         if (primitiveValue->getIdent()) {
3269             switch (primitiveValue->getIdent()) {
3270                 case CSSValueSmall:
3271                     m_style->setMarqueeIncrement(Length(1, Fixed)); // 1px.
3272                     break;
3273                 case CSSValueNormal:
3274                     m_style->setMarqueeIncrement(Length(6, Fixed)); // 6px. The WinIE default.
3275                     break;
3276                 case CSSValueLarge:
3277                     m_style->setMarqueeIncrement(Length(36, Fixed)); // 36px.
3278                     break;
3279             }
3280         }
3281         else {
3282             bool ok = true;
3283             Length marqueeLength = convertToIntLength(primitiveValue, style(), m_rootElementStyle, 1, &ok);
3284             if (ok)
3285                 m_style->setMarqueeIncrement(marqueeLength);
3286         }
3287         return;
3288     }
3289     case CSSPropertyWebkitMarqueeStyle:
3290         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(marqueeBehavior, MarqueeBehavior)
3291         return;
3292     case CSSPropertyWebkitRegionOverflow:
3293         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(regionOverflow, RegionOverflow);
3294         return;
3295     case CSSPropertyWebkitMarqueeDirection:
3296         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(marqueeDirection, MarqueeDirection)
3297         return;
3298     case CSSPropertyWebkitUserDrag:
3299         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(userDrag, UserDrag)
3300         return;
3301     case CSSPropertyWebkitUserModify:
3302         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(userModify, UserModify)
3303         return;
3304     case CSSPropertyWebkitUserSelect:
3305         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(userSelect, UserSelect)
3306         return;
3307
3308     case CSSPropertyTextOverflow: {
3309         // This property is supported by WinIE, and so we leave off the "-webkit-" in order to
3310         // work with WinIE-specific pages that use the property.
3311         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(textOverflow, TextOverflow)
3312         return;
3313     }
3314     case CSSPropertyWebkitLineClamp: {
3315         HANDLE_INHERIT_AND_INITIAL(lineClamp, LineClamp)
3316         if (!primitiveValue)
3317             return;
3318         int type = primitiveValue->primitiveType();
3319         if (type == CSSPrimitiveValue::CSS_NUMBER)
3320             m_style->setLineClamp(LineClampValue(primitiveValue->getIntValue(CSSPrimitiveValue::CSS_NUMBER), LineClampLineCount));
3321         else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
3322             m_style->setLineClamp(LineClampValue(primitiveValue->getIntValue(CSSPrimitiveValue::CSS_PERCENTAGE), LineClampPercentage));
3323         return;
3324     }
3325     case CSSPropertyWebkitHyphens:
3326         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(hyphens, Hyphens);
3327         return;
3328     case CSSPropertyWebkitLocale: {
3329         HANDLE_INHERIT_AND_INITIAL(locale, Locale);
3330         if (primitiveValue->getIdent() == CSSValueAuto)
3331             m_style->setLocale(nullAtom);
3332         else
3333             m_style->setLocale(primitiveValue->getStringValue());
3334         FontDescription fontDescription = m_style->fontDescription();
3335         fontDescription.setScript(localeToScriptCodeForFontSelection(m_style->locale()));
3336         setFontDescription(fontDescription);
3337         return;
3338     }
3339     case CSSPropertyWebkitBorderFit:
3340         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(borderFit, BorderFit);
3341         return;
3342     case CSSPropertyWebkitTextSizeAdjust: {
3343         HANDLE_INHERIT_AND_INITIAL(textSizeAdjust, TextSizeAdjust)
3344         if (!primitiveValue || !primitiveValue->getIdent())
3345             return;
3346         setTextSizeAdjust(primitiveValue->getIdent() == CSSValueAuto);
3347         return;
3348     }
3349     case CSSPropertyWebkitTextSecurity:
3350         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(textSecurity, TextSecurity)
3351         return;
3352
3353 #if ENABLE(DASHBOARD_SUPPORT)
3354     case CSSPropertyWebkitDashboardRegion: {
3355         HANDLE_INHERIT_AND_INITIAL(dashboardRegions, DashboardRegions)
3356         if (!primitiveValue)
3357             return;
3358
3359         if (primitiveValue->getIdent() == CSSValueNone) {
3360             m_style->setDashboardRegions(RenderStyle::noneDashboardRegions());
3361             return;
3362         }
3363
3364         DashboardRegion *region = primitiveValue->getDashboardRegionValue();
3365         if (!region)
3366             return;
3367
3368         DashboardRegion *first = region;
3369         while (region) {
3370             Length top = convertToIntLength(region->top(), style(), m_rootElementStyle);
3371             Length right = convertToIntLength(region->right(), style(), m_rootElementStyle);
3372             Length bottom = convertToIntLength(region->bottom(), style(), m_rootElementStyle);
3373             Length left = convertToIntLength(region->left(), style(), m_rootElementStyle);
3374             if (region->m_isCircle)
3375                 m_style->setDashboardRegion(StyleDashboardRegion::Circle, region->m_label, top, right, bottom, left, region == first ? false : true);
3376             else if (region->m_isRectangle)
3377                 m_style->setDashboardRegion(StyleDashboardRegion::Rectangle, region->m_label, top, right, bottom, left, region == first ? false : true);
3378             region = region->m_next.get();
3379         }
3380
3381         m_element->document()->setHasDashboardRegions(true);
3382
3383         return;
3384     }
3385 #endif
3386     case CSSPropertyWebkitRtlOrdering:
3387         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(rtlOrdering, RTLOrdering)
3388         return;
3389     case CSSPropertyWebkitTextStrokeWidth: {
3390         HANDLE_INHERIT_AND_INITIAL(textStrokeWidth, TextStrokeWidth)
3391         float width = 0;
3392         switch (primitiveValue->getIdent()) {
3393             case CSSValueThin:
3394             case CSSValueMedium:
3395             case CSSValueThick: {
3396                 double result = 1.0 / 48;
3397                 if (primitiveValue->getIdent() == CSSValueMedium)
3398                     result *= 3;
3399                 else if (primitiveValue->getIdent() == CSSValueThick)
3400                     result *= 5;
3401                 width = CSSPrimitiveValue::create(result, CSSPrimitiveValue::CSS_EMS)->computeLength<float>(style(), m_rootElementStyle, zoomFactor);
3402                 break;
3403             }
3404             default:
3405                 width = primitiveValue->computeLength<float>(style(), m_rootElementStyle, zoomFactor);
3406                 break;
3407         }
3408         m_style->setTextStrokeWidth(width);
3409         return;
3410     }
3411     case CSSPropertyWebkitTransform: {
3412         HANDLE_INHERIT_AND_INITIAL(transform, Transform);
3413         TransformOperations operations;
3414         createTransformOperations(value, style(), m_rootElementStyle, operations);
3415         m_style->setTransform(operations);
3416         return;
3417     }
3418     case CSSPropertyWebkitTransformStyle:
3419         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(transformStyle3D, TransformStyle3D)
3420         return;
3421     case CSSPropertyWebkitPrintColorAdjust:
3422         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(printColorAdjust, PrintColorAdjust);
3423         return;
3424     case CSSPropertyWebkitPerspective: {
3425         HANDLE_INHERIT_AND_INITIAL(perspective, Perspective)
3426         if (primitiveValue && primitiveValue->getIdent() == CSSValueNone) {
3427             m_style->setPerspective(0);
3428             return;
3429         }
3430
3431         float perspectiveValue;
3432         int type = primitiveValue->primitiveType();
3433         if (CSSPrimitiveValue::isUnitTypeLength(type))
3434             perspectiveValue = primitiveValue->computeLength<float>(style(), m_rootElementStyle, zoomFactor);
3435         else if (type == CSSPrimitiveValue::CSS_NUMBER) {
3436             // For backward compatibility, treat valueless numbers as px.
3437             perspectiveValue = CSSPrimitiveValue::create(primitiveValue->getDoubleValue(), CSSPrimitiveValue::CSS_PX)->computeLength<float>(style(), m_rootElementStyle, zoomFactor);
3438         } else
3439             return;
3440
3441         if (perspectiveValue >= 0.0f)
3442             m_style->setPerspective(perspectiveValue);
3443         return;
3444     }
3445     case CSSPropertyWebkitAnimation:
3446         if (isInitial)
3447             m_style->clearAnimations();
3448         else if (isInherit)
3449             m_style->inheritAnimations(m_parentStyle->animations());
3450         return;
3451     case CSSPropertyWebkitTransition:
3452         if (isInitial)
3453             m_style->clearTransitions();
3454         else if (isInherit)
3455             m_style->inheritTransitions(m_parentStyle->transitions());
3456         return;
3457     case CSSPropertyPointerEvents:
3458     {
3459 #if ENABLE(DASHBOARD_SUPPORT)
3460         // <rdar://problem/6561077> Work around the Stocks widget's misuse of the
3461         // pointer-events property by not applying it in Dashboard.
3462         Settings* settings = m_checker.document()->settings();
3463         if (settings && settings->usesDashboardBackwardCompatibilityMode())
3464             return;
3465 #endif
3466         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(pointerEvents, PointerEvents)
3467         return;
3468     }
3469 #if ENABLE(TOUCH_EVENTS)
3470     case CSSPropertyWebkitTapHighlightColor: {
3471         HANDLE_INHERIT_AND_INITIAL(tapHighlightColor, TapHighlightColor);
3472         if (!primitiveValue)
3473             break;
3474
3475         Color col = colorFromPrimitiveValue(primitiveValue);
3476         m_style->setTapHighlightColor(col);
3477         return;
3478     }
3479 #endif
3480     case CSSPropertyWebkitColorCorrection:
3481         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(colorSpace, ColorSpace);
3482         return;
3483     case CSSPropertySpeak:
3484         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(speak, Speak);
3485         return;
3486     case CSSPropertyInvalid:
3487         return;
3488     // Directional properties are resolved by resolveDirectionAwareProperty() before the switch.
3489     case CSSPropertyWebkitBorderEnd:
3490     case CSSPropertyWebkitBorderEndColor:
3491     case CSSPropertyWebkitBorderEndStyle:
3492     case CSSPropertyWebkitBorderEndWidth:
3493     case CSSPropertyWebkitBorderStart:
3494     case CSSPropertyWebkitBorderStartColor:
3495     case CSSPropertyWebkitBorderStartStyle:
3496     case CSSPropertyWebkitBorderStartWidth:
3497     case CSSPropertyWebkitBorderBefore:
3498     case CSSPropertyWebkitBorderBeforeColor:
3499     case CSSPropertyWebkitBorderBeforeStyle:
3500     case CSSPropertyWebkitBorderBeforeWidth:
3501     case CSSPropertyWebkitBorderAfter:
3502     case CSSPropertyWebkitBorderAfterColor:
3503     case CSSPropertyWebkitBorderAfterStyle:
3504     case CSSPropertyWebkitBorderAfterWidth:
3505     case CSSPropertyWebkitMarginEnd:
3506     case CSSPropertyWebkitMarginStart:
3507     case CSSPropertyWebkitMarginBefore:
3508     case CSSPropertyWebkitMarginAfter:
3509     case CSSPropertyWebkitMarginCollapse:
3510     case CSSPropertyWebkitMarginBeforeCollapse:
3511     case CSSPropertyWebkitMarginTopCollapse:
3512     case CSSPropertyWebkitMarginAfterCollapse:
3513     case CSSPropertyWebkitMarginBottomCollapse:
3514     case CSSPropertyWebkitPaddingEnd:
3515     case CSSPropertyWebkitPaddingStart:
3516     case CSSPropertyWebkitPaddingBefore:
3517     case CSSPropertyWebkitPaddingAfter:
3518     case CSSPropertyWebkitLogicalWidth:
3519     case CSSPropertyWebkitLogicalHeight:
3520     case CSSPropertyWebkitMinLogicalWidth:
3521     case CSSPropertyWebkitMinLogicalHeight:
3522     case CSSPropertyWebkitMaxLogicalWidth:
3523     case CSSPropertyWebkitMaxLogicalHeight:
3524     {
3525         int newId = CSSProperty::resolveDirectionAwareProperty(id, m_style->direction(), m_style->writingMode());
3526         ASSERT(newId != id);
3527         return applyProperty(newId, value);
3528     }
3529     case CSSPropertyFontStretch:
3530     case CSSPropertyPage:
3531     case CSSPropertyTextLineThrough:
3532     case CSSPropertyTextLineThroughColor:
3533     case CSSPropertyTextLineThroughMode:
3534     case CSSPropertyTextLineThroughStyle:
3535     case CSSPropertyTextLineThroughWidth:
3536     case CSSPropertyTextOverline:
3537     case CSSPropertyTextOverlineColor:
3538     case CSSPropertyTextOverlineMode:
3539     case CSSPropertyTextOverlineStyle:
3540     case CSSPropertyTextOverlineWidth:
3541     case CSSPropertyTextUnderline:
3542     case CSSPropertyTextUnderlineColor:
3543     case CSSPropertyTextUnderlineMode:
3544     case CSSPropertyTextUnderlineStyle:
3545     case CSSPropertyTextUnderlineWidth:
3546     case CSSPropertyWebkitFontSizeDelta:
3547     case CSSPropertyWebkitTextDecorationsInEffect:
3548     case CSSPropertyWebkitTextStroke:
3549     case CSSPropertyWebkitTextEmphasis:
3550         return;
3551
3552     // CSS Text Layout Module Level 3: Vertical writing support
3553     case CSSPropertyWebkitWritingMode: {
3554         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(writingMode, WritingMode)
3555         if (!isInherit && !isInitial && m_element && m_element == m_element->document()->documentElement())
3556             m_element->document()->setWritingModeSetOnDocumentElement(true);
3557         FontDescription fontDescription = m_style->fontDescription();
3558         fontDescription.setOrientation(m_style->isHorizontalWritingMode() ? Horizontal : Vertical);
3559         setFontDescription(fontDescription);
3560         return;
3561     }
3562
3563     case CSSPropertyWebkitLineBoxContain: {
3564         HANDLE_INHERIT_AND_INITIAL(lineBoxContain, LineBoxContain)
3565         if (primitiveValue && primitiveValue->getIdent() == CSSValueNone) {
3566             m_style->setLineBoxContain(LineBoxContainNone);
3567             return;
3568         }
3569
3570         if (!value->isCSSLineBoxContainValue())
3571             return;
3572
3573         CSSLineBoxContainValue* lineBoxContainValue = static_cast<CSSLineBoxContainValue*>(value);
3574         m_style->setLineBoxContain(lineBoxContainValue->value());
3575         return;
3576     }
3577
3578     case CSSPropertyWebkitColumnAxis:
3579         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(columnAxis, ColumnAxis);
3580         return;
3581
3582     case CSSPropertyWebkitWrapShapeInside:
3583         HANDLE_INHERIT_AND_INITIAL(wrapShapeInside, WrapShapeInside);
3584         if (!primitiveValue)
3585             return;
3586         if (primitiveValue->getIdent() == CSSValueAuto)
3587             m_style->setWrapShapeInside(0);
3588         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_SHAPE)
3589             m_style->setWrapShapeInside(primitiveValue->getShapeValue());
3590         return;
3591
3592     case CSSPropertyWebkitWrapShapeOutside:
3593         HANDLE_INHERIT_AND_INITIAL(wrapShapeOutside, WrapShapeOutside);
3594         if (!primitiveValue)
3595             return;
3596         if (primitiveValue->getIdent() == CSSValueAuto)
3597             m_style->setWrapShapeOutside(0);
3598         else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_SHAPE)
3599             m_style->setWrapShapeOutside(primitiveValue->getShapeValue());
3600         return;
3601
3602     // CSS Fonts Module Level 3
3603     case CSSPropertyWebkitFontFeatureSettings: {
3604         if (primitiveValue && primitiveValue->getIdent() == CSSValueNormal) {
3605             setFontDescription(m_style->fontDescription().makeNormalFeatureSettings());
3606             return;
3607         }
3608
3609         if (!value->isValueList())
3610             return;
3611
3612         FontDescription fontDescription = m_style->fontDescription();
3613         CSSValueList* list = static_cast<CSSValueList*>(value);
3614         RefPtr<FontFeatureSettings> settings = FontFeatureSettings::create();
3615         int len = list->length();
3616         for (int i = 0; i < len; ++i) {
3617             CSSValue* item = list->itemWithoutBoundsCheck(i);
3618             if (!item->isFontFeatureValue())
3619                 continue;
3620             FontFeatureValue* feature = static_cast<FontFeatureValue*>(item);
3621             settings->append(FontFeature(feature->tag(), feature->value()));
3622         }
3623         fontDescription.setFeatureSettings(settings.release());
3624         setFontDescription(fontDescription);
3625         return;
3626     }
3627
3628 #if ENABLE(CSS_FILTERS)
3629     case CSSPropertyWebkitFilter: {
3630         HANDLE_INHERIT_AND_INITIAL(filter, Filter);
3631         FilterOperations operations;
3632         createFilterOperations(value, style(), m_rootElementStyle, operations);
3633         m_style->setFilter(operations);
3634         return;
3635     }
3636 #endif
3637 #if ENABLE(CSS_GRID_LAYOUT)
3638     case CSSPropertyWebkitGridColumns: {
3639         Vector<Length> lengths;
3640         if (!createGridTrackList(value, lengths, this))
3641             return;
3642         m_style->setGridColumns(lengths);
3643         return;
3644     }
3645     case CSSPropertyWebkitGridRows: {
3646         Vector<Length> lengths;
3647         if (!createGridTrackList(value, lengths, this))
3648             return;
3649         m_style->setGridRows(lengths);
3650         return;
3651     }
3652 #endif
3653
3654     // These properties are implemented in the CSSStyleApplyProperty lookup table.
3655     case CSSPropertyColor:
3656     case CSSPropertyDirection:
3657     case CSSPropertyDisplay:
3658     case CSSPropertyBackgroundAttachment:
3659     case CSSPropertyBackgroundClip:
3660     case CSSPropertyWebkitBackgroundClip:
3661     case CSSPropertyWebkitBackgroundComposite:
3662     case CSSPropertyBackgroundOrigin:
3663     case CSSPropertyWebkitBackgroundOrigin:
3664     case CSSPropertyBackgroundImage:
3665     case CSSPropertyWebkitAspectRatio:
3666     case CSSPropertyBackgroundSize:
3667     case CSSPropertyWebkitBackgroundSize:
3668     case CSSPropertyWebkitMaskAttachment:
3669     case CSSPropertyWebkitMaskClip:
3670     case CSSPropertyWebkitMaskComposite:
3671     case CSSPropertyWebkitMaskOrigin:
3672     case CSSPropertyWebkitMaskImage:
3673     case CSSPropertyWebkitMaskSize:
3674     case CSSPropertyBackgroundColor:
3675     case CSSPropertyBorderBottomColor:
3676     case CSSPropertyBorderLeftColor:
3677     case CSSPropertyBorderRightColor:
3678     case CSSPropertyBorderTopColor:
3679     case CSSPropertyBorderTopStyle:
3680     case CSSPropertyBorderRightStyle:
3681     case CSSPropertyBorderBottomStyle:
3682     case CSSPropertyBorderLeftStyle:
3683     case CSSPropertyBorderTopWidth:
3684     case CSSPropertyBorderRightWidth:
3685     case CSSPropertyBorderBottomWidth:
3686     case CSSPropertyBorderLeftWidth:
3687     case CSSPropertyBorder:
3688     case CSSPropertyBorderStyle:
3689     case CSSPropertyBorderWidth:
3690     case CSSPropertyBorderColor:
3691     case CSSPropertyBorderImage:
3692     case CSSPropertyWebkitBorderImage:
3693     case CSSPropertyWebkitMaskBoxImage:
3694     case CSSPropertyBorderImageOutset:
3695     case CSSPropertyWebkitMaskBoxImageOutset:
3696     case CSSPropertyBorderImageRepeat:
3697     case CSSPropertyWebkitMaskBoxImageRepeat:
3698     case CSSPropertyBorderImageSlice:
3699     case CSSPropertyWebkitMaskBoxImageSlice:
3700     case CSSPropertyBorderImageWidth:
3701     case CSSPropertyWebkitMaskBoxImageWidth:
3702     case CSSPropertyBorderImageSource:
3703     case CSSPropertyWebkitMaskBoxImageSource:
3704     case CSSPropertyBorderTop:
3705     case CSSPropertyBorderRight:
3706     case CSSPropertyBorderBottom:
3707     case CSSPropertyBorderLeft:
3708     case CSSPropertyBorderRadius:
3709     case CSSPropertyWebkitBorderRadius:
3710     case CSSPropertyBorderTopLeftRadius:
3711     case CSSPropertyBorderTopRightRadius:
3712     case CSSPropertyBorderBottomLeftRadius:
3713     case CSSPropertyBorderBottomRightRadius:
3714     case CSSPropertyBorderSpacing:
3715     case CSSPropertyWebkitBorderHorizontalSpacing:
3716     case CSSPropertyWebkitBorderVerticalSpacing:
3717     case CSSPropertyCounterIncrement:
3718     case CSSPropertyCounterReset:
3719     case CSSPropertyLetterSpacing:
3720     case CSSPropertyWordSpacing:
3721     case CSSPropertyWebkitFlexOrder:
3722     case CSSPropertyWebkitFlexPack:
3723     case CSSPropertyWebkitFlexItemAlign:
3724     case CSSPropertyWebkitFlexDirection:
3725     case CSSPropertyWebkitFlexFlow:
3726     case CSSPropertyWebkitFlexWrap:
3727     case CSSPropertyFontSize:
3728     case CSSPropertyFontStyle:
3729     case CSSPropertyFontVariant:
3730     case CSSPropertyTextRendering:
3731     case CSSPropertyWebkitTextOrientation:
3732     case CSSPropertyWebkitFontSmoothing:
3733     case CSSPropertyFontWeight:
3734     case CSSPropertyOutline:
3735     case CSSPropertyOutlineStyle:
3736     case CSSPropertyOutlineWidth:
3737     case CSSPropertyOutlineOffset:
3738     case CSSPropertyWebkitColumnRuleWidth:
3739     case CSSPropertyOutlineColor:
3740     case CSSPropertyWebkitColumnRuleColor:
3741     case CSSPropertyWebkitTextEmphasisColor:
3742     case CSSPropertyWebkitTextFillColor:
3743     case CSSPropertyWebkitTextStrokeColor:
3744     case CSSPropertyBackgroundPosition:
3745     case CSSPropertyBackgroundPositionX:
3746     case CSSPropertyBackgroundPositionY:
3747     case CSSPropertyWebkitMaskPosition:
3748     case CSSPropertyWebkitMaskPositionX:
3749     case CSSPropertyWebkitMaskPositionY:
3750     case CSSPropertyBackgroundRepeat:
3751     case CSSPropertyBackgroundRepeatX:
3752     case CSSPropertyBackgroundRepeatY:
3753     case CSSPropertyWebkitMaskRepeat:
3754     case CSSPropertyWebkitMaskRepeatX:
3755     case CSSPropertyWebkitMaskRepeatY:
3756     case CSSPropertyOverflow:
3757     case CSSPropertyOverflowX:
3758     case CSSPropertyOverflowY:
3759     case CSSPropertyMaxWidth:
3760     case CSSPropertyTop:
3761     case CSSPropertyLeft:
3762     case CSSPropertyRight:
3763     case CSSPropertyBottom:
3764     case CSSPropertyWidth:
3765     case CSSPropertyMinWidth:
3766     case CSSPropertyLineHeight:
3767     case CSSPropertyListStyle:
3768     case CSSPropertyListStyleImage:
3769     case CSSPropertyListStylePosition:
3770     case CSSPropertyListStyleType:
3771     case CSSPropertyMarginTop:
3772     case CSSPropertyMarginRight:
3773     case CSSPropertyMarginBottom:
3774     case CSSPropertyMarginLeft:
3775     case CSSPropertyMargin:
3776     case CSSPropertyPaddingTop:
3777     case CSSPropertyPaddingRight:
3778     case CSSPropertyPaddingBottom:
3779     case CSSPropertyPaddingLeft:
3780     case CSSPropertyPadding:
3781     case CSSPropertyResize:
3782     case CSSPropertySize:
3783     case CSSPropertyTextAlign:
3784     case CSSPropertyTextDecoration:
3785     case CSSPropertyTextIndent:
3786     case CSSPropertyMaxHeight:
3787     case CSSPropertyHeight:
3788     case CSSPropertyMinHeight:
3789     case CSSPropertyVerticalAlign:
3790     case CSSPropertyWebkitTransformOriginX:
3791     case CSSPropertyWebkitTransformOriginY:
3792     case CSSPropertyWebkitTransformOriginZ:
3793     case CSSPropertyWebkitTransformOrigin:
3794     case CSSPropertyWebkitPerspectiveOriginX:
3795     case CSSPropertyWebkitPerspectiveOriginY:
3796     case CSSPropertyWebkitPerspectiveOrigin:
3797     case CSSPropertyWebkitAnimationDelay:
3798     case CSSPropertyWebkitAnimationDirection:
3799     case CSSPropertyWebkitAnimationDuration:
3800     case CSSPropertyWebkitAnimationFillMode:
3801     case CSSPropertyWebkitAnimationIterationCount:
3802     case CSSPropertyWebkitAnimationName:
3803     case CSSPropertyWebkitAnimationPlayState:
3804     case CSSPropertyWebkitAnimationTimingFunction:
3805     case CSSPropertyWebkitTransitionDelay:
3806     case CSSPropertyWebkitTransitionDuration:
3807     case CSSPropertyWebkitTransitionProperty:
3808     case CSSPropertyWebkitTransitionTimingFunction:
3809     case CSSPropertyCursor:
3810     case CSSPropertyWebkitColumns:
3811     case CSSPropertyWebkitColumnCount:
3812     case CSSPropertyWebkitColumnGap:
3813     case CSSPropertyWebkitColumnWidth:
3814     case CSSPropertyWebkitFlowInto:
3815     case CSSPropertyWebkitFlowFrom:
3816     case CSSPropertyWebkitFontKerning:
3817     case CSSPropertyWebkitHighlight:
3818     case CSSPropertyWebkitHyphenateCharacter:
3819     case CSSPropertyWebkitHyphenateLimitAfter:
3820     case CSSPropertyWebkitHyphenateLimitBefore:
3821     case CSSPropertyWebkitHyphenateLimitLines:
3822     case CSSPropertyWebkitLineGrid:
3823     case CSSPropertyWebkitLineGridSnap:
3824     case CSSPropertyWebkitTextCombine:
3825     case CSSPropertyWebkitTextEmphasisPosition:
3826     case CSSPropertyWebkitTextEmphasisStyle:
3827     case CSSPropertyWebkitWrapMargin:
3828     case CSSPropertyWebkitWrapPadding:
3829     case CSSPropertyWebkitWrapFlow:
3830     case CSSPropertyWebkitWrapThrough:
3831     case CSSPropertyWebkitWrap:
3832     case CSSPropertyZIndex:
3833     case CSSPropertyZoom:
3834         ASSERT_NOT_REACHED();
3835         return;
3836 #if ENABLE(SVG)
3837     default:
3838         // Try the SVG properties
3839         applySVGProperty(id, value);
3840         return;
3841 #endif
3842     }
3843 }
3844
3845 void CSSStyleSelector::mapFillAttachment(CSSPropertyID, FillLayer* layer, CSSValue* value)
3846 {
3847     if (value->isInitialValue()) {
3848         layer->setAttachment(FillLayer::initialFillAttachment(layer->type()));
3849         return;
3850     }
3851
3852     if (!value->isPrimitiveValue())
3853         return;
3854
3855     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
3856     switch (primitiveValue->getIdent()) {
3857         case CSSValueFixed:
3858             layer->setAttachment(FixedBackgroundAttachment);
3859             break;
3860         case CSSValueScroll:
3861             layer->setAttachment(ScrollBackgroundAttachment);
3862             break;
3863         case CSSValueLocal:
3864             layer->setAttachment(LocalBackgroundAttachment);
3865             break;
3866         default:
3867             return;
3868     }
3869 }
3870
3871 void CSSStyleSelector::mapFillClip(CSSPropertyID, FillLayer* layer, CSSValue* value)