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-09-24 16:34:04 -06:00
# include <LibWeb/Bindings/CSSImportRulePrototype.h>
# include <LibWeb/Bindings/Intrinsics.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>
2022-08-28 13:42:07 +02:00
# include <LibWeb/HTML/Window.h>
2021-11-18 17:34:53 +00:00
# include <LibWeb/Loader/ResourceLoader.h>
2021-02-21 18:36:34 +02:00
namespace Web : : CSS {
2023-02-12 22:47:47 +01:00
WebIDL : : ExceptionOr < JS : : NonnullGCPtr < CSSImportRule > > CSSImportRule : : create ( AK : : URL url , DOM : : Document & document )
2022-08-07 15:46:44 +02:00
{
2022-09-24 16:34:04 -06:00
auto & realm = document . realm ( ) ;
2023-02-12 22:47:47 +01:00
return MUST_OR_THROW_OOM ( realm . heap ( ) . allocate < CSSImportRule > ( realm , move ( url ) , document ) ) ;
2022-08-07 15:46:44 +02:00
}
2021-11-18 17:34:53 +00:00
CSSImportRule : : CSSImportRule ( AK : : URL url , DOM : : Document & document )
2022-09-24 16:34:04 -06:00
: CSSRule ( document . realm ( ) )
2022-08-07 15:46:44 +02:00
, m_url ( move ( url ) )
2021-11-18 17:34:53 +00:00
, m_document ( document )
2021-02-21 18:36:34 +02:00
{
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
}
2023-01-28 12:33:35 -05:00
JS : : ThrowCompletionOr < void > CSSImportRule : : initialize ( JS : : Realm & realm )
2023-01-10 06:28:20 -05:00
{
2023-01-28 12:33:35 -05:00
MUST_OR_THROW_OOM ( Base : : initialize ( realm ) ) ;
2023-01-10 06:28:20 -05:00
set_prototype ( & Bindings : : ensure_web_prototype < Bindings : : CSSImportRulePrototype > ( realm , " CSSImportRule " ) ) ;
2023-01-28 12:33:35 -05:00
return { } ;
2023-01-10 06:28:20 -05:00
}
2022-08-07 15:46:44 +02:00
void CSSImportRule : : visit_edges ( Cell : : Visitor & visitor )
{
Base : : visit_edges ( visitor ) ;
2022-09-03 15:44:06 +02:00
visitor . visit ( m_document ) ;
2022-08-07 15:46:44 +02:00
visitor . visit ( m_style_sheet ) ;
}
2021-10-15 19:38:39 +01:00
// https://www.w3.org/TR/cssom/#serialize-a-css-rule
2022-12-04 18:02:33 +00:00
DeprecatedString CSSImportRule : : serialized ( ) const
2021-10-01 19:57:45 +02:00
{
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 ) ;
2022-12-06 01:12:49 +00:00
builder . append ( m_url . to_deprecated_string ( ) ) ;
2021-10-01 19:57:45 +02:00
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 ( ' ; ' ) ;
2022-12-06 01:12:49 +00:00
return builder . to_deprecated_string ( ) ;
2021-10-01 19:57:45 +02:00
}
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
}