2020-08-01 03:05:43 +01:00
/*
2021-04-28 22:46:44 +02:00
* Copyright ( c ) 2020 , the SerenityOS developers .
2023-07-28 02:20:57 +01:00
* Copyright ( c ) 2023 , Luke Wilde < lukew @ serenityos . org >
2020-08-01 03:05:43 +01:00
*
2021-04-22 01:24:48 -07:00
* SPDX - License - Identifier : BSD - 2 - Clause
2020-08-01 03:05:43 +01:00
*/
2024-11-05 09:12:11 +01:00
# include <AK/GenericLexer.h>
2024-04-27 12:09:58 +12:00
# include <LibWeb/Bindings/HTMLMetaElementPrototype.h>
2022-09-30 17:16:16 -06:00
# include <LibWeb/Bindings/Intrinsics.h>
2023-09-19 01:51:48 +02:00
# include <LibWeb/CSS/Parser/Parser.h>
# include <LibWeb/CSS/Parser/ParsingContext.h>
# include <LibWeb/CSS/PropertyID.h>
2024-08-14 16:37:02 +01:00
# include <LibWeb/CSS/StyleValues/CSSColorValue.h>
2023-07-28 02:20:57 +01:00
# include <LibWeb/DOM/Document.h>
2020-08-01 03:05:43 +01:00
# include <LibWeb/HTML/HTMLMetaElement.h>
2023-09-19 01:51:48 +02:00
# include <LibWeb/Infra/CharacterTypes.h>
# include <LibWeb/Page/Page.h>
2020-08-01 03:05:43 +01:00
namespace Web : : HTML {
2023-11-19 19:47:52 +01:00
JS_DEFINE_ALLOCATOR ( HTMLMetaElement ) ;
2022-02-18 21:00:52 +01:00
HTMLMetaElement : : HTMLMetaElement ( DOM : : Document & document , DOM : : QualifiedName qualified_name )
2021-02-07 11:20:15 +01:00
: HTMLElement ( document , move ( qualified_name ) )
2020-08-01 03:05:43 +01:00
{
}
2022-03-14 13:21:51 -06:00
HTMLMetaElement : : ~ HTMLMetaElement ( ) = default ;
2020-08-01 03:05:43 +01:00
2023-08-07 08:41:28 +02:00
void HTMLMetaElement : : initialize ( JS : : Realm & realm )
2023-01-10 06:28:20 -05:00
{
2023-08-07 08:41:28 +02:00
Base : : initialize ( realm ) ;
2024-03-16 13:13:08 +01:00
WEB_SET_PROTOTYPE_FOR_INTERFACE ( HTMLMetaElement ) ;
2023-01-10 06:28:20 -05:00
}
2023-07-28 02:20:57 +01:00
Optional < HTMLMetaElement : : HttpEquivAttributeState > HTMLMetaElement : : http_equiv_state ( ) const
{
2024-01-16 19:04:45 +01:00
auto value = get_attribute_value ( HTML : : AttributeNames : : http_equiv ) ;
2023-07-28 02:20:57 +01:00
# define __ENUMERATE_HTML_META_HTTP_EQUIV_ATTRIBUTE(keyword, state) \
2024-09-13 11:35:34 +02:00
if ( value . equals_ignoring_ascii_case ( keyword # # sv ) ) \
2023-07-28 02:20:57 +01:00
return HTMLMetaElement : : HttpEquivAttributeState : : state ;
ENUMERATE_HTML_META_HTTP_EQUIV_ATTRIBUTES
# undef __ENUMERATE_HTML_META_HTTP_EQUIV_ATTRIBUTE
return OptionalNone { } ;
}
void HTMLMetaElement : : inserted ( )
{
Base : : inserted ( ) ;
2023-09-19 01:51:48 +02:00
// https://html.spec.whatwg.org/multipage/semantics.html#meta-theme-color
// 1. To obtain a page's theme color, user agents must run the following steps:
// * The element is in a document tree
// * The element has a name attribute, whose value is an ASCII case-insensitive match for theme-color
// * The element has a content attribute
auto content = attribute ( AttributeNames : : content ) ;
2024-01-13 20:12:25 +13:00
if ( name ( ) . has_value ( ) & & name ( ) - > equals_ignoring_ascii_case ( " theme-color " sv ) & & content . has_value ( ) ) {
2023-09-19 01:51:48 +02:00
auto context = CSS : : Parser : : ParsingContext { document ( ) } ;
// 2. For each element in candidate elements:
// 1. If element has a media attribute and the value of element's media attribute does not match the environment, then continue.
auto media = attribute ( AttributeNames : : media ) ;
if ( media . has_value ( ) ) {
auto query = parse_media_query ( context , media . value ( ) ) ;
2024-03-10 08:41:18 +01:00
if ( document ( ) . window ( ) & & ! query - > evaluate ( * document ( ) . window ( ) ) )
2023-09-19 01:51:48 +02:00
return ;
}
// 2. Let value be the result of stripping leading and trailing ASCII whitespace from the value of element's content attribute.
auto value = content - > bytes_as_string_view ( ) . trim ( Infra : : ASCII_WHITESPACE ) ;
// 3. Let color be the result of parsing value.
auto css_value = parse_css_value ( context , value , CSS : : PropertyID : : Color ) ;
if ( css_value . is_null ( ) | | ! css_value - > is_color ( ) )
return ;
2024-08-16 16:42:16 +01:00
auto color = css_value - > to_color ( { } ) ; // TODO: Pass a layout node?
2023-09-19 01:51:48 +02:00
// 4. If color is not failure, then return color.
2023-12-15 15:41:28 +01:00
document ( ) . page ( ) . client ( ) . page_did_change_theme_color ( color ) ;
2023-09-19 01:51:48 +02:00
return ;
}
2023-07-28 02:20:57 +01:00
// https://html.spec.whatwg.org/multipage/semantics.html#pragma-directives
// When a meta element is inserted into the document, if its http-equiv attribute is present and represents one of
// the above states, then the user agent must run the algorithm appropriate for that state, as described in the
// following list:
auto http_equiv = http_equiv_state ( ) ;
if ( http_equiv . has_value ( ) ) {
switch ( http_equiv . value ( ) ) {
2024-09-13 11:44:35 +02:00
case HttpEquivAttributeState : : EncodingDeclaration :
// https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-content-type
// The Encoding declaration state is just an alternative form of setting the charset attribute: it is a character encoding declaration.
// This state's user agent requirements are all handled by the parsing section of the specification.
break ;
2023-07-28 02:20:57 +01:00
case HttpEquivAttributeState : : Refresh : {
// https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-refresh
// 1. If the meta element has no content attribute, or if that attribute's value is the empty string, then return.
// 2. Let input be the value of the element's content attribute.
if ( ! has_attribute ( AttributeNames : : content ) )
break ;
2024-01-16 19:04:45 +01:00
auto input = get_attribute_value ( AttributeNames : : content ) ;
2023-07-28 02:20:57 +01:00
if ( input . is_empty ( ) )
break ;
// 3. Run the shared declarative refresh steps with the meta element's node document, input, and the meta element.
document ( ) . shared_declarative_refresh_steps ( input , this ) ;
break ;
}
2024-09-13 11:44:35 +02:00
case HttpEquivAttributeState : : SetCookie :
// https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-set-cookie
// This pragma is non-conforming and has no effect.
// User agents are required to ignore this pragma.
break ;
case HttpEquivAttributeState : : XUACompatible :
// https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-x-ua-compatible
// In practice, this pragma encourages Internet Explorer to more closely follow the specifications.
// For meta elements with an http-equiv attribute in the X-UA-Compatible state, the content attribute must have a value that is an ASCII case-insensitive match for the string "IE=edge".
// User agents are required to ignore this pragma.
break ;
2024-11-05 09:12:11 +01:00
case HttpEquivAttributeState : : ContentLanguage : {
// https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-content-language
// 1. If the meta element has no content attribute, then return.
if ( ! has_attribute ( AttributeNames : : content ) )
break ;
// 2. If the element's content attribute contains a U+002C COMMA character (,) then return.
auto content = get_attribute_value ( AttributeNames : : content ) ;
if ( content . contains ( " , " sv ) )
break ;
// 3. Let input be the value of the element's content attribute.
// 4. Let position point at the first character of input.
GenericLexer lexer { content } ;
// 5. Skip ASCII whitespace within input given position.
lexer . ignore_while ( Web : : Infra : : is_ascii_whitespace ) ;
// 6. Collect a sequence of code points that are not ASCII whitespace from input given position.
// 7. Let candidate be the string that resulted from the previous step.
auto candidate = lexer . consume_until ( Web : : Infra : : is_ascii_whitespace ) ;
// 8. If candidate is the empty string, return.
if ( candidate . is_empty ( ) )
break ;
// 9. Set the pragma-set default language to candidate.
auto language = String : : from_utf8_without_validation ( candidate . bytes ( ) ) ;
document ( ) . set_pragma_set_default_language ( language ) ;
break ;
}
2023-07-28 02:20:57 +01:00
default :
2024-01-16 19:04:45 +01:00
dbgln ( " FIXME: Implement '{}' http-equiv state " , get_attribute_value ( AttributeNames : : http_equiv ) ) ;
2023-07-28 02:20:57 +01:00
break ;
}
}
}
2020-08-01 03:05:43 +01:00
}