瀏覽代碼

LibWeb: Compute value for `content` property

Sam Atkins 3 年之前
父節點
當前提交
1de0ca3286

+ 15 - 0
Userland/Libraries/LibWeb/CSS/ComputedValues.h

@@ -87,11 +87,24 @@ struct BoxShadowData {
     CSS::BoxShadowPlacement placement { CSS::BoxShadowPlacement::Outer };
 };
 
+struct ContentData {
+    enum class Type {
+        Normal,
+        None,
+        String,
+    } type { Type::Normal };
+
+    // FIXME: Data is a list of identifiers, strings and image values.
+    String data {};
+    String alt_text {};
+};
+
 class ComputedValues {
 public:
     CSS::Float float_() const { return m_noninherited.float_; }
     CSS::Clear clear() const { return m_noninherited.clear; }
     CSS::Cursor cursor() const { return m_inherited.cursor; }
+    CSS::ContentData content() const { return m_noninherited.content; }
     CSS::PointerEvents pointer_events() const { return m_inherited.pointer_events; }
     CSS::Display display() const { return m_noninherited.display; }
     Optional<int> const& z_index() const { return m_noninherited.z_index; }
@@ -216,6 +229,7 @@ protected:
         Vector<BoxShadowData> box_shadow {};
         Vector<CSS::Transformation> transformations {};
         CSS::BoxSizing box_sizing { InitialValues::box_sizing() };
+        CSS::ContentData content;
     } m_noninherited;
 };
 
@@ -227,6 +241,7 @@ public:
     void set_font_size(float font_size) { m_inherited.font_size = font_size; }
     void set_font_weight(int font_weight) { m_inherited.font_weight = font_weight; }
     void set_color(const Color& color) { m_inherited.color = color; }
+    void set_content(ContentData const& content) { m_noninherited.content = content; }
     void set_cursor(CSS::Cursor cursor) { m_inherited.cursor = cursor; }
     void set_image_rendering(CSS::ImageRendering value) { m_inherited.image_rendering = value; }
     void set_pointer_events(CSS::PointerEvents value) { m_inherited.pointer_events = value; }

+ 53 - 0
Userland/Libraries/LibWeb/CSS/StyleProperties.cpp

@@ -538,6 +538,59 @@ Optional<CSS::Clear> StyleProperties::clear() const
     }
 }
 
+CSS::ContentData StyleProperties::content() const
+{
+    auto maybe_value = property(CSS::PropertyID::Content);
+    if (!maybe_value.has_value())
+        return CSS::ContentData {};
+
+    auto& value = maybe_value.value();
+    if (value->is_content()) {
+        auto& content_style_value = value->as_content();
+
+        CSS::ContentData content_data;
+
+        // FIXME: The content is a list of things: strings, identifiers or functions that return strings, and images.
+        //        So it can't always be represented as a single String, but may have to be multiple boxes.
+        //        For now, we'll just assume strings since that is easiest.
+        StringBuilder builder;
+        for (auto const& item : content_style_value.content().values()) {
+            if (item.is_string()) {
+                builder.append(item.to_string());
+            } else {
+                // TODO: Implement quotes, counters, images, and other things.
+            }
+        }
+        content_data.type = ContentData::Type::String;
+        content_data.data = builder.to_string();
+
+        if (content_style_value.has_alt_text()) {
+            StringBuilder alt_text_builder;
+            for (auto const& item : content_style_value.alt_text()->values()) {
+                if (item.is_string()) {
+                    alt_text_builder.append(item.to_string());
+                } else {
+                    // TODO: Implement counters
+                }
+            }
+            content_data.alt_text = alt_text_builder.to_string();
+        }
+
+        return content_data;
+    }
+
+    switch (value->to_identifier()) {
+    case ValueID::None:
+        return { ContentData::Type::None };
+    case ValueID::Normal:
+        return { ContentData::Type::Normal };
+    default:
+        break;
+    }
+
+    return CSS::ContentData {};
+}
+
 Optional<CSS::Cursor> StyleProperties::cursor() const
 {
     auto value = property(CSS::PropertyID::Cursor);

+ 1 - 0
Userland/Libraries/LibWeb/CSS/StyleProperties.h

@@ -50,6 +50,7 @@ public:
     CSS::Display display() const;
     Optional<CSS::Float> float_() const;
     Optional<CSS::Clear> clear() const;
+    CSS::ContentData content() const;
     Optional<CSS::Cursor> cursor() const;
     Optional<CSS::WhiteSpace> white_space() const;
     Optional<CSS::LineStyle> line_style(CSS::PropertyID) const;

+ 2 - 0
Userland/Libraries/LibWeb/Layout/Node.cpp

@@ -478,6 +478,8 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& specified_style)
     do_border_style(computed_values.border_right(), CSS::PropertyID::BorderRightWidth, CSS::PropertyID::BorderRightColor, CSS::PropertyID::BorderRightStyle);
     do_border_style(computed_values.border_bottom(), CSS::PropertyID::BorderBottomWidth, CSS::PropertyID::BorderBottomColor, CSS::PropertyID::BorderBottomStyle);
 
+    computed_values.set_content(specified_style.content());
+
     if (auto fill = specified_style.property(CSS::PropertyID::Fill); fill.has_value())
         computed_values.set_fill(fill.value()->to_color(*this));
     if (auto stroke = specified_style.property(CSS::PropertyID::Stroke); stroke.has_value())