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