[CSS Shapes] CORS-enabled fetch for shape image values
[WebKit-https.git] / Source / WebCore / css / StyleResolver.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, 2013 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  * Copyright (C) 2012 Google Inc. All rights reserved.
12  *
13  * This library is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU Library General Public
15  * License as published by the Free Software Foundation; either
16  * version 2 of the License, or (at your option) any later version.
17  *
18  * This library is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21  * Library General Public License for more details.
22  *
23  * You should have received a copy of the GNU Library General Public License
24  * along with this library; see the file COPYING.LIB.  If not, write to
25  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
26  * Boston, MA 02110-1301, USA.
27  */
28
29 #include "config.h"
30 #include "StyleResolver.h"
31
32 #include "Attribute.h"
33 #include "CSSBorderImage.h"
34 #include "CSSCalculationValue.h"
35 #include "CSSCursorImageValue.h"
36 #include "CSSDefaultStyleSheets.h"
37 #include "CSSFilterImageValue.h"
38 #include "CSSFontFaceRule.h"
39 #include "CSSFontFeatureValue.h"
40 #include "CSSFontSelector.h"
41 #include "CSSFontValue.h"
42 #include "CSSGridTemplateValue.h"
43 #include "CSSLineBoxContainValue.h"
44 #include "CSSPageRule.h"
45 #include "CSSParser.h"
46 #include "CSSPrimitiveValueMappings.h"
47 #include "CSSPropertyNames.h"
48 #include "CSSReflectValue.h"
49 #include "CSSSelector.h"
50 #include "CSSSelectorList.h"
51 #include "CSSShadowValue.h"
52 #include "CSSStyleRule.h"
53 #include "CSSSupportsRule.h"
54 #include "CSSTimingFunctionValue.h"
55 #include "CSSValueList.h"
56 #include "CachedImage.h"
57 #include "CalculationValue.h"
58 #include "ContentData.h"
59 #include "Counter.h"
60 #include "CounterContent.h"
61 #include "CursorList.h"
62 #include "DeprecatedStyleBuilder.h"
63 #include "DocumentStyleSheetCollection.h"
64 #include "ElementRuleCollector.h"
65 #include "Frame.h"
66 #include "FrameSelection.h"
67 #include "FrameView.h"
68 #include "HTMLDocument.h"
69 #include "HTMLIFrameElement.h"
70 #include "HTMLInputElement.h"
71 #include "HTMLNames.h"
72 #include "HTMLOptGroupElement.h"
73 #include "HTMLOptionElement.h"
74 #include "HTMLProgressElement.h"
75 #include "HTMLStyleElement.h"
76 #include "HTMLTableElement.h"
77 #include "HTMLTextAreaElement.h"
78 #include "InsertionPoint.h"
79 #include "InspectorInstrumentation.h"
80 #include "KeyframeList.h"
81 #include "LinkHash.h"
82 #include "LocaleToScriptMapping.h"
83 #include "MathMLNames.h"
84 #include "MediaList.h"
85 #include "MediaQueryEvaluator.h"
86 #include "NodeRenderStyle.h"
87 #include "NodeRenderingTraversal.h"
88 #include "Page.h"
89 #include "PageRuleCollector.h"
90 #include "Pair.h"
91 #include "QuotesData.h"
92 #include "Rect.h"
93 #include "RenderRegion.h"
94 #include "RenderScrollbar.h"
95 #include "RenderScrollbarTheme.h"
96 #include "RenderStyleConstants.h"
97 #include "RenderTheme.h"
98 #include "RenderView.h"
99 #include "RuleSet.h"
100 #include "SVGDocumentExtensions.h"
101 #include "SVGFontFaceElement.h"
102 #include "SecurityOrigin.h"
103 #include "SelectorCheckerFastPath.h"
104 #include "Settings.h"
105 #include "ShadowData.h"
106 #include "ShadowRoot.h"
107 #include "StyleCachedImage.h"
108 #include "StyleFontSizeFunctions.h"
109 #include "StyleGeneratedImage.h"
110 #include "StylePendingImage.h"
111 #include "StylePropertySet.h"
112 #include "StylePropertyShorthand.h"
113 #include "StyleRule.h"
114 #include "StyleRuleImport.h"
115 #include "StyleSheetContents.h"
116 #include "StyleSheetList.h"
117 #include "Text.h"
118 #include "TransformFunctions.h"
119 #include "TransformOperations.h"
120 #include "UserAgentStyleSheets.h"
121 #include "ViewportStyleResolver.h"
122 #include "VisitedLinkState.h"
123 #include "WebKitCSSKeyframeRule.h"
124 #include "WebKitCSSKeyframesRule.h"
125 #include "WebKitCSSRegionRule.h"
126 #include "WebKitCSSTransformValue.h"
127 #include "WebKitFontFamilyNames.h"
128 #include "XMLNames.h"
129 #include <wtf/StdLibExtras.h>
130 #include <wtf/Vector.h>
131
132 #if ENABLE(CSS_FILTERS)
133 #include "FilterOperation.h"
134 #include "WebKitCSSFilterValue.h"
135 #endif
136
137 #if ENABLE(CSS_IMAGE_SET)
138 #include "CSSImageSetValue.h"
139 #include "StyleCachedImageSet.h"
140 #endif
141
142 #if ENABLE(CSS_SHADERS)
143 #include "CustomFilterArrayParameter.h"
144 #include "CustomFilterColorParameter.h"
145 #include "CustomFilterConstants.h"
146 #include "CustomFilterNumberParameter.h"
147 #include "CustomFilterOperation.h"
148 #include "CustomFilterParameter.h"
149 #include "CustomFilterProgramInfo.h"
150 #include "CustomFilterTransformParameter.h"
151 #include "StyleCachedShader.h"
152 #include "StyleCustomFilterProgram.h"
153 #include "StyleCustomFilterProgramCache.h"
154 #include "StylePendingShader.h"
155 #include "StyleShader.h"
156 #include "WebKitCSSMixFunctionValue.h"
157 #include "WebKitCSSShaderValue.h"
158 #endif
159
160 #if ENABLE(CSS_SHAPES)
161 #include "CachedResourceLoader.h"
162 #endif
163
164 #if ENABLE(CSS_VARIABLES)
165 #include "CSSVariableValue.h"
166 #endif
167
168 #if ENABLE(DASHBOARD_SUPPORT)
169 #include "DashboardRegion.h"
170 #endif
171
172 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
173 #include "HTMLAudioElement.h"
174 #endif
175
176 #if ENABLE(SVG)
177 #include "CachedSVGDocument.h"
178 #include "CachedSVGDocumentReference.h"
179 #include "SVGDocument.h"
180 #include "SVGElement.h"
181 #include "SVGNames.h"
182 #include "SVGURIReference.h"
183 #include "WebKitCSSSVGDocumentValue.h"
184 #endif
185
186 #if ENABLE(VIDEO_TRACK)
187 #include "WebVTTElement.h"
188 #endif
189
190 namespace WebCore {
191
192 using namespace HTMLNames;
193
194 #define HANDLE_INHERIT(prop, Prop) \
195 if (isInherit) { \
196     m_state.style()->set##Prop(m_state.parentStyle()->prop()); \
197     return; \
198 }
199
200 #define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
201 HANDLE_INHERIT(prop, Prop) \
202 if (isInitial) { \
203     m_state.style()->set##Prop(RenderStyle::initial##Prop()); \
204     return; \
205 }
206
207 RenderStyle* StyleResolver::s_styleNotYetAvailable;
208
209 inline void StyleResolver::State::cacheBorderAndBackground()
210 {
211     m_hasUAAppearance = m_style->hasAppearance();
212     if (m_hasUAAppearance) {
213         m_borderData = m_style->border();
214         m_backgroundData = *m_style->backgroundLayers();
215         m_backgroundColor = m_style->backgroundColor();
216     }
217 }
218
219 inline void StyleResolver::State::clear()
220 {
221     m_element = 0;
222     m_styledElement = 0;
223     m_parentStyle = 0;
224     m_parentNode = 0;
225     m_regionForStyling = 0;
226     m_pendingImageProperties.clear();
227 #if ENABLE(CSS_SHADERS)
228     m_hasPendingShaders = false;
229 #endif
230 #if ENABLE(CSS_FILTERS) && ENABLE(SVG)
231     m_pendingSVGDocuments.clear();
232 #endif
233 }
234
235 void StyleResolver::MatchResult::addMatchedProperties(const StylePropertySet& properties, StyleRule* rule, unsigned linkMatchType, PropertyWhitelistType propertyWhitelistType)
236 {
237     matchedProperties.grow(matchedProperties.size() + 1);
238     StyleResolver::MatchedProperties& newProperties = matchedProperties.last();
239     newProperties.properties = const_cast<StylePropertySet*>(&properties);
240     newProperties.linkMatchType = linkMatchType;
241     newProperties.whitelistType = propertyWhitelistType;
242     matchedRules.append(rule);
243 }
244
245 StyleResolver::StyleResolver(Document& document, bool matchAuthorAndUserStyles)
246     : m_matchedPropertiesCacheAdditionsSinceLastSweep(0)
247     , m_matchedPropertiesCacheSweepTimer(this, &StyleResolver::sweepMatchedPropertiesCache)
248     , m_document(document)
249     , m_matchAuthorAndUserStyles(matchAuthorAndUserStyles)
250     , m_fontSelector(CSSFontSelector::create(&m_document))
251 #if ENABLE(CSS_DEVICE_ADAPTATION)
252     , m_viewportStyleResolver(ViewportStyleResolver::create(&document))
253 #endif
254     , m_deprecatedStyleBuilder(DeprecatedStyleBuilder::sharedStyleBuilder())
255     , m_styleMap(this)
256 {
257     Element* root = m_document.documentElement();
258
259     CSSDefaultStyleSheets::initDefaultStyle(root);
260
261     // construct document root element default style. this is needed
262     // to evaluate media queries that contain relative constraints, like "screen and (max-width: 10em)"
263     // This is here instead of constructor, because when constructor is run,
264     // document doesn't have documentElement
265     // NOTE: this assumes that element that gets passed to styleForElement -call
266     // is always from the document that owns the style selector
267     FrameView* view = m_document.view();
268     if (view)
269         m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType()));
270     else
271         m_medium = adoptPtr(new MediaQueryEvaluator("all"));
272
273     if (root)
274         m_rootDefaultStyle = styleForElement(root, 0, DisallowStyleSharing, MatchOnlyUserAgentRules);
275
276     if (m_rootDefaultStyle && view)
277         m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType(), &view->frame(), m_rootDefaultStyle.get()));
278
279     m_ruleSets.resetAuthorStyle();
280
281     DocumentStyleSheetCollection& styleSheetCollection = m_document.styleSheetCollection();
282     m_ruleSets.initUserStyle(styleSheetCollection, *m_medium, *this);
283
284 #if ENABLE(SVG_FONTS)
285     if (m_document.svgExtensions()) {
286         const HashSet<SVGFontFaceElement*>& svgFontFaceElements = m_document.svgExtensions()->svgFontFaceElements();
287         HashSet<SVGFontFaceElement*>::const_iterator end = svgFontFaceElements.end();
288         for (HashSet<SVGFontFaceElement*>::const_iterator it = svgFontFaceElements.begin(); it != end; ++it)
289             fontSelector()->addFontFaceRule((*it)->fontFaceRule());
290     }
291 #endif
292
293     appendAuthorStyleSheets(0, styleSheetCollection.activeAuthorStyleSheets());
294 }
295
296 void StyleResolver::appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet>>& styleSheets)
297 {
298     m_ruleSets.appendAuthorStyleSheets(firstNew, styleSheets, m_medium.get(), m_inspectorCSSOMWrappers, document().isViewSource(), this);
299     if (document().renderView() && document().renderView()->style())
300         document().renderView()->style()->font().update(fontSelector());
301
302 #if ENABLE(CSS_DEVICE_ADAPTATION)
303     viewportStyleResolver()->resolve();
304 #endif
305 }
306
307 void StyleResolver::pushParentElement(Element* parent)
308 {
309     const ContainerNode* parentsParent = parent->parentOrShadowHostElement();
310
311     // We are not always invoked consistently. For example, script execution can cause us to enter
312     // style recalc in the middle of tree building. We may also be invoked from somewhere within the tree.
313     // Reset the stack in this case, or if we see a new root element.
314     // Otherwise just push the new parent.
315     if (!parentsParent || m_selectorFilter.parentStackIsEmpty())
316         m_selectorFilter.setupParentStack(parent);
317     else
318         m_selectorFilter.pushParent(parent);
319
320     // Note: We mustn't skip ShadowRoot nodes for the scope stack.
321     if (m_scopeResolver)
322         m_scopeResolver->push(parent, parent->parentOrShadowHostNode());
323 }
324
325 void StyleResolver::popParentElement(Element* parent)
326 {
327     // Note that we may get invoked for some random elements in some wacky cases during style resolve.
328     // Pause maintaining the stack in this case.
329     if (m_selectorFilter.parentStackIsConsistent(parent))
330         m_selectorFilter.popParent();
331     if (m_scopeResolver)
332         m_scopeResolver->pop(parent);
333 }
334
335 void StyleResolver::pushParentShadowRoot(const ShadowRoot* shadowRoot)
336 {
337     ASSERT(shadowRoot->hostElement());
338     if (m_scopeResolver)
339         m_scopeResolver->push(shadowRoot, shadowRoot->hostElement());
340 }
341
342 void StyleResolver::popParentShadowRoot(const ShadowRoot* shadowRoot)
343 {
344     ASSERT(shadowRoot->hostElement());
345     if (m_scopeResolver)
346         m_scopeResolver->pop(shadowRoot);
347 }
348
349 // This is a simplified style setting function for keyframe styles
350 void StyleResolver::addKeyframeStyle(PassRefPtr<StyleRuleKeyframes> rule)
351 {
352     AtomicString s(rule->name());
353     m_keyframesRuleMap.set(s.impl(), rule);
354 }
355
356 StyleResolver::~StyleResolver()
357 {
358     m_fontSelector->clearDocument();
359
360 #if ENABLE(CSS_DEVICE_ADAPTATION)
361     m_viewportStyleResolver->clearDocument();
362 #endif
363 }
364
365 void StyleResolver::sweepMatchedPropertiesCache(Timer<StyleResolver>*)
366 {
367     // Look for cache entries containing a style declaration with a single ref and remove them.
368     // This may happen when an element attribute mutation causes it to generate a new inlineStyle()
369     // or presentationAttributeStyle(), potentially leaving this cache with the last ref on the old one.
370     Vector<unsigned, 16> toRemove;
371     MatchedPropertiesCache::iterator it = m_matchedPropertiesCache.begin();
372     MatchedPropertiesCache::iterator end = m_matchedPropertiesCache.end();
373     for (; it != end; ++it) {
374         Vector<MatchedProperties>& matchedProperties = it->value.matchedProperties;
375         for (size_t i = 0; i < matchedProperties.size(); ++i) {
376             if (matchedProperties[i].properties->hasOneRef()) {
377                 toRemove.append(it->key);
378                 break;
379             }
380         }
381     }
382     for (size_t i = 0; i < toRemove.size(); ++i)
383         m_matchedPropertiesCache.remove(toRemove[i]);
384
385     m_matchedPropertiesCacheAdditionsSinceLastSweep = 0;
386 }
387
388 inline bool StyleResolver::styleSharingCandidateMatchesHostRules()
389 {
390 #if ENABLE(SHADOW_DOM)
391     return m_scopeResolver && m_scopeResolver->styleSharingCandidateMatchesHostRules(m_state.element());
392 #else
393     return false;
394 #endif
395 }
396
397 bool StyleResolver::classNamesAffectedByRules(const SpaceSplitString& classNames) const
398 {
399     for (unsigned i = 0; i < classNames.size(); ++i) {
400         if (m_ruleSets.features().classesInRules.contains(classNames[i].impl()))
401             return true;
402     }
403     return false;
404 }
405
406 inline void StyleResolver::State::initElement(Element* e)
407 {
408     m_element = e;
409     m_styledElement = e && e->isStyledElement() ? static_cast<StyledElement*>(e) : 0;
410     m_elementLinkState = e ? e->document().visitedLinkState().determineLinkState(e) : NotInsideLink;
411 }
412
413 inline void StyleResolver::initElement(Element* e)
414 {
415     if (m_state.element() != e) {
416         m_state.initElement(e);
417         if (e && e == e->document().documentElement()) {
418             e->document().setDirectionSetOnDocumentElement(false);
419             e->document().setWritingModeSetOnDocumentElement(false);
420         }
421     }
422 }
423
424 inline void StyleResolver::State::initForStyleResolve(Document& document, Element* e, RenderStyle* parentStyle, RenderRegion* regionForStyling)
425 {
426     m_regionForStyling = regionForStyling;
427
428     if (e) {
429         m_parentNode = NodeRenderingTraversal::parent(e);
430         bool resetStyleInheritance = hasShadowRootParent(e) && toShadowRoot(e->parentNode())->resetStyleInheritance();
431         m_parentStyle = resetStyleInheritance ? 0 :
432             parentStyle ? parentStyle :
433             m_parentNode ? m_parentNode->renderStyle() : 0;
434     } else {
435         m_parentNode = 0;
436         m_parentStyle = parentStyle;
437     }
438
439     Node* docElement = e ? e->document().documentElement() : 0;
440     RenderStyle* docStyle = document.renderStyle();
441     m_rootElementStyle = docElement && e != docElement ? docElement->renderStyle() : docStyle;
442
443     m_style = 0;
444     m_pendingImageProperties.clear();
445     m_fontDirty = false;
446 }
447
448 static const unsigned cStyleSearchThreshold = 10;
449 static const unsigned cStyleSearchLevelThreshold = 10;
450
451 static inline bool parentElementPreventsSharing(const Element* parentElement)
452 {
453     if (!parentElement)
454         return false;
455     return parentElement->hasFlagsSetDuringStylingOfChildren();
456 }
457
458 Node* StyleResolver::locateCousinList(Element* parent, unsigned& visitedNodeCount) const
459 {
460     if (visitedNodeCount >= cStyleSearchThreshold * cStyleSearchLevelThreshold)
461         return 0;
462     if (!parent || !parent->isStyledElement())
463         return 0;
464     StyledElement* p = static_cast<StyledElement*>(parent);
465     if (p->inlineStyle())
466         return 0;
467 #if ENABLE(SVG)
468     if (p->isSVGElement() && toSVGElement(p)->animatedSMILStyleProperties())
469         return 0;
470 #endif
471     if (p->hasID() && m_ruleSets.features().idsInRules.contains(p->idForStyleResolution().impl()))
472         return 0;
473
474     RenderStyle* parentStyle = p->renderStyle();
475     unsigned subcount = 0;
476     Node* thisCousin = p;
477     Node* currentNode = p->previousSibling();
478
479     // Reserve the tries for this level. This effectively makes sure that the algorithm
480     // will never go deeper than cStyleSearchLevelThreshold levels into recursion.
481     visitedNodeCount += cStyleSearchThreshold;
482     while (thisCousin) {
483         while (currentNode) {
484             ++subcount;
485             if (currentNode->renderStyle() == parentStyle && currentNode->lastChild()
486                 && currentNode->isElementNode() && !parentElementPreventsSharing(toElement(currentNode))
487 #if ENABLE(SHADOW_DOM)
488                 && !toElement(currentNode)->authorShadowRoot()
489 #endif
490                 ) {
491                 // Adjust for unused reserved tries.
492                 visitedNodeCount -= cStyleSearchThreshold - subcount;
493                 return currentNode->lastChild();
494             }
495             if (subcount >= cStyleSearchThreshold)
496                 return 0;
497             currentNode = currentNode->previousSibling();
498         }
499         currentNode = locateCousinList(thisCousin->parentElement(), visitedNodeCount);
500         thisCousin = currentNode;
501     }
502
503     return 0;
504 }
505
506 bool StyleResolver::styleSharingCandidateMatchesRuleSet(RuleSet* ruleSet)
507 {
508     if (!ruleSet)
509         return false;
510
511     ElementRuleCollector collector(this, m_state);
512     return collector.hasAnyMatchingRules(ruleSet);
513 }
514
515 bool StyleResolver::canShareStyleWithControl(StyledElement* element) const
516 {
517     const State& state = m_state;
518     HTMLInputElement* thisInputElement = element->toInputElement();
519     HTMLInputElement* otherInputElement = state.element()->toInputElement();
520
521     if (!thisInputElement || !otherInputElement)
522         return false;
523
524     if (thisInputElement->elementData() != otherInputElement->elementData()) {
525         if (thisInputElement->fastGetAttribute(typeAttr) != otherInputElement->fastGetAttribute(typeAttr))
526             return false;
527         if (thisInputElement->fastGetAttribute(readonlyAttr) != otherInputElement->fastGetAttribute(readonlyAttr))
528             return false;
529     }
530
531     if (thisInputElement->isAutofilled() != otherInputElement->isAutofilled())
532         return false;
533     if (thisInputElement->shouldAppearChecked() != otherInputElement->shouldAppearChecked())
534         return false;
535     if (thisInputElement->shouldAppearIndeterminate() != otherInputElement->shouldAppearIndeterminate())
536         return false;
537     if (thisInputElement->isRequired() != otherInputElement->isRequired())
538         return false;
539
540     if (element->isDisabledFormControl() != state.element()->isDisabledFormControl())
541         return false;
542
543     if (element->isDefaultButtonForForm() != state.element()->isDefaultButtonForForm())
544         return false;
545
546     if (state.document().containsValidityStyleRules()) {
547         bool willValidate = element->willValidate();
548
549         if (willValidate != state.element()->willValidate())
550             return false;
551
552         if (willValidate && (element->isValidFormControlElement() != state.element()->isValidFormControlElement()))
553             return false;
554
555         if (element->isInRange() != state.element()->isInRange())
556             return false;
557
558         if (element->isOutOfRange() != state.element()->isOutOfRange())
559             return false;
560     }
561
562     return true;
563 }
564
565 static inline bool elementHasDirectionAuto(Element* element)
566 {
567     // FIXME: This line is surprisingly hot, we may wish to inline hasDirectionAuto into StyleResolver.
568     return element->isHTMLElement() && toHTMLElement(element)->hasDirectionAuto();
569 }
570
571 bool StyleResolver::sharingCandidateHasIdenticalStyleAffectingAttributes(StyledElement* sharingCandidate) const
572 {
573     const State& state = m_state;
574     if (state.element()->elementData() == sharingCandidate->elementData())
575         return true;
576     if (state.element()->fastGetAttribute(XMLNames::langAttr) != sharingCandidate->fastGetAttribute(XMLNames::langAttr))
577         return false;
578     if (state.element()->fastGetAttribute(langAttr) != sharingCandidate->fastGetAttribute(langAttr))
579         return false;
580
581     if (!state.elementAffectedByClassRules()) {
582         if (sharingCandidate->hasClass() && classNamesAffectedByRules(sharingCandidate->classNames()))
583             return false;
584     } else if (sharingCandidate->hasClass()) {
585 #if ENABLE(SVG)
586         // SVG elements require a (slow!) getAttribute comparision because "class" is an animatable attribute for SVG.
587         if (state.element()->isSVGElement()) {
588             if (state.element()->getAttribute(classAttr) != sharingCandidate->getAttribute(classAttr))
589                 return false;
590         } else {
591 #endif
592             if (state.element()->classNames() != sharingCandidate->classNames())
593                 return false;
594 #if ENABLE(SVG)
595         }
596 #endif
597     } else
598         return false;
599
600     if (state.styledElement()->presentationAttributeStyle() != sharingCandidate->presentationAttributeStyle())
601         return false;
602
603 #if ENABLE(PROGRESS_ELEMENT)
604     if (state.element()->hasTagName(progressTag)) {
605         if (state.element()->shouldAppearIndeterminate() != sharingCandidate->shouldAppearIndeterminate())
606             return false;
607     }
608 #endif
609
610     return true;
611 }
612
613 bool StyleResolver::canShareStyleWithElement(StyledElement* element) const
614 {
615     RenderStyle* style = element->renderStyle();
616     const State& state = m_state;
617
618     if (!style)
619         return false;
620     if (style->unique())
621         return false;
622     if (style->hasUniquePseudoStyle())
623         return false;
624     if (element->tagQName() != state.element()->tagQName())
625         return false;
626     if (element->inlineStyle())
627         return false;
628     if (element->needsStyleRecalc())
629         return false;
630 #if ENABLE(SVG)
631     if (element->isSVGElement() && toSVGElement(element)->animatedSMILStyleProperties())
632         return false;
633 #endif
634     if (element->isLink() != state.element()->isLink())
635         return false;
636     if (element->hovered() != state.element()->hovered())
637         return false;
638     if (element->active() != state.element()->active())
639         return false;
640     if (element->focused() != state.element()->focused())
641         return false;
642     if (element->shadowPseudoId() != state.element()->shadowPseudoId())
643         return false;
644     if (element == element->document().cssTarget())
645         return false;
646     if (!sharingCandidateHasIdenticalStyleAffectingAttributes(element))
647         return false;
648     if (element->additionalPresentationAttributeStyle() != state.styledElement()->additionalPresentationAttributeStyle())
649         return false;
650
651     if (element->hasID() && m_ruleSets.features().idsInRules.contains(element->idForStyleResolution().impl()))
652         return false;
653
654     // FIXME: We should share style for option and optgroup whenever possible.
655     // Before doing so, we need to resolve issues in HTMLSelectElement::recalcListItems
656     // and RenderMenuList::setText. See also https://bugs.webkit.org/show_bug.cgi?id=88405
657     if (isHTMLOptionElement(element) || isHTMLOptGroupElement(element))
658         return false;
659
660     bool isControl = element->isFormControlElement();
661
662     if (isControl != state.element()->isFormControlElement())
663         return false;
664
665     if (isControl && !canShareStyleWithControl(element))
666         return false;
667
668     if (style->transitions() || style->animations())
669         return false;
670
671 #if USE(ACCELERATED_COMPOSITING)
672     // Turn off style sharing for elements that can gain layers for reasons outside of the style system.
673     // See comments in RenderObject::setStyle().
674     if (element->hasTagName(iframeTag) || element->hasTagName(frameTag) || element->hasTagName(embedTag) || element->hasTagName(objectTag) || element->hasTagName(appletTag) || element->hasTagName(canvasTag)
675 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
676         // With proxying, the media elements are backed by a RenderEmbeddedObject.
677         || element->hasTagName(videoTag) || isHTMLAudioElement(element)
678 #endif
679         )
680         return false;
681 #endif
682
683     if (elementHasDirectionAuto(element))
684         return false;
685
686     if (element->isLink() && state.elementLinkState() != style->insideLink())
687         return false;
688
689 #if ENABLE(VIDEO_TRACK)
690     // Deny sharing styles between WebVTT and non-WebVTT nodes.
691     if (element->isWebVTTElement() != state.element()->isWebVTTElement())
692         return false;
693
694     if (element->isWebVTTElement() && state.element()->isWebVTTElement() && toWebVTTElement(element)->isPastNode() != toWebVTTElement(state.element())->isPastNode())
695         return false;
696 #endif
697
698 #if ENABLE(FULLSCREEN_API)
699     if (element == element->document().webkitCurrentFullScreenElement() || state.element() == state.document().webkitCurrentFullScreenElement())
700         return false;
701 #endif
702     return true;
703 }
704
705 inline StyledElement* StyleResolver::findSiblingForStyleSharing(Node* node, unsigned& count) const
706 {
707     for (; node; node = node->previousSibling()) {
708         if (!node->isStyledElement())
709             continue;
710         if (canShareStyleWithElement(static_cast<StyledElement*>(node)))
711             break;
712         if (count++ == cStyleSearchThreshold)
713             return 0;
714     }
715     return static_cast<StyledElement*>(node);
716 }
717
718 RenderStyle* StyleResolver::locateSharedStyle()
719 {
720     State& state = m_state;
721     if (!state.styledElement() || !state.parentStyle())
722         return 0;
723
724     // If the element has inline style it is probably unique.
725     if (state.styledElement()->inlineStyle())
726         return 0;
727 #if ENABLE(SVG)
728     if (state.styledElement()->isSVGElement() && toSVGElement(state.styledElement())->animatedSMILStyleProperties())
729         return 0;
730 #endif
731     // Ids stop style sharing if they show up in the stylesheets.
732     if (state.styledElement()->hasID() && m_ruleSets.features().idsInRules.contains(state.styledElement()->idForStyleResolution().impl()))
733         return 0;
734     if (parentElementPreventsSharing(state.element()->parentElement()))
735         return 0;
736     if (state.element() == state.document().cssTarget())
737         return 0;
738     if (elementHasDirectionAuto(state.element()))
739         return 0;
740
741     // Cache whether state.element is affected by any known class selectors.
742     // FIXME: This shouldn't be a member variable. The style sharing code could be factored out of StyleResolver.
743     state.setElementAffectedByClassRules(state.element() && state.element()->hasClass() && classNamesAffectedByRules(state.element()->classNames()));
744
745     // Check previous siblings and their cousins.
746     unsigned count = 0;
747     unsigned visitedNodeCount = 0;
748     StyledElement* shareElement = 0;
749     Node* cousinList = state.styledElement()->previousSibling();
750     while (cousinList) {
751         shareElement = findSiblingForStyleSharing(cousinList, count);
752         if (shareElement)
753             break;
754         cousinList = locateCousinList(cousinList->parentElement(), visitedNodeCount);
755     }
756
757     // If we have exhausted all our budget or our cousins.
758     if (!shareElement)
759         return 0;
760
761     // Can't share if sibling rules apply. This is checked at the end as it should rarely fail.
762     if (styleSharingCandidateMatchesRuleSet(m_ruleSets.sibling()))
763         return 0;
764     // Can't share if attribute rules apply.
765     if (styleSharingCandidateMatchesRuleSet(m_ruleSets.uncommonAttribute()))
766         return 0;
767     // Can't share if @host @-rules apply.
768     if (styleSharingCandidateMatchesHostRules())
769         return 0;
770     // Tracking child index requires unique style for each node. This may get set by the sibling rule match above.
771     if (parentElementPreventsSharing(state.element()->parentElement()))
772         return 0;
773     return shareElement->renderStyle();
774 }
775
776 static inline bool isAtShadowBoundary(const Element* element)
777 {
778     if (!element)
779         return false;
780     ContainerNode* parentNode = element->parentNode();
781     return parentNode && parentNode->isShadowRoot();
782 }
783
784 PassRef<RenderStyle> StyleResolver::styleForElement(Element* element, RenderStyle* defaultParent,
785     StyleSharingBehavior sharingBehavior, RuleMatchingBehavior matchingBehavior, RenderRegion* regionForStyling)
786 {
787     // Once an element has a renderer, we don't try to destroy it, since otherwise the renderer
788     // will vanish if a style recalc happens during loading.
789     if (sharingBehavior == AllowStyleSharing && !element->document().haveStylesheetsLoaded() && !element->renderer()) {
790         if (!s_styleNotYetAvailable) {
791             s_styleNotYetAvailable = &RenderStyle::create().leakRef();
792             s_styleNotYetAvailable->setDisplay(NONE);
793             s_styleNotYetAvailable->font().update(m_fontSelector);
794         }
795         element->document().setHasNodesWithPlaceholderStyle();
796         return *s_styleNotYetAvailable;
797     }
798
799     State& state = m_state;
800     initElement(element);
801     state.initForStyleResolve(document(), element, defaultParent, regionForStyling);
802     if (sharingBehavior == AllowStyleSharing) {
803         if (RenderStyle* sharedStyle = locateSharedStyle()) {
804             state.clear();
805             return *sharedStyle;
806         }
807     }
808
809     if (state.parentStyle()) {
810         state.setStyle(RenderStyle::create());
811         state.style()->inheritFrom(state.parentStyle(), isAtShadowBoundary(element) ? RenderStyle::AtShadowBoundary : RenderStyle::NotAtShadowBoundary);
812     } else {
813         state.setStyle(defaultStyleForElement());
814         state.setParentStyle(RenderStyle::clone(state.style()));
815     }
816
817     if (element->isLink()) {
818         state.style()->setIsLink(true);
819         EInsideLink linkState = state.elementLinkState();
820         if (linkState != NotInsideLink) {
821             bool forceVisited = InspectorInstrumentation::forcePseudoState(element, CSSSelector::PseudoVisited);
822             if (forceVisited)
823                 linkState = InsideVisitedLink;
824         }
825         state.style()->setInsideLink(linkState);
826     }
827
828     bool needsCollection = false;
829     CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement(element, needsCollection);
830     if (needsCollection)
831         m_ruleSets.collectFeatures(document().isViewSource(), m_scopeResolver.get());
832
833     ElementRuleCollector collector(this, state);
834     collector.setRegionForStyling(regionForStyling);
835     collector.setMedium(m_medium.get());
836
837     if (matchingBehavior == MatchOnlyUserAgentRules)
838         collector.matchUARules();
839     else
840         collector.matchAllRules(m_matchAuthorAndUserStyles, matchingBehavior != MatchAllRulesExcludingSMIL);
841
842     applyMatchedProperties(collector.matchedResult(), element);
843
844     // Clean up our style object's display and text decorations (among other fixups).
845     adjustRenderStyle(state.style(), state.parentStyle(), element);
846
847     state.clear(); // Clear out for the next resolve.
848
849     document().didAccessStyleResolver();
850
851     // Now return the style.
852     return state.takeStyle();
853 }
854
855 PassRef<RenderStyle> StyleResolver::styleForKeyframe(const RenderStyle* elementStyle, const StyleKeyframe* keyframe, KeyframeValue& keyframeValue)
856 {
857     MatchResult result;
858     result.addMatchedProperties(keyframe->properties());
859
860     ASSERT(!m_state.style());
861
862     State& state = m_state;
863
864     // Create the style
865     state.setStyle(RenderStyle::clone(elementStyle));
866     state.setLineHeightValue(0);
867
868     // We don't need to bother with !important. Since there is only ever one
869     // decl, there's nothing to override. So just add the first properties.
870     bool inheritedOnly = false;
871     applyMatchedProperties<HighPriorityProperties>(result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
872
873     // If our font got dirtied, go ahead and update it now.
874     updateFont();
875
876     // Line-height is set when we are sure we decided on the font-size
877     if (state.lineHeightValue())
878         applyProperty(CSSPropertyLineHeight, state.lineHeightValue());
879
880     // Now do rest of the properties.
881     applyMatchedProperties<LowPriorityProperties>(result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
882
883     // If our font got dirtied by one of the non-essential font props,
884     // go ahead and update it a second time.
885     updateFont();
886
887     // Start loading resources referenced by this style.
888     loadPendingResources();
889     
890     // Add all the animating properties to the keyframe.
891     unsigned propertyCount = keyframe->properties().propertyCount();
892     for (unsigned i = 0; i < propertyCount; ++i) {
893         CSSPropertyID property = keyframe->properties().propertyAt(i).id();
894         // Timing-function within keyframes is special, because it is not animated; it just
895         // describes the timing function between this keyframe and the next.
896         if (property != CSSPropertyWebkitAnimationTimingFunction)
897             keyframeValue.addProperty(property);
898     }
899
900     document().didAccessStyleResolver();
901
902     return state.takeStyle();
903 }
904
905 void StyleResolver::keyframeStylesForAnimation(Element* e, const RenderStyle* elementStyle, KeyframeList& list)
906 {
907     list.clear();
908
909     // Get the keyframesRule for this name
910     if (!e || list.animationName().isEmpty())
911         return;
912
913     m_keyframesRuleMap.checkConsistency();
914
915     KeyframesRuleMap::iterator it = m_keyframesRuleMap.find(list.animationName().impl());
916     if (it == m_keyframesRuleMap.end())
917         return;
918
919     const StyleRuleKeyframes* keyframesRule = it->value.get();
920
921     // Construct and populate the style for each keyframe
922     const Vector<RefPtr<StyleKeyframe>>& keyframes = keyframesRule->keyframes();
923     for (unsigned i = 0; i < keyframes.size(); ++i) {
924         // Apply the declaration to the style. This is a simplified version of the logic in styleForElement
925         initElement(e);
926         m_state.initForStyleResolve(document(), e);
927
928         const StyleKeyframe* keyframe = keyframes[i].get();
929
930         KeyframeValue keyframeValue(0, 0);
931         keyframeValue.setStyle(styleForKeyframe(elementStyle, keyframe, keyframeValue));
932
933         // Add this keyframe style to all the indicated key times
934         Vector<double> keys;
935         keyframe->getKeys(keys);
936         for (size_t keyIndex = 0; keyIndex < keys.size(); ++keyIndex) {
937             keyframeValue.setKey(keys[keyIndex]);
938             list.insert(keyframeValue);
939         }
940     }
941
942     // If the 0% keyframe is missing, create it (but only if there is at least one other keyframe)
943     int initialListSize = list.size();
944     if (initialListSize > 0 && list[0].key()) {
945         static StyleKeyframe* zeroPercentKeyframe;
946         if (!zeroPercentKeyframe) {
947             zeroPercentKeyframe = StyleKeyframe::create(MutableStylePropertySet::create()).leakRef();
948             zeroPercentKeyframe->setKeyText("0%");
949         }
950         KeyframeValue keyframeValue(0, 0);
951         keyframeValue.setStyle(styleForKeyframe(elementStyle, zeroPercentKeyframe, keyframeValue));
952         list.insert(keyframeValue);
953     }
954
955     // If the 100% keyframe is missing, create it (but only if there is at least one other keyframe)
956     if (initialListSize > 0 && (list[list.size() - 1].key() != 1)) {
957         static StyleKeyframe* hundredPercentKeyframe;
958         if (!hundredPercentKeyframe) {
959             hundredPercentKeyframe = StyleKeyframe::create(MutableStylePropertySet::create()).leakRef();
960             hundredPercentKeyframe->setKeyText("100%");
961         }
962         KeyframeValue keyframeValue(1, 0);
963         keyframeValue.setStyle(styleForKeyframe(elementStyle, hundredPercentKeyframe, keyframeValue));
964         list.insert(keyframeValue);
965     }
966 }
967
968 PassRefPtr<RenderStyle> StyleResolver::pseudoStyleForElement(Element* e, const PseudoStyleRequest& pseudoStyleRequest, RenderStyle* parentStyle)
969 {
970     ASSERT(parentStyle);
971     if (!e)
972         return 0;
973
974     State& state = m_state;
975
976     initElement(e);
977
978     state.initForStyleResolve(document(), e, parentStyle);
979
980     if (m_state.parentStyle()) {
981         state.setStyle(RenderStyle::create());
982         state.style()->inheritFrom(m_state.parentStyle());
983     } else {
984         state.setStyle(defaultStyleForElement());
985         state.setParentStyle(RenderStyle::clone(state.style()));
986     }
987
988     // Since we don't use pseudo-elements in any of our quirk/print user agent rules, don't waste time walking
989     // those rules.
990
991     // Check UA, user and author rules.
992     ElementRuleCollector collector(this, state);
993     collector.setPseudoStyleRequest(pseudoStyleRequest);
994     collector.setMedium(m_medium.get());
995     collector.matchUARules();
996
997     if (m_matchAuthorAndUserStyles) {
998         collector.matchUserRules(false);
999         collector.matchAuthorRules(false);
1000     }
1001
1002     if (collector.matchedResult().matchedProperties.isEmpty())
1003         return 0;
1004
1005     state.style()->setStyleType(pseudoStyleRequest.pseudoId);
1006
1007     applyMatchedProperties(collector.matchedResult(), e);
1008
1009     // Clean up our style object's display and text decorations (among other fixups).
1010     adjustRenderStyle(state.style(), m_state.parentStyle(), 0);
1011
1012     // Start loading resources referenced by this style.
1013     loadPendingResources();
1014
1015     document().didAccessStyleResolver();
1016
1017     // Now return the style.
1018     return state.takeStyle();
1019 }
1020
1021 PassRef<RenderStyle> StyleResolver::styleForPage(int pageIndex)
1022 {
1023     m_state.initForStyleResolve(document(), document().documentElement()); // m_rootElementStyle will be set to the document style.
1024
1025     m_state.setStyle(RenderStyle::create());
1026     m_state.style()->inheritFrom(m_state.rootElementStyle());
1027
1028     PageRuleCollector collector(m_state, m_ruleSets);
1029     collector.matchAllPageRules(pageIndex);
1030     m_state.setLineHeightValue(0);
1031     bool inheritedOnly = false;
1032
1033     MatchResult& result = collector.matchedResult();
1034 #if ENABLE(CSS_VARIABLES)
1035     applyMatchedProperties<VariableDefinitions>(result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
1036 #endif
1037     applyMatchedProperties<HighPriorityProperties>(result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
1038
1039     // If our font got dirtied, go ahead and update it now.
1040     updateFont();
1041
1042     // Line-height is set when we are sure we decided on the font-size.
1043     if (m_state.lineHeightValue())
1044         applyProperty(CSSPropertyLineHeight, m_state.lineHeightValue());
1045
1046     applyMatchedProperties<LowPriorityProperties>(result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
1047
1048     // Start loading resources referenced by this style.
1049     loadPendingResources();
1050
1051     document().didAccessStyleResolver();
1052
1053     // Now return the style.
1054     return m_state.takeStyle();
1055 }
1056
1057 PassRef<RenderStyle> StyleResolver::defaultStyleForElement()
1058 {
1059     m_state.setStyle(RenderStyle::create());
1060     // Make sure our fonts are initialized if we don't inherit them from our parent style.
1061     if (Settings* settings = documentSettings()) {
1062         initializeFontStyle(settings);
1063         m_state.style()->font().update(fontSelector());
1064     } else
1065         m_state.style()->font().update(0);
1066
1067     return m_state.takeStyle();
1068 }
1069
1070 static void addIntrinsicMargins(RenderStyle* style)
1071 {
1072     // Intrinsic margin value.
1073     const int intrinsicMargin = 2 * style->effectiveZoom();
1074
1075     // FIXME: Using width/height alone and not also dealing with min-width/max-width is flawed.
1076     // FIXME: Using "quirk" to decide the margin wasn't set is kind of lame.
1077     if (style->width().isIntrinsicOrAuto()) {
1078         if (style->marginLeft().quirk())
1079             style->setMarginLeft(Length(intrinsicMargin, Fixed));
1080         if (style->marginRight().quirk())
1081             style->setMarginRight(Length(intrinsicMargin, Fixed));
1082     }
1083
1084     if (style->height().isAuto()) {
1085         if (style->marginTop().quirk())
1086             style->setMarginTop(Length(intrinsicMargin, Fixed));
1087         if (style->marginBottom().quirk())
1088             style->setMarginBottom(Length(intrinsicMargin, Fixed));
1089     }
1090 }
1091
1092 static EDisplay equivalentBlockDisplay(EDisplay display, bool isFloating, bool strictParsing)
1093 {
1094     switch (display) {
1095     case BLOCK:
1096     case TABLE:
1097     case BOX:
1098     case FLEX:
1099     case GRID:
1100         return display;
1101
1102     case LIST_ITEM:
1103         // It is a WinIE bug that floated list items lose their bullets, so we'll emulate the quirk, but only in quirks mode.
1104         if (!strictParsing && isFloating)
1105             return BLOCK;
1106         return display;
1107     case INLINE_TABLE:
1108         return TABLE;
1109     case INLINE_BOX:
1110         return BOX;
1111     case INLINE_FLEX:
1112         return FLEX;
1113     case INLINE_GRID:
1114         return GRID;
1115
1116     case INLINE:
1117     case RUN_IN:
1118     case COMPACT:
1119     case INLINE_BLOCK:
1120     case TABLE_ROW_GROUP:
1121     case TABLE_HEADER_GROUP:
1122     case TABLE_FOOTER_GROUP:
1123     case TABLE_ROW:
1124     case TABLE_COLUMN_GROUP:
1125     case TABLE_COLUMN:
1126     case TABLE_CELL:
1127     case TABLE_CAPTION:
1128         return BLOCK;
1129     case NONE:
1130         ASSERT_NOT_REACHED();
1131         return NONE;
1132     }
1133     ASSERT_NOT_REACHED();
1134     return BLOCK;
1135 }
1136
1137 // CSS requires text-decoration to be reset at each DOM element for tables, 
1138 // inline blocks, inline tables, run-ins, shadow DOM crossings, floating elements,
1139 // and absolute or relatively positioned elements.
1140 static bool doesNotInheritTextDecoration(RenderStyle* style, Element* e)
1141 {
1142     return style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN
1143         || style->display() == INLINE_BLOCK || style->display() == INLINE_BOX || isAtShadowBoundary(e)
1144         || style->isFloating() || style->hasOutOfFlowPosition();
1145 }
1146
1147 static bool isDisplayFlexibleBox(EDisplay display)
1148 {
1149     return display == FLEX || display == INLINE_FLEX;
1150 }
1151
1152 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
1153 static bool isScrollableOverflow(EOverflow overflow)
1154 {
1155     return overflow == OSCROLL || overflow == OAUTO || overflow == OOVERLAY;
1156 }
1157 #endif
1158
1159 void StyleResolver::adjustRenderStyle(RenderStyle* style, RenderStyle* parentStyle, Element *e)
1160 {
1161     ASSERT(parentStyle);
1162
1163     // Cache our original display.
1164     style->setOriginalDisplay(style->display());
1165
1166     if (style->display() != NONE) {
1167         // If we have a <td> that specifies a float property, in quirks mode we just drop the float
1168         // property.
1169         // Sites also commonly use display:inline/block on <td>s and <table>s. In quirks mode we force
1170         // these tags to retain their display types.
1171         if (document().inQuirksMode() && e) {
1172             if (e->hasTagName(tdTag)) {
1173                 style->setDisplay(TABLE_CELL);
1174                 style->setFloating(NoFloat);
1175             } else if (isHTMLTableElement(e))
1176                 style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE);
1177         }
1178
1179         if (e && (e->hasTagName(tdTag) || e->hasTagName(thTag))) {
1180             if (style->whiteSpace() == KHTML_NOWRAP) {
1181                 // Figure out if we are really nowrapping or if we should just
1182                 // use normal instead. If the width of the cell is fixed, then
1183                 // we don't actually use NOWRAP.
1184                 if (style->width().isFixed())
1185                     style->setWhiteSpace(NORMAL);
1186                 else
1187                     style->setWhiteSpace(NOWRAP);
1188             }
1189         }
1190
1191         // Tables never support the -webkit-* values for text-align and will reset back to the default.
1192         if (e && isHTMLTableElement(e) && (style->textAlign() == WEBKIT_LEFT || style->textAlign() == WEBKIT_CENTER || style->textAlign() == WEBKIT_RIGHT))
1193             style->setTextAlign(TASTART);
1194
1195         // Frames and framesets never honor position:relative or position:absolute. This is necessary to
1196         // fix a crash where a site tries to position these objects. They also never honor display.
1197         if (e && (e->hasTagName(frameTag) || e->hasTagName(framesetTag))) {
1198             style->setPosition(StaticPosition);
1199             style->setDisplay(BLOCK);
1200         }
1201
1202         // Ruby text does not support float or position. This might change with evolution of the specification.
1203         if (e && e->hasTagName(rtTag)) {
1204             style->setPosition(StaticPosition);
1205             style->setFloating(NoFloat);
1206         }
1207
1208         // FIXME: We shouldn't be overriding start/-webkit-auto like this. Do it in html.css instead.
1209         // Table headers with a text-align of -webkit-auto will change the text-align to center.
1210         if (e && e->hasTagName(thTag) && style->textAlign() == TASTART)
1211             style->setTextAlign(CENTER);
1212
1213         if (e && e->hasTagName(legendTag))
1214             style->setDisplay(BLOCK);
1215
1216         // Absolute/fixed positioned elements, floating elements and the document element need block-like outside display.
1217         if (style->hasOutOfFlowPosition() || style->isFloating() || (e && e->document().documentElement() == e))
1218             style->setDisplay(equivalentBlockDisplay(style->display(), style->isFloating(), !document().inQuirksMode()));
1219
1220         // FIXME: Don't support this mutation for pseudo styles like first-letter or first-line, since it's not completely
1221         // clear how that should work.
1222         if (style->display() == INLINE && style->styleType() == NOPSEUDO && style->writingMode() != parentStyle->writingMode())
1223             style->setDisplay(INLINE_BLOCK);
1224
1225         // After performing the display mutation, check table rows. We do not honor position:relative or position:sticky on
1226         // table rows or cells. This has been established for position:relative in CSS2.1 (and caused a crash in containingBlock()
1227         // on some sites).
1228         if ((style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW_GROUP
1229             || style->display() == TABLE_FOOTER_GROUP || style->display() == TABLE_ROW)
1230             && style->hasInFlowPosition())
1231             style->setPosition(StaticPosition);
1232
1233         // writing-mode does not apply to table row groups, table column groups, table rows, and table columns.
1234         // FIXME: Table cells should be allowed to be perpendicular or flipped with respect to the table, though.
1235         if (style->display() == TABLE_COLUMN || style->display() == TABLE_COLUMN_GROUP || style->display() == TABLE_FOOTER_GROUP
1236             || style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW || style->display() == TABLE_ROW_GROUP
1237             || style->display() == TABLE_CELL)
1238             style->setWritingMode(parentStyle->writingMode());
1239
1240         // FIXME: Since we don't support block-flow on flexible boxes yet, disallow setting
1241         // of block-flow to anything other than TopToBottomWritingMode.
1242         // https://bugs.webkit.org/show_bug.cgi?id=46418 - Flexible box support.
1243         if (style->writingMode() != TopToBottomWritingMode && (style->display() == BOX || style->display() == INLINE_BOX))
1244             style->setWritingMode(TopToBottomWritingMode);
1245
1246         if (isDisplayFlexibleBox(parentStyle->display())) {
1247             style->setFloating(NoFloat);
1248             style->setDisplay(equivalentBlockDisplay(style->display(), style->isFloating(), !document().inQuirksMode()));
1249         }
1250     }
1251
1252     // Make sure our z-index value is only applied if the object is positioned.
1253     if (style->position() == StaticPosition && !isDisplayFlexibleBox(parentStyle->display()))
1254         style->setHasAutoZIndex();
1255
1256     // Auto z-index becomes 0 for the root element and transparent objects. This prevents
1257     // cases where objects that should be blended as a single unit end up with a non-transparent
1258     // object wedged in between them. Auto z-index also becomes 0 for objects that specify transforms/masks/reflections.
1259     if (style->hasAutoZIndex() && ((e && e->document().documentElement() == e)
1260         || style->opacity() < 1.0f
1261         || style->hasTransformRelatedProperty()
1262         || style->hasMask()
1263         || style->clipPath()
1264         || style->boxReflect()
1265         || style->hasFilter()
1266         || style->hasBlendMode()
1267         || style->position() == StickyPosition
1268         || (style->position() == FixedPosition && e && e->document().page() && e->document().page()->settings().fixedPositionCreatesStackingContext())
1269         || style->hasFlowFrom()
1270         ))
1271         style->setZIndex(0);
1272
1273     // Textarea considers overflow visible as auto.
1274     if (e && isHTMLTextAreaElement(e)) {
1275         style->setOverflowX(style->overflowX() == OVISIBLE ? OAUTO : style->overflowX());
1276         style->setOverflowY(style->overflowY() == OVISIBLE ? OAUTO : style->overflowY());
1277     }
1278
1279     if (doesNotInheritTextDecoration(style, e))
1280         style->setTextDecorationsInEffect(style->textDecoration());
1281     else
1282         style->addToTextDecorationsInEffect(style->textDecoration());
1283
1284     // If either overflow value is not visible, change to auto.
1285     if (style->overflowX() == OMARQUEE && style->overflowY() != OMARQUEE)
1286         style->setOverflowY(OMARQUEE);
1287     else if (style->overflowY() == OMARQUEE && style->overflowX() != OMARQUEE)
1288         style->setOverflowX(OMARQUEE);
1289     else if (style->overflowX() == OVISIBLE && style->overflowY() != OVISIBLE) {
1290         // FIXME: Once we implement pagination controls, overflow-x should default to hidden
1291         // if overflow-y is set to -webkit-paged-x or -webkit-page-y. For now, we'll let it
1292         // default to auto so we can at least scroll through the pages.
1293         style->setOverflowX(OAUTO);
1294     } else if (style->overflowY() == OVISIBLE && style->overflowX() != OVISIBLE)
1295         style->setOverflowY(OAUTO);
1296
1297     // Call setStylesForPaginationMode() if a pagination mode is set for any non-root elements. If these
1298     // styles are specified on a root element, then they will be incorporated in
1299     // Style::createForDocument().
1300     if ((style->overflowY() == OPAGEDX || style->overflowY() == OPAGEDY) && !(e && (e->hasTagName(htmlTag) || e->hasTagName(bodyTag))))
1301         style->setColumnStylesFromPaginationMode(WebCore::paginationModeForRenderStyle(style));
1302
1303     // Table rows, sections and the table itself will support overflow:hidden and will ignore scroll/auto.
1304     // FIXME: Eventually table sections will support auto and scroll.
1305     if (style->display() == TABLE || style->display() == INLINE_TABLE
1306         || style->display() == TABLE_ROW_GROUP || style->display() == TABLE_ROW) {
1307         if (style->overflowX() != OVISIBLE && style->overflowX() != OHIDDEN)
1308             style->setOverflowX(OVISIBLE);
1309         if (style->overflowY() != OVISIBLE && style->overflowY() != OHIDDEN)
1310             style->setOverflowY(OVISIBLE);
1311     }
1312
1313     // Menulists should have visible overflow
1314     if (style->appearance() == MenulistPart) {
1315         style->setOverflowX(OVISIBLE);
1316         style->setOverflowY(OVISIBLE);
1317     }
1318
1319 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
1320     // Touch overflow scrolling creates a stacking context.
1321     if (style->hasAutoZIndex() && style->useTouchOverflowScrolling() && (isScrollableOverflow(style->overflowX()) || isScrollableOverflow(style->overflowY())))
1322         style->setZIndex(0);
1323 #endif
1324
1325     // Cull out any useless layers and also repeat patterns into additional layers.
1326     style->adjustBackgroundLayers();
1327     style->adjustMaskLayers();
1328
1329     // Do the same for animations and transitions.
1330     style->adjustAnimations();
1331     style->adjustTransitions();
1332
1333     // Important: Intrinsic margins get added to controls before the theme has adjusted the style, since the theme will
1334     // alter fonts and heights/widths.
1335     if (e && e->isFormControlElement() && style->fontSize() >= 11) {
1336         // Don't apply intrinsic margins to image buttons. The designer knows how big the images are,
1337         // so we have to treat all image buttons as though they were explicitly sized.
1338         if (!isHTMLInputElement(e) || !toHTMLInputElement(e)->isImageButton())
1339             addIntrinsicMargins(style);
1340     }
1341
1342     // Let the theme also have a crack at adjusting the style.
1343     if (style->hasAppearance())
1344         RenderTheme::defaultTheme()->adjustStyle(this, style, e, m_state.hasUAAppearance(), m_state.borderData(), m_state.backgroundData(), m_state.backgroundColor());
1345
1346     // If we have first-letter pseudo style, do not share this style.
1347     if (style->hasPseudoStyle(FIRST_LETTER))
1348         style->setUnique();
1349
1350     // FIXME: when dropping the -webkit prefix on transform-style, we should also have opacity < 1 cause flattening.
1351     if (style->preserves3D() && (style->overflowX() != OVISIBLE
1352         || style->overflowY() != OVISIBLE
1353         || style->hasFilter()))
1354         style->setTransformStyle3D(TransformStyle3DFlat);
1355
1356     // Seamless iframes behave like blocks. Map their display to inline-block when marked inline.
1357     if (e && e->hasTagName(iframeTag) && style->display() == INLINE && toHTMLIFrameElement(e)->shouldDisplaySeamlessly())
1358         style->setDisplay(INLINE_BLOCK);
1359
1360     adjustGridItemPosition(style);
1361
1362 #if ENABLE(SVG)
1363     if (e && e->isSVGElement()) {
1364         // Spec: http://www.w3.org/TR/SVG/masking.html#OverflowProperty
1365         if (style->overflowY() == OSCROLL)
1366             style->setOverflowY(OHIDDEN);
1367         else if (style->overflowY() == OAUTO)
1368             style->setOverflowY(OVISIBLE);
1369
1370         if (style->overflowX() == OSCROLL)
1371             style->setOverflowX(OHIDDEN);
1372         else if (style->overflowX() == OAUTO)
1373             style->setOverflowX(OVISIBLE);
1374
1375         // Only the root <svg> element in an SVG document fragment tree honors css position
1376         if (!(e->hasTagName(SVGNames::svgTag) && e->parentNode() && !e->parentNode()->isSVGElement()))
1377             style->setPosition(RenderStyle::initialPosition());
1378
1379         // RenderSVGRoot handles zooming for the whole SVG subtree, so foreignObject content should
1380         // not be scaled again.
1381         if (e->hasTagName(SVGNames::foreignObjectTag))
1382             style->setEffectiveZoom(RenderStyle::initialZoom());
1383     }
1384 #endif
1385 }
1386
1387 void StyleResolver::adjustGridItemPosition(RenderStyle* style) const
1388 {
1389     // If opposing grid-placement properties both specify a grid span, they both compute to ‘auto’.
1390     if (style->gridItemColumnStart().isSpan() && style->gridItemColumnEnd().isSpan()) {
1391         style->setGridItemColumnStart(GridPosition());
1392         style->setGridItemColumnEnd(GridPosition());
1393     }
1394
1395     if (style->gridItemRowStart().isSpan() && style->gridItemRowEnd().isSpan()) {
1396         style->setGridItemRowStart(GridPosition());
1397         style->setGridItemRowEnd(GridPosition());
1398     }
1399 }
1400
1401 bool StyleResolver::checkRegionStyle(Element* regionElement)
1402 {
1403     // FIXME (BUG 72472): We don't add @-webkit-region rules of scoped style sheets for the moment,
1404     // so all region rules are global by default. Verify whether that can stand or needs changing.
1405
1406     unsigned rulesSize = m_ruleSets.authorStyle()->regionSelectorsAndRuleSets().size();
1407     for (unsigned i = 0; i < rulesSize; ++i) {
1408         ASSERT(m_ruleSets.authorStyle()->regionSelectorsAndRuleSets().at(i).ruleSet.get());
1409         if (checkRegionSelector(m_ruleSets.authorStyle()->regionSelectorsAndRuleSets().at(i).selector, regionElement))
1410             return true;
1411     }
1412
1413     if (m_ruleSets.userStyle()) {
1414         rulesSize = m_ruleSets.userStyle()->regionSelectorsAndRuleSets().size();
1415         for (unsigned i = 0; i < rulesSize; ++i) {
1416             ASSERT(m_ruleSets.userStyle()->regionSelectorsAndRuleSets().at(i).ruleSet.get());
1417             if (checkRegionSelector(m_ruleSets.userStyle()->regionSelectorsAndRuleSets().at(i).selector, regionElement))
1418                 return true;
1419         }
1420     }
1421
1422     return false;
1423 }
1424
1425 static void checkForOrientationChange(RenderStyle* style)
1426 {
1427     FontOrientation fontOrientation;
1428     NonCJKGlyphOrientation glyphOrientation;
1429     style->getFontAndGlyphOrientation(fontOrientation, glyphOrientation);
1430
1431     const FontDescription& fontDescription = style->fontDescription();
1432     if (fontDescription.orientation() == fontOrientation && fontDescription.nonCJKGlyphOrientation() == glyphOrientation)
1433         return;
1434
1435     FontDescription newFontDescription(fontDescription);
1436     newFontDescription.setNonCJKGlyphOrientation(glyphOrientation);
1437     newFontDescription.setOrientation(fontOrientation);
1438     style->setFontDescription(newFontDescription);
1439 }
1440
1441 void StyleResolver::updateFont()
1442 {
1443     if (!m_state.fontDirty())
1444         return;
1445
1446     RenderStyle* style = m_state.style();
1447 #if ENABLE(IOS_TEXT_AUTOSIZING)
1448     checkForTextSizeAdjust(style);
1449 #endif
1450     checkForGenericFamilyChange(style, m_state.parentStyle());
1451     checkForZoomChange(style, m_state.parentStyle());
1452     checkForOrientationChange(style);
1453     style->font().update(m_fontSelector);
1454     m_state.setFontDirty(false);
1455 }
1456
1457 Vector<RefPtr<StyleRuleBase>> StyleResolver::styleRulesForElement(Element* e, unsigned rulesToInclude)
1458 {
1459     return pseudoStyleRulesForElement(e, NOPSEUDO, rulesToInclude);
1460 }
1461
1462 Vector<RefPtr<StyleRuleBase>> StyleResolver::pseudoStyleRulesForElement(Element* e, PseudoId pseudoId, unsigned rulesToInclude)
1463 {
1464     if (!e || !e->document().haveStylesheetsLoaded())
1465         return Vector<RefPtr<StyleRuleBase>>();
1466
1467     initElement(e);
1468     m_state.initForStyleResolve(document(), e, 0);
1469
1470     ElementRuleCollector collector(this, m_state);
1471     collector.setMode(SelectorChecker::CollectingRules);
1472     collector.setPseudoStyleRequest(PseudoStyleRequest(pseudoId));
1473     collector.setMedium(m_medium.get());
1474
1475     if (rulesToInclude & UAAndUserCSSRules) {
1476         // First we match rules from the user agent sheet.
1477         collector.matchUARules();
1478         
1479         // Now we check user sheet rules.
1480         if (m_matchAuthorAndUserStyles)
1481             collector.matchUserRules(rulesToInclude & EmptyCSSRules);
1482     }
1483
1484     if (m_matchAuthorAndUserStyles && (rulesToInclude & AuthorCSSRules)) {
1485         collector.setSameOriginOnly(!(rulesToInclude & CrossOriginCSSRules));
1486
1487         // Check the rules in author sheets.
1488         collector.matchAuthorRules(rulesToInclude & EmptyCSSRules);
1489     }
1490
1491     return collector.matchedRuleList();
1492 }
1493
1494 // -------------------------------------------------------------------------------------
1495 // this is mostly boring stuff on how to apply a certain rule to the renderstyle...
1496
1497 Length StyleResolver::convertToIntLength(const CSSPrimitiveValue* primitiveValue, const RenderStyle* style, const RenderStyle* rootStyle, double multiplier)
1498 {
1499     return primitiveValue ? primitiveValue->convertToLength<FixedIntegerConversion | PercentConversion | CalculatedConversion | FractionConversion | ViewportPercentageConversion>(style, rootStyle, multiplier) : Length(Undefined);
1500 }
1501
1502 Length StyleResolver::convertToFloatLength(const CSSPrimitiveValue* primitiveValue, const RenderStyle* style, const RenderStyle* rootStyle, double multiplier)
1503 {
1504     return primitiveValue ? primitiveValue->convertToLength<FixedFloatConversion | PercentConversion | CalculatedConversion | FractionConversion | ViewportPercentageConversion>(style, rootStyle, multiplier) : Length(Undefined);
1505 }
1506
1507 template <StyleResolver::StyleApplicationPass pass>
1508 void StyleResolver::applyProperties(const StylePropertySet* properties, StyleRule* rule, bool isImportant, bool inheritedOnly, PropertyWhitelistType propertyWhitelistType)
1509 {
1510     ASSERT((propertyWhitelistType != PropertyWhitelistRegion) || m_state.regionForStyling());
1511     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willProcessRule(&document(), rule, *this);
1512
1513     unsigned propertyCount = properties->propertyCount();
1514     for (unsigned i = 0; i < propertyCount; ++i) {
1515         StylePropertySet::PropertyReference current = properties->propertyAt(i);
1516         if (isImportant != current.isImportant())
1517             continue;
1518         if (inheritedOnly && !current.isInherited()) {
1519             // If the property value is explicitly inherited, we need to apply further non-inherited properties
1520             // as they might override the value inherited here. For this reason we don't allow declarations with
1521             // explicitly inherited properties to be cached.
1522             ASSERT(!current.value()->isInheritedValue());
1523             continue;
1524         }
1525         CSSPropertyID property = current.id();
1526
1527         if (propertyWhitelistType == PropertyWhitelistRegion && !StyleResolver::isValidRegionStyleProperty(property))
1528             continue;
1529 #if ENABLE(VIDEO_TRACK)
1530         if (propertyWhitelistType == PropertyWhitelistCue && !StyleResolver::isValidCueStyleProperty(property))
1531             continue;
1532 #endif
1533         switch (pass) {
1534 #if ENABLE(CSS_VARIABLES)
1535         case VariableDefinitions:
1536             COMPILE_ASSERT(CSSPropertyVariable < firstCSSProperty, CSS_variable_is_before_first_property);
1537             if (property == CSSPropertyVariable)
1538                 applyProperty(current.id(), current.value());
1539             break;
1540 #endif
1541         case HighPriorityProperties:
1542             COMPILE_ASSERT(firstCSSProperty == CSSPropertyColor, CSS_color_is_first_property);
1543 #if ENABLE(IOS_TEXT_AUTOSIZING)
1544             COMPILE_ASSERT(CSSPropertyZoom == CSSPropertyColor + 18, CSS_zoom_is_end_of_first_prop_range);
1545 #else
1546             COMPILE_ASSERT(CSSPropertyZoom == CSSPropertyColor + 17, CSS_zoom_is_end_of_first_prop_range);
1547 #endif
1548             COMPILE_ASSERT(CSSPropertyLineHeight == CSSPropertyZoom + 1, CSS_line_height_is_after_zoom);
1549 #if ENABLE(CSS_VARIABLES)
1550             if (property == CSSPropertyVariable)
1551                 continue;
1552 #endif
1553             // give special priority to font-xxx, color properties, etc
1554             if (property < CSSPropertyLineHeight)
1555                 applyProperty(current.id(), current.value());
1556             // we apply line-height later
1557             else if (property == CSSPropertyLineHeight)
1558                 m_state.setLineHeightValue(current.value());
1559             break;
1560         case LowPriorityProperties:
1561             if (property > CSSPropertyLineHeight)
1562                 applyProperty(current.id(), current.value());
1563         }
1564     }
1565     InspectorInstrumentation::didProcessRule(cookie);
1566 }
1567
1568 template <StyleResolver::StyleApplicationPass pass>
1569 void StyleResolver::applyMatchedProperties(const MatchResult& matchResult, bool isImportant, int startIndex, int endIndex, bool inheritedOnly)
1570 {
1571     if (startIndex == -1)
1572         return;
1573
1574     State& state = m_state;
1575     if (state.style()->insideLink() != NotInsideLink) {
1576         for (int i = startIndex; i <= endIndex; ++i) {
1577             const MatchedProperties& matchedProperties = matchResult.matchedProperties[i];
1578             unsigned linkMatchType = matchedProperties.linkMatchType;
1579             // FIXME: It would be nicer to pass these as arguments but that requires changes in many places.
1580             state.setApplyPropertyToRegularStyle(linkMatchType & SelectorChecker::MatchLink);
1581             state.setApplyPropertyToVisitedLinkStyle(linkMatchType & SelectorChecker::MatchVisited);
1582
1583             applyProperties<pass>(matchedProperties.properties.get(), matchResult.matchedRules[i], isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.whitelistType));
1584         }
1585         state.setApplyPropertyToRegularStyle(true);
1586         state.setApplyPropertyToVisitedLinkStyle(false);
1587         return;
1588     }
1589     for (int i = startIndex; i <= endIndex; ++i) {
1590         const MatchedProperties& matchedProperties = matchResult.matchedProperties[i];
1591         applyProperties<pass>(matchedProperties.properties.get(), matchResult.matchedRules[i], isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.whitelistType));
1592     }
1593 }
1594
1595 unsigned StyleResolver::computeMatchedPropertiesHash(const MatchedProperties* properties, unsigned size)
1596 {
1597     
1598     return StringHasher::hashMemory(properties, sizeof(MatchedProperties) * size);
1599 }
1600
1601 bool operator==(const StyleResolver::MatchRanges& a, const StyleResolver::MatchRanges& b)
1602 {
1603     return a.firstUARule == b.firstUARule
1604         && a.lastUARule == b.lastUARule
1605         && a.firstAuthorRule == b.firstAuthorRule
1606         && a.lastAuthorRule == b.lastAuthorRule
1607         && a.firstUserRule == b.firstUserRule
1608         && a.lastUserRule == b.lastUserRule;
1609 }
1610
1611 bool operator!=(const StyleResolver::MatchRanges& a, const StyleResolver::MatchRanges& b)
1612 {
1613     return !(a == b);
1614 }
1615
1616 bool operator==(const StyleResolver::MatchedProperties& a, const StyleResolver::MatchedProperties& b)
1617 {
1618     return a.properties == b.properties && a.linkMatchType == b.linkMatchType;
1619 }
1620
1621 bool operator!=(const StyleResolver::MatchedProperties& a, const StyleResolver::MatchedProperties& b)
1622 {
1623     return !(a == b);
1624 }
1625
1626 const StyleResolver::MatchedPropertiesCacheItem* StyleResolver::findFromMatchedPropertiesCache(unsigned hash, const MatchResult& matchResult)
1627 {
1628     ASSERT(hash);
1629
1630     MatchedPropertiesCache::iterator it = m_matchedPropertiesCache.find(hash);
1631     if (it == m_matchedPropertiesCache.end())
1632         return 0;
1633     MatchedPropertiesCacheItem& cacheItem = it->value;
1634
1635     size_t size = matchResult.matchedProperties.size();
1636     if (size != cacheItem.matchedProperties.size())
1637         return 0;
1638     for (size_t i = 0; i < size; ++i) {
1639         if (matchResult.matchedProperties[i] != cacheItem.matchedProperties[i])
1640             return 0;
1641     }
1642     if (cacheItem.ranges != matchResult.ranges)
1643         return 0;
1644     return &cacheItem;
1645 }
1646
1647 void StyleResolver::addToMatchedPropertiesCache(const RenderStyle* style, const RenderStyle* parentStyle, unsigned hash, const MatchResult& matchResult)
1648 {
1649     static const unsigned matchedDeclarationCacheAdditionsBetweenSweeps = 100;
1650     if (++m_matchedPropertiesCacheAdditionsSinceLastSweep >= matchedDeclarationCacheAdditionsBetweenSweeps
1651         && !m_matchedPropertiesCacheSweepTimer.isActive()) {
1652         static const unsigned matchedDeclarationCacheSweepTimeInSeconds = 60;
1653         m_matchedPropertiesCacheSweepTimer.startOneShot(matchedDeclarationCacheSweepTimeInSeconds);
1654     }
1655
1656     ASSERT(hash);
1657     MatchedPropertiesCacheItem cacheItem;
1658     cacheItem.matchedProperties.appendVector(matchResult.matchedProperties);
1659     cacheItem.ranges = matchResult.ranges;
1660     // Note that we don't cache the original RenderStyle instance. It may be further modified.
1661     // The RenderStyle in the cache is really just a holder for the substructures and never used as-is.
1662     cacheItem.renderStyle = RenderStyle::clone(style);
1663     cacheItem.parentRenderStyle = RenderStyle::clone(parentStyle);
1664     m_matchedPropertiesCache.add(hash, cacheItem);
1665 }
1666
1667 void StyleResolver::invalidateMatchedPropertiesCache()
1668 {
1669     m_matchedPropertiesCache.clear();
1670 }
1671
1672 static bool isCacheableInMatchedPropertiesCache(const Element* element, const RenderStyle* style, const RenderStyle* parentStyle)
1673 {
1674     // FIXME: CSSPropertyWebkitWritingMode modifies state when applying to document element. We can't skip the applying by caching.
1675     if (element == element->document().documentElement() && element->document().writingModeSetOnDocumentElement())
1676         return false;
1677     if (style->unique() || (style->styleType() != NOPSEUDO && parentStyle->unique()))
1678         return false;
1679     if (style->hasAppearance())
1680         return false;
1681     if (style->zoom() != RenderStyle::initialZoom())
1682         return false;
1683     if (style->writingMode() != RenderStyle::initialWritingMode())
1684         return false;
1685     // The cache assumes static knowledge about which properties are inherited.
1686     if (parentStyle->hasExplicitlyInheritedProperties())
1687         return false;
1688     return true;
1689 }
1690
1691 void StyleResolver::applyMatchedProperties(const MatchResult& matchResult, const Element* element)
1692 {
1693     ASSERT(element);
1694     State& state = m_state;
1695     unsigned cacheHash = matchResult.isCacheable ? computeMatchedPropertiesHash(matchResult.matchedProperties.data(), matchResult.matchedProperties.size()) : 0;
1696     bool applyInheritedOnly = false;
1697     const MatchedPropertiesCacheItem* cacheItem = 0;
1698     if (cacheHash && (cacheItem = findFromMatchedPropertiesCache(cacheHash, matchResult))) {
1699         // We can build up the style by copying non-inherited properties from an earlier style object built using the same exact
1700         // style declarations. We then only need to apply the inherited properties, if any, as their values can depend on the 
1701         // element context. This is fast and saves memory by reusing the style data structures.
1702         state.style()->copyNonInheritedFrom(cacheItem->renderStyle.get());
1703         if (state.parentStyle()->inheritedDataShared(cacheItem->parentRenderStyle.get()) && !isAtShadowBoundary(element)) {
1704             EInsideLink linkStatus = state.style()->insideLink();
1705             // If the cache item parent style has identical inherited properties to the current parent style then the
1706             // resulting style will be identical too. We copy the inherited properties over from the cache and are done.
1707             state.style()->inheritFrom(cacheItem->renderStyle.get());
1708
1709             // Unfortunately the link status is treated like an inherited property. We need to explicitly restore it.
1710             state.style()->setInsideLink(linkStatus);
1711             return;
1712         }
1713         applyInheritedOnly = true; 
1714     }
1715
1716 #if ENABLE(CSS_VARIABLES)
1717     // First apply all variable definitions, as they may be used during application of later properties.
1718     applyMatchedProperties<VariableDefinitions>(matchResult, false, 0, matchResult.matchedProperties.size() - 1, applyInheritedOnly);
1719     applyMatchedProperties<VariableDefinitions>(matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
1720     applyMatchedProperties<VariableDefinitions>(matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
1721     applyMatchedProperties<VariableDefinitions>(matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
1722 #endif
1723
1724     // Now we have all of the matched rules in the appropriate order. Walk the rules and apply
1725     // high-priority properties first, i.e., those properties that other properties depend on.
1726     // The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
1727     // and (4) normal important.
1728     state.setLineHeightValue(0);
1729     applyMatchedProperties<HighPriorityProperties>(matchResult, false, 0, matchResult.matchedProperties.size() - 1, applyInheritedOnly);
1730     applyMatchedProperties<HighPriorityProperties>(matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
1731     applyMatchedProperties<HighPriorityProperties>(matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
1732     applyMatchedProperties<HighPriorityProperties>(matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
1733
1734     if (cacheItem && cacheItem->renderStyle->effectiveZoom() != state.style()->effectiveZoom()) {
1735         state.setFontDirty(true);
1736         applyInheritedOnly = false;
1737     }
1738
1739     // If our font got dirtied, go ahead and update it now.
1740     updateFont();
1741
1742     // Line-height is set when we are sure we decided on the font-size.
1743     if (state.lineHeightValue())
1744         applyProperty(CSSPropertyLineHeight, state.lineHeightValue());
1745
1746     // Many properties depend on the font. If it changes we just apply all properties.
1747     if (cacheItem && cacheItem->renderStyle->fontDescription() != state.style()->fontDescription())
1748         applyInheritedOnly = false;
1749
1750     // Now do the normal priority UA properties.
1751     applyMatchedProperties<LowPriorityProperties>(matchResult, false, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
1752     
1753     // Cache our border and background so that we can examine them later.
1754     state.cacheBorderAndBackground();
1755     
1756     // Now do the author and user normal priority properties and all the !important properties.
1757     applyMatchedProperties<LowPriorityProperties>(matchResult, false, matchResult.ranges.lastUARule + 1, matchResult.matchedProperties.size() - 1, applyInheritedOnly);
1758     applyMatchedProperties<LowPriorityProperties>(matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
1759     applyMatchedProperties<LowPriorityProperties>(matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
1760     applyMatchedProperties<LowPriorityProperties>(matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
1761    
1762     // Start loading resources referenced by this style.
1763     loadPendingResources();
1764     
1765     ASSERT(!state.fontDirty());
1766     
1767     if (cacheItem || !cacheHash)
1768         return;
1769     if (!isCacheableInMatchedPropertiesCache(state.element(), state.style(), state.parentStyle()))
1770         return;
1771     addToMatchedPropertiesCache(state.style(), state.parentStyle(), cacheHash, matchResult);
1772 }
1773
1774 void StyleResolver::applyPropertyToStyle(CSSPropertyID id, CSSValue* value, RenderStyle* style)
1775 {
1776     initElement(0);
1777     m_state.initForStyleResolve(document(), 0, style);
1778     m_state.setStyle(*style);
1779     applyPropertyToCurrentStyle(id, value);
1780 }
1781
1782 void StyleResolver::applyPropertyToCurrentStyle(CSSPropertyID id, CSSValue* value)
1783 {
1784     if (value)
1785         applyProperty(id, value);
1786 }
1787
1788 inline bool isValidVisitedLinkProperty(CSSPropertyID id)
1789 {
1790     switch (id) {
1791     case CSSPropertyBackgroundColor:
1792     case CSSPropertyBorderLeftColor:
1793     case CSSPropertyBorderRightColor:
1794     case CSSPropertyBorderTopColor:
1795     case CSSPropertyBorderBottomColor:
1796     case CSSPropertyColor:
1797     case CSSPropertyOutlineColor:
1798     case CSSPropertyWebkitColumnRuleColor:
1799 #if ENABLE(CSS3_TEXT)
1800     case CSSPropertyWebkitTextDecorationColor:
1801 #endif // CSS3_TEXT
1802     case CSSPropertyWebkitTextEmphasisColor:
1803     case CSSPropertyWebkitTextFillColor:
1804     case CSSPropertyWebkitTextStrokeColor:
1805 #if ENABLE(SVG)
1806     case CSSPropertyFill:
1807     case CSSPropertyStroke:
1808 #endif
1809         return true;
1810     default:
1811         break;
1812     }
1813
1814     return false;
1815 }
1816
1817 // http://dev.w3.org/csswg/css3-regions/#the-at-region-style-rule
1818 // FIXME: add incremental support for other region styling properties.
1819 inline bool StyleResolver::isValidRegionStyleProperty(CSSPropertyID id)
1820 {
1821     switch (id) {
1822     case CSSPropertyBackgroundColor:
1823     case CSSPropertyColor:
1824         return true;
1825     default:
1826         break;
1827     }
1828
1829     return false;
1830 }
1831
1832 #if ENABLE(VIDEO_TRACK)
1833 inline bool StyleResolver::isValidCueStyleProperty(CSSPropertyID id)
1834 {
1835     switch (id) {
1836     case CSSPropertyBackground:
1837     case CSSPropertyBackgroundAttachment:
1838     case CSSPropertyBackgroundClip:
1839     case CSSPropertyBackgroundColor:
1840     case CSSPropertyBackgroundImage:
1841     case CSSPropertyBackgroundOrigin:
1842     case CSSPropertyBackgroundPosition:
1843     case CSSPropertyBackgroundPositionX:
1844     case CSSPropertyBackgroundPositionY:
1845     case CSSPropertyBackgroundRepeat:
1846     case CSSPropertyBackgroundRepeatX:
1847     case CSSPropertyBackgroundRepeatY:
1848     case CSSPropertyBackgroundSize:
1849     case CSSPropertyColor:
1850     case CSSPropertyFont:
1851     case CSSPropertyFontFamily:
1852     case CSSPropertyFontSize:
1853     case CSSPropertyFontStyle:
1854     case CSSPropertyFontVariant:
1855     case CSSPropertyFontWeight:
1856     case CSSPropertyLineHeight:
1857     case CSSPropertyOpacity:
1858     case CSSPropertyOutline:
1859     case CSSPropertyOutlineColor:
1860     case CSSPropertyOutlineOffset:
1861     case CSSPropertyOutlineStyle:
1862     case CSSPropertyOutlineWidth:
1863     case CSSPropertyVisibility:
1864     case CSSPropertyWhiteSpace:
1865     case CSSPropertyTextDecoration:
1866     case CSSPropertyTextShadow:
1867     case CSSPropertyBorderStyle:
1868         return true;
1869     default:
1870         break;
1871     }
1872     return false;
1873 }
1874 #endif
1875 // SVG handles zooming in a different way compared to CSS. The whole document is scaled instead
1876 // of each individual length value in the render style / tree. CSSPrimitiveValue::computeLength*()
1877 // multiplies each resolved length with the zoom multiplier - so for SVG we need to disable that.
1878 // Though all CSS values that can be applied to outermost <svg> elements (width/height/border/padding...)
1879 // need to respect the scaling. RenderBox (the parent class of RenderSVGRoot) grabs values like
1880 // width/height/border/padding/... from the RenderStyle -> for SVG these values would never scale,
1881 // if we'd pass a 1.0 zoom factor everyhwere. So we only pass a zoom factor of 1.0 for specific
1882 // properties that are NOT allowed to scale within a zoomed SVG document (letter/word-spacing/font-size).
1883 bool StyleResolver::useSVGZoomRules()
1884 {
1885     return m_state.element() && m_state.element()->isSVGElement();
1886 }
1887
1888 static bool createGridTrackBreadth(CSSPrimitiveValue* primitiveValue, const StyleResolver::State& state, GridLength& workingLength)
1889 {
1890     if (primitiveValue->getValueID() == CSSValueWebkitMinContent) {
1891         workingLength = Length(MinContent);
1892         return true;
1893     }
1894
1895     if (primitiveValue->getValueID() == CSSValueWebkitMaxContent) {
1896         workingLength = Length(MaxContent);
1897         return true;
1898     }
1899
1900     if (primitiveValue->isFlex()) {
1901         // Fractional unit.
1902         workingLength.setFlex(primitiveValue->getDoubleValue());
1903         return true;
1904     }
1905
1906     workingLength = primitiveValue->convertToLength<FixedIntegerConversion | PercentConversion | ViewportPercentageConversion | AutoConversion>(state.style(), state.rootElementStyle(), state.style()->effectiveZoom());
1907     if (workingLength.length().isUndefined())
1908         return false;
1909
1910     if (primitiveValue->isLength())
1911         workingLength.length().setQuirk(primitiveValue->isQuirkValue());
1912
1913     return true;
1914 }
1915
1916 static bool createGridTrackSize(CSSValue* value, GridTrackSize& trackSize, const StyleResolver::State& state)
1917 {
1918     if (!value->isPrimitiveValue())
1919         return false;
1920
1921     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
1922     Pair* minMaxTrackBreadth = primitiveValue->getPairValue();
1923     if (!minMaxTrackBreadth) {
1924         GridLength workingLength;
1925         if (!createGridTrackBreadth(primitiveValue, state, workingLength))
1926             return false;
1927
1928         trackSize.setLength(workingLength);
1929         return true;
1930     }
1931
1932     GridLength minTrackBreadth;
1933     GridLength maxTrackBreadth;
1934     if (!createGridTrackBreadth(minMaxTrackBreadth->first(), state, minTrackBreadth) || !createGridTrackBreadth(minMaxTrackBreadth->second(), state, maxTrackBreadth))
1935         return false;
1936
1937     trackSize.setMinMax(minTrackBreadth, maxTrackBreadth);
1938     return true;
1939 }
1940
1941 static bool createGridTrackList(CSSValue* value, Vector<GridTrackSize>& trackSizes, NamedGridLinesMap& namedGridLines, const StyleResolver::State& state)
1942 {
1943     // Handle 'none'.
1944     if (value->isPrimitiveValue()) {
1945         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
1946         return primitiveValue->getValueID() == CSSValueNone;
1947     }
1948
1949     if (!value->isValueList())
1950         return false;
1951
1952     size_t currentNamedGridLine = 0;
1953     for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
1954         CSSValue* currValue = i.value();
1955         if (currValue->isPrimitiveValue()) {
1956             CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(currValue);
1957             if (primitiveValue->isString()) {
1958                 NamedGridLinesMap::AddResult result = namedGridLines.add(primitiveValue->getStringValue(), Vector<size_t>());
1959                 result.iterator->value.append(currentNamedGridLine);
1960                 continue;
1961             }
1962         }
1963
1964         ++currentNamedGridLine;
1965         GridTrackSize trackSize;
1966         if (!createGridTrackSize(currValue, trackSize, state))
1967             return false;
1968
1969         trackSizes.append(trackSize);
1970     }
1971
1972     if (trackSizes.isEmpty())
1973         return false;
1974
1975     return true;
1976 }
1977
1978
1979 static bool createGridPosition(CSSValue* value, GridPosition& position)
1980 {
1981     // For now, we only accept: 'auto' | [ <integer> || <string> ] | span && <integer>?
1982     if (value->isPrimitiveValue()) {
1983 #if !ASSERT_DISABLED
1984         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
1985         ASSERT(primitiveValue->getValueID() == CSSValueAuto);
1986 #endif
1987         return true;
1988     }
1989
1990     CSSValueList* values = toCSSValueList(value);
1991     ASSERT(values->length());
1992
1993     bool isSpanPosition = false;
1994     // The specification makes the <integer> optional, in which case it default to '1'.
1995     int gridLineNumber = 1;
1996     String gridLineName;
1997
1998     CSSValueListIterator it = values;
1999     CSSPrimitiveValue* currentValue = toCSSPrimitiveValue(it.value());
2000     if (currentValue->getValueID() == CSSValueSpan) {
2001         isSpanPosition = true;
2002         it.advance();
2003         currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0;
2004     }
2005
2006     if (currentValue && currentValue->isNumber()) {
2007         gridLineNumber = currentValue->getIntValue();
2008         it.advance();
2009         currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0;
2010     }
2011
2012     if (currentValue && currentValue->isString()) {
2013         gridLineName = currentValue->getStringValue();
2014         it.advance();
2015     }
2016
2017     ASSERT(!it.hasMore());
2018     if (isSpanPosition)
2019         position.setSpanPosition(gridLineNumber, gridLineName);
2020     else
2021         position.setExplicitPosition(gridLineNumber, gridLineName);
2022
2023     return true;
2024 }
2025
2026 #if ENABLE(CSS_VARIABLES)
2027 static bool hasVariableReference(CSSValue* value)
2028 {
2029     if (value->isPrimitiveValue()) {
2030         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
2031         return primitiveValue->hasVariableReference();
2032     }
2033
2034     if (value->isCalcValue())
2035         return toCSSCalcValue(value)->hasVariableReference();
2036
2037     if (value->isReflectValue()) {
2038         CSSReflectValue* reflectValue = toCSSReflectValue(value);
2039         CSSPrimitiveValue* direction = reflectValue->direction();
2040         CSSPrimitiveValue* offset = reflectValue->offset();
2041         CSSValue* mask = reflectValue->mask();
2042         return (direction && hasVariableReference(direction)) || (offset && hasVariableReference(offset)) || (mask && hasVariableReference(mask));
2043     }
2044
2045     for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
2046         if (hasVariableReference(i.value()))
2047             return true;
2048     }
2049
2050     return false;
2051 }
2052
2053 void StyleResolver::resolveVariables(CSSPropertyID id, CSSValue* value, Vector<std::pair<CSSPropertyID, String>>& knownExpressions)
2054 {
2055     std::pair<CSSPropertyID, String> expression(id, value->serializeResolvingVariables(*m_state.style()->variables()));
2056
2057     if (knownExpressions.contains(expression))
2058         return; // cycle detected.
2059
2060     knownExpressions.append(expression);
2061
2062     // FIXME: It would be faster not to re-parse from strings, but for now CSS property validation lives inside the parser so we do it there.
2063     RefPtr<MutableStylePropertySet> resultSet = MutableStylePropertySet::create();
2064     if (!CSSParser::parseValue(resultSet.get(), id, expression.second, false, document()))
2065         return; // expression failed to parse.
2066
2067     for (unsigned i = 0; i < resultSet->propertyCount(); i++) {
2068         StylePropertySet::PropertyReference property = resultSet->propertyAt(i);
2069         if (property.id() != CSSPropertyVariable && hasVariableReference(property.value()))
2070             resolveVariables(property.id(), property.value(), knownExpressions);
2071         else
2072             applyProperty(property.id(), property.value());
2073     }
2074 }
2075 #endif
2076
2077 void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value)
2078 {
2079 #if ENABLE(CSS_VARIABLES)
2080     if (id != CSSPropertyVariable && hasVariableReference(value)) {
2081         Vector<std::pair<CSSPropertyID, String>> knownExpressions;
2082         resolveVariables(id, value, knownExpressions);
2083         return;
2084     }
2085 #endif
2086
2087     // CSS variables don't resolve shorthands at parsing time, so this should be *after* handling variables.
2088     ASSERT_WITH_MESSAGE(!isExpandedShorthand(id), "Shorthand property id = %d wasn't expanded at parsing time", id);
2089
2090     State& state = m_state;
2091     bool isInherit = state.parentNode() && value->isInheritedValue();
2092     bool isInitial = value->isInitialValue() || (!state.parentNode() && value->isInheritedValue());
2093
2094     ASSERT(!isInherit || !isInitial); // isInherit -> !isInitial && isInitial -> !isInherit
2095     ASSERT(!isInherit || (state.parentNode() && state.parentStyle())); // isInherit -> (state.parentNode() && state.parentStyle())
2096
2097     if (!state.applyPropertyToRegularStyle() && (!state.applyPropertyToVisitedLinkStyle() || !isValidVisitedLinkProperty(id))) {
2098         // Limit the properties that can be applied to only the ones honored by :visited.
2099         return;
2100     }
2101
2102     if (isInherit && !state.parentStyle()->hasExplicitlyInheritedProperties() && !CSSProperty::isInheritedProperty(id))
2103         state.parentStyle()->setHasExplicitlyInheritedProperties();
2104
2105 #if ENABLE(CSS_VARIABLES)
2106     if (id == CSSPropertyVariable) {
2107         CSSVariableValue* variable = toCSSVariableValue(value);
2108         ASSERT(!variable->name().isEmpty());
2109         ASSERT(!variable->value().isEmpty());
2110         state.style()->setVariable(variable->name(), variable->value());
2111         return;
2112     }
2113 #endif
2114
2115     // Check lookup table for implementations and use when available.
2116     const PropertyHandler& handler = m_deprecatedStyleBuilder.propertyHandler(id);
2117     if (handler.isValid()) {
2118         if (isInherit)
2119             handler.applyInheritValue(id, this);
2120         else if (isInitial)
2121             handler.applyInitialValue(id, this);
2122         else
2123             handler.applyValue(id, this, value);
2124         return;
2125     }
2126
2127     CSSPrimitiveValue* primitiveValue = value->isPrimitiveValue() ? toCSSPrimitiveValue(value) : 0;
2128
2129     float zoomFactor = state.style()->effectiveZoom();
2130
2131     // What follows is a list that maps the CSS properties into their corresponding front-end
2132     // RenderStyle values.
2133     switch (id) {
2134     // lists
2135     case CSSPropertyContent:
2136         // list of string, uri, counter, attr, i
2137         {
2138             // FIXME: In CSS3, it will be possible to inherit content. In CSS2 it is not. This
2139             // note is a reminder that eventually "inherit" needs to be supported.
2140
2141             if (isInitial) {
2142                 state.style()->clearContent();
2143                 return;
2144             }
2145
2146             if (!value->isValueList())
2147                 return;
2148
2149             bool didSet = false;
2150             for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
2151                 CSSValue* item = i.value();
2152                 if (item->isImageGeneratorValue()) {
2153                     if (item->isGradientValue())
2154                         state.style()->setContent(StyleGeneratedImage::create(toCSSGradientValue(item)->gradientWithStylesResolved(this).get()), didSet);
2155                     else
2156                         state.style()->setContent(StyleGeneratedImage::create(static_cast<CSSImageGeneratorValue*>(item)), didSet);
2157                     didSet = true;
2158 #if ENABLE(CSS_IMAGE_SET)
2159                 } else if (item->isImageSetValue()) {
2160                     state.style()->setContent(setOrPendingFromValue(CSSPropertyContent, toCSSImageSetValue(item)), didSet);
2161                     didSet = true;
2162 #endif
2163                 }
2164
2165                 if (item->isImageValue()) {
2166                     state.style()->setContent(cachedOrPendingFromValue(CSSPropertyContent, toCSSImageValue(item)), didSet);
2167                     didSet = true;
2168                     continue;
2169                 }
2170
2171                 if (!item->isPrimitiveValue())
2172                     continue;
2173
2174                 CSSPrimitiveValue* contentValue = toCSSPrimitiveValue(item);
2175
2176                 if (contentValue->isString()) {
2177                     state.style()->setContent(contentValue->getStringValue().impl(), didSet);
2178                     didSet = true;
2179                 } else if (contentValue->isAttr()) {
2180                     // FIXME: Can a namespace be specified for an attr(foo)?
2181                     if (state.style()->styleType() == NOPSEUDO)
2182                         state.style()->setUnique();
2183                     else
2184                         state.parentStyle()->setUnique();
2185                     QualifiedName attr(nullAtom, contentValue->getStringValue().impl(), nullAtom);
2186                     const AtomicString& value = state.element()->getAttribute(attr);
2187                     state.style()->setContent(value.isNull() ? emptyAtom : value.impl(), didSet);
2188                     didSet = true;
2189                     // register the fact that the attribute value affects the style
2190                     m_ruleSets.features().attrsInRules.add(attr.localName().impl());
2191                 } else if (contentValue->isCounter()) {
2192                     Counter* counterValue = contentValue->getCounterValue();
2193                     EListStyleType listStyleType = NoneListStyle;
2194                     CSSValueID listStyleIdent = counterValue->listStyleIdent();
2195                     if (listStyleIdent != CSSValueNone)
2196                         listStyleType = static_cast<EListStyleType>(listStyleIdent - CSSValueDisc);
2197                     auto counter = std::make_unique<CounterContent>(counterValue->identifier(), listStyleType, counterValue->separator());
2198                     state.style()->setContent(std::move(counter), didSet);
2199                     didSet = true;
2200                 } else {
2201                     switch (contentValue->getValueID()) {
2202                     case CSSValueOpenQuote:
2203                         state.style()->setContent(OPEN_QUOTE, didSet);
2204                         didSet = true;
2205                         break;
2206                     case CSSValueCloseQuote:
2207                         state.style()->setContent(CLOSE_QUOTE, didSet);
2208                         didSet = true;
2209                         break;
2210                     case CSSValueNoOpenQuote:
2211                         state.style()->setContent(NO_OPEN_QUOTE, didSet);
2212                         didSet = true;
2213                         break;
2214                     case CSSValueNoCloseQuote:
2215                         state.style()->setContent(NO_CLOSE_QUOTE, didSet);
2216                         didSet = true;
2217                         break;
2218                     default:
2219                         // normal and none do not have any effect.
2220                         { }
2221                     }
2222                 }
2223             }
2224             if (!didSet)
2225                 state.style()->clearContent();
2226             return;
2227         }
2228     case CSSPropertyQuotes:
2229         if (isInherit) {
2230             state.style()->setQuotes(state.parentStyle()->quotes());
2231             return;
2232         }
2233         if (isInitial) {
2234             state.style()->setQuotes(0);
2235             return;
2236         }
2237         if (value->isValueList()) {
2238             CSSValueList* list = toCSSValueList(value);
2239             Vector<std::pair<String, String>> quotes;
2240             for (size_t i = 0; i < list->length(); i += 2) {
2241                 CSSValue* first = list->itemWithoutBoundsCheck(i);
2242                 // item() returns null if out of bounds so this is safe.
2243                 CSSValue* second = list->item(i + 1);
2244                 if (!second)
2245                     continue;
2246                 ASSERT_WITH_SECURITY_IMPLICATION(first->isPrimitiveValue());
2247                 ASSERT_WITH_SECURITY_IMPLICATION(second->isPrimitiveValue());
2248                 String startQuote = toCSSPrimitiveValue(first)->getStringValue();
2249                 String endQuote = toCSSPrimitiveValue(second)->getStringValue();
2250                 quotes.append(std::make_pair(startQuote, endQuote));
2251             }
2252             state.style()->setQuotes(QuotesData::create(quotes));
2253             return;
2254         }
2255         if (primitiveValue) {
2256             if (primitiveValue->getValueID() == CSSValueNone)
2257                 state.style()->setQuotes(QuotesData::create(Vector<std::pair<String, String>>()));
2258         }
2259         return;
2260     // Shorthand properties.
2261     case CSSPropertyFont:
2262         if (isInherit) {
2263             FontDescription fontDescription = state.parentStyle()->fontDescription();
2264             state.style()->setLineHeight(state.parentStyle()->specifiedLineHeight());
2265             state.setLineHeightValue(0);
2266             setFontDescription(fontDescription);
2267         } else if (isInitial) {
2268             Settings* settings = documentSettings();
2269             ASSERT(settings); // If we're doing style resolution, this document should always be in a frame and thus have settings
2270             if (!settings)
2271                 return;
2272             initializeFontStyle(settings);
2273         } else if (primitiveValue) {
2274             state.style()->setLineHeight(RenderStyle::initialLineHeight());
2275             state.setLineHeightValue(0);
2276
2277             FontDescription fontDescription;
2278             RenderTheme::defaultTheme()->systemFont(primitiveValue->getValueID(), fontDescription);
2279
2280             // Double-check and see if the theme did anything. If not, don't bother updating the font.
2281             if (fontDescription.isAbsoluteSize()) {
2282                 // Make sure the rendering mode and printer font settings are updated.
2283                 Settings* settings = documentSettings();
2284                 ASSERT(settings); // If we're doing style resolution, this document should always be in a frame and thus have settings
2285                 if (!settings)
2286                     return;
2287                 fontDescription.setRenderingMode(settings->fontRenderingMode());
2288                 fontDescription.setUsePrinterFont(document().printing() || !settings->screenFontSubstitutionEnabled());
2289
2290                 // Handle the zoom factor.
2291                 fontDescription.setComputedSize(Style::computedFontSizeFromSpecifiedSize(fontDescription.specifiedSize(), fontDescription.isAbsoluteSize(), useSVGZoomRules(), state.style(), document()));
2292                 setFontDescription(fontDescription);
2293             }
2294         } else if (value->isFontValue()) {
2295             CSSFontValue* font = toCSSFontValue(value);
2296             if (!font->style || !font->variant || !font->weight
2297                 || !font->size || !font->lineHeight || !font->family)
2298                 return;
2299             applyProperty(CSSPropertyFontStyle, font->style.get());
2300             applyProperty(CSSPropertyFontVariant, font->variant.get());
2301             applyProperty(CSSPropertyFontWeight, font->weight.get());
2302             // The previous properties can dirty our font but they don't try to read the font's
2303             // properties back, which is safe. However if font-size is using the 'ex' unit, it will
2304             // need query the dirtied font's x-height to get the computed size. To be safe in this
2305             // case, let's just update the font now.
2306             updateFont();
2307             applyProperty(CSSPropertyFontSize, font->size.get());
2308
2309             state.setLineHeightValue(font->lineHeight.get());
2310
2311             applyProperty(CSSPropertyFontFamily, font->family.get());
2312         }
2313         return;
2314
2315     case CSSPropertyBackground:
2316     case CSSPropertyBackgroundPosition:
2317     case CSSPropertyBackgroundRepeat:
2318     case CSSPropertyBorder:
2319     case CSSPropertyBorderBottom:
2320     case CSSPropertyBorderColor:
2321     case CSSPropertyBorderImage:
2322     case CSSPropertyBorderLeft:
2323     case CSSPropertyBorderRadius:
2324     case CSSPropertyBorderRight:
2325     case CSSPropertyBorderSpacing:
2326     case CSSPropertyBorderStyle:
2327     case CSSPropertyBorderTop:
2328     case CSSPropertyBorderWidth:
2329     case CSSPropertyListStyle:
2330     case CSSPropertyMargin:
2331     case CSSPropertyOutline:
2332     case CSSPropertyOverflow:
2333     case CSSPropertyPadding:
2334     case CSSPropertyTransition:
2335     case CSSPropertyWebkitAnimation:
2336     case CSSPropertyWebkitBorderAfter:
2337     case CSSPropertyWebkitBorderBefore:
2338     case CSSPropertyWebkitBorderEnd:
2339     case CSSPropertyWebkitBorderStart:
2340     case CSSPropertyWebkitBorderRadius:
2341     case CSSPropertyWebkitColumns:
2342     case CSSPropertyWebkitColumnRule:
2343     case CSSPropertyWebkitFlex:
2344     case CSSPropertyWebkitFlexFlow:
2345     case CSSPropertyWebkitGridArea:
2346     case CSSPropertyWebkitGridColumn:
2347     case CSSPropertyWebkitGridRow:
2348     case CSSPropertyWebkitMarginCollapse:
2349     case CSSPropertyWebkitMarquee:
2350     case CSSPropertyWebkitMask:
2351     case CSSPropertyWebkitMaskPosition:
2352     case CSSPropertyWebkitMaskRepeat:
2353     case CSSPropertyWebkitTextEmphasis:
2354     case CSSPropertyWebkitTextStroke:
2355     case CSSPropertyWebkitTransition:
2356     case CSSPropertyWebkitTransformOrigin:
2357         ASSERT(isExpandedShorthand(id));
2358         ASSERT_NOT_REACHED();
2359         break;
2360
2361     // CSS3 Properties
2362     case CSSPropertyTextShadow:
2363     case CSSPropertyBoxShadow:
2364     case CSSPropertyWebkitBoxShadow: {
2365         if (isInherit) {
2366             if (id == CSSPropertyTextShadow)
2367                 return state.style()->setTextShadow(state.parentStyle()->textShadow() ? adoptPtr(new ShadowData(*state.parentStyle()->textShadow())) : nullptr);
2368             return state.style()->setBoxShadow(state.parentStyle()->boxShadow() ? adoptPtr(new ShadowData(*state.parentStyle()->boxShadow())) : nullptr);
2369         }
2370         if (isInitial || primitiveValue) // initial | none
2371             return id == CSSPropertyTextShadow ? state.style()->setTextShadow(nullptr) : state.style()->setBoxShadow(nullptr);
2372
2373         if (!value->isValueList())
2374             return;
2375
2376         for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
2377             CSSValue* currValue = i.value();
2378             if (!currValue->isShadowValue())
2379                 continue;
2380             CSSShadowValue* item = toCSSShadowValue(currValue);
2381             int x = item->x->computeLength<int>(state.style(), state.rootElementStyle(), zoomFactor);
2382             if (item->x->isViewportPercentageLength())
2383                 x = viewportPercentageValue(*item->x, x);
2384             int y = item->y->computeLength<int>(state.style(), state.rootElementStyle(), zoomFactor);
2385             if (item->y->isViewportPercentageLength())
2386                 y = viewportPercentageValue(*item->y, y);
2387             int blur = item->blur ? item->blur->computeLength<int>(state.style(), state.rootElementStyle(), zoomFactor) : 0;
2388             if (item->blur && item->blur->isViewportPercentageLength())
2389                 blur = viewportPercentageValue(*item->blur, blur);
2390             int spread = item->spread ? item->spread->computeLength<int>(state.style(), state.rootElementStyle(), zoomFactor) : 0;
2391             if (item->spread && item->spread->isViewportPercentageLength())
2392                 spread = viewportPercentageValue(*item->spread, spread);
2393             ShadowStyle shadowStyle = item->style && item->style->getValueID() == CSSValueInset ? Inset : Normal;
2394             Color color;
2395             if (item->color)
2396                 color = colorFromPrimitiveValue(item->color.get());
2397             else if (state.style())
2398                 color = state.style()->color();
2399
2400             OwnPtr<ShadowData> shadowData = adoptPtr(new ShadowData(IntPoint(x, y), blur, spread, shadowStyle, id == CSSPropertyWebkitBoxShadow, color.isValid() ? color : Color::transparent));
2401             if (id == CSSPropertyTextShadow)
2402                 state.style()->setTextShadow(shadowData.release(), i.index()); // add to the list if this is not the first entry
2403             else
2404                 state.style()->setBoxShadow(shadowData.release(), i.index()); // add to the list if this is not the first entry
2405         }
2406         return;
2407     }
2408     case CSSPropertyWebkitBoxReflect: {
2409         HANDLE_INHERIT_AND_INITIAL(boxReflect, BoxReflect)
2410         if (primitiveValue) {
2411             state.style()->setBoxReflect(RenderStyle::initialBoxReflect());
2412             return;
2413         }
2414
2415         if (!value->isReflectValue())
2416             return;
2417
2418         CSSReflectValue* reflectValue = toCSSReflectValue(value);
2419         RefPtr<StyleReflection> reflection = StyleReflection::create();
2420         reflection->setDirection(*reflectValue->direction());
2421         if (reflectValue->offset())
2422             reflection->setOffset(reflectValue->offset()->convertToLength<FixedIntegerConversion | PercentConversion | CalculatedConversion>(state.style(), state.rootElementStyle(), zoomFactor));
2423         NinePieceImage mask;
2424         mask.setMaskDefaults();
2425         m_styleMap.mapNinePieceImage(id, reflectValue->mask(), mask);
2426         reflection->setMask(mask);
2427
2428         state.style()->setBoxReflect(reflection.release());
2429         return;
2430     }
2431     case CSSPropertySrc: // Only used in @font-face rules.
2432         return;
2433     case CSSPropertyUnicodeRange: // Only used in @font-face rules.
2434         return;
2435     case CSSPropertyWebkitLocale: {
2436         HANDLE_INHERIT_AND_INITIAL(locale, Locale);
2437         if (!primitiveValue)
2438             return;
2439         if (primitiveValue->getValueID() == CSSValueAuto)
2440             state.style()->setLocale(nullAtom);
2441         else
2442             state.style()->setLocale(primitiveValue->getStringValue());
2443         FontDescription fontDescription = state.style()->fontDescription();
2444         fontDescription.setScript(localeToScriptCodeForFontSelection(state.style()->locale()));
2445         setFontDescription(fontDescription);
2446         return;
2447     }
2448 #if ENABLE(IOS_TEXT_AUTOSIZING)
2449     case CSSPropertyWebkitTextSizeAdjust: {
2450         HANDLE_INHERIT_AND_INITIAL(textSizeAdjust, TextSizeAdjust)
2451         if (!primitiveValue)
2452             return;
2453
2454         if (primitiveValue->getValueID() == CSSValueAuto)
2455             state.style()->setTextSizeAdjust(TextSizeAdjustment(AutoTextSizeAdjustment));
2456         else if (primitiveValue->getValueID() == CSSValueNone)
2457             state.style()->setTextSizeAdjust(TextSizeAdjustment(NoTextSizeAdjustment));
2458         else
2459             state.style()->setTextSizeAdjust(TextSizeAdjustment(primitiveValue->getFloatValue()));
2460
2461         state.setFontDirty(true);
2462         return;
2463     }
2464 #endif
2465 #if ENABLE(DASHBOARD_SUPPORT)
2466     case CSSPropertyWebkitDashboardRegion:
2467     {
2468         HANDLE_INHERIT_AND_INITIAL(dashboardRegions, DashboardRegions)
2469         if (!primitiveValue)
2470             return;
2471
2472         if (primitiveValue->getValueID() == CSSValueNone) {
2473             state.style()->setDashboardRegions(RenderStyle::noneDashboardRegions());
2474             return;
2475         }
2476
2477         DashboardRegion* region = primitiveValue->getDashboardRegionValue();
2478         if (!region)
2479             return;
2480
2481         DashboardRegion* first = region;
2482         while (region) {
2483             Length top = convertToIntLength(region->top(), state.style(), state.rootElementStyle());
2484             Length right = convertToIntLength(region->right(), state.style(), state.rootElementStyle());
2485             Length bottom = convertToIntLength(region->bottom(), state.style(), state.rootElementStyle());
2486             Length left = convertToIntLength(region->left(), state.style(), state.rootElementStyle());
2487
2488             if (top.isUndefined())
2489                 top = Length();
2490             if (right.isUndefined())
2491                 right = Length();
2492             if (bottom.isUndefined())
2493                 bottom = Length();
2494             if (left.isUndefined())
2495                 left = Length();
2496
2497             if (region->m_isCircle)
2498                 state.style()->setDashboardRegion(StyleDashboardRegion::Circle, region->m_label, top, right, bottom, left, region == first ? false : true);
2499             else if (region->m_isRectangle)
2500                 state.style()->setDashboardRegion(StyleDashboardRegion::Rectangle, region->m_label, top, right, bottom, left, region == first ? false : true);
2501             region = region->m_next.get();
2502         }
2503
2504         state.document().setHasAnnotatedRegions(true);
2505
2506         return;
2507     }
2508 #endif
2509 #if ENABLE(DRAGGABLE_REGION)
2510     case CSSPropertyWebkitAppRegion: {
2511         if (!primitiveValue || !primitiveValue->getValueID())
2512             return;
2513         state.style()->setDraggableRegionMode(primitiveValue->getValueID() == CSSValueDrag ? DraggableRegionDrag : DraggableRegionNoDrag);
2514         state.document().setHasAnnotatedRegions(true);
2515         return;
2516     }
2517 #endif
2518     case CSSPropertyWebkitTextStrokeWidth: {
2519         HANDLE_INHERIT_AND_INITIAL(textStrokeWidth, TextStrokeWidth)
2520         float width = 0;
2521         switch (primitiveValue->getValueID()) {
2522         case CSSValueThin:
2523         case CSSValueMedium:
2524         case CSSValueThick: {
2525             double result = 1.0 / 48;
2526             if (primitiveValue->getValueID() == CSSValueMedium)
2527                 result *= 3;
2528             else if (primitiveValue->getValueID() == CSSValueThick)
2529                 result *= 5;
2530             width = CSSPrimitiveValue::create(result, CSSPrimitiveValue::CSS_EMS)->computeLength<float>(state.style(), state.rootElementStyle(), zoomFactor);
2531             break;
2532         }
2533         default:
2534             width = primitiveValue->computeLength<float>(state.style(), state.rootElementStyle(), zoomFactor);
2535             break;
2536         }
2537         state.style()->setTextStrokeWidth(width);
2538         return;
2539     }
2540     case CSSPropertyWebkitTransform: {
2541         HANDLE_INHERIT_AND_INITIAL(transform, Transform);
2542         TransformOperations operations;
2543         transformsForValue(state.style(), state.rootElementStyle(), value, operations);
2544         state.style()->setTransform(operations);
2545         return;
2546     }
2547     case CSSPropertyWebkitPerspective: {
2548         HANDLE_INHERIT_AND_INITIAL(perspective, Perspective)
2549
2550         if (!primitiveValue)
2551             return;
2552
2553         if (primitiveValue->getValueID() == CSSValueNone) {
2554             state.style()->setPerspective(0);
2555             return;
2556         }
2557
2558         float perspectiveValue;
2559         if (primitiveValue->isLength())
2560             perspectiveValue = primitiveValue->computeLength<float>(state.style(), state.rootElementStyle(), zoomFactor);
2561         else if (primitiveValue->isNumber()) {
2562             // For backward compatibility, treat valueless numbers as px.
2563             perspectiveValue = CSSPrimitiveValue::create(primitiveValue->getDoubleValue(), CSSPrimitiveValue::CSS_PX)->computeLength<float>(state.style(), state.rootElementStyle(), zoomFactor);
2564         } else
2565             return;
2566
2567         if (perspectiveValue >= 0.0f)
2568             state.style()->setPerspective(perspectiveValue);
2569         return;
2570     }
2571 #if PLATFORM(IOS)
2572     case CSSPropertyWebkitTouchCallout: {
2573         HANDLE_INHERIT_AND_INITIAL(touchCalloutEnabled, TouchCalloutEnabled);
2574         if (!primitiveValue)
2575             break;
2576
2577         state.style()->setTouchCalloutEnabled(primitiveValue->getStringValue().lower() != "none");
2578         return;
2579     }
2580 #endif
2581 #if ENABLE(TOUCH_EVENTS)
2582     case CSSPropertyWebkitTapHighlightColor: {
2583         HANDLE_INHERIT_AND_INITIAL(tapHighlightColor, TapHighlightColor);
2584         if (!primitiveValue)
2585             break;
2586
2587         Color col = colorFromPrimitiveValue(primitiveValue);
2588         state.style()->setTapHighlightColor(col);
2589         return;
2590     }
2591 #endif
2592 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
2593     case CSSPropertyWebkitOverflowScrolling: {
2594         HANDLE_INHERIT_AND_INITIAL(useTouchOverflowScrolling, UseTouchOverflowScrolling);
2595         if (!primitiveValue)
2596             break;
2597         state.style()->setUseTouchOverflowScrolling(primitiveValue->getValueID() == CSSValueTouch);
2598         return;
2599     }
2600 #endif
2601     case CSSPropertyInvalid:
2602         return;
2603     // Directional properties are resolved by resolveDirectionAwareProperty() before the switch.
2604     case CSSPropertyWebkitBorderEndColor:
2605     case CSSPropertyWebkitBorderEndStyle:
2606     case CSSPropertyWebkitBorderEndWidth:
2607     case CSSPropertyWebkitBorderStartColor:
2608     case CSSPropertyWebkitBorderStartStyle:
2609     case CSSPropertyWebkitBorderStartWidth:
2610     case CSSPropertyWebkitBorderBeforeColor:
2611     case CSSPropertyWebkitBorderBeforeStyle:
2612     case CSSPropertyWebkitBorderBeforeWidth:
2613     case CSSPropertyWebkitBorderAfterColor:
2614     case CSSPropertyWebkitBorderAfterStyle:
2615     case CSSPropertyWebkitBorderAfterWidth:
2616     case CSSPropertyWebkitMarginEnd:
2617     case CSSPropertyWebkitMarginStart:
2618     case CSSPropertyWebkitMarginBefore:
2619     case CSSPropertyWebkitMarginAfter:
2620     case CSSPropertyWebkitMarginBeforeCollapse:
2621     case CSSPropertyWebkitMarginTopCollapse:
2622     case CSSPropertyWebkitMarginAfterCollapse:
2623     case CSSPropertyWebkitMarginBottomCollapse:
2624     case CSSPropertyWebkitPaddingEnd:
2625     case CSSPropertyWebkitPaddingStart:
2626     case CSSPropertyWebkitPaddingBefore:
2627     case CSSPropertyWebkitPaddingAfter:
2628     case CSSPropertyWebkitLogicalWidth:
2629     case CSSPropertyWebkitLogicalHeight:
2630     case CSSPropertyWebkitMinLogicalWidth:
2631     case CSSPropertyWebkitMinLogicalHeight:
2632     case CSSPropertyWebkitMaxLogicalWidth:
2633     case CSSPropertyWebkitMaxLogicalHeight:
2634     {
2635         CSSPropertyID newId = CSSProperty::resolveDirectionAwareProperty(id, state.style()->direction(), state.style()->writingMode());
2636         ASSERT(newId != id);
2637         return applyProperty(newId, value);
2638     }
2639     case CSSPropertyFontStretch:
2640     case CSSPropertyPage:
2641     case CSSPropertyTextLineThrough:
2642     case CSSPropertyTextLineThroughColor:
2643     case CSSPropertyTextLineThroughMode:
2644     case CSSPropertyTextLineThroughStyle:
2645     case CSSPropertyTextLineThroughWidth:
2646     case CSSPropertyTextOverline:
2647     case CSSPropertyTextOverlineColor:
2648     case CSSPropertyTextOverlineMode:
2649     case CSSPropertyTextOverlineStyle:
2650     case CSSPropertyTextOverlineWidth:
2651     case CSSPropertyTextUnderline:
2652     case CSSPropertyTextUnderlineColor:
2653     case CSSPropertyTextUnderlineMode:
2654     case CSSPropertyTextUnderlineStyle:
2655     case CSSPropertyTextUnderlineWidth:
2656     case CSSPropertyWebkitFontSizeDelta:
2657     case CSSPropertyWebkitTextDecorationsInEffect:
2658         return;
2659
2660     // CSS Text Layout Module Level 3: Vertical writing support
2661     case CSSPropertyWebkitWritingMode: {
2662         HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode);
2663         
2664         if (primitiveValue)
2665             setWritingMode(*primitiveValue);
2666
2667         // FIXME: It is not ok to modify document state while applying style.
2668         if (state.element() && state.element() == state.document().documentElement())
2669             state.document().setWritingModeSetOnDocumentElement(true);
2670         return;
2671     }
2672
2673     case CSSPropertyWebkitTextOrientation: {
2674         HANDLE_INHERIT_AND_INITIAL(textOrientation, TextOrientation);
2675
2676         if (primitiveValue)
2677             setTextOrientation(*primitiveValue);
2678
2679         return;
2680     }
2681
2682     case CSSPropertyWebkitLineBoxContain: {
2683         HANDLE_INHERIT_AND_INITIAL(lineBoxContain, LineBoxContain)
2684         if (primitiveValue && primitiveValue->getValueID() == CSSValueNone) {
2685             state.style()->setLineBoxContain(LineBoxContainNone);
2686             return;
2687         }
2688
2689         if (!value->isLineBoxContainValue())
2690             return;
2691
2692         state.style()->setLineBoxContain(toCSSLineBoxContainValue(value)->value());
2693         return;
2694     }
2695
2696     // CSS Fonts Module Level 3
2697     case CSSPropertyWebkitFontFeatureSettings: {
2698         if (primitiveValue && primitiveValue->getValueID() == CSSValueNormal) {
2699             setFontDescription(state.style()->fontDescription().makeNormalFeatureSettings());
2700             return;
2701         }
2702
2703         if (!value->isValueList())
2704             return;
2705
2706         FontDescription fontDescription = state.style()->fontDescription();
2707         CSSValueList* list = toCSSValueList(value);
2708         RefPtr<FontFeatureSettings> settings = FontFeatureSettings::create();
2709         int len = list->length();
2710         for (int i = 0; i < len; ++i) {
2711             CSSValue* item = list->itemWithoutBoundsCheck(i);
2712             if (!item->isFontFeatureValue())
2713                 continue;
2714             CSSFontFeatureValue* feature = toCSSFontFeatureValue(item);
2715             settings->append(FontFeature(feature->tag(), feature->value()));
2716         }
2717         fontDescription.setFeatureSettings(settings.release());
2718         setFontDescription(fontDescription);
2719         return;
2720     }
2721
2722 #if ENABLE(CSS_FILTERS)
2723     case CSSPropertyWebkitFilter: {
2724         HANDLE_INHERIT_AND_INITIAL(filter, Filter);
2725         FilterOperations operations;
2726         if (createFilterOperations(value, operations))
2727             state.style()->setFilter(operations);
2728         return;
2729     }
2730 #endif
2731     case CSSPropertyWebkitGridAutoColumns: {
2732         GridTrackSize trackSize;
2733         if (!createGridTrackSize(value, trackSize, state))
2734             return;
2735         state.style()->setGridAutoColumns(trackSize);
2736         return;
2737     }
2738     case CSSPropertyWebkitGridAutoRows: {
2739         GridTrackSize trackSize;
2740         if (!createGridTrackSize(value, trackSize, state))
2741             return;
2742         state.style()->setGridAutoRows(trackSize);
2743         return;
2744     }
2745     case CSSPropertyWebkitGridDefinitionColumns: {
2746         Vector<GridTrackSize> trackSizes;
2747         NamedGridLinesMap namedGridLines;
2748         if (!createGridTrackList(value, trackSizes, namedGridLines, state))
2749             return;
2750         state.style()->setGridColumns(trackSizes);
2751         state.style()->setNamedGridColumnLines(namedGridLines);
2752         return;
2753     }
2754     case CSSPropertyWebkitGridDefinitionRows: {
2755         Vector<GridTrackSize> trackSizes;
2756         NamedGridLinesMap namedGridLines;
2757         if (!createGridTrackList(value, trackSizes, namedGridLines, state))
2758             return;
2759         state.style()->setGridRows(trackSizes);
2760         state.style()->setNamedGridRowLines(namedGridLines);
2761         return;
2762     }
2763
2764     case CSSPropertyWebkitGridColumnStart: {
2765         GridPosition columnStartPosition;
2766         if (!createGridPosition(value, columnStartPosition))
2767             return;
2768         state.style()->setGridItemColumnStart(columnStartPosition);
2769         return;
2770     }
2771     case CSSPropertyWebkitGridColumnEnd: {
2772         GridPosition columnEndPosition;
2773         if (!createGridPosition(value, columnEndPosition))
2774             return;
2775         state.style()->setGridItemColumnEnd(columnEndPosition);
2776         return;
2777     }
2778
2779     case CSSPropertyWebkitGridRowStart: {
2780         GridPosition rowStartPosition;
2781         if (!createGridPosition(value, rowStartPosition))
2782             return;
2783         state.style()->setGridItemRowStart(rowStartPosition);
2784         return;
2785     }
2786     case CSSPropertyWebkitGridRowEnd: {
2787         GridPosition rowEndPosition;
2788         if (!createGridPosition(value, rowEndPosition))
2789             return;
2790         state.style()->setGridItemRowEnd(rowEndPosition);
2791         return;
2792     }
2793     case CSSPropertyWebkitGridTemplate: {
2794         if (isInherit) {
2795             state.style()->setNamedGridArea(state.parentStyle()->namedGridArea());
2796             state.style()->setNamedGridAreaRowCount(state.parentStyle()->namedGridAreaRowCount());
2797             state.style()->setNamedGridAreaColumnCount(state.parentStyle()->namedGridAreaColumnCount());
2798             return;
2799         }
2800         if (isInitial) {
2801             state.style()->setNamedGridArea(RenderStyle::initialNamedGridArea());
2802             state.style()->setNamedGridAreaRowCount(RenderStyle::initialNamedGridAreaCount());
2803             state.style()->setNamedGridAreaColumnCount(RenderStyle::initialNamedGridAreaCount());
2804             return;
2805         }
2806
2807         if (value->isPrimitiveValue()) {
2808             ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone);
2809             return;
2810         }
2811
2812         CSSGridTemplateValue* gridTemplateValue = toCSSGridTemplateValue(value);
2813         state.style()->setNamedGridArea(gridTemplateValue->gridAreaMap());
2814         state.style()->setNamedGridAreaRowCount(gridTemplateValue->rowCount());
2815         state.style()->setNamedGridAreaColumnCount(gridTemplateValue->columnCount());
2816         return;
2817     }
2818
2819     // These properties are aliased and DeprecatedStyleBuilder already applied the property on the prefixed version.
2820     case CSSPropertyTransitionDelay:
2821     case CSSPropertyTransitionDuration:
2822     case CSSPropertyTransitionProperty:
2823     case CSSPropertyTransitionTimingFunction:
2824         return;
2825     // These properties are implemented in the DeprecatedStyleBuilder lookup table.
2826     case CSSPropertyBackgroundAttachment:
2827     case CSSPropertyBackgroundClip:
2828     case CSSPropertyBackgroundColor:
2829     case CSSPropertyBackgroundImage:
2830     case CSSPropertyBackgroundOrigin:
2831     case CSSPropertyBackgroundPositionX:
2832     case CSSPropertyBackgroundPositionY:
2833     case CSSPropertyBackgroundRepeatX:
2834     case CSSPropertyBackgroundRepeatY:
2835     case CSSPropertyBackgroundSize:
2836     case CSSPropertyBorderBottomColor:
2837     case CSSPropertyBorderBottomLeftRadius:
2838     case CSSPropertyBorderBottomRightRadius:
2839     case CSSPropertyBorderBottomStyle:
2840     case CSSPropertyBorderBottomWidth:
2841     case CSSPropertyBorderCollapse:
2842     case CSSPropertyBorderImageOutset:
2843     case CSSPropertyBorderImageRepeat:
2844     case CSSPropertyBorderImageSlice:
2845     case CSSPropertyBorderImageSource:
2846     case CSSPropertyBorderImageWidth:
2847     case CSSPropertyBorderLeftColor:
2848     case CSSPropertyBorderLeftStyle:
2849     case CSSPropertyBorderLeftWidth:
2850     case CSSPropertyBorderRightColor:
2851     case CSSPropertyBorderRightStyle:
2852     case CSSPropertyBorderRightWidth:
2853     case CSSPropertyBorderTopColor:
2854     case CSSPropertyBorderTopLeftRadius:
2855     case CSSPropertyBorderTopRightRadius:
2856     case CSSPropertyBorderTopStyle:
2857     case CSSPropertyBorderTopWidth:
2858     case CSSPropertyBottom:
2859     case CSSPropertyBoxSizing:
2860     case CSSPropertyCaptionSide:
2861     case CSSPropertyClear:
2862     case CSSPropertyClip:
2863     case CSSPropertyColor:
2864     case CSSPropertyCounterIncrement:
2865     case CSSPropertyCounterReset:
2866     case CSSPropertyCursor:
2867     case CSSPropertyDirection:
2868     case CSSPropertyDisplay:
2869     case CSSPropertyEmptyCells:
2870     case CSSPropertyFloat:
2871     case CSSPropertyFontSize:
2872     case CSSPropertyFontStyle:
2873     case CSSPropertyFontVariant:
2874     case CSSPropertyFontWeight:
2875     case CSSPropertyHeight:
2876 #if ENABLE(CSS_IMAGE_ORIENTATION)
2877     case CSSPropertyImageOrientation:
2878 #endif
2879     case CSSPropertyImageRendering:
2880 #if ENABLE(CSS_IMAGE_RESOLUTION)
2881     case CSSPropertyImageResolution:
2882 #endif
2883     case CSSPropertyLeft:
2884     case CSSPropertyLetterSpacing:
2885     case CSSPropertyLineHeight:
2886     case CSSPropertyListStyleImage:
2887     case CSSPropertyListStylePosition:
2888     case CSSPropertyListStyleType:
2889     case CSSPropertyMarginBottom:
2890     case CSSPropertyMarginLeft:
2891     case CSSPropertyMarginRight:
2892     case CSSPropertyMarginTop:
2893     case CSSPropertyMaxHeight:
2894     case CSSPropertyMaxWidth:
2895     case CSSPropertyMinHeight:
2896     case CSSPropertyMinWidth:
2897     case CSSPropertyObjectFit:
2898     case CSSPropertyOpacity:
2899     case CSSPropertyOrphans:
2900     case CSSPropertyOutlineColor:
2901     case CSSPropertyOutlineOffset:
2902     case CSSPropertyOutlineStyle:
2903     case CSSPropertyOutlineWidth:
2904     case CSSPropertyOverflowWrap:
2905     case CSSPropertyOverflowX:
2906     case CSSPropertyOverflowY:
2907     case CSSPropertyPaddingBottom:
2908     case CSSPropertyPaddingLeft:
2909     case CSSPropertyPaddingRight:
2910     case CSSPropertyPaddingTop:
2911     case CSSPropertyPageBreakAfter:
2912     case CSSPropertyPageBreakBefore:
2913     case CSSPropertyPageBreakInside:
2914     case CSSPropertyPointerEvents:
2915     case CSSPropertyPosition:
2916     case CSSPropertyResize:
2917     case CSSPropertyRight:
2918     case CSSPropertySize:
2919     case CSSPropertySpeak:
2920     case CSSPropertyTabSize:
2921     case CSSPropertyTableLayout:
2922     case CSSPropertyTextAlign:
2923     case CSSPropertyTextDecoration:
2924     case CSSPropertyTextIndent:
2925     case CSSPropertyTextOverflow:
2926     case CSSPropertyTextRendering:
2927     case CSSPropertyTextTransform:
2928     case CSSPropertyTop:
2929     case CSSPropertyUnicodeBidi:
2930 #if ENABLE(CSS_VARIABLES)
2931     case CSSPropertyVariable:
2932 #endif
2933     case CSSPropertyVerticalAlign:
2934     case CSSPropertyVisibility:
2935     case CSSPropertyWebkitAnimationDelay:
2936     case CSSPropertyWebkitAnimationDirection:
2937     case CSSPropertyWebkitAnimationDuration:
2938     case CSSPropertyWebkitAnimationFillMode:
2939     case CSSPropertyWebkitAnimationIterationCount:
2940     case CSSPropertyWebkitAnimationName:
2941     case CSSPropertyWebkitAnimationPlayState:
2942     case CSSPropertyWebkitAnimationTimingFunction:
2943     case CSSPropertyWebkitAppearance:
2944     case CSSPropertyWebkitAspectRatio:
2945     case CSSPropertyWebkitBackfaceVisibility:
2946     case CSSPropertyWebkitBackgroundClip:
2947     case CSSPropertyWebkitBackgroundComposite:
2948     case CSSPropertyWebkitBackgroundOrigin:
2949     case CSSPropertyWebkitBackgroundSize:
2950     case CSSPropertyWebkitBorderFit:
2951     case CSSPropertyWebkitBorderHorizontalSpacing:
2952     case CSSPropertyWebkitBorderImage:
2953     case CSSPropertyWebkitBorderVerticalSpacing:
2954     case CSSPropertyWebkitBoxAlign:
2955 #if ENABLE(CSS_BOX_DECORATION_BREAK)
2956     case CSSPropertyWebkitBoxDecorationBreak:
2957 #endif
2958     case CSSPropertyWebkitBoxDirection:
2959     case CSSPropertyWebkitBoxFlex:
2960     case CSSPropertyWebkitBoxFlexGroup:
2961     case CSSPropertyWebkitBoxLines:
2962     case CSSPropertyWebkitBoxOrdinalGroup:
2963     case CSSPropertyWebkitBoxOrient:
2964     case CSSPropertyWebkitBoxPack:
2965     case CSSPropertyWebkitColorCorrection:
2966     case CSSPropertyWebkitColumnAxis:
2967     case CSSPropertyWebkitColumnBreakAfter:
2968     case CSSPropertyWebkitColumnBreakBefore:
2969     case CSSPropertyWebkitColumnBreakInside:
2970     case CSSPropertyWebkitColumnCount:
2971     case CSSPropertyWebkitColumnGap:
2972     case CSSPropertyWebkitColumnProgression:
2973     case CSSPropertyWebkitColumnRuleColor:
2974     case CSSPropertyWebkitColumnRuleStyle:
2975     case CSSPropertyWebkitColumnRuleWidth:
2976     case CSSPropertyWebkitColumnSpan:
2977     case CSSPropertyWebkitColumnWidth:
2978 #if ENABLE(CURSOR_VISIBILITY)
2979     case CSSPropertyWebkitCursorVisibility:
2980 #endif
2981     case CSSPropertyWebkitAlignContent:
2982     case CSSPropertyWebkitAlignItems:
2983     case CSSPropertyWebkitAlignSelf:
2984     case CSSPropertyWebkitFlexBasis:
2985     case CSSPropertyWebkitFlexDirection:
2986     case CSSPropertyWebkitFlexGrow:
2987     case CSSPropertyWebkitFlexShrink:
2988     case CSSPropertyWebkitFlexWrap:
2989     case CSSPropertyWebkitJustifyContent:
2990     case CSSPropertyWebkitOrder:
2991 #if ENABLE(CSS_REGIONS)
2992     case CSSPropertyWebkitFlowFrom:
2993     case CSSPropertyWebkitFlowInto:
2994 #endif
2995     case CSSPropertyWebkitFontKerning:
2996     case CSSPropertyWebkitFontSmoothing:
2997     case CSSPropertyWebkitFontVariantLigatures:
2998     case CSSPropertyWebkitHighlight:
2999     case CSSPropertyWebkitHyphenateCharacter:
3000     case CSSPropertyWebkitHyphenateLimitAfter:
3001     case CSSPropertyWebkitHyphenateLimitBefore:
3002     case CSSPropertyWebkitHyphenateLimitLines:
3003     case CSSPropertyWebkitHyphens:
3004     case CSSPropertyWebkitLineAlign:
3005     case CSSPropertyWebkitLineBreak:
3006     case CSSPropertyWebkitLineClamp:
3007     case CSSPropertyWebkitLineGrid:
3008     case CSSPropertyWebkitLineSnap:
3009     case CSSPropertyWebkitMarqueeDirection:
3010     case CSSPropertyWebkitMarqueeIncrement:
3011     case CSSPropertyWebkitMarqueeRepetition:
3012     case CSSPropertyWebkitMarqueeSpeed:
3013     case CSSPropertyWebkitMarqueeStyle:
3014     case CSSPropertyWebkitMaskBoxImage:
3015     case CSSPropertyWebkitMaskBoxImageOutset:
3016     case CSSPropertyWebkitMaskBoxImageRepeat:
3017     case CSSPropertyWebkitMaskBoxImageSlice:
3018     case CSSPropertyWebkitMaskBoxImageSource:
3019     case CSSPropertyWebkitMaskBoxImageWidth:
3020     case CSSPropertyWebkitMaskClip:
3021     case CSSPropertyWebkitMaskComposite:
3022     case CSSPropertyWebkitMaskImage:
3023     case CSSPropertyWebkitMaskOrigin:
3024     case CSSPropertyWebkitMaskPositionX:
3025     case CSSPropertyWebkitMaskPositionY:
3026     case CSSPropertyWebkitMaskRepeatX:
3027     case CSSPropertyWebkitMaskRepeatY:
3028     case CSSPropertyWebkitMaskSize:
3029     case CSSPropertyWebkitMaskSourceType:
3030     case CSSPropertyWebkitNbspMode:
3031     case CSSPropertyWebkitPerspectiveOrigin:
3032     case CSSPropertyWebkitPerspectiveOriginX:
3033     case CSSPropertyWebkitPerspectiveOriginY:
3034     case CSSPropertyWebkitPrintColorAdjust:
3035 #if ENABLE(CSS_REGIONS)
3036     case CSSPropertyWebkitRegionBreakAfter:
3037     case CSSPropertyWebkitRegionBreakBefore:
3038     case CSSPropertyWebkitRegionBreakInside:
3039     case CSSPropertyWebkitRegionFragment:
3040 #endif
3041     case CSSPropertyWebkitRtlOrdering:
3042     case CSSPropertyWebkitRubyPosition:
3043     case CSSPropertyWebkitTextCombine:
3044 #if ENABLE(CSS3_TEXT)
3045     case CSSPropertyWebkitTextDecorationLine:
3046     case CSSPropertyWebkitTextDecorationStyle:
3047     case CSSPropertyWebkitTextDecorationColor:
3048     case CSSPropertyWebkitTextAlignLast:
3049     case CSSPropertyWebkitTextJustify:
3050     case CSSPropertyWebkitTextUnderlinePosition:
3051 #endif // CSS3_TEXT
3052     case CSSPropertyWebkitTextEmphasisColor:
3053     case CSSPropertyWebkitTextEmphasisPosition:
3054     case CSSPropertyWebkitTextEmphasisStyle:
3055     case CSSPropertyWebkitTextFillColor:
3056     case CSSPropertyWebkitTextSecurity:
3057     case CSSPropertyWebkitTextStrokeColor:
3058     case CSSPropertyWebkitTransformOriginX:
3059     case CSSPropertyWebkitTransformOriginY:
3060     case CSSPropertyWebkitTransformOriginZ:
3061     case CSSPropertyWebkitTransformStyle:
3062     case CSSPropertyWebkitTransitionDelay:
3063     case CSSPropertyWebkitTransitionDuration:
3064     case CSSPropertyWebkitTransitionProperty:
3065     case CSSPropertyWebkitTransitionTimingFunction:
3066     case CSSPropertyWebkitUserDrag:
3067     case CSSPropertyWebkitUserModify:
3068     case CSSPropertyWebkitUserSelect:
3069     case CSSPropertyWebkitClipPath:
3070 #if ENABLE(CSS_SHAPES)
3071     case CSSPropertyWebkitShapeMargin:
3072     case CSSPropertyWebkitShapePadding:
3073     case CSSPropertyWebkitShapeImageThreshold:
3074     case CSSPropertyWebkitShapeInside:
3075     case CSSPropertyWebkitShapeOutside:
3076 #endif
3077 #if ENABLE(CSS_EXCLUSIONS)
3078     case CSSPropertyWebkitWrapFlow:
3079     case CSSPropertyWebkitWrapThrough:
3080 #endif
3081 #if ENABLE(CSS_SHADERS)
3082     case CSSPropertyMix:
3083     case CSSPropertyParameters:
3084 #endif
3085     case CSSPropertyWhiteSpace:
3086     case CSSPropertyWidows:
3087     case CSSPropertyWidth:
3088     case CSSPropertyWordBreak:
3089     case CSSPropertyWordSpacing:
3090     case CSSPropertyWordWrap:
3091     case CSSPropertyZIndex:
3092     case CSSPropertyZoom:
3093 #if ENABLE(CSS_DEVICE_ADAPTATION)
3094     case CSSPropertyMaxZoom:
3095     case CSSPropertyMinZoom:
3096     case CSSPropertyOrientation:
3097     case CSSPropertyUserZoom:
3098 #endif
3099         ASSERT_NOT_REACHED();
3100         return;
3101     default:
3102 #if ENABLE(SVG)
3103         // Try the SVG properties
3104         applySVGProperty(id, value);
3105 #endif
3106         return;
3107     }
3108 }
3109
3110 PassRefPtr<StyleImage> StyleResolver::styleImage(CSSPropertyID property, CSSValue* value)
3111 {
3112     if (value->isImageValue())
3113         return cachedOrPendingFromValue(property, toCSSImageValue(value));
3114
3115     if (value->isImageGeneratorValue()) {
3116         if (value->isGradientValue())
3117             return generatedOrPendingFromValue(property, toCSSGradientValue(value)->gradientWithStylesResolved(this).get());
3118         return generatedOrPendingFromValue(property, static_cast<CSSImageGeneratorValue*>(value));
3119     }
3120
3121 #if ENABLE(CSS_IMAGE_SET)
3122     if (value->isImageSetValue())
3123         return setOrPendingFromValue(property, toCSSImageSetValue(value));
3124 #endif
3125
3126     if (value->isCursorImageValue())
3127         return cursorOrPendingFromValue(property, toCSSCursorImageValue(value));
3128
3129     return 0;
3130 }
3131
3132 PassRefPtr<StyleImage> StyleResolver::cachedOrPendingFromValue(CSSPropertyID property, CSSImageValue* value)
3133 {
3134     RefPtr<StyleImage> image = value->cachedOrPendingImage();
3135     if (image && image->isPendingImage())
3136         m_state.pendingImageProperties().set(property, value);
3137     return image.release();
3138 }
3139
3140 PassRefPtr<StyleImage> StyleResolver::generatedOrPendingFromValue(CSSPropertyID property, CSSImageGeneratorValue* value)
3141 {
3142 #if ENABLE(CSS_FILTERS)
3143     if (value->isFilterImageValue()) {
3144         // FilterImage needs to calculate FilterOperations.
3145         toCSSFilterImageValue(value)->createFilterOperations(this);
3146     }
3147 #endif
3148     if (value->isPending()) {
3149         m_state.pendingImageProperties().set(property, value);
3150         return StylePendingImage::create(value);
3151     }
3152     return StyleGeneratedImage::create(value);
3153 }
3154
3155 #if ENABLE(CSS_IMAGE_SET)
3156 PassRefPtr<StyleImage> StyleResolver::setOrPendingFromValue(CSSPropertyID property, CSSImageSetValue* value)
3157 {
3158     RefPtr<StyleImage> image = value->cachedOrPendingImageSet(document());
3159     if (image && image->isPendingImage())
3160         m_state.pendingImageProperties().set(property, value);
3161     return image.release();
3162 }
3163 #endif
3164
3165 PassRefPtr<StyleImage> StyleResolver::cursorOrPendingFromValue(CSSPropertyID property, CSSCursorImageValue* value)
3166 {
3167     RefPtr<StyleImage> image = value->cachedOrPendingImage(document());
3168     if (image && image->isPendingImage())
3169         m_state.pendingImageProperties().set(property, value);
3170     return image.release();
3171 }
3172
3173 #if ENABLE(IOS_TEXT_AUTOSIZING)
3174 void StyleResolver::checkForTextSizeAdjust(RenderStyle* style)
3175 {
3176     if (style->textSizeAdjust().isAuto())
3177         return;
3178
3179     FontDescription newFontDescription(style->fontDescription());
3180     if (!style->textSizeAdjust().isNone())
3181         newFontDescription.setComputedSize(newFontDescription.specifiedSize() * style->textSizeAdjust().multiplier());
3182     else
3183         newFontDescription.setComputedSize(newFontDescription.specifiedSize());
3184     style->setFontDescription(newFontDescription);
3185 }
3186 #endif
3187
3188 void StyleResolver::checkForZoomChange(RenderStyle* style, RenderStyle* parentStyle)
3189 {
3190     if (style->effectiveZoom() == parentStyle->effectiveZoom())
3191         return;
3192
3193     const FontDescription& childFont = style->fontDescription();
3194     FontDescription newFontDescription(childFont);
3195     setFontSize(newFontDescription, childFont.specifiedSize());
3196     style->setFontDescription(newFontDescription);
3197 }
3198
3199 void StyleResolver::checkForGenericFamilyChange(RenderStyle* style, RenderStyle* parentStyle)
3200 {
3201     const FontDescription& childFont = style->fontDescription();
3202
3203     if (childFont.isAbsoluteSize() || !parentStyle)
3204         return;
3205
3206     const FontDescription& parentFont = parentStyle->fontDescription();
3207     if (childFont.useFixedDefaultSize() == parentFont.useFixedDefaultSize())
3208         return;
3209
3210     // For now, lump all families but monospace together.
3211     if (childFont.genericFamily() != FontDescription::MonospaceFamily
3212         && parentFont.genericFamily() != FontDescription::MonospaceFamily)
3213         return;
3214
3215     // We know the parent is monospace or the child is monospace, and that font
3216     // size was unspecified. We want to scale our font size as appropriate.
3217     // If the font uses a keyword size, then we refetch from the table rather than
3218     // multiplying by our scale factor.
3219     float size;
3220     if (childFont.keywordSize())
3221         size = Style::fontSizeForKeyword(CSSValueXxSmall + childFont.keywordSize() - 1, childFont.useFixedDefaultSize(), document());
3222     else {
3223         Settings* settings = documentSettings();
3224         float fixedScaleFactor = (settings && settings->defaultFixedFontSize() && settings->defaultFontSize())
3225             ? static_cast<float>(settings->defaultFixedFontSize()) / settings->defaultFontSize()
3226             : 1;
3227         size = parentFont.useFixedDefaultSize() ?
3228                 childFont.specifiedSize() / fixedScaleFactor :
3229                 childFont.specifiedSize() * fixedScaleFactor;
3230     }
3231
3232     FontDescription newFontDescription(childFont);
3233     setFontSize(newFontDescription, size);
3234     style->setFontDescription(newFontDescription);
3235 }
3236
3237 void StyleResolver::initializeFontStyle(Settings* settings)
3238 {
3239     FontDescription fontDescription;
3240     fontDescription.setGenericFamily(FontDescription::StandardFamily);
3241     fontDescription.setRenderingMode(settings->fontRenderingMode());
3242     fontDescription.setUsePrinterFont(document().printing() || !settings->screenFontSubstitutionEnabled());
3243     const AtomicString& standardFontFamily = documentSettings()->standardFontFamily();
3244     if (!standardFontFamily.isEmpty())
3245         fontDescription.setOneFamily(standardFontFamily);
3246     fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
3247     setFontSize(fontDescription, Style::fontSizeForKeyword(CSSValueMedium, false, document()));
3248     m_state.style()->setLineHeight(RenderStyle::initialLineHeight());
3249     m_state.setLineHeightValue(0);
3250     setFontDescription(fontDescription);
3251 }
3252
3253 void StyleResolver::setFontSize(FontDescription& fontDescription, float size)
3254 {
3255     fontDescription.setSpecifiedSize(size);
3256     fontDescription.setComputedSize(Style::computedFontSizeFromSpecifiedSize(size, fontDescription.isAbsoluteSize(), useSVGZoomRules(), m_state.style(), document()));
3257 }
3258
3259 static Color colorForCSSValue(CSSValueID cssValueId)
3260 {
3261     struct ColorValue {
3262         CSSValueID cssValueId;
3263         RGBA32 color;
3264     };
3265
3266     static const ColorValue colorValues[] = {
3267         { CSSValueAqua, 0xFF00FFFF },
3268         { CSSValueBlack, 0xFF000000 },
3269         { CSSValueBlue, 0xFF0000FF },
3270         { CSSValueFuchsia, 0xFFFF00FF },
3271         { CSSValueGray, 0xFF808080 },
3272         { CSSValueGreen, 0xFF008000  },
3273         { CSSValueGrey, 0xFF808080 },
3274         { CSSValueLime, 0xFF00FF00 },
3275         { CSSValueMaroon, 0xFF800000 },
3276         { CSSValueNavy, 0xFF000080 },
3277         { CSSValueOlive, 0xFF808000  },
3278         { CSSValueOrange, 0xFFFFA500 },
3279         { CSSValuePurple, 0xFF800080 },
3280         { CSSValueRed, 0xFFFF0000 },
3281         { CSSValueSilver, 0xFFC0C0C0 },
3282         { CSSValueTeal, 0xFF008080  },
3283         { CSSValueTransparent, 0x00000000 },
3284         { CSSValueWhite, 0xFFFFFFFF },
3285         { CSSValueYellow, 0xFFFFFF00 },
3286         { CSSValueInvalid, CSSValueInvalid }
3287     };
3288
3289     for (const ColorValue* col = colorValues; col->cssValueId; ++col) {
3290         if (col->cssValueId == cssValueId)
3291             return col->color;
3292     }
3293     return RenderTheme::defaultTheme()->systemColor(cssValueId);
3294 }
3295
3296 bool StyleResolver::colorFromPrimitiveValueIsDerivedFromElement(CSSPrimitiveValue* value)
3297 {
3298     int ident = value->getValueID();
3299     switch (ident) {
3300     case CSSValueWebkitText:
3301     case CSSValueWebkitLink:
3302     case CSSValueWebkitActivelink:
3303     case CSSValueCurrentcolor:
3304         return true;
3305     default:
3306         return false;
3307     }
3308 }
3309
3310 Color StyleResolver::colorFromPrimitiveValue(CSSPrimitiveValue* value, bool forVisitedLink) const
3311 {
3312     if (value->isRGBColor())
3313         return Color(value->getRGBA32Value());
3314
3315     const State& state = m_state;
3316     CSSValueID ident = value->getValueID();
3317     switch (ident) {
3318     case 0:
3319         return Color();
3320     case CSSValueWebkitText:
3321         return state.document().textColor();
3322     case CSSValueWebkitLink:
3323         return (state.element()->isLink() && forVisitedLink) ? state.document().visitedLinkColor() : state.document().linkColor();
3324     case CSSValueWebkitActivelink:
3325         return state.document().activeLinkColor();
3326     case CSSValueWebkitFocusRingColor:
3327         return RenderTheme::focusRingColor();
3328     case CSSValueCurrentcolor:
3329         return state.style()->color();
3330     default:
3331         return colorForCSSValue(ident);
3332     }
3333 }
3334
3335 void StyleResolver::addViewportDependentMediaQueryResult(const MediaQueryExp* expr, bool result)
3336 {
3337     m_viewportDependentMediaQueryResults.append(adoptPtr(new MediaQueryResult(*expr, result)));
3338 }
3339
3340 bool StyleResolver::affectedByViewportChange() const
3341 {
3342     unsigned s = m_viewportDependentMediaQueryResults.size();
3343     for (unsigned i = 0; i < s; i++) {
3344         if (m_medium->eval(&m_viewportDependentMediaQueryResults[i]->m_expression) != m_viewportDependentMediaQueryResults[i]->m_result)
3345             return true;
3346     }
3347     return false;
3348 }
3349
3350 #if ENABLE(CSS_FILTERS)
3351 static FilterOperation::OperationType filterOperationForType(WebKitCSSFilterValue::FilterOperationType type)
3352 {
3353     switch (type) {
3354     case WebKitCSSFilterValue::ReferenceFilterOperation:
3355         return FilterOperation::REFERENCE;
3356     case WebKitCSSFilterValue::GrayscaleFilterOperation:
3357         return FilterOperation::GRAYSCALE;
3358     case WebKitCSSFilterValue::SepiaFilterOperation:
3359         return FilterOperation::SEPIA;
3360     case WebKitCSSFilterValue::SaturateFilterOperation:
3361         return FilterOperation::SATURATE;
3362     case WebKitCSSFilterValue::HueRotateFilterOperation:
3363         return FilterOperation::HUE_ROTATE;
3364     case WebKitCSSFilterValue::InvertFilterOperation:
3365         return FilterOperation::INVERT;
3366     case WebKitCSSFilterValue::OpacityFilterOperation:
3367         return FilterOperation::OPACITY;
3368     case WebKitCSSFilterValue::BrightnessFilterOperation:
3369         return FilterOperation::BRIGHTNESS;
3370     case WebKitCSSFilterValue::ContrastFilterOperation:
3371         return FilterOperation::CONTRAST;
3372     case WebKitCSSFilterValue::BlurFilterOperation:
3373         return FilterOperation::BLUR;
3374     case WebKitCSSFilterValue::DropShadowFilterOperation:
3375         return FilterOperation::DROP_SHADOW;
3376 #if ENABLE(CSS_SHADERS)
3377     case WebKitCSSFilterValue::CustomFilterOperation:
3378         return FilterOperation::CUSTOM;
3379 #endif
3380     case WebKitCSSFilterValue::UnknownFilterOperation:
3381         return FilterOperation::NONE;
3382     }
3383     return FilterOperation::NONE;
3384 }
3385
3386 #if ENABLE(CSS_FILTERS) && ENABLE(SVG)
3387 void StyleResolver::loadPendingSVGDocuments()
3388 {
3389     State& state = m_state;
3390
3391     // Crash reports indicate that we've seen calls to this function when our
3392     // style is NULL. We don't know exactly why this happens. Our guess is
3393     // reentering styleForElement().
3394     ASSERT(state.style());
3395     if (!state.style() || !state.style()->hasFilter() || state.pendingSVGDocuments().isEmpty())
3396         return;
3397
3398     CachedResourceLoader* cachedResourceLoader = state.document().cachedResourceLoader();
3399     Vector<RefPtr<FilterOperation>>& filterOperations = state.style()->mutableFilter().operations();
3400     for (unsigned i = 0; i < filterOperations.size(); ++i) {
3401         RefPtr<FilterOperation> filterOperation = filterOperations.at(i);
3402         if (filterOperation->type() == FilterOperation::REFERENCE) {
3403             ReferenceFilterOperation* referenceFilter = static_cast<ReferenceFilterOperation*>(filterOperation.get());
3404
3405             WebKitCSSSVGDocumentValue* value = state.pendingSVGDocuments().get(referenceFilter);
3406             if (!value)
3407                 continue;
3408             CachedSVGDocument* cachedDocument = value->load(cachedResourceLoader);
3409             if (!cachedDocument)
3410                 continue;
3411
3412             // Stash the CachedSVGDocument on the reference filter.
3413             referenceFilter->setCachedSVGDocumentReference(adoptPtr(new CachedSVGDocumentReference(cachedDocument)));
3414         }
3415     }
3416     state.pendingSVGDocuments().clear();
3417 }
3418 #endif
3419
3420 #if ENABLE(CSS_SHADERS)
3421 StyleShader* StyleResolver::styleShader(CSSValue* value)
3422 {
3423     if (value->isWebKitCSSShaderValue())
3424         return cachedOrPendingStyleShaderFromValue(toWebKitCSSShaderValue(value));
3425     return 0;
3426 }
3427
3428 StyleShader* StyleResolver::cachedOrPendingStyleShaderFromValue(WebKitCSSShaderValue* value)
3429 {
3430     StyleShader* shader = value->cachedOrPendingShader();
3431     if (shader && shader->isPendingShader())
3432         m_state.setHasPendingShaders(true);