2021-02-21 18:36:34 +02:00
/*
* Copyright ( c ) 2021 , the SerenityOS developers .
2021-11-18 17:34:53 +00:00
* Copyright ( c ) 2021 , Sam Atkins < atkinssj @ serenityos . org >
2022-08-07 15:46:44 +02:00
* Copyright ( c ) 2022 , Andreas Kling < kling @ serenityos . org >
2021-02-21 18:36:34 +02:00
*
2021-04-22 01:24:48 -07:00
* SPDX - License - Identifier : BSD - 2 - Clause
2021-02-21 18:36:34 +02:00
*/
2021-11-18 17:34:53 +00:00
# include <AK/Debug.h>
2021-02-21 18:36:34 +02:00
# include <AK/URL.h>
2022-08-07 15:46:44 +02:00
# include <LibWeb/Bindings/CSSImportRulePrototype.h>
# include <LibWeb/Bindings/WindowObject.h>
2021-02-21 18:36:34 +02:00
# include <LibWeb/CSS/CSSImportRule.h>
2021-11-18 17:34:53 +00:00
# include <LibWeb/CSS/Parser/Parser.h>
# include <LibWeb/DOM/Document.h>
# include <LibWeb/Loader/ResourceLoader.h>
2021-02-21 18:36:34 +02:00
namespace Web : : CSS {
2022-08-07 15:46:44 +02:00
CSSImportRule * CSSImportRule : : create ( AK : : URL url , DOM : : Document & document )
{
auto & window_object = document . preferred_window_object ( ) ;
return window_object . heap ( ) . allocate < CSSImportRule > ( window_object . realm ( ) , move ( url ) , document ) ;
}
2021-11-18 17:34:53 +00:00
CSSImportRule : : CSSImportRule ( AK : : URL url , DOM : : Document & document )
2022-08-07 15:46:44 +02:00
: CSSRule ( document . preferred_window_object ( ) )
, m_url ( move ( url ) )
2021-11-18 17:34:53 +00:00
, m_document ( document )
2021-02-21 18:36:34 +02:00
{
2022-08-07 15:46:44 +02:00
set_prototype ( & document . preferred_window_object ( ) . ensure_web_prototype < Bindings : : CSSImportRulePrototype > ( " CSSImportRule " ) ) ;
2021-11-18 17:34:53 +00:00
dbgln_if ( CSS_LOADER_DEBUG , " CSSImportRule: Loading import URL: {} " , m_url ) ;
auto request = LoadRequest : : create_for_url_on_page ( m_url , document . page ( ) ) ;
2022-02-15 14:10:16 +01:00
// NOTE: Mark this rule as delaying the document load event *before* calling set_resource()
// as it may trigger a synchronous resource_did_load() callback.
2021-12-05 15:28:38 +01:00
m_document_load_event_delayer . emplace ( document ) ;
2022-02-15 14:10:16 +01:00
set_resource ( ResourceLoader : : the ( ) . load_resource ( Resource : : Type : : Generic , request ) ) ;
2021-02-21 18:36:34 +02:00
}
2022-08-07 15:46:44 +02:00
void CSSImportRule : : visit_edges ( Cell : : Visitor & visitor )
{
Base : : visit_edges ( visitor ) ;
visitor . visit ( m_style_sheet ) ;
}
2021-10-15 19:38:39 +01:00
// https://www.w3.org/TR/cssom/#serialize-a-css-rule
2021-10-01 19:57:45 +02:00
String CSSImportRule : : serialized ( ) const
{
StringBuilder builder ;
// The result of concatenating the following:
// 1. The string "@import" followed by a single SPACE (U+0020).
builder . append ( " @import " sv ) ;
// 2. The result of performing serialize a URL on the rule’ s location.
// FIXME: Look into the correctness of this serialization
builder . append ( " url( " sv ) ;
builder . append ( m_url . to_string ( ) ) ;
builder . append ( ' ) ' ) ;
// FIXME: 3. If the rule’ s associated media list is not empty, a single SPACE (U+0020) followed by the result of performing serialize a media query list on the media list.
// 4. The string ";", i.e., SEMICOLON (U+003B).
builder . append ( ' ; ' ) ;
return builder . to_string ( ) ;
}
2021-11-18 17:34:53 +00:00
void CSSImportRule : : resource_did_fail ( )
{
dbgln_if ( CSS_LOADER_DEBUG , " CSSImportRule: Resource did fail. URL: {} " , resource ( ) - > url ( ) ) ;
m_document_load_event_delayer . clear ( ) ;
}
void CSSImportRule : : resource_did_load ( )
{
VERIFY ( resource ( ) ) ;
2021-12-05 15:28:38 +01:00
if ( ! m_document )
return ;
2021-11-18 17:34:53 +00:00
m_document_load_event_delayer . clear ( ) ;
if ( ! resource ( ) - > has_encoded_data ( ) ) {
dbgln_if ( CSS_LOADER_DEBUG , " CSSImportRule: Resource did load, no encoded data. URL: {} " , resource ( ) - > url ( ) ) ;
} else {
dbgln_if ( CSS_LOADER_DEBUG , " CSSImportRule: Resource did load, has encoded data. URL: {} " , resource ( ) - > url ( ) ) ;
}
2022-08-07 13:14:54 +02:00
auto * sheet = parse_css_stylesheet ( CSS : : Parser : : ParsingContext ( * m_document , resource ( ) - > url ( ) ) , resource ( ) - > encoded_data ( ) ) ;
2021-11-18 17:34:53 +00:00
if ( ! sheet ) {
dbgln_if ( CSS_LOADER_DEBUG , " CSSImportRule: Failed to parse stylesheet: {} " , resource ( ) - > url ( ) ) ;
return ;
}
2022-08-07 15:46:44 +02:00
m_style_sheet = sheet ;
2022-03-14 20:56:05 +01:00
2022-03-14 20:31:57 +01:00
m_document - > style_computer ( ) . invalidate_rule_cache ( ) ;
2022-03-14 20:56:05 +01:00
m_document - > invalidate_style ( ) ;
2021-11-18 17:34:53 +00:00
}
2021-02-21 18:36:34 +02:00
}