AX: Implement updated CSS3 Speech for 'speak' and 'speak-as' properties
[WebKit-https.git] / Source / WebCore / css / CSSComputedStyleDeclaration.cpp
index 9da202b..d6b421d 100644 (file)
 #include "CSSComputedStyleDeclaration.h"
 
 #include "BasicShapeFunctions.h"
-#include "BasicShapes.h"
 #include "CSSAnimationController.h"
 #include "CSSAnimationTriggerScrollValue.h"
 #include "CSSAspectRatioValue.h"
 #include "CSSBasicShapes.h"
 #include "CSSBorderImage.h"
 #include "CSSBorderImageSliceValue.h"
-#include "CSSCustomPropertyValue.h"
 #include "CSSFontFeatureValue.h"
 #include "CSSFontStyleValue.h"
 #include "CSSFontValue.h"
 #include "CSSValuePool.h"
 #include "ComposedTreeAncestorIterator.h"
 #include "ContentData.h"
-#include "CounterContent.h"
 #include "CursorList.h"
 #include "DeprecatedCSSOMValue.h"
 #include "Document.h"
-#include "ExceptionCode.h"
+#include "DocumentTimeline.h"
+#include "FontCascade.h"
 #include "FontSelectionValueInlines.h"
 #include "FontTaggedSettings.h"
-#include "HTMLFrameOwnerElement.h"
 #include "NodeRenderStyle.h"
 #include "Pair.h"
-#include "PseudoElement.h"
 #include "Rect.h"
 #include "RenderBlock.h"
 #include "RenderBox.h"
 #include "SVGElement.h"
 #include "Settings.h"
 #include "ShapeValue.h"
-#include "StyleInheritedData.h"
 #include "StyleProperties.h"
 #include "StylePropertyShorthand.h"
 #include "StylePropertyShorthandFunctions.h"
 #include "StyleResolver.h"
 #include "StyleScope.h"
 #include "StyleScrollSnapPoints.h"
-#include "Text.h"
 #include "WebKitFontFamilyNames.h"
 #include "WillChangeData.h"
 #include <wtf/NeverDestroyed.h>
@@ -144,6 +138,7 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyBoxShadow,
     CSSPropertyBoxSizing,
     CSSPropertyCaptionSide,
+    CSSPropertyCaretColor,
     CSSPropertyClear,
     CSSPropertyClip,
     CSSPropertyColor,
@@ -210,7 +205,7 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyPosition,
     CSSPropertyResize,
     CSSPropertyRight,
-    CSSPropertySpeak,
+    CSSPropertySpeakAs,
     CSSPropertyTableLayout,
     CSSPropertyTabSize,
     CSSPropertyTextAlign,
@@ -423,14 +418,6 @@ static const CSSPropertyID computedProperties[] = {
     CSSPropertyWebkitUserDrag,
     CSSPropertyWebkitUserModify,
     CSSPropertyWebkitUserSelect,
-#if ENABLE(CSS_REGIONS)
-    CSSPropertyWebkitFlowInto,
-    CSSPropertyWebkitFlowFrom,
-    CSSPropertyWebkitRegionBreakAfter,
-    CSSPropertyWebkitRegionBreakBefore,
-    CSSPropertyWebkitRegionBreakInside,
-    CSSPropertyWebkitRegionFragment,
-#endif
     CSSPropertyShapeImageThreshold,
     CSSPropertyShapeMargin,
     CSSPropertyShapeOutside,
@@ -708,41 +695,100 @@ static Ref<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, co
     return list;
 }
 
