Переглянути джерело

LibWeb: Add spec comments to style_value_for_property()

Also, re-order things to match. No behaviour changes.

This reveals quite a few properties that are missing here, or which we
implement somewhat incorrectly.
Sam Atkins 1 рік тому
батько
коміт
77fb85d27a
1 змінених файлів з 146 додано та 79 видалено
  1. 146 79
      Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp

+ 146 - 79
Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp

@@ -142,9 +142,155 @@ RefPtr<StyleValue const> ResolvedCSSStyleDeclaration::style_value_for_property(L
     // We also have to manually construct shorthands from their longhands here.
     // Everything else uses the computed value.
     // https://www.w3.org/TR/cssom-1/#resolved-values
+
+    // The resolved value for a given longhand property can be determined as follows:
     switch (property_id) {
+        // -> background-color
+        // FIXME: -> border-block-end-color
+        // FIXME: -> border-block-start-color
+        // -> border-bottom-color
+        // FIXME: -> border-inline-end-color
+        // FIXME: -> border-inline-start-color
+        // -> border-left-color
+        // -> border-right-color
+        // -> border-top-color
+        // FIXME: -> box-shadow
+        // FIXME: -> caret-color
+        // -> color
+        // -> outline-color
+        // -> A resolved value special case property like color defined in another specification
+        //    The resolved value is the used value.
     case PropertyID::BackgroundColor:
         return ColorStyleValue::create(layout_node.computed_values().background_color());
+    case PropertyID::BorderBottomColor:
+        return ColorStyleValue::create(layout_node.computed_values().border_bottom().color);
+    case PropertyID::BorderLeftColor:
+        return ColorStyleValue::create(layout_node.computed_values().border_left().color);
+    case PropertyID::BorderRightColor:
+        return ColorStyleValue::create(layout_node.computed_values().border_right().color);
+    case PropertyID::BorderTopColor:
+        return ColorStyleValue::create(layout_node.computed_values().border_top().color);
+    case PropertyID::Color:
+        return ColorStyleValue::create(layout_node.computed_values().color());
+    case PropertyID::OutlineColor:
+        return ColorStyleValue::create(layout_node.computed_values().outline_color());
+    case PropertyID::TextDecorationColor:
+        return ColorStyleValue::create(layout_node.computed_values().text_decoration_color());
+
+        // FIXME: -> line-height
+        //    The resolved value is normal if the computed value is normal, or the used value otherwise.
+
+        // FIXME: -> block-size
+        // -> height
+        // FIXME: -> inline-size
+        // FIXME: -> margin-block-end
+        // FIXME: -> margin-block-start
+        // -> margin-bottom
+        // FIXME: -> margin-inline-end
+        // FIXME: -> margin-inline-start
+        // -> margin-left
+        // -> margin-right
+        // -> margin-top
+        // FIXME: -> padding-block-end
+        // FIXME: -> padding-block-start
+        // -> padding-bottom
+        // FIXME: -> padding-inline-end
+        // FIXME: -> padding-inline-start
+        // -> padding-left
+        // -> padding-right
+        // -> padding-top
+        // FIXME: -> width
+        // -> A resolved value special case property like height defined in another specification
+        // FIXME: If the property applies to the element or pseudo-element and the resolved value of the
+        //    display property is not none or contents, then the resolved value is the used value.
+        //    Otherwise the resolved value is the computed value.
+    case PropertyID::Height:
+        return style_value_for_size(layout_node.computed_values().height());
+    case PropertyID::MarginBottom:
+        return style_value_for_length_percentage(layout_node.computed_values().margin().bottom());
+    case PropertyID::MarginLeft:
+        return style_value_for_length_percentage(layout_node.computed_values().margin().left());
+    case PropertyID::MarginRight:
+        return style_value_for_length_percentage(layout_node.computed_values().margin().right());
+    case PropertyID::MarginTop:
+        return style_value_for_length_percentage(layout_node.computed_values().margin().top());
+    case PropertyID::PaddingBottom:
+        return style_value_for_length_percentage(layout_node.computed_values().padding().bottom());
+    case PropertyID::PaddingLeft:
+        return style_value_for_length_percentage(layout_node.computed_values().padding().left());
+    case PropertyID::PaddingRight:
+        return style_value_for_length_percentage(layout_node.computed_values().padding().right());
+    case PropertyID::PaddingTop:
+        return style_value_for_length_percentage(layout_node.computed_values().padding().top());
+    case PropertyID::Width:
+        return style_value_for_size(layout_node.computed_values().width());
+
+        // -> bottom
+        // -> left
+        // FIXME: -> inset-block-end
+        // FIXME: -> inset-block-start
+        // FIXME: -> inset-inline-end
+        // FIXME: -> inset-inline-start
+        // -> right
+        // -> top
+        // -> A resolved value special case property like top defined in another specification
+        // FIXME: If the property applies to a positioned element and the resolved value of the display property is not
+        //    none or contents, and the property is not over-constrained, then the resolved value is the used value.
+        //    Otherwise the resolved value is the computed value.
+    case PropertyID::Bottom:
+        return style_value_for_length_percentage(layout_node.computed_values().inset().bottom());
+    case PropertyID::Left:
+        return style_value_for_length_percentage(layout_node.computed_values().inset().left());
+    case PropertyID::Right:
+        return style_value_for_length_percentage(layout_node.computed_values().inset().right());
+    case PropertyID::Top:
+        return style_value_for_length_percentage(layout_node.computed_values().inset().top());
+
+        // -> A resolved value special case property defined in another specification
+        //    As defined in the relevant specification.
+    case PropertyID::Transform: {
+        // NOTE: The computed value for `transform` serializes as a single `matrix(...)` value, instead of
+        //       the original list of transform functions. So, we produce a StyleValue for that.
+        //       https://www.w3.org/TR/css-transforms-1/#serialization-of-the-computed-value
+        // FIXME: Computing values should happen in the StyleComputer!
+        auto transformations = layout_node.computed_values().transformations();
+        if (transformations.is_empty())
+            return IdentifierStyleValue::create(ValueID::None);
+
+        // The transform matrix is held by the StackingContext, so we need to make sure we have one first.
+        auto const* viewport = layout_node.document().paintable();
+        VERIFY(viewport);
+        const_cast<Painting::ViewportPaintable&>(*viewport).build_stacking_context_tree_if_needed();
+
+        VERIFY(layout_node.paintable());
+        auto const& paintable_box = verify_cast<Painting::PaintableBox const>(layout_node.paintable());
+        VERIFY(paintable_box->stacking_context());
+
+        // FIXME: This needs to serialize to matrix3d if the transformation matrix is a 3D matrix.
+        //        https://w3c.github.io/csswg-drafts/css-transforms-2/#serialization-of-the-computed-value
+        auto affine_matrix = paintable_box->stacking_context()->affine_transform_matrix();
+
+        StyleValueVector parameters;
+        parameters.ensure_capacity(6);
+        parameters.unchecked_append(NumberStyleValue::create(affine_matrix.a()));
+        parameters.unchecked_append(NumberStyleValue::create(affine_matrix.b()));
+        parameters.unchecked_append(NumberStyleValue::create(affine_matrix.c()));
+        parameters.unchecked_append(NumberStyleValue::create(affine_matrix.d()));
+        parameters.unchecked_append(NumberStyleValue::create(affine_matrix.e()));
+        parameters.unchecked_append(NumberStyleValue::create(affine_matrix.f()));
+
+        NonnullRefPtr<StyleValue> matrix_function = TransformationStyleValue::create(TransformFunction::Matrix, move(parameters));
+        // Elsewhere we always store the transform property's value as a StyleValueList of TransformationStyleValues,
+        // so this is just for consistency.
+        StyleValueVector matrix_functions { matrix_function };
+        return StyleValueList::create(move(matrix_functions), StyleValueList::Separator::Space);
+    }
+
+        // -> Any other property
+        //    The resolved value is the computed value.
+        //    NOTE: This is handled inside the `default` case.
+
+        // NOTE: Everything below is a shorthand that requires some manual construction.
     case PropertyID::BackgroundPosition:
         return style_value_for_background_property(
             layout_node,
@@ -182,8 +328,6 @@ RefPtr<StyleValue const> ResolvedCSSStyleDeclaration::style_value_for_property(L
             { PropertyID::BorderBottomWidth, PropertyID::BorderBottomStyle, PropertyID::BorderBottomColor },
             { width, style, color });
     }
-    case PropertyID::BorderBottomColor:
-        return ColorStyleValue::create(layout_node.computed_values().border_bottom().color);
     case PropertyID::BorderColor: {
         auto top = ColorStyleValue::create(layout_node.computed_values().border_top().color);
         auto right = ColorStyleValue::create(layout_node.computed_values().border_right().color);
@@ -200,8 +344,6 @@ RefPtr<StyleValue const> ResolvedCSSStyleDeclaration::style_value_for_property(L
             { PropertyID::BorderLeftWidth, PropertyID::BorderLeftStyle, PropertyID::BorderLeftColor },
             { width, style, color });
     }
-    case PropertyID::BorderLeftColor:
-        return ColorStyleValue::create(layout_node.computed_values().border_left().color);
     case PropertyID::BorderRight: {
         auto border = layout_node.computed_values().border_right();
         auto width = LengthStyleValue::create(Length::make_px(border.width));
@@ -211,8 +353,6 @@ RefPtr<StyleValue const> ResolvedCSSStyleDeclaration::style_value_for_property(L
             { PropertyID::BorderRightWidth, PropertyID::BorderRightStyle, PropertyID::BorderRightColor },
             { width, style, color });
     }
-    case PropertyID::BorderRightColor:
-        return ColorStyleValue::create(layout_node.computed_values().border_right().color);
     case PropertyID::BorderStyle: {
         auto top = IdentifierStyleValue::create(to_value_id(layout_node.computed_values().border_top().line_style));
         auto right = IdentifierStyleValue::create(to_value_id(layout_node.computed_values().border_right().line_style));
@@ -229,8 +369,6 @@ RefPtr<StyleValue const> ResolvedCSSStyleDeclaration::style_value_for_property(L
             { PropertyID::BorderTopWidth, PropertyID::BorderTopStyle, PropertyID::BorderTopColor },
             { width, style, color });
     }
-    case PropertyID::BorderTopColor:
-        return ColorStyleValue::create(layout_node.computed_values().border_top().color);
     case PropertyID::BorderWidth: {
         auto top = LengthStyleValue::create(Length::make_px(layout_node.computed_values().border_top().width));
         auto right = LengthStyleValue::create(Length::make_px(layout_node.computed_values().border_right().width));
@@ -238,14 +376,6 @@ RefPtr<StyleValue const> ResolvedCSSStyleDeclaration::style_value_for_property(L
         auto left = LengthStyleValue::create(Length::make_px(layout_node.computed_values().border_left().width));
         return style_value_for_sided_shorthand(top, right, bottom, left);
     }
-    case PropertyID::Bottom:
-        return style_value_for_length_percentage(layout_node.computed_values().inset().bottom());
-    case PropertyID::Color:
-        return ColorStyleValue::create(layout_node.computed_values().color());
-    case PropertyID::Height:
-        return style_value_for_size(layout_node.computed_values().height());
-    case PropertyID::Left:
-        return style_value_for_length_percentage(layout_node.computed_values().inset().left());
     case PropertyID::Margin: {
         auto margin = layout_node.computed_values().margin();
         auto top = style_value_for_length_percentage(margin.top());
@@ -254,16 +384,6 @@ RefPtr<StyleValue const> ResolvedCSSStyleDeclaration::style_value_for_property(L
         auto left = style_value_for_length_percentage(margin.left());
         return style_value_for_sided_shorthand(move(top), move(right), move(bottom), move(left));
     }
-    case PropertyID::MarginBottom:
-        return style_value_for_length_percentage(layout_node.computed_values().margin().bottom());
-    case PropertyID::MarginLeft:
-        return style_value_for_length_percentage(layout_node.computed_values().margin().left());
-    case PropertyID::MarginRight:
-        return style_value_for_length_percentage(layout_node.computed_values().margin().right());
-    case PropertyID::MarginTop:
-        return style_value_for_length_percentage(layout_node.computed_values().margin().top());
-    case PropertyID::OutlineColor:
-        return ColorStyleValue::create(layout_node.computed_values().outline_color());
     case PropertyID::Padding: {
         auto padding = layout_node.computed_values().padding();
         auto top = style_value_for_length_percentage(padding.top());
@@ -272,59 +392,6 @@ RefPtr<StyleValue const> ResolvedCSSStyleDeclaration::style_value_for_property(L
         auto left = style_value_for_length_percentage(padding.left());
         return style_value_for_sided_shorthand(move(top), move(right), move(bottom), move(left));
     }
-    case PropertyID::PaddingBottom:
-        return style_value_for_length_percentage(layout_node.computed_values().padding().bottom());
-    case PropertyID::PaddingLeft:
-        return style_value_for_length_percentage(layout_node.computed_values().padding().left());
-    case PropertyID::PaddingRight:
-        return style_value_for_length_percentage(layout_node.computed_values().padding().right());
-    case PropertyID::PaddingTop:
-        return style_value_for_length_percentage(layout_node.computed_values().padding().top());
-    case PropertyID::Right:
-        return style_value_for_length_percentage(layout_node.computed_values().inset().right());
-    case PropertyID::TextDecorationColor:
-        return ColorStyleValue::create(layout_node.computed_values().text_decoration_color());
-    case PropertyID::Top:
-        return style_value_for_length_percentage(layout_node.computed_values().inset().top());
-    case PropertyID::Transform: {
-        // NOTE: The computed value for `transform` serializes as a single `matrix(...)` value, instead of
-        //       the original list of transform functions. So, we produce a StyleValue for that.
-        //       https://www.w3.org/TR/css-transforms-1/#serialization-of-the-computed-value
-        // FIXME: Computing values should happen in the StyleComputer!
-        auto transformations = layout_node.computed_values().transformations();
-        if (transformations.is_empty())
-            return IdentifierStyleValue::create(ValueID::None);
-
-        // The transform matrix is held by the StackingContext, so we need to make sure we have one first.
-        auto const* viewport = layout_node.document().paintable();
-        VERIFY(viewport);
-        const_cast<Painting::ViewportPaintable&>(*viewport).build_stacking_context_tree_if_needed();
-
-        VERIFY(layout_node.paintable());
-        auto const& paintable_box = verify_cast<Painting::PaintableBox const>(layout_node.paintable());
-        VERIFY(paintable_box->stacking_context());
-
-        // FIXME: This needs to serialize to matrix3d if the transformation matrix is a 3D matrix.
-        //        https://w3c.github.io/csswg-drafts/css-transforms-2/#serialization-of-the-computed-value
-        auto affine_matrix = paintable_box->stacking_context()->affine_transform_matrix();
-
-        StyleValueVector parameters;
-        parameters.ensure_capacity(6);
-        parameters.unchecked_append(NumberStyleValue::create(affine_matrix.a()));
-        parameters.unchecked_append(NumberStyleValue::create(affine_matrix.b()));
-        parameters.unchecked_append(NumberStyleValue::create(affine_matrix.c()));
-        parameters.unchecked_append(NumberStyleValue::create(affine_matrix.d()));
-        parameters.unchecked_append(NumberStyleValue::create(affine_matrix.e()));
-        parameters.unchecked_append(NumberStyleValue::create(affine_matrix.f()));
-
-        NonnullRefPtr<StyleValue> matrix_function = TransformationStyleValue::create(TransformFunction::Matrix, move(parameters));
-        // Elsewhere we always store the transform property's value as a StyleValueList of TransformationStyleValues,
-        // so this is just for consistency.
-        StyleValueVector matrix_functions { matrix_function };
-        return StyleValueList::create(move(matrix_functions), StyleValueList::Separator::Space);
-    }
-    case PropertyID::Width:
-        return style_value_for_size(layout_node.computed_values().width());
     case PropertyID::Invalid:
         return IdentifierStyleValue::create(ValueID::Invalid);
     case PropertyID::Custom: