summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibWeb/Bindings/CSSStyleDeclarationWrapperCustom.cpp35
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp59
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h46
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp12
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.h8
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleResolver.cpp6
-rw-r--r--Userland/Libraries/LibWeb/DOM/Window.cpp2
-rw-r--r--Userland/Libraries/LibWeb/Dump.cpp2
-rw-r--r--Userland/Libraries/LibWeb/Forward.h1
9 files changed, 104 insertions, 67 deletions
diff --git a/Userland/Libraries/LibWeb/Bindings/CSSStyleDeclarationWrapperCustom.cpp b/Userland/Libraries/LibWeb/Bindings/CSSStyleDeclarationWrapperCustom.cpp
index 6a20362c08..d5e572fcf3 100644
--- a/Userland/Libraries/LibWeb/Bindings/CSSStyleDeclarationWrapperCustom.cpp
+++ b/Userland/Libraries/LibWeb/Bindings/CSSStyleDeclarationWrapperCustom.cpp
@@ -4,9 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
-#include <AK/ScopeGuard.h>
#include <LibWeb/Bindings/CSSStyleDeclarationWrapper.h>
-#include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/DOM/Element.h>
namespace Web::Bindings {
@@ -28,10 +26,8 @@ JS::Value CSSStyleDeclarationWrapper::internal_get(JS::PropertyName const& name,
auto property_id = CSS::property_id_from_string(name.to_string());
if (property_id == CSS::PropertyID::Invalid)
return Base::internal_get(name, receiver);
- for (auto& property : impl().properties()) {
- if (property.property_id == property_id)
- return js_string(vm(), property.value->to_string());
- }
+ if (auto maybe_property = impl().property(property_id); maybe_property.has_value())
+ return js_string(vm(), maybe_property->value->to_string());
return js_string(vm(), String::empty());
}
@@ -48,32 +44,7 @@ bool CSSStyleDeclarationWrapper::internal_set(JS::PropertyName const& name, JS::
if (vm().exception())
return false;
- auto new_value = parse_css_value(CSS::ParsingContext {}, css_text, property_id);
- // FIXME: What are we supposed to do if we can't parse it?
- if (!new_value)
- return false;
-
- ScopeGuard style_invalidation_guard = [&] {
- auto& declaration = verify_cast<CSS::ElementInlineCSSStyleDeclaration>(impl());
- if (auto* element = declaration.element())
- element->invalidate_style();
- };
-
- // FIXME: I don't think '!important' is being handled correctly here..
-
- for (auto& property : impl().m_properties) {
- if (property.property_id == property_id) {
- property.value = new_value.release_nonnull();
- return true;
- }
- }
-
- impl().m_properties.append(CSS::StyleProperty {
- .property_id = property_id,
- .value = new_value.release_nonnull(),
- .important = false,
- });
- return true;
+ return impl().set_property(property_id, css_text);
}
}
diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp
index 1dd5929e45..c5a7b1c50f 100644
--- a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp
+++ b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp
@@ -5,21 +5,26 @@
*/
#include <LibWeb/CSS/CSSStyleDeclaration.h>
+#include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/DOM/Element.h>
namespace Web::CSS {
-CSSStyleDeclaration::CSSStyleDeclaration(Vector<StyleProperty>&& properties, HashMap<String, StyleProperty>&& custom_properties)
+PropertyOwningCSSStyleDeclaration::PropertyOwningCSSStyleDeclaration(Vector<StyleProperty> properties, HashMap<String, StyleProperty> custom_properties)
: m_properties(move(properties))
, m_custom_properties(move(custom_properties))
{
}
+PropertyOwningCSSStyleDeclaration::~PropertyOwningCSSStyleDeclaration()
+{
+}
+
CSSStyleDeclaration::~CSSStyleDeclaration()
{
}
-String CSSStyleDeclaration::item(size_t index) const
+String PropertyOwningCSSStyleDeclaration::item(size_t index) const
{
if (index >= m_properties.size())
return {};
@@ -27,13 +32,13 @@ String CSSStyleDeclaration::item(size_t index) const
}
ElementInlineCSSStyleDeclaration::ElementInlineCSSStyleDeclaration(DOM::Element& element)
- : CSSStyleDeclaration({}, {})
+ : PropertyOwningCSSStyleDeclaration({}, {})
, m_element(element.make_weak_ptr<DOM::Element>())
{
}
-ElementInlineCSSStyleDeclaration::ElementInlineCSSStyleDeclaration(DOM::Element& element, CSSStyleDeclaration& declaration)
- : CSSStyleDeclaration(move(declaration.m_properties), move(declaration.m_custom_properties))
+ElementInlineCSSStyleDeclaration::ElementInlineCSSStyleDeclaration(DOM::Element& element, PropertyOwningCSSStyleDeclaration& declaration)
+ : PropertyOwningCSSStyleDeclaration(move(declaration.m_properties), move(declaration.m_custom_properties))
, m_element(element.make_weak_ptr<DOM::Element>())
{
}
@@ -42,4 +47,48 @@ ElementInlineCSSStyleDeclaration::~ElementInlineCSSStyleDeclaration()
{
}
+size_t PropertyOwningCSSStyleDeclaration::length() const
+{
+ return m_properties.size();
+}
+
+Optional<StyleProperty> PropertyOwningCSSStyleDeclaration::property(PropertyID property_id) const
+{
+ for (auto& property : m_properties) {
+ if (property.property_id == property_id)
+ return property;
+ }
+ return {};
+}
+
+bool PropertyOwningCSSStyleDeclaration::set_property(PropertyID property_id, StringView css_text)
+{
+ auto new_value = parse_css_value(CSS::ParsingContext {}, css_text, property_id);
+ // FIXME: What are we supposed to do if we can't parse it?
+ if (!new_value)
+ return false;
+
+ ScopeGuard style_invalidation_guard = [&] {
+ auto& declaration = verify_cast<CSS::ElementInlineCSSStyleDeclaration>(*this);
+ if (auto* element = declaration.element())
+ element->invalidate_style();
+ };
+
+ // FIXME: I don't think '!important' is being handled correctly here..
+
+ for (auto& property : m_properties) {
+ if (property.property_id == property_id) {
+ property.value = new_value.release_nonnull();
+ return true;
+ }
+ }
+
+ m_properties.append(CSS::StyleProperty {
+ .property_id = property_id,
+ .value = new_value.release_nonnull(),
+ .important = false,
+ });
+ return true;
+}
+
}
diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h
index 37a29d838a..6c8410e3f1 100644
--- a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h
+++ b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h
@@ -26,35 +26,51 @@ class CSSStyleDeclaration
public:
using WrapperType = Bindings::CSSStyleDeclarationWrapper;
- static NonnullRefPtr<CSSStyleDeclaration> create(Vector<StyleProperty>&& properties, HashMap<String, StyleProperty>&& custom_properties)
+ virtual ~CSSStyleDeclaration();
+
+ virtual size_t length() const = 0;
+ virtual String item(size_t index) const = 0;
+
+ virtual Optional<StyleProperty> property(PropertyID) const = 0;
+ virtual bool set_property(PropertyID, StringView css_text) = 0;
+
+protected:
+ CSSStyleDeclaration() { }
+};
+
+class PropertyOwningCSSStyleDeclaration : public CSSStyleDeclaration {
+ friend class ElementInlineCSSStyleDeclaration;
+
+public:
+ static NonnullRefPtr<PropertyOwningCSSStyleDeclaration> create(Vector<StyleProperty> properties, HashMap<String, StyleProperty> custom_properties)
{
- return adopt_ref(*new CSSStyleDeclaration(move(properties), move(custom_properties)));
+ return adopt_ref(*new PropertyOwningCSSStyleDeclaration(move(properties), move(custom_properties)));
}
- virtual ~CSSStyleDeclaration();
+ virtual ~PropertyOwningCSSStyleDeclaration() override;
- const Vector<StyleProperty>& properties() const { return m_properties; }
- const Optional<StyleProperty> custom_property(const String& custom_property_name) const { return m_custom_properties.get(custom_property_name); }
- size_t custom_property_count() const { return m_custom_properties.size(); };
+ virtual size_t length() const override;
+ virtual String item(size_t index) const override;
- size_t length() const { return m_properties.size(); }
- String item(size_t index) const;
+ virtual Optional<StyleProperty> property(PropertyID) const override;
+ virtual bool set_property(PropertyID, StringView css_text) override;
+
+ const Vector<StyleProperty>& properties() const { return m_properties; }
+ Optional<StyleProperty> custom_property(const String& custom_property_name) const { return m_custom_properties.get(custom_property_name); }
+ size_t custom_property_count() const { return m_custom_properties.size(); }
protected:
- explicit CSSStyleDeclaration(Vector<StyleProperty>&&, HashMap<String, StyleProperty>&&);
+ explicit PropertyOwningCSSStyleDeclaration(Vector<StyleProperty>, HashMap<String, StyleProperty>);
private:
- friend class ElementInlineCSSStyleDeclaration;
- friend class Bindings::CSSStyleDeclarationWrapper;
-
Vector<StyleProperty> m_properties;
HashMap<String, StyleProperty> m_custom_properties;
};
-class ElementInlineCSSStyleDeclaration final : public CSSStyleDeclaration {
+class ElementInlineCSSStyleDeclaration final : public PropertyOwningCSSStyleDeclaration {
public:
static NonnullRefPtr<ElementInlineCSSStyleDeclaration> create(DOM::Element& element) { return adopt_ref(*new ElementInlineCSSStyleDeclaration(element)); }
- static NonnullRefPtr<ElementInlineCSSStyleDeclaration> create_and_take_properties_from(DOM::Element& element, CSSStyleDeclaration& declaration) { return adopt_ref(*new ElementInlineCSSStyleDeclaration(element, declaration)); }
+ static NonnullRefPtr<ElementInlineCSSStyleDeclaration> create_and_take_properties_from(DOM::Element& element, PropertyOwningCSSStyleDeclaration& declaration) { return adopt_ref(*new ElementInlineCSSStyleDeclaration(element, declaration)); }
virtual ~ElementInlineCSSStyleDeclaration() override;
DOM::Element* element() { return m_element.ptr(); }
@@ -62,7 +78,7 @@ public:
private:
explicit ElementInlineCSSStyleDeclaration(DOM::Element&);
- explicit ElementInlineCSSStyleDeclaration(DOM::Element&, CSSStyleDeclaration&);
+ explicit ElementInlineCSSStyleDeclaration(DOM::Element&, PropertyOwningCSSStyleDeclaration&);
WeakPtr<DOM::Element> m_element;
};
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
index 2f907ac40d..0fe7343138 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
@@ -1085,13 +1085,13 @@ Optional<StyleProperty> Parser::parse_a_declaration(TokenStream<T>& tokens)
return {};
}
-RefPtr<CSSStyleDeclaration> Parser::parse_as_list_of_declarations()
+RefPtr<PropertyOwningCSSStyleDeclaration> Parser::parse_as_list_of_declarations()
{
return parse_a_list_of_declarations(m_token_stream);
}
template<typename T>
-RefPtr<CSSStyleDeclaration> Parser::parse_a_list_of_declarations(TokenStream<T>& tokens)
+RefPtr<PropertyOwningCSSStyleDeclaration> Parser::parse_a_list_of_declarations(TokenStream<T>& tokens)
{
dbgln_if(CSS_PARSER_DEBUG, "Parser::parse_as_list_of_declarations");
@@ -1119,7 +1119,7 @@ RefPtr<CSSStyleDeclaration> Parser::parse_a_list_of_declarations(TokenStream<T>&
}
}
- return CSSStyleDeclaration::create(move(properties), move(custom_properties));
+ return PropertyOwningCSSStyleDeclaration::create(move(properties), move(custom_properties));
}
Optional<StyleComponentValueRule> Parser::parse_as_component_value()
@@ -1295,7 +1295,7 @@ RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<StyleRule> rule)
return {};
}
-RefPtr<CSSStyleDeclaration> Parser::convert_to_declaration(NonnullRefPtr<StyleBlockRule> block)
+RefPtr<PropertyOwningCSSStyleDeclaration> Parser::convert_to_declaration(NonnullRefPtr<StyleBlockRule> block)
{
dbgln_if(CSS_PARSER_DEBUG, "Parser::convert_to_declaration");
@@ -3487,10 +3487,10 @@ RefPtr<CSS::CSSStyleSheet> parse_css(CSS::ParsingContext const& context, StringV
return parser.parse_as_stylesheet();
}
-RefPtr<CSS::CSSStyleDeclaration> parse_css_declaration(CSS::ParsingContext const& context, StringView const& css)
+RefPtr<CSS::PropertyOwningCSSStyleDeclaration> parse_css_declaration(CSS::ParsingContext const& context, StringView const& css)
{
if (css.is_empty())
- return CSS::CSSStyleDeclaration::create({}, {});
+ return CSS::PropertyOwningCSSStyleDeclaration::create({}, {});
CSS::Parser parser(context, css);
return parser.parse_as_list_of_declarations();
}
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h
index 062830520e..7b9c566fbc 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h
@@ -86,7 +86,7 @@ public:
// Used in @supports conditions. [CSS3-CONDITIONAL]
Optional<StyleProperty> parse_as_declaration();
// For the contents of a style attribute, which parses text into the contents of a single style rule.
- RefPtr<CSSStyleDeclaration> parse_as_list_of_declarations();
+ RefPtr<PropertyOwningCSSStyleDeclaration> parse_as_list_of_declarations();
// For things that need to consume a single value, like the parsing rules for attr().
Optional<StyleComponentValueRule> parse_as_component_value();
// For the contents of presentational attributes, which parse text into a single declaration’s value, or for parsing a stand-alone selector [SELECT] or list of Media Queries [MEDIAQ], as in Selectors API or the media HTML attribute.
@@ -109,7 +109,7 @@ private:
template<typename T>
Optional<StyleProperty> parse_a_declaration(TokenStream<T>&);
template<typename T>
- RefPtr<CSSStyleDeclaration> parse_a_list_of_declarations(TokenStream<T>&);
+ RefPtr<PropertyOwningCSSStyleDeclaration> parse_a_list_of_declarations(TokenStream<T>&);
template<typename T>
Optional<StyleComponentValueRule> parse_a_component_value(TokenStream<T>&);
template<typename T>
@@ -160,7 +160,7 @@ private:
[[nodiscard]] NonnullRefPtr<StyleFunctionRule> consume_a_function(TokenStream<T>&);
[[nodiscard]] RefPtr<CSSRule> convert_to_rule(NonnullRefPtr<StyleRule>);
- [[nodiscard]] RefPtr<CSSStyleDeclaration> convert_to_declaration(NonnullRefPtr<StyleBlockRule>);
+ [[nodiscard]] RefPtr<PropertyOwningCSSStyleDeclaration> convert_to_declaration(NonnullRefPtr<StyleBlockRule>);
[[nodiscard]] Optional<StyleProperty> convert_to_style_property(StyleDeclarationRule&);
static Optional<float> try_parse_float(StringView string);
@@ -228,7 +228,7 @@ private:
namespace Web {
RefPtr<CSS::CSSStyleSheet> parse_css(CSS::ParsingContext const&, StringView const&);
-RefPtr<CSS::CSSStyleDeclaration> parse_css_declaration(CSS::ParsingContext const&, StringView const&);
+RefPtr<CSS::PropertyOwningCSSStyleDeclaration> parse_css_declaration(CSS::ParsingContext const&, StringView const&);
RefPtr<CSS::StyleValue> parse_css_value(CSS::ParsingContext const&, StringView const&, CSS::PropertyID property_id = CSS::PropertyID::Invalid);
Optional<CSS::SelectorList> parse_selector(CSS::ParsingContext const&, StringView const&);
diff --git a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp
index ef5a1e38e8..f3fa43e3cf 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp
@@ -514,7 +514,7 @@ StyleResolver::CustomPropertyResolutionTuple StyleResolver::resolve_custom_prope
if (match.specificity < parent_resolved.specificity)
continue;
- auto custom_property_style = match.rule->declaration().custom_property(custom_property_name);
+ auto custom_property_style = verify_cast<PropertyOwningCSSStyleDeclaration>(match.rule->declaration()).custom_property(custom_property_name);
if (custom_property_style.has_value()) {
element.add_custom_property(custom_property_name, { custom_property_style.value(), match.specificity });
return { custom_property_style.value(), match.specificity };
@@ -548,7 +548,7 @@ NonnullRefPtr<StyleProperties> StyleResolver::resolve_style(DOM::Element& elemen
sort_matching_rules(matching_rules);
for (auto& match : matching_rules) {
- for (auto& property : match.rule->declaration().properties()) {
+ for (auto& property : verify_cast<PropertyOwningCSSStyleDeclaration>(match.rule->declaration()).properties()) {
auto property_value = property.value;
if (property.value->is_custom_property()) {
auto prop = reinterpret_cast<CSS::CustomStyleValue const*>(property.value.ptr());
@@ -562,7 +562,7 @@ NonnullRefPtr<StyleProperties> StyleResolver::resolve_style(DOM::Element& elemen
}
}
- if (auto* inline_style = element.inline_style()) {
+ if (auto* inline_style = verify_cast<ElementInlineCSSStyleDeclaration>(element.inline_style())) {
for (auto& property : inline_style->properties()) {
set_property_expanding_shorthands(style, property.property_id, property.value, m_document);
}
diff --git a/Userland/Libraries/LibWeb/DOM/Window.cpp b/Userland/Libraries/LibWeb/DOM/Window.cpp
index bf969d811b..e3bbc741d5 100644
--- a/Userland/Libraries/LibWeb/DOM/Window.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Window.cpp
@@ -192,7 +192,7 @@ NonnullRefPtr<CSS::CSSStyleDeclaration> Window::get_computed_style(DOM::Element&
dbgln("Generating CSS computed style for {} @ {:p}", element.node_name(), &element);
Vector<CSS::StyleProperty> properties;
HashMap<String, CSS::StyleProperty> custom_properties;
- return CSS::CSSStyleDeclaration::create(move(properties), move(custom_properties));
+ return CSS::PropertyOwningCSSStyleDeclaration::create(move(properties), move(custom_properties));
}
NonnullRefPtr<CSS::MediaQueryList> Window::match_media(String media)
diff --git a/Userland/Libraries/LibWeb/Dump.cpp b/Userland/Libraries/LibWeb/Dump.cpp
index 6990dd2327..641443dca9 100644
--- a/Userland/Libraries/LibWeb/Dump.cpp
+++ b/Userland/Libraries/LibWeb/Dump.cpp
@@ -499,7 +499,7 @@ void dump_style_rule(StringBuilder& builder, CSS::CSSStyleRule const& rule)
dump_selector(builder, selector);
}
builder.append(" Declarations:\n");
- for (auto& property : rule.declaration().properties()) {
+ for (auto& property : verify_cast<CSS::PropertyOwningCSSStyleDeclaration>(rule.declaration()).properties()) {
builder.appendff(" {}: '{}'\n", CSS::string_from_property_id(property.property_id), property.value->to_string());
}
}
diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h
index 13114612db..f99f71c7ed 100644
--- a/Userland/Libraries/LibWeb/Forward.h
+++ b/Userland/Libraries/LibWeb/Forward.h
@@ -22,6 +22,7 @@ class CSSStyleRule;
class CSSStyleSheet;
class ElementInlineCSSStyleDeclaration;
class Length;
+class PropertyOwningCSSStyleDeclaration;
class Screen;
class Selector;
class StyleProperties;