-static RefPtr<CSSValue> positionOffsetValue(const RenderStyle& style, CSSPropertyID propertyID)
+static Length getOffsetComputedLength(const RenderStyle& style, CSSPropertyID propertyID)
 {
-    Length length;
+    // If specified as a length, the corresponding absolute length; if specified as
+    // a percentage, the specified value; otherwise, 'auto'. Hence, we can just
+    // return the value in the style.
+    //
+    // See http://www.w3.org/TR/CSS21/cascade.html#computed-value
     switch (propertyID) {
-        case CSSPropertyLeft:
-            length = style.left();
-            break;
-        case CSSPropertyRight:
-            length = style.right();
-            break;
-        case CSSPropertyTop:
-            length = style.top();
-            break;
-        case CSSPropertyBottom:
-            length = style.bottom();
-            break;
-        default:
-            return nullptr;
+    case CSSPropertyLeft:
+        return style.left();
+    case CSSPropertyRight:
+        return style.right();
+    case CSSPropertyTop:
+        return style.top();
+    case CSSPropertyBottom:
+        return style.bottom();
+    default:
+        ASSERT_NOT_REACHED();
     }
 
-    if (style.hasOutOfFlowPosition()) {
-        if (length.isFixed())
-            return zoomAdjustedPixelValue(length.value(), style);
+    return { };
+}
 
-        return CSSValuePool::singleton().createValue(length);
+static LayoutUnit getOffsetUsedStyleRelative(RenderBox& box, CSSPropertyID propertyID)
+{
+    // For relatively positioned boxes, the offset is with respect to the top edges
+    // of the box itself. This ties together top/bottom and left/right to be
+    // opposites of each other.
+    //
+    // See http://www.w3.org/TR/CSS2/visuren.html#relative-positioning
+    //
+    // Specifically;
+    //   Since boxes are not split or stretched as a result of 'left' or
+    //   'right', the used values are always: left = -right.
+    // and
+    //   Since boxes are not split or stretched as a result of 'top' or
+    //   'bottom', the used values are always: top = -bottom.
+    switch (propertyID) {
+    case CSSPropertyTop:
+        return box.relativePositionOffset().height();
+    case CSSPropertyBottom:
+        return -(box.relativePositionOffset().height());
+    case CSSPropertyLeft:
+        return box.relativePositionOffset().width();
+    case CSSPropertyRight:
+        return -(box.relativePositionOffset().width());
+    default:
+        ASSERT_NOT_REACHED();
     }
 
-    if (style.hasInFlowPosition()) {
-        // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
-        // In other words if left is auto and right is not auto, then left's computed value is negative right().
-        // So we should get the opposite length unit and see if it is auto.
-        return CSSValuePool::singleton().createValue(length);
+    return 0;
+}
+
+static LayoutUnit getOffsetUsedStyleOutOfFlowPositioned(RenderBlock& container, RenderBox& box, CSSPropertyID propertyID)
+{
+    // For out-of-flow positioned boxes, the offset is how far an box's margin
+    // edge is offset below the edge of the box's containing block.
+    // See http://www.w3.org/TR/CSS2/visuren.html#position-props
+
+    // Margins are included in offsetTop/offsetLeft so we need to remove them here.
+    switch (propertyID) {
+    case CSSPropertyTop:
+        return box.offsetTop() - box.marginTop();
+    case CSSPropertyBottom:
+        return container.clientHeight() - (box.offsetTop() + box.offsetHeight()) - box.marginBottom();
+    case CSSPropertyLeft:
+        return box.offsetLeft() - box.marginLeft();
+    case CSSPropertyRight:
+        return container.clientWidth() - (box.offsetLeft() + box.offsetWidth()) - box.marginRight();
+    default:
+        ASSERT_NOT_REACHED();
     }
 
-    return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
+    return 0;
+}
+
+static RefPtr<CSSValue> positionOffsetValue(const RenderStyle& style, CSSPropertyID propertyID, RenderObject* renderer)
+{
+    // If the element is not displayed; return the "computed value".
+    if (!renderer || !renderer->isBox())
+        return zoomAdjustedPixelValueForLength(getOffsetComputedLength(style, propertyID), style);
+
+    // We should return the "used value".
+    auto& box = downcast<RenderBox>(*renderer);
+    auto* containingBlock = box.containingBlock();
+    if (box.isRelativelyPositioned() || !containingBlock)
+        return zoomAdjustedPixelValue(getOffsetUsedStyleRelative(box, propertyID), style);
+    if (renderer->isOutOfFlowPositioned())
+        return zoomAdjustedPixelValue(getOffsetUsedStyleOutOfFlowPositioned(*containingBlock, box, propertyID), style);
+    // In-flow element.
+    auto offset = getOffsetComputedLength(style, propertyID);
+    if (offset.isAuto())
+        return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
+    return zoomAdjustedPixelValueForLength(offset, style);
 }
 
 RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::currentColorOrValidColor(const RenderStyle* style, const Color& color) const
@@ -1615,9 +1661,7 @@ CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(Element& element, bool
     (pseudoElementName.substringSharingImpl(nameWithoutColonsStart))));
 }
 
-CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
-{
-}
+CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration() = default;
 
 void CSSComputedStyleDeclaration::ref()
 {
@@ -1649,7 +1693,7 @@ String CSSComputedStyleDeclaration::cssText() const
 
 ExceptionOr<void> CSSComputedStyleDeclaration::setCssText(const String&)
 {
-    return Exception { NO_MODIFICATION_ALLOWED_ERR };
+    return Exception { NoModificationAllowedError };
 }
 
 RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::getFontSizeCSSValuePreferringKeyword()
@@ -1783,6 +1827,25 @@ static Ref<CSSValue> renderEmphasisPositionFlagsToCSSValue(TextEmphasisPosition
     return WTFMove(list);
 }
 
+static Ref<CSSValue> speakAsToCSSValue(ESpeakAs speakAs)
+{
+    auto& cssValuePool = CSSValuePool::singleton();
+    auto list = CSSValueList::createSpaceSeparated();
+    if (speakAs & SpeakNormal)
+        list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
+    if (speakAs & SpeakSpellOut)
+        list->append(cssValuePool.createIdentifierValue(CSSValueSpellOut));
+    if (speakAs & SpeakDigits)
+        list->append(cssValuePool.createIdentifierValue(CSSValueDigits));
+    if (speakAs & SpeakLiteralPunctuation)
+        list->append(cssValuePool.createIdentifierValue(CSSValueLiteralPunctuation));
+    if (speakAs & SpeakNoPunctuation)
+        list->append(cssValuePool.createIdentifierValue(CSSValueNoPunctuation));
+    if (!list->length())
+        return cssValuePool.createIdentifierValue(CSSValueNormal);
+    return WTFMove(list);
+}
+    
 static Ref<CSSValue> hangingPunctuationToCSSValue(HangingPunctuation hangingPunctuation)
 {
     auto& cssValuePool = CSSValuePool::singleton();
@@ -1863,8 +1926,6 @@ static Ref<CSSValueList> contentToCSSValue(const RenderStyle& style)
         else if (is<TextContentData>(*contentData))
             list->append(cssValuePool.createValue(downcast<TextContentData>(*contentData).text(), CSSPrimitiveValue::CSS_STRING));
     }
-    if (style.hasFlowFrom())
-        list->append(cssValuePool.createValue(style.regionThread(), CSSPrimitiveValue::CSS_STRING));
     return list;
 }
 
@@ -1918,7 +1979,7 @@ static Ref<CSSPrimitiveValue> lineHeightFromStyle(const RenderStyle& style)
         // for how high to be in pixels does include things like minimum font size and the zoom factor.
         // On the other hand, since font-size doesn't include the zoom factor, we really can't do
         // that here either.
-        return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style.fontDescription().specifiedSize()) / 100, style);
+        return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style.fontDescription().computedSize()) / 100, style);
     }
     return zoomAdjustedPixelValue(floatValueForLength(length, 0), style);
 }
@@ -2199,6 +2260,11 @@ static bool paddingOrMarginIsRendererDependent(const RenderStyle* style, RenderO
     return renderer && style && renderer->isBox() && !(style->*lengthGetter)().isFixed();
 }
 
+static bool positionOffsetValueIsRendererDependent(const RenderStyle* style, RenderObject* renderer)
+{
+    return renderer && style && renderer->isBox();
+}
+
 static CSSValueID convertToPageBreak(BreakBetween value)
 {
     if (value == PageBreakBetween || value == LeftPageBreakBetween || value == RightPageBreakBetween
@@ -2232,35 +2298,28 @@ static CSSValueID convertToColumnBreak(BreakInside value)
     return CSSValueAuto;
 }
 
-#if ENABLE(CSS_REGIONS)
-static CSSValueID convertToRegionBreak(BreakBetween value)
+static inline bool isNonReplacedInline(RenderObject& renderer)
 {
-    if (value == RegionBreakBetween)
-        return CSSValueAlways;
-    if (value == AvoidBreakBetween || value == AvoidRegionBreakBetween)
-        return CSSValueAvoid;
-    return CSSValueAuto;
+    return renderer.isInline() && !renderer.isReplaced();
 }
-    
-static CSSValueID convertToRegionBreak(BreakInside value)
-{
-    if (value == AvoidBreakInside || value == AvoidRegionBreakInside)
-        return CSSValueAvoid;
-    return CSSValueAuto;
-}
-#endif
-    
+
 static bool isLayoutDependent(CSSPropertyID propertyID, const RenderStyle* style, RenderObject* renderer)
 {
     switch (propertyID) {
+    case CSSPropertyTop:
+    case CSSPropertyBottom:
+    case CSSPropertyLeft:
+    case CSSPropertyRight:
+        return positionOffsetValueIsRendererDependent(style, renderer);
     case CSSPropertyWidth:
     case CSSPropertyHeight:
+        return renderer && !renderer->isRenderSVGModelObject() && !isNonReplacedInline(*renderer);
     case CSSPropertyPerspectiveOrigin:
     case CSSPropertyTransformOrigin:
     case CSSPropertyTransform:
-    case CSSPropertyFilter:
+    case CSSPropertyFilter: // Why are filters layout-dependent?
 #if ENABLE(FILTERS_LEVEL_2)
-    case CSSPropertyWebkitBackdropFilter:
+    case CSSPropertyWebkitBackdropFilter: // Ditto for backdrop-filter.
 #endif
         return true;
     case CSSPropertyMargin: {
@@ -2301,7 +2360,7 @@ static bool isLayoutDependent(CSSPropertyID propertyID, const RenderStyle* style
     }
 }
 
-Element* ComputedStyleExtractor::styledElement()
+Element* ComputedStyleExtractor::styledElement() const
 {
     if (!m_element)
         return nullptr;
@@ -2313,47 +2372,17 @@ Element* ComputedStyleExtractor::styledElement()
     return m_element.get();
 }
 
-static StyleSelfAlignmentData resolveLegacyJustifyItems(const StyleSelfAlignmentData& data)
-{
-    if (data.positionType() == LegacyPosition)
-        return { data.position(), OverflowAlignmentDefault };
-    return data;
-}
-
-static StyleSelfAlignmentData resolveJustifyItemsAuto(const StyleSelfAlignmentData& data, Node* parent)
-{
-    if (data.position() != ItemPositionAuto)
-        return data;
-
-    // If the inherited value of justify-items includes the 'legacy' keyword, 'auto' computes to the inherited value.
-    const auto& inheritedValue = (!parent || !parent->computedStyle()) ? RenderStyle::initialDefaultAlignment() : parent->computedStyle()->justifyItems();
-    if (inheritedValue.positionType() == LegacyPosition)
-        return inheritedValue;
-    if (inheritedValue.position() == ItemPositionAuto)
-        return resolveJustifyItemsAuto(inheritedValue, parent->parentNode());
-    return { ItemPositionNormal, OverflowAlignmentDefault };
-}
-
-static StyleSelfAlignmentData resolveJustifySelfAuto(const StyleSelfAlignmentData& data, Node* parent)
-{
-    if (data.position() != ItemPositionAuto)
-        return data;
-
-    // The 'auto' keyword computes to the computed value of justify-items on the parent or 'normal' if the box has no parent.
-    if (!parent || !parent->computedStyle())
-        return { ItemPositionNormal, OverflowAlignmentDefault };
-    return resolveLegacyJustifyItems(resolveJustifyItemsAuto(parent->computedStyle()->justifyItems(), parent->parentNode()));
-}
 
-static StyleSelfAlignmentData resolveAlignSelfAuto(const StyleSelfAlignmentData& data, Node* parent)
+RenderElement* ComputedStyleExtractor::styledRenderer() const
 {
-    if (data.position() != ItemPositionAuto)
-        return data;
-
-    // The 'auto' keyword computes to the computed value of align-items on the parent or 'normal' if the box has no parent.
-    if (!parent || !parent->computedStyle())
-        return { ItemPositionNormal, OverflowAlignmentDefault };
-    return parent->computedStyle()->alignItems();
+    auto* element = styledElement();
+    if (!element)
+        return nullptr;
+    if (m_pseudoElementSpecifier != NOPSEUDO && element == m_element.get())
+        return nullptr;
+    if (element->hasDisplayContents())
+        return nullptr;
+    return element->renderer();
 }
 
 static bool isImplicitlyInheritedGridOrFlexProperty(CSSPropertyID propertyID)
@@ -2371,6 +2400,13 @@ static bool isImplicitlyInheritedGridOrFlexProperty(CSSPropertyID propertyID)
     }
 }
 
+// In CSS 2.1 the returned object should actually contain the "used values"
+// rather then the "computed values" (despite the name saying otherwise).
+//
+// See;
+// http://www.w3.org/TR/CSS21/cascade.html#used-value
+// http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration
+// https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle#Notes
 RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
 {
     return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout);
@@ -2433,7 +2469,10 @@ static inline const RenderStyle* computeRenderStyleForProperty(Element& element,
     auto* renderer = element.renderer();
 
     if (renderer && renderer->isComposited() && CSSAnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) {
-        ownedStyle = renderer->animation().getAnimatedStyleForRenderer(*renderer);
+        if (auto timeline = element.document().existingTimeline())
+            ownedStyle = timeline->animatedStyleForRenderer(*renderer);
+        else
+            ownedStyle = renderer->animation().animatedStyleForRenderer(*renderer);
         if (pseudoElementSpecifier && !element.isPseudoElement()) {
             // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
             return ownedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
@@ -2626,7 +2665,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
 
     std::unique_ptr<RenderStyle> ownedStyle;
     const RenderStyle* style = nullptr;
-    RenderObject* renderer = nullptr;
+    RenderElement* renderer = nullptr;
     bool forceFullLayout = false;
     if (updateLayout) {
         Document& document = m_element->document();
@@ -2635,7 +2674,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             // Style update may change styledElement() to PseudoElement or back.
             styledElement = this->styledElement();
         }
-        renderer = styledElement->renderer();
+        renderer = styledRenderer();
 
         if (propertyID == CSSPropertyDisplay && !renderer && is<SVGElement>(*styledElement) && !downcast<SVGElement>(*styledElement).isValid())
             return nullptr;
@@ -2655,7 +2694,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
 
     if (!updateLayout || forceFullLayout) {
         style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, propertyID, ownedStyle);
-        renderer = styledElement->renderer();
+        renderer = styledRenderer();
     }
 
     if (!style)
@@ -2829,7 +2868,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         case CSSPropertyBorderLeftWidth:
             return zoomAdjustedPixelValue(style->borderLeftWidth(), *style);
         case CSSPropertyBottom:
-            return positionOffsetValue(*style, CSSPropertyBottom);
+            return positionOffsetValue(*style, CSSPropertyBottom, renderer);
         case CSSPropertyWebkitBoxAlign:
             return cssValuePool.createValue(style->boxAlign());
 #if ENABLE(CSS_BOX_DECORATION_BREAK)
@@ -2859,6 +2898,8 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             return valueForShadow(style->boxShadow(), propertyID, *style);
         case CSSPropertyCaptionSide:
             return cssValuePool.createValue(style->captionSide());
+        case CSSPropertyCaretColor:
+            return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyCaretColor)) : currentColorOrValidColor(style, style->caretColor());
         case CSSPropertyClear:
             return cssValuePool.createValue(style->clear());
         case CSSPropertyColor:
@@ -2899,14 +2940,6 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             return zoomAdjustedPixelValue(style->columnWidth(), *style);
         case CSSPropertyTabSize:
             return cssValuePool.createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
-#if ENABLE(CSS_REGIONS)
-        case CSSPropertyWebkitRegionBreakAfter:
-            return cssValuePool.createValue(convertToRegionBreak(style->breakAfter()));
-        case CSSPropertyWebkitRegionBreakBefore:
-            return cssValuePool.createValue(convertToRegionBreak(style->breakBefore()));
-        case CSSPropertyWebkitRegionBreakInside:
-            return cssValuePool.createValue(convertToRegionBreak(style->breakInside()));
-#endif
         case CSSPropertyCursor: {
             RefPtr<CSSValueList> list;
             auto* cursors = style->cursors();
@@ -2938,7 +2971,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         case CSSPropertyAlignItems:
             return valueForItemPositionWithOverflowAlignment(style->alignItems());
         case CSSPropertyAlignSelf:
-            return valueForItemPositionWithOverflowAlignment(resolveAlignSelfAuto(style->alignSelf(), styledElement->parentNode()));
+            return valueForItemPositionWithOverflowAlignment(style->alignSelf());
         case CSSPropertyFlex:
             return getCSSPropertyValuesForShorthandProperties(flexShorthand());
         case CSSPropertyFlexBasis:
@@ -2956,9 +2989,9 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         case CSSPropertyJustifyContent:
             return valueForContentPositionAndDistributionWithOverflowAlignment(style->justifyContent(), CSSValueFlexStart);
         case CSSPropertyJustifyItems:
-            return valueForItemPositionWithOverflowAlignment(resolveJustifyItemsAuto(style->justifyItems(), styledElement->parentNode()));
+            return valueForItemPositionWithOverflowAlignment(style->justifyItems().position() == ItemPositionAuto ? RenderStyle::initialDefaultAlignment() : style->justifyItems());
         case CSSPropertyJustifySelf:
-            return valueForItemPositionWithOverflowAlignment(resolveJustifySelfAuto(style->justifySelf(), styledElement->parentNode()));
+            return valueForItemPositionWithOverflowAlignment(style->justifySelf());
         case CSSPropertyPlaceContent:
             return getCSSPropertyValuesForShorthandProperties(placeContentShorthand());
         case CSSPropertyPlaceItems:
@@ -3077,7 +3110,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             if (renderer && !renderer->isRenderSVGModelObject()) {
                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
                 // the "height" property does not apply for non-replaced inline elements.
-                if (!renderer->isReplaced() && renderer->isInline())
+                if (isNonReplacedInline(*renderer))
                     return cssValuePool.createIdentifierValue(CSSValueAuto);
                 return zoomAdjustedPixelValue(sizingBox(*renderer).height(), *style);
             }
@@ -3115,7 +3148,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             return cssValuePool.createValue(style->imageResolution(), CSSPrimitiveValue::CSS_DPPX);
 #endif
         case CSSPropertyLeft:
-            return positionOffsetValue(*style, CSSPropertyLeft);
+            return positionOffsetValue(*style, CSSPropertyLeft, renderer);
         case CSSPropertyLetterSpacing:
             if (!style->letterSpacing())
                 return cssValuePool.createIdentifierValue(CSSValueNormal);
@@ -3253,7 +3286,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         case CSSPropertyPosition:
             return cssValuePool.createValue(style->position());
         case CSSPropertyRight:
-            return positionOffsetValue(*style, CSSPropertyRight);
+            return positionOffsetValue(*style, CSSPropertyRight, renderer);
         case CSSPropertyWebkitRubyPosition:
             return cssValuePool.createValue(style->rubyPosition());
         case CSSPropertyTableLayout:
@@ -3309,6 +3342,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
                 list->append(cssValuePool.createValue(style->textEmphasisMark()));
                 return WTFMove(list);
             }
+            RELEASE_ASSERT_NOT_REACHED();
         case CSSPropertyTextIndent: {
             // If CSS3_TEXT is disabled or text-indent has only one value(<length> | <percentage>),
             // getPropertyCSSValue() returns CSSValue.
@@ -3353,7 +3387,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         case CSSPropertyTextTransform:
             return cssValuePool.createValue(style->textTransform());
         case CSSPropertyTop:
-            return positionOffsetValue(*style, CSSPropertyTop);
+            return positionOffsetValue(*style, CSSPropertyTop, renderer);
         case CSSPropertyUnicodeBidi:
             return cssValuePool.createValue(style->unicodeBidi());
         case CSSPropertyVerticalAlign:
@@ -3393,7 +3427,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             if (renderer && !renderer->isRenderSVGModelObject()) {
                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
                 // the "width" property does not apply for non-replaced inline elements.
-                if (!renderer->isReplaced() && renderer->isInline())
+                if (isNonReplacedInline(*renderer))
                     return cssValuePool.createIdentifierValue(CSSValueAuto);
                 return zoomAdjustedPixelValue(sizingBox(*renderer).width(), *style);
             }
@@ -3679,8 +3713,8 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
             rect->setLeft(autoOrZoomAdjustedValue(style->clip().left(), *style));
             return cssValuePool.createValue(WTFMove(rect));
         }
-        case CSSPropertySpeak:
-            return cssValuePool.createValue(style->speak());
+        case CSSPropertySpeakAs:
+            return speakAsToCSSValue(style->speakAs());
         case CSSPropertyTransform:
             return computedTransform(renderer, *style);
         case CSSPropertyTransformBox:
@@ -3781,18 +3815,6 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
                 list->append(cssValuePool.createValue(downcast<BoxClipPathOperation>(*operation).referenceBox()));
             return WTFMove(list);
         }
