summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-10-06 10:25:08 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-10-06 10:25:08 +0200
commit847072c2b10b17bc5eeb88037fb5173c33e70d73 (patch)
treef0cc00d4379cc62208a0cfcc4439427b236f5f16
parent83a6474d82a6ea516ab67eedabca1fe1f1dc29a3 (diff)
downloadserenity-847072c2b10b17bc5eeb88037fb5173c33e70d73.zip
LibHTML: Respect the link color set via <body link>
The default style for "a" tags now has { color: -libhtml-link; }. We implement this vendor-specific property by querying the containing document for the appropriate link color. Currently we only use the basic link color, but in the future this can be extended to remember visited links, etc.
-rw-r--r--Libraries/LibHTML/CSS/Default.css2
-rw-r--r--Libraries/LibHTML/CSS/StyleProperties.cpp6
-rw-r--r--Libraries/LibHTML/CSS/StyleProperties.h2
-rw-r--r--Libraries/LibHTML/CSS/StyleValue.cpp22
-rw-r--r--Libraries/LibHTML/CSS/StyleValue.h38
-rw-r--r--Libraries/LibHTML/Layout/LayoutBlock.cpp2
-rw-r--r--Libraries/LibHTML/Layout/LayoutNode.cpp4
-rw-r--r--Libraries/LibHTML/Layout/LayoutText.cpp2
-rw-r--r--Libraries/LibHTML/Parser/CSSParser.cpp3
9 files changed, 68 insertions, 13 deletions
diff --git a/Libraries/LibHTML/CSS/Default.css b/Libraries/LibHTML/CSS/Default.css
index 956a63942d..95c232d525 100644
--- a/Libraries/LibHTML/CSS/Default.css
+++ b/Libraries/LibHTML/CSS/Default.css
@@ -86,7 +86,7 @@ li {
}
a {
- color: #0000ff;
+ color: -libhtml-link;
text-decoration: underline;
}
diff --git a/Libraries/LibHTML/CSS/StyleProperties.cpp b/Libraries/LibHTML/CSS/StyleProperties.cpp
index 7fa1ba5714..754af996d6 100644
--- a/Libraries/LibHTML/CSS/StyleProperties.cpp
+++ b/Libraries/LibHTML/CSS/StyleProperties.cpp
@@ -29,12 +29,10 @@ String StyleProperties::string_or_fallback(const StringView& property_name, cons
return value.value()->to_string();
}
-Color StyleProperties::color_or_fallback(const StringView& property_name, Color fallback) const
+Color StyleProperties::color_or_fallback(const StringView& property_name, const Document& document, Color fallback) const
{
auto value = property(property_name);
if (!value.has_value())
return fallback;
- if (value.value()->type() != StyleValue::Type::Color)
- return fallback;
- return static_cast<ColorStyleValue&>(*value.value()).color();
+ return value.value()->to_color(document);
}
diff --git a/Libraries/LibHTML/CSS/StyleProperties.h b/Libraries/LibHTML/CSS/StyleProperties.h
index cb4771fe72..3fbb8ab1db 100644
--- a/Libraries/LibHTML/CSS/StyleProperties.h
+++ b/Libraries/LibHTML/CSS/StyleProperties.h
@@ -22,7 +22,7 @@ public:
Length length_or_fallback(const StringView& property_name, const Length& fallback) const;
String string_or_fallback(const StringView& property_name, const StringView& fallback) const;
- Color color_or_fallback(const StringView& property_name, Color fallback) const;
+ Color color_or_fallback(const StringView& property_name, const Document&, Color fallback) const;
private:
HashMap<String, NonnullRefPtr<StyleValue>> m_property_values;
diff --git a/Libraries/LibHTML/CSS/StyleValue.cpp b/Libraries/LibHTML/CSS/StyleValue.cpp
index e0d0a1764d..77ee2f9c58 100644
--- a/Libraries/LibHTML/CSS/StyleValue.cpp
+++ b/Libraries/LibHTML/CSS/StyleValue.cpp
@@ -1,4 +1,5 @@
-#include "StyleValue.h"
+#include <LibHTML/CSS/StyleValue.h>
+#include <LibHTML/DOM/Document.h>
StyleValue::StyleValue(Type type)
: m_type(type)
@@ -8,3 +9,22 @@ StyleValue::StyleValue(Type type)
StyleValue::~StyleValue()
{
}
+
+String IdentifierStyleValue::to_string() const
+{
+ switch (id()) {
+ case CSS::ValueID::Invalid:
+ return "(invalid)";
+ case CSS::ValueID::VendorSpecificLink:
+ return "-libhtml-link";
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
+Color IdentifierStyleValue::to_color(const Document& document) const
+{
+ if (id() == CSS::ValueID::VendorSpecificLink)
+ return document.link_color();
+ return {};
+}
diff --git a/Libraries/LibHTML/CSS/StyleValue.h b/Libraries/LibHTML/CSS/StyleValue.h
index 240acf15cf..3a0f43e69b 100644
--- a/Libraries/LibHTML/CSS/StyleValue.h
+++ b/Libraries/LibHTML/CSS/StyleValue.h
@@ -7,6 +7,15 @@
#include <LibDraw/Color.h>
#include <LibHTML/CSS/Length.h>
+class Document;
+
+namespace CSS {
+enum class ValueID {
+ Invalid,
+ VendorSpecificLink,
+};
+}
+
class StyleValue : public RefCounted<StyleValue> {
public:
virtual ~StyleValue();
@@ -18,6 +27,7 @@ public:
String,
Length,
Color,
+ Identifier,
};
Type type() const { return m_type; }
@@ -25,10 +35,11 @@ public:
bool is_inherit() const { return type() == Type::Inherit; }
bool is_initial() const { return type() == Type::Initial; }
bool is_color() const { return type() == Type::Color; }
+ bool is_identifier() const { return type() == Type::Identifier; }
virtual String to_string() const = 0;
virtual Length to_length() const { return {}; }
- virtual Color to_color() const { return {}; }
+ virtual Color to_color(const Document&) const { return {}; }
virtual bool is_auto() const { return false; }
@@ -122,7 +133,7 @@ public:
Color color() const { return m_color; }
String to_string() const override { return m_color.to_string(); }
- Color to_color() const override { return m_color; }
+ Color to_color(const Document&) const override { return m_color; }
private:
explicit ColorStyleValue(Color color)
@@ -133,3 +144,26 @@ private:
Color m_color;
};
+
+class IdentifierStyleValue final : public StyleValue {
+public:
+ static NonnullRefPtr<IdentifierStyleValue> create(CSS::ValueID id)
+ {
+ return adopt(*new IdentifierStyleValue(id));
+ }
+ virtual ~IdentifierStyleValue() override {}
+
+ CSS::ValueID id() const { return m_id; }
+
+ virtual String to_string() const override;
+ virtual Color to_color(const Document&) const override;
+
+private:
+ explicit IdentifierStyleValue(CSS::ValueID id)
+ : StyleValue(Type::Identifier)
+ , m_id(id)
+ {
+ }
+
+ CSS::ValueID m_id { CSS::ValueID::Invalid };
+};
diff --git a/Libraries/LibHTML/Layout/LayoutBlock.cpp b/Libraries/LibHTML/Layout/LayoutBlock.cpp
index a2a7bf9564..626ea2e737 100644
--- a/Libraries/LibHTML/Layout/LayoutBlock.cpp
+++ b/Libraries/LibHTML/Layout/LayoutBlock.cpp
@@ -205,7 +205,7 @@ void LayoutBlock::render(RenderingContext& context)
3
};
- context.painter().fill_rect(bullet_rect, style().color_or_fallback("color", Color::Black));
+ context.painter().fill_rect(bullet_rect, style().color_or_fallback("color", document(), Color::Black));
}
if (children_are_inline()) {
diff --git a/Libraries/LibHTML/Layout/LayoutNode.cpp b/Libraries/LibHTML/Layout/LayoutNode.cpp
index 704946bdcd..9373b521de 100644
--- a/Libraries/LibHTML/Layout/LayoutNode.cpp
+++ b/Libraries/LibHTML/Layout/LayoutNode.cpp
@@ -55,7 +55,7 @@ void LayoutNode::render(RenderingContext& context)
auto bgcolor = style().property("background-color");
if (bgcolor.has_value() && bgcolor.value()->is_color()) {
- context.painter().fill_rect(padded_rect, bgcolor.value()->to_color());
+ context.painter().fill_rect(padded_rect, bgcolor.value()->to_color(document()));
}
auto border_width_value = style().property("border-width");
@@ -63,7 +63,7 @@ void LayoutNode::render(RenderingContext& context)
auto border_style_value = style().property("border-style");
if (border_width_value.has_value() && border_color_value.has_value()) {
int border_width = border_width_value.value()->to_length().to_px();
- Color border_color = border_color_value.value()->to_color();
+ Color border_color = border_color_value.value()->to_color(document());
if (border_style_value.has_value() && border_style_value.value()->to_string() == "inset") {
// border-style: inset
diff --git a/Libraries/LibHTML/Layout/LayoutText.cpp b/Libraries/LibHTML/Layout/LayoutText.cpp
index 8c21338715..43b640f43f 100644
--- a/Libraries/LibHTML/Layout/LayoutText.cpp
+++ b/Libraries/LibHTML/Layout/LayoutText.cpp
@@ -93,7 +93,7 @@ void LayoutText::render_fragment(RenderingContext& context, const LineBoxFragmen
auto& painter = context.painter();
painter.set_font(*m_font);
- auto color = style().color_or_fallback("color", Color::Black);
+ auto color = style().color_or_fallback("color", document(), Color::Black);
auto text_decoration = style().string_or_fallback("text-decoration", "none");
bool is_underline = text_decoration == "underline";
diff --git a/Libraries/LibHTML/Parser/CSSParser.cpp b/Libraries/LibHTML/Parser/CSSParser.cpp
index 19ed848277..61489b5d53 100644
--- a/Libraries/LibHTML/Parser/CSSParser.cpp
+++ b/Libraries/LibHTML/Parser/CSSParser.cpp
@@ -41,6 +41,9 @@ NonnullRefPtr<StyleValue> parse_css_value(const StringView& view)
if (color.has_value())
return ColorStyleValue::create(color.value());
+ if (string == "-libhtml-link")
+ return IdentifierStyleValue::create(CSS::ValueID::VendorSpecificLink);
+
return StringStyleValue::create(string);
}