1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 05:47:34 +00:00

LibWeb: Respect media attribute of style tag

This commit is contained in:
Aliaksandr Kalenik 2022-10-23 21:05:34 +03:00 committed by Sam Atkins
parent bd4bb4fd51
commit 93238edf8f
7 changed files with 44 additions and 15 deletions

View file

@ -14,13 +14,13 @@
namespace Web::CSS { namespace Web::CSS {
CSSStyleSheet* CSSStyleSheet::create(JS::Realm& realm, CSSRuleList& rules, Optional<AK::URL> location) CSSStyleSheet* CSSStyleSheet::create(JS::Realm& realm, CSSRuleList& rules, MediaList& media, Optional<AK::URL> location)
{ {
return realm.heap().allocate<CSSStyleSheet>(realm, realm, rules, move(location)); return realm.heap().allocate<CSSStyleSheet>(realm, realm, rules, media, move(location));
} }
CSSStyleSheet::CSSStyleSheet(JS::Realm& realm, CSSRuleList& rules, Optional<AK::URL> location) CSSStyleSheet::CSSStyleSheet(JS::Realm& realm, CSSRuleList& rules, MediaList& media, Optional<AK::URL> location)
: StyleSheet(realm) : StyleSheet(realm, media)
, m_rules(&rules) , m_rules(&rules)
{ {
set_prototype(&Bindings::ensure_web_prototype<Bindings::CSSStyleSheetPrototype>(realm, "CSSStyleSheet")); set_prototype(&Bindings::ensure_web_prototype<Bindings::CSSStyleSheetPrototype>(realm, "CSSStyleSheet"));
@ -99,12 +99,23 @@ WebIDL::ExceptionOr<void> CSSStyleSheet::remove_rule(unsigned index)
void CSSStyleSheet::for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const void CSSStyleSheet::for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const
{ {
m_rules->for_each_effective_style_rule(callback); if (m_media.matches()) {
m_rules->for_each_effective_style_rule(callback);
}
} }
bool CSSStyleSheet::evaluate_media_queries(HTML::Window const& window) bool CSSStyleSheet::evaluate_media_queries(HTML::Window const& window)
{ {
return m_rules->evaluate_media_queries(window); bool any_media_queries_changed_match_state = false;
bool did_match = m_media.matches();
bool now_matches = m_media.evaluate(window);
if (did_match != now_matches)
any_media_queries_changed_match_state = true;
if (now_matches && m_rules->evaluate_media_queries(window))
any_media_queries_changed_match_state = true;
return any_media_queries_changed_match_state;
} }
void CSSStyleSheet::set_style_sheet_list(Badge<StyleSheetList>, StyleSheetList* list) void CSSStyleSheet::set_style_sheet_list(Badge<StyleSheetList>, StyleSheetList* list)

View file

@ -24,7 +24,7 @@ class CSSStyleSheet final
WEB_PLATFORM_OBJECT(CSSStyleSheet, StyleSheet); WEB_PLATFORM_OBJECT(CSSStyleSheet, StyleSheet);
public: public:
static CSSStyleSheet* create(JS::Realm&, CSSRuleList& rules, Optional<AK::URL> location); static CSSStyleSheet* create(JS::Realm&, CSSRuleList& rules, MediaList& media, Optional<AK::URL> location);
virtual ~CSSStyleSheet() override = default; virtual ~CSSStyleSheet() override = default;
@ -50,7 +50,7 @@ public:
void set_style_sheet_list(Badge<StyleSheetList>, StyleSheetList*); void set_style_sheet_list(Badge<StyleSheetList>, StyleSheetList*);
private: private:
CSSStyleSheet(JS::Realm&, CSSRuleList&, Optional<AK::URL> location); CSSStyleSheet(JS::Realm&, CSSRuleList&, MediaList&, Optional<AK::URL> location);
virtual void visit_edges(Cell::Visitor&) override; virtual void visit_edges(Cell::Visitor&) override;

View file

@ -85,6 +85,10 @@ bool MediaList::evaluate(HTML::Window const& window)
bool MediaList::matches() const bool MediaList::matches() const
{ {
if (m_media.is_empty()) {
return true;
}
for (auto& media : m_media) { for (auto& media : m_media) {
if (media.matches()) if (media.matches())
return true; return true;

View file

@ -21,6 +21,7 @@
#include <LibWeb/CSS/CSSStyleRule.h> #include <LibWeb/CSS/CSSStyleRule.h>
#include <LibWeb/CSS/CSSStyleSheet.h> #include <LibWeb/CSS/CSSStyleSheet.h>
#include <LibWeb/CSS/CSSSupportsRule.h> #include <LibWeb/CSS/CSSSupportsRule.h>
#include <LibWeb/CSS/MediaList.h>
#include <LibWeb/CSS/Parser/Block.h> #include <LibWeb/CSS/Parser/Block.h>
#include <LibWeb/CSS/Parser/ComponentValue.h> #include <LibWeb/CSS/Parser/ComponentValue.h>
#include <LibWeb/CSS/Parser/DeclarationOrAtRule.h> #include <LibWeb/CSS/Parser/DeclarationOrAtRule.h>
@ -127,7 +128,7 @@ CSSStyleSheet* Parser::parse_as_css_stylesheet(Optional<AK::URL> location)
} }
auto* rule_list = CSSRuleList::create(m_context.realm(), rules); auto* rule_list = CSSRuleList::create(m_context.realm(), rules);
return CSSStyleSheet::create(m_context.realm(), *rule_list, move(location)); return CSSStyleSheet::create(m_context.realm(), *rule_list, *MediaList::create(m_context.realm(), {}), move(location));
} }
Optional<SelectorList> Parser::parse_as_selector(SelectorParsingMode parsing_mode) Optional<SelectorList> Parser::parse_as_selector(SelectorParsingMode parsing_mode)
@ -7111,7 +7112,7 @@ namespace Web {
CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const& context, StringView css, Optional<AK::URL> location) CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const& context, StringView css, Optional<AK::URL> location)
{ {
if (css.is_empty()) if (css.is_empty())
return CSS::CSSStyleSheet::create(context.realm(), *CSS::CSSRuleList::create_empty(context.realm()), location); return CSS::CSSStyleSheet::create(context.realm(), *CSS::CSSRuleList::create_empty(context.realm()), *CSS::MediaList::create(context.realm(), {}), location);
CSS::Parser::Parser parser(context, css); CSS::Parser::Parser parser(context, css);
return parser.parse_as_css_stylesheet(location); return parser.parse_as_css_stylesheet(location);
} }

View file

@ -11,8 +11,9 @@
namespace Web::CSS { namespace Web::CSS {
StyleSheet::StyleSheet(JS::Realm& realm) StyleSheet::StyleSheet(JS::Realm& realm, MediaList& media)
: PlatformObject(realm) : PlatformObject(realm)
, m_media(media)
{ {
} }
@ -21,6 +22,7 @@ void StyleSheet::visit_edges(Cell::Visitor& visitor)
Base::visit_edges(visitor); Base::visit_edges(visitor);
visitor.visit(m_owner_node); visitor.visit(m_owner_node);
visitor.visit(m_parent_style_sheet); visitor.visit(m_parent_style_sheet);
visitor.visit(m_media);
} }
void StyleSheet::set_owner_node(DOM::Element* element) void StyleSheet::set_owner_node(DOM::Element* element)

View file

@ -8,6 +8,7 @@
#pragma once #pragma once
#include <LibWeb/Bindings/PlatformObject.h> #include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/CSS/MediaList.h>
#include <LibWeb/Forward.h> #include <LibWeb/Forward.h>
namespace Web::CSS { namespace Web::CSS {
@ -32,7 +33,16 @@ public:
void set_title(String title) { m_title = move(title); } void set_title(String title) { m_title = move(title); }
void set_type(String type) { m_type_string = move(type); } void set_type(String type) { m_type_string = move(type); }
void set_media(String media) { m_media_string = move(media); }
MediaList* media() const
{
return &m_media;
}
void set_media(String media)
{
m_media.set_media_text(media);
}
bool is_alternate() const { return m_alternate; } bool is_alternate() const { return m_alternate; }
void set_alternate(bool alternate) { m_alternate = alternate; } void set_alternate(bool alternate) { m_alternate = alternate; }
@ -46,9 +56,11 @@ public:
void set_parent_css_style_sheet(CSSStyleSheet*); void set_parent_css_style_sheet(CSSStyleSheet*);
protected: protected:
explicit StyleSheet(JS::Realm&); explicit StyleSheet(JS::Realm&, MediaList& media);
virtual void visit_edges(Cell::Visitor&) override; virtual void visit_edges(Cell::Visitor&) override;
MediaList& m_media;
private: private:
JS::GCPtr<DOM::Element> m_owner_node; JS::GCPtr<DOM::Element> m_owner_node;
JS::GCPtr<CSSStyleSheet> m_parent_style_sheet; JS::GCPtr<CSSStyleSheet> m_parent_style_sheet;
@ -56,7 +68,6 @@ private:
String m_location; String m_location;
String m_title; String m_title;
String m_type_string; String m_type_string;
String m_media_string;
bool m_disabled { false }; bool m_disabled { false };
bool m_alternate { false }; bool m_alternate { false };

View file

@ -12,7 +12,7 @@ interface StyleSheet {
readonly attribute USVString? href; readonly attribute USVString? href;
readonly attribute CSSStyleSheet? parentStyleSheet; readonly attribute CSSStyleSheet? parentStyleSheet;
readonly attribute DOMString? title; readonly attribute DOMString? title;
// [SameObject, PutForwards=mediaText] readonly attribute MediaList media; [SameObject, PutForwards=mediaText] readonly attribute MediaList media;
attribute boolean disabled; attribute boolean disabled;
}; };