-#if ENABLE(CSS_REGIONS)
-        case CSSPropertyWebkitFlowInto:
-            if (!style->hasFlowInto())
-                return cssValuePool.createIdentifierValue(CSSValueNone);
-            return cssValuePool.createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING);
-        case CSSPropertyWebkitFlowFrom:
-            if (!style->hasFlowFrom())
-                return cssValuePool.createIdentifierValue(CSSValueNone);
-            return cssValuePool.createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING);
-        case CSSPropertyWebkitRegionFragment:
-            return cssValuePool.createValue(style->regionFragment());
-#endif
         case CSSPropertyShapeMargin:
             return cssValuePool.createValue(style->shapeMargin(), *style);
         case CSSPropertyShapeImageThreshold:
@@ -3982,6 +4004,7 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
         /* Unimplemented @font-face properties */
         case CSSPropertySrc:
         case CSSPropertyUnicodeRange:
+        case CSSPropertyFontDisplay:
             break;
 
         /* Other unimplemented properties */
@@ -4095,9 +4118,8 @@ String CSSComputedStyleDeclaration::item(unsigned i) const
     const auto& customProperties = style->customProperties();
     if (index >= customProperties.size())
         return String();
-    
-    Vector<String, 4> results;
-    copyKeysToVector(customProperties, results);
+
+    auto results = copyToVector(customProperties.keys());
     return results.at(index);
 }
 
@@ -4191,7 +4213,7 @@ RefPtr<DeprecatedCSSOMValue> CSSComputedStyleDeclaration::getPropertyCSSValue(co
         auto value = ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyValue(propertyName);
         if (!value)
             return nullptr;
-        return value->createDeprecatedCSSOMWrapper();
+        return value->createDeprecatedCSSOMWrapper(*this);
     }
 
     CSSPropertyID propertyID = cssPropertyID(propertyName);
@@ -4200,7 +4222,7 @@ RefPtr<DeprecatedCSSOMValue> CSSComputedStyleDeclaration::getPropertyCSSValue(co
     auto value = getPropertyCSSValue(propertyID);
     if (!value)
         return nullptr;
-    return value->createDeprecatedCSSOMWrapper();
+    return value->createDeprecatedCSSOMWrapper(*this);
 }
 
 String CSSComputedStyleDeclaration::getPropertyValue(const String &propertyName)
@@ -4232,12 +4254,12 @@ bool CSSComputedStyleDeclaration::isPropertyImplicit(const String&)
 
 ExceptionOr<void> CSSComputedStyleDeclaration::setProperty(const String&, const String&, const String&)
 {
-    return Exception { NO_MODIFICATION_ALLOWED_ERR };
+    return Exception { NoModificationAllowedError };
 }
 
 ExceptionOr<String> CSSComputedStyleDeclaration::removeProperty(const String&)
 {
-    return Exception { NO_MODIFICATION_ALLOWED_ERR };
+    return Exception { NoModificationAllowedError };
 }
     
 RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
@@ -4252,7 +4274,7 @@ String CSSComputedStyleDeclaration::getPropertyValueInternal(CSSPropertyID prope
 
 ExceptionOr<bool> CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID, const String&, bool)
 {
-    return Exception { NO_MODIFICATION_ALLOWED_ERR };
+    return Exception { NoModificationAllowedError };
 }
 
 Ref<CSSValueList> ComputedStyleExtractor::getBackgroundShorthandValue()