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
Notes: sideshowbarker 2024-07-17 06:46:15 +09:00
7 changed files with 44 additions and 15 deletions

View file

@ -14,13 +14,13 @@
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)
: StyleSheet(realm)
CSSStyleSheet::CSSStyleSheet(JS::Realm& realm, CSSRuleList& rules, MediaList& media, Optional<AK::URL> location)
: StyleSheet(realm, media)
, m_rules(&rules)
{
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
{
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)
{
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)

View file

@ -24,7 +24,7 @@ class CSSStyleSheet final
WEB_PLATFORM_OBJECT(CSSStyleSheet, StyleSheet);
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;
@ -50,7 +50,7 @@ public:
void set_style_sheet_list(Badge<StyleSheetList>, StyleSheetList*);
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;

View file

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

View file

@ -21,6 +21,7 @@
#include <LibWeb/CSS/CSSStyleRule.h>
#include <LibWeb/CSS/CSSStyleSheet.h>
#include <LibWeb/CSS/CSSSupportsRule.h>
#include <LibWeb/CSS/MediaList.h>
#include <LibWeb/CSS/Parser/Block.h>
#include <LibWeb/CSS/Parser/ComponentValue.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);
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)
@ -7111,7 +7112,7 @@ namespace Web {
CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const& context, StringView css, Optional<AK::URL> location)
{
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);
return parser.parse_as_css_stylesheet(location);
}

View file

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

View file

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

View file